]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG/FLOW/Base/AliFlowAnalysisWithMultiparticleCorrelations.cxx
Merge branch 'feature-movesplit'
[u/mrichter/AliRoot.git] / PWG / FLOW / Base / AliFlowAnalysisWithMultiparticleCorrelations.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  * flow analysis with multi-particle *
18  *           correlations            * 
19  *                                   * 
20  * author: Ante Bilandzic            * 
21  *        (abilandzic@gmail.com)     *
22  ************************************/ 
23
24 #define AliFlowAnalysisWithMultiparticleCorrelations_cxx
25
26 #include "AliFlowAnalysisWithMultiparticleCorrelations.h"
27
28 using std::endl;
29 using std::cout;
30 using std::flush;
31 using std::ofstream;
32 using std::ios;
33
34 //================================================================================================================
35
36 ClassImp(AliFlowAnalysisWithMultiparticleCorrelations)
37
38 AliFlowAnalysisWithMultiparticleCorrelations::AliFlowAnalysisWithMultiparticleCorrelations(): 
39  // 0.) Base:
40  fHistList(NULL),
41  fInternalFlagsPro(NULL),
42  fUseInternalFlags(kFALSE),
43  fMinNoRPs(-44),
44  fMaxNoRPs(-44),
45  fExactNoRPs(-44),
46  fPropagateError(kTRUE),
47  fAnalysisTag(""),
48  fDumpThePoints(kFALSE),
49  fMaxNoEventsPerFile(100),
50  // 1.) Control histograms:
51  fControlHistogramsList(NULL),
52  fControlHistogramsFlagsPro(NULL),
53  fFillControlHistograms(kFALSE),
54  fFillKinematicsHist(kFALSE),
55  fFillMultDistributionsHist(kFALSE),   
56  fFillMultCorrelationsHist(kFALSE),
57  // 2.) Q-vector:
58  fQvectorList(NULL),       
59  fQvectorFlagsPro(NULL),
60  fCalculateQvector(kFALSE),
61  fCalculateDiffQvectors(kFALSE),
62  // 3.) Correlations:
63  fCorrelationsList(NULL),
64  fCorrelationsFlagsPro(NULL),
65  fCalculateCorrelations(kFALSE),
66  fMaxHarmonic(6), // TBI this shall not be hardwired in the ideal world...
67  fMaxCorrelator(8),
68  fCalculateIsotropic(kFALSE),
69  fCalculateSame(kFALSE),
70  fSkipZeroHarmonics(kFALSE),
71  fCalculateSameIsotropic(kFALSE),
72  fCalculateAll(kFALSE),
73  fDontGoBeyond(0),
74  fCalculateOnlyForHarmonicQC(kFALSE),
75  fCalculateOnlyForSC(kFALSE),
76  fCalculateOnlyCos(kFALSE),
77  fCalculateOnlySin(kFALSE),
78  // 4.) Event-by-event cumulants:
79  fEbECumulantsList(NULL),
80  fEbECumulantsFlagsPro(NULL),
81  fCalculateEbECumulants(kFALSE),
82  // 5.) Weights:
83  fWeightsList(NULL),
84  fWeightsFlagsPro(NULL),
85  // 6.) Nested loops:
86  fNestedLoopsList(NULL),
87  fNestedLoopsFlagsPro(NULL),
88  fCrossCheckWithNestedLoops(kFALSE),
89  fCrossCheckDiffWithNestedLoops(kFALSE),
90  fNestedLoopsResultsCosPro(NULL),
91  fNestedLoopsResultsSinPro(NULL),
92  fNestedLoopsDiffResultsPro(NULL),
93  // 7.) 'Standard candles':
94  fStandardCandlesList(NULL),
95  fStandardCandlesFlagsPro(NULL),
96  fCalculateStandardCandles(kFALSE),
97  fPropagateErrorSC(kTRUE),
98  fStandardCandlesHist(NULL),
99  fProductsSCPro(NULL), 
100  // 8.) Q-cumulants:
101  fQcumulantsList(NULL),
102  fQcumulantsFlagsPro(NULL),
103  fCalculateQcumulants(kFALSE),
104  fHarmonicQC(2),
105  fPropagateErrorQC(kTRUE),
106  fQcumulantsHist(NULL),
107  fReferenceFlowHist(NULL),
108  fProductsQCPro(NULL),
109  // 9.) Differential correlations:
110  fDiffCorrelationsList(NULL),
111  fDiffCorrelationsFlagsPro(NULL),
112  fCalculateDiffCorrelations(kFALSE),
113  fCalculateDiffCos(kTRUE),
114  fCalculateDiffSin(kFALSE),
115  fCalculateDiffCorrelationsVsPt(kTRUE),
116  fUseDefaultBinning(kTRUE),
117  fnDiffBins(-44),
118  fRangesDiffBins(NULL),
119  fDiffBinNo(-1)
120  {
121   // Constructor.  
122   
123   // a) Book grandmother of all lists;
124   // b) Initialize all arrays.
125
126   // a) Book grandmother of all lists:
127   fHistList = new TList();
128   fHistList->SetName("cobjMPC");
129   fHistList->SetOwner(kTRUE);
130
131   // b) Initialize all arrays:
132   this->InitializeArraysForControlHistograms();
133   this->InitializeArraysForQvector();
134   this->InitializeArraysForCorrelations();
135   this->InitializeArraysForEbECumulants();
136   this->InitializeArraysForWeights();
137   this->InitializeArraysForQcumulants();
138   this->InitializeArraysForDiffCorrelations(); 
139   this->InitializeArraysForNestedLoops(); 
140
141  } // end of AliFlowAnalysisWithMultiparticleCorrelations::AliFlowAnalysisWithMultiparticleCorrelations()
142  
143 //================================================================================================================  
144
145 AliFlowAnalysisWithMultiparticleCorrelations::~AliFlowAnalysisWithMultiparticleCorrelations()
146 {
147  // Destructor.
148  
149  delete fHistList;
150
151 } // end of AliFlowAnalysisWithMultiparticleCorrelations::~AliFlowAnalysisWithMultiparticleCorrelations()
152
153 //================================================================================================================
154
155 void AliFlowAnalysisWithMultiparticleCorrelations::Init()
156 {
157  // Well, this is method Init().
158
159  // a) Trick to avoid name clashes, part 1; 
160  // b) Cross-check the initial settings before starting this adventure;
161  // c) Book all objects;
162  // d) Set all flags;
163  // *) Trick to avoid name clashes, part 2. 
164
165  // a) Trick to avoid name clashes, part 1: 
166  Bool_t oldHistAddStatus = TH1::AddDirectoryStatus(); 
167  TH1::AddDirectory(kFALSE);
168  
169  // b) Cross-check the initial settings before starting this adventure:
170  this->CrossCheckSettings();
171
172  // c) Book all objects:
173  this->BookAndNestAllLists();
174  this->BookEverythingForBase();
175  this->BookEverythingForControlHistograms();
176  this->BookEverythingForQvector();
177  this->BookEverythingForWeights();
178  this->BookEverythingForCorrelations();
179  this->BookEverythingForEbECumulants();
180  this->BookEverythingForNestedLoops();
181  this->BookEverythingForStandardCandles();
182  this->BookEverythingForQcumulants();
183  this->BookEverythingForDiffCorrelations(); 
184
185  // d) Set all flags:
186  // ... 
187
188  // *) Trick to avoid name clashes, part 2:
189  TH1::AddDirectory(oldHistAddStatus);
190
191 } // end of void AliFlowAnalysisWithMultiparticleCorrelations::Init()
192
193 //================================================================================================================
194
195 void AliFlowAnalysisWithMultiparticleCorrelations::Make(AliFlowEventSimple *anEvent)
196 {
197  // Running over data only in this method.
198  
199  // a) Cross-check internal flags;
200  // b) Cross-check all pointers used in this method;
201  // c) Fill control histograms;
202  // d) Fill Q-vector components;
203  // e) Calculate multi-particle correlations from Q-vector components; 
204  // f) Calculate e-b-e cumulants; 
205  // g) Reset Q-vector components;
206  // h) Cross-check results with nested loops;
207  // i) Dump the points.
208
209  // a) Cross-check internal flags:
210  if(fUseInternalFlags){if(!this->CrossCheckInternalFlags(anEvent)){return;}}
211
212  // b) Cross-check all pointers used in this method:
213  this->CrossCheckPointersUsedInMake(); // TBI shall I call this method first  
214
215  // c) Fill control histograms:
216  if(fFillControlHistograms){this->FillControlHistograms(anEvent);}
217  
218  // d) Fill Q-vector components:
219  if(fCalculateQvector||fCalculateDiffQvectors){this->FillQvector(anEvent);}
220
221  // e) Calculate multi-particle correlations from Q-vector components:
222  if(fCalculateCorrelations){this->CalculateCorrelations(anEvent);}
223  if(fCalculateDiffCorrelations){this->CalculateDiffCorrelations(anEvent);}
224
225  // f) Calculate e-b-e cumulants: 
226  if(fCalculateEbECumulants){this->CalculateEbECumulants(anEvent);}
227
228  // g) Reset Q-vector components:
229  if(fCalculateQvector||fCalculateDiffQvectors){this->ResetQvector();}
230
231  // h) Cross-check results with nested loops:
232  if(fCrossCheckWithNestedLoops){this->CrossCheckWithNestedLoops(anEvent);}
233  if(fCrossCheckDiffWithNestedLoops){this->CrossCheckDiffWithNestedLoops(anEvent);}
234
235  // i) Dump the points:
236  if(fDumpThePoints){this->DumpThePoints(anEvent);}
237  
238 } // end of AliFlowAnalysisWithMultiparticleCorrelations::Make(AliFlowEventSimple *anEvent)
239
240 //=======================================================================================================================
241
242 void AliFlowAnalysisWithMultiparticleCorrelations::Finish()
243 {
244  // Closing the curtains. 
245
246  // a) Cross-check pointers used in this method;
247  // b) Calculate 'standard candles';
248  // c) Calculate Q-cumulants.
249  
250  // a) Cross-check pointers used in this method:
251  this->CrossCheckPointersUsedInFinish();
252
253  // b) Calculate 'standard candles':
254  if(fCalculateStandardCandles){this->CalculateStandardCandles();}
255
256  // c) Calculate Q-cumulants:
257  if(fCalculateQcumulants){this->CalculateQcumulants();this->CalculateReferenceFlow();}
258
259  // ...
260
261  printf("\n  ... Closing the curtains ... \n\n");
262
263 } // end of AliFlowAnalysisWithMultiparticleCorrelations::Finish()
264
265 //=======================================================================================================================
266
267 void AliFlowAnalysisWithMultiparticleCorrelations::CrossCheckPointersUsedInFinish()
268 {
269  // Cross-check all pointers used in method Finish().
270
271  // a) Correlations;
272  // b) 'Standard candles';
273  // c) Q-cumulants.
274
275  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::CrossCheckPointersUsedInFinish()"; 
276
277  // a) Correlations:
278  if(fCalculateCorrelations)
279  {
280   for(Int_t cs=0;cs<2;cs++) 
281   {
282    if(fCalculateOnlyCos && 1==cs){continue;}
283    else if(fCalculateOnlySin && 0==cs){continue;}
284    for(Int_t c=0;c<fMaxCorrelator;c++) 
285    {
286     if(c==fDontGoBeyond){continue;}
287     if(fCalculateOnlyForHarmonicQC && c%2==0){continue;}
288     if(!fCorrelationsPro[cs][c]){Fatal(sMethodName.Data(),"fCorrelationsPro[%d][%d] is NULL, for one reason or another...",cs,c);}
289    }
290   }
291   if(fCalculateQcumulants && fPropagateErrorQC && !fProductsQCPro)
292    {Fatal(sMethodName.Data(),"fCalculateQcumulants && fPropagateErrorQC && !fProductsQCPro");}
293  } // if(fCalculateCorrelations)
294
295  // b) 'Standard candles':
296  if(fCalculateStandardCandles)
297  {
298   if(!fStandardCandlesHist){Fatal(sMethodName.Data(),"fStandardCandlesHist is NULL, for one reason or another...");}
299   if(fPropagateErrorSC)
300   {
301    if(!fProductsSCPro){Fatal(sMethodName.Data(),"fProductsSCPro is NULL, for one reason or another...");}
302   }
303  } // if(fCalculateStandardCandles)
304
305  // c) Q-cumulants:
306  if(fCalculateQcumulants)
307  {
308   if(!fQcumulantsHist){Fatal(sMethodName.Data(),"fQcumulantsHist is NULL, for one reason or another...");}
309   if(!fReferenceFlowHist){Fatal(sMethodName.Data(),"fReferenceFlowHist is NULL, for one reason or another...");}
310   if(fPropagateErrorQC)
311   {
312    if(!fProductsQCPro){Fatal(sMethodName.Data(),"fProductsQCPro is NULL, for one reason or another...");}
313   }
314  } // if(fCalculateQcumulants)
315
316 } // void AliFlowAnalysisWithMultiparticleCorrelations::CrossCheckPointersUsedInFinish()
317
318 //=======================================================================================================================
319
320 void AliFlowAnalysisWithMultiparticleCorrelations::CrossCheckPointersUsedInMake()
321 {
322  // Cross-check all pointers used in method Make().
323
324  // a) Correlations;
325  // b) Event-by-event cumulants;
326  // c) ...
327
328  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::CrossCheckPointersUsedInMake()"; 
329
330  // a) Correlations:
331  if(fCalculateCorrelations)
332  {
333   for(Int_t cs=0;cs<2;cs++) 
334   {
335    if(fCalculateOnlyCos && 1==cs){continue;}
336    else if(fCalculateOnlySin && 0==cs){continue;}
337    for(Int_t c=0;c<fMaxCorrelator;c++) 
338    {
339     if(c==fDontGoBeyond){continue;}
340     if(fCalculateOnlyForHarmonicQC && c%2==0){continue;}
341     if(!fCorrelationsPro[cs][c]){Fatal(sMethodName.Data(),"fCorrelationsPro[%d][%d] is NULL, for one reason or another...",cs,c);}
342    }
343   }
344   if(fCalculateQcumulants && fPropagateErrorQC && !fProductsQCPro)
345    {Fatal(sMethodName.Data(),"fCalculateQcumulants && fPropagateErrorQC && !fProductsQCPro");}
346  } // if(fCalculateCorrelations)
347
348  // b) Event-by-event cumulants:
349  if(fCalculateEbECumulants)
350  {
351   for(Int_t cs=0;cs<2;cs++) 
352   {
353    for(Int_t c=0;c<fMaxCorrelator;c++) 
354    {
355     if(!fEbECumulantsPro[cs][c]){Fatal(sMethodName.Data(),"fEbECumulantsPro[%d][%d] is NULL, for one reason or another...",cs,c);}
356    }
357   }
358  } // if(fCalculateEbECumulants)
359
360 } // void AliFlowAnalysisWithMultiparticleCorrelations::CrossCheckPointersUsedInMake()
361
362 //=======================================================================================================================
363
364 void AliFlowAnalysisWithMultiparticleCorrelations::CalculateStandardCandles()
365 {
366  // Calculate 'standard candles'.
367
368  // 'Standard candle' (SC) is defined in terms of average (all-event!) correlations as follows: 
369  //   SC(-n1,-n2,n2,n1) = <<Cos(-n1,-n2,n2,n1)>> - <<Cos(-n1,n1)>>*<<Cos(-n2,n2)>>, n1 > n2.
370
371  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::CalculateStandardCandles()"; 
372
373  Int_t nBins = fStandardCandlesHist->GetNbinsX(); 
374  Int_t nBins2p = fCorrelationsPro[0][1]->GetNbinsX();
375  Int_t nBins4p = fCorrelationsPro[0][3]->GetNbinsX();
376  for(Int_t b=1;b<=nBins;b++)
377  {
378   // Standard candle:
379   Double_t dSCn1n2n2n1 = 0.; // SC(-n1,-n2,n2,n1)
380   Double_t dSCn1n2n2n1Err = 0.; // SC(-n1,-n2,n2,n1) stat. error
381   fPropagateError = kTRUE;
382  
383   // Correlations:
384   Double_t dCosn1n2n2n1 = 0.; // <<Cos(-n1,-n2,n2,n1)>>
385   Double_t dCosn1n2n2n1Err = 0.; // <<Cos(-n1,-n2,n2,n1)>> stat. error
386   Double_t dCosn1n1 = 0.; // <<Cos(-n1,n1)>>
387   Double_t dCosn1n1Err = 0.; // <<Cos(-n1,n1)>> stat. error
388   Double_t dCosn2n2 = 0.; // <<Cos(-n2,n2)>>
389   Double_t dCosn2n2Err = 0.; // <<Cos(-n2,n2)>> stat. error
390   
391   // Labels:
392   TString labeln1n2n2n1 = TString(fStandardCandlesHist->GetXaxis()->GetBinLabel(b)).ReplaceAll("SC","Cos");
393   TString n1 = TString(fStandardCandlesHist->GetXaxis()->GetBinLabel(b))(4);  
394   TString n2 = TString(fStandardCandlesHist->GetXaxis()->GetBinLabel(b))(7);
395   if(n1.EqualTo("-") || n1.EqualTo(",")){Fatal(sMethodName.Data(),"n1.EqualTo...");}
396   if(n2.EqualTo("-") || n2.EqualTo(",")){Fatal(sMethodName.Data(),"n2.EqualTo...");}
397   TString labeln1n1 = Form("Cos(-%s,%s)",n1.Data(),n1.Data());
398   TString labeln2n2 = Form("Cos(-%s,%s)",n2.Data(),n2.Data());
399   //cout<<labeln1n2n2n1.Data()<<endl;
400   //cout<<labeln1n1.Data()<<endl;
401   //cout<<labeln2n2.Data()<<endl;
402   //cout<<endl;  
403
404   // Access <<Cos(-n1,-n2,n2,n1)>>:
405   for(Int_t b4p=1;b4p<=nBins4p;b4p++)
406   {
407    if(labeln1n2n2n1.EqualTo(fCorrelationsPro[0][3]->GetXaxis()->GetBinLabel(b4p)))   
408    {
409     //cout<<labeln1n2n2n1.Data()<<endl;
410     dCosn1n2n2n1 = fCorrelationsPro[0][3]->GetBinContent(b4p);
411     dCosn1n2n2n1Err = fCorrelationsPro[0][3]->GetBinError(b4p);
412     break; 
413    }
414   } // for(Int_t b4p=1;b4p<=nBins4p;b4p++)
415   if(TMath::Abs(dCosn1n2n2n1) < 1.e-44)
416   {
417    cout<<Form("labeln1n2n2n1 = %s",labeln1n2n2n1.Data())<<endl;
418    Warning(sMethodName.Data(),"TMath::Abs(dCosn1n2n2n1) < 1.e-44 !!!!");
419   }
420
421   // Access <<Cos(-n1,n1)>> and <<Cos(-n2,n2)>>:
422   for(Int_t b2p=1;b2p<=nBins2p;b2p++)
423   {
424    if(labeln1n1.EqualTo(fCorrelationsPro[0][1]->GetXaxis()->GetBinLabel(b2p)))   
425    {
426     //cout<<labeln1n1.Data()<<endl;
427     dCosn1n1 = fCorrelationsPro[0][1]->GetBinContent(b2p);
428     dCosn1n1Err = fCorrelationsPro[0][1]->GetBinError(b2p);
429    }  
430    else if(labeln2n2.EqualTo(fCorrelationsPro[0][1]->GetXaxis()->GetBinLabel(b2p)))   
431    {
432     //cout<<labeln2n2.Data()<<endl;
433     dCosn2n2 = fCorrelationsPro[0][1]->GetBinContent(b2p);
434     dCosn2n2Err = fCorrelationsPro[0][1]->GetBinError(b2p);
435    }
436    if(TMath::Abs(dCosn1n1) > 0. && TMath::Abs(dCosn2n2) > 0.){break;} // found 'em both!
437   } // for(Int_t b2p=1;b2p<=nBins2p;b2p++)
438   if(TMath::Abs(dCosn1n1) < 1.e-44)
439   {
440    cout<<Form("labeln1n1 = %s",labeln1n1.Data())<<endl;
441    Warning(sMethodName.Data(),"TMath::Abs(dCosn1n1) < 1.e-44 !!!!");
442   }
443   if(TMath::Abs(dCosn2n2) < 1.e-44)
444   {
445    cout<<Form("labeln2n2 = %s",labeln2n2.Data())<<endl;
446    Warning(sMethodName.Data(),"TMath::Abs(dCosn2n2) < 1.e-44 !!!!");
447   }
448
449   // Calculate standard candles:
450   dSCn1n2n2n1 = dCosn1n2n2n1-dCosn1n1*dCosn2n2;
451
452   // Store the final results:
453   fStandardCandlesHist->SetBinContent(b,dSCn1n2n2n1);
454
455   // Error propagation:
456   if(!fPropagateErrorSC)
457   {
458    fStandardCandlesHist->SetBinError(b,0.);
459    continue;
460   }
461
462   // Access covariances (multiplied by weight dependent prefactor):
463   Double_t wCovCosn1n2n2n1Cosn1n1 = Covariance(labeln1n2n2n1.Data(),labeln1n1.Data(),fProductsSCPro); // weighted Cov(<Cos(-n1,-n2,n2,n1)>,<Cos(-n1,n1)>)
464   Double_t wCovCosn1n2n2n1Cosn2n2 = Covariance(labeln1n2n2n1.Data(),labeln2n2.Data(),fProductsSCPro); // weighted Cov(<Cos(-n1,-n2,n2,n1)>,<Cos(-n2,n2)>)
465   Double_t wCovCosn1n1Cosn2n2 = Covariance(labeln1n1.Data(),labeln2n2.Data(),fProductsSCPro); // weighted Cov(<Cos(-n1,n1)>,<Cos(-n2,n2)>)
466
467   // Explicit error propagation:
468   Double_t dSCn1n2n2n1ErrSquared = pow(dCosn1n1,2.)*pow(dCosn2n2Err,2.) + pow(dCosn2n2,2.)*pow(dCosn1n1Err,2.) 
469                                  + pow(dCosn1n2n2n1Err,2.) + 2.*dCosn1n1*dCosn2n2*wCovCosn1n1Cosn2n2 
470                                  - 2.*dCosn1n1*wCovCosn1n2n2n1Cosn2n2 - 2.*dCosn2n2*wCovCosn1n2n2n1Cosn1n1;
471   if(dSCn1n2n2n1ErrSquared > 0.)
472   {
473    dSCn1n2n2n1Err = pow(dSCn1n2n2n1ErrSquared,0.5);
474   } else
475     {
476      Warning(sMethodName.Data(),"dSCn1n2n2n1ErrSquared > 0. is not satisfied for %s !!!!",labeln1n2n2n1.ReplaceAll("Cos","SC").Data());
477      fPropagateError = kFALSE;
478     }
479
480   // Store the final stat. error:
481   if(fPropagateError)
482   {
483    fStandardCandlesHist->SetBinError(b,dSCn1n2n2n1Err);
484   }
485  } // for(Int_t b=1;b<=nBins;b++)
486
487  fPropagateError = kTRUE;
488
489  return; 
490
491 } // void AliFlowAnalysisWithMultiparticleCorrelations::CalculateStandardCandles()
492
493 //=======================================================================================================================
494
495 void AliFlowAnalysisWithMultiparticleCorrelations::InitializeArraysForCorrelations()
496 {
497  // Initialize all arrays for correlations.
498
499  for(Int_t cs=0;cs<2;cs++) // [0=cos,1=sin]
500  {
501   for(Int_t c=0;c<8;c++) // [1p,2p,...,8p]
502   {
503    fCorrelationsPro[cs][c] = NULL;
504   }
505  }
506
507 } // void AliFlowAnalysisWithMultiparticleCorrelations::InitializeArraysForCorrelations()
508
509 //=======================================================================================================================
510
511 void AliFlowAnalysisWithMultiparticleCorrelations::InitializeArraysForEbECumulants()
512 {
513  // Initialize all arrays for event-by-event cumulants.
514
515  for(Int_t cs=0;cs<2;cs++) // [0=cos,1=sin]
516  {
517   for(Int_t c=0;c<8;c++) // [1p,2p,...,8p]
518   {
519    fEbECumulantsPro[cs][c] = NULL;
520   }
521  }
522
523 } // void AliFlowAnalysisWithMultiparticleCorrelations::InitializeArraysForEbECumulants()
524
525 //=======================================================================================================================
526
527 void AliFlowAnalysisWithMultiparticleCorrelations::InitializeArraysForDiffCorrelations()
528 {
529  // Initialize all arrays for differential correlations.
530
531  for(Int_t cs=0;cs<2;cs++) // [0=cos,1=sin]
532  {
533   for(Int_t c=0;c<4;c++) // [1p,2p,3p,4p]
534   {
535    fDiffCorrelationsPro[cs][c] = NULL;
536    fDiffHarmonics[cs][c] = 0;
537   }
538  }
539
540  // Default values:
541  // Cos, 2p:
542  fDiffHarmonics[1][0] = -2;
543  fDiffHarmonics[1][1] = 2;
544  // Cos, 3p:
545  fDiffHarmonics[2][0] = -3;
546  fDiffHarmonics[2][1] = 1;
547  fDiffHarmonics[2][2] = 2;
548  // Cos, 4p:
549  fDiffHarmonics[3][0] = -2;
550  fDiffHarmonics[3][1] = -2;
551  fDiffHarmonics[3][2] = 2;
552  fDiffHarmonics[3][3] = 2;
553
554 } // void AliFlowAnalysisWithMultiparticleCorrelations::InitializeArraysForDiffCorrelations()
555
556 //=======================================================================================================================
557
558 void AliFlowAnalysisWithMultiparticleCorrelations::InitializeArraysForNestedLoops()
559 {
560  // Initialize all arrays for nested loops.  
561
562  fCrossCheckDiffCSCOBN[0] = 0; // cos/sin
563  fCrossCheckDiffCSCOBN[1] = 2; // correlator order
564  fCrossCheckDiffCSCOBN[2] = 4; // bin number
565
566 } // void AliFlowAnalysisWithMultiparticleCorrelations::InitializeArraysForNestedLoops()
567
568 //=======================================================================================================================
569
570 void AliFlowAnalysisWithMultiparticleCorrelations::CalculateCorrelations(AliFlowEventSimple *anEvent)
571 {
572  // Calculate multi-particle correlations from Q-vector components.
573
574  // a) Calculate all booked multi-particle correlations;
575  // b) Calculate products needed for QC error propagation;
576  // c) Calculate products needed for SC error propagation.
577
578  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::CalculateCorrelations(AliFlowEventSimple *anEvent)"; 
579  if(!anEvent){Fatal(sMethodName.Data(),"'anEvent'!?!? You again!!!!");}
580
581  // a) Calculate all booked multi-particle correlations:
582  Double_t dMultRP = anEvent->GetNumberOfRPs(); // TBI shall I promote this variable into data member? 
583  for(Int_t cs=0;cs<2;cs++) // cos/sin 
584  {
585   if(fCalculateOnlyCos && 1==cs){continue;}
586   else if(fCalculateOnlySin && 0==cs){continue;}
587   for(Int_t co=0;co<8;co++) // correlator order (TBI hardwired 8) 
588   {
589    if(dMultRP < co+1){break;} // defines min. number of particles in an event for a certain correlator to make sense
590    Int_t nBins = 0;
591    if(fCorrelationsPro[cs][co]){nBins = fCorrelationsPro[cs][co]->GetNbinsX();}
592    else{continue;}
593    for(Int_t b=1;b<=nBins;b++)
594    {
595     TString sBinLabel = fCorrelationsPro[cs][co]->GetXaxis()->GetBinLabel(b);
596     if(sBinLabel.EqualTo("")){break;} 
597     Double_t num = CastStringToCorrelation(sBinLabel.Data(),kTRUE);
598     Double_t den = CastStringToCorrelation(sBinLabel.Data(),kFALSE);
599     Double_t weight = den; // TBI: add support for other options for the weight eventually
600     if(den>0.) 
601     {
602      fCorrelationsPro[cs][co]->Fill(b-.5,num/den,weight);
603     } else{Warning(sMethodName.Data(),"if(den>0.)");}
604    } // for(Int_t b=1;b<=nBins;b++)
605   } // for(Int_t co=0;co<8;co++) // correlator order (TBI hardwired 8) 
606  } // for(Int_t cs=0;cs<=1;cs++) // cos/sin 
607
608  // b) Calculate products needed for QC error propagation:
609  if(fCalculateQcumulants && fPropagateErrorQC){this->CalculateProductsOfCorrelations(anEvent,fProductsQCPro);}
610
611  // c) Calculate products needed for SC error propagation:
612  if(fCalculateStandardCandles && fPropagateErrorSC){this->CalculateProductsOfCorrelations(anEvent,fProductsSCPro);}
613
614 } // void AliFlowAnalysisWithMultiparticleCorrelations::CalculateCorrelations(AliFlowEventSimple *anEvent)
615
616 //=======================================================================================================================
617
618 void AliFlowAnalysisWithMultiparticleCorrelations::CalculateDiffCorrelations(AliFlowEventSimple *anEvent)
619 {
620  // Calculate differential multi-particle correlations from Q-, p- and q-vector components.
621
622  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::CalculateCorrelations(AliFlowEventSimple *anEvent)"; 
623  if(!anEvent){Fatal(sMethodName.Data(),"'anEvent'!?!? You again!!!!");}
624
625  Int_t nBins = 0; // TBI promote this to data member? 
626  for(Int_t cs=0;cs<2;cs++) // [0=cos,1=sin]
627  {
628   if(nBins != 0){break;}
629   for(Int_t co=0;co<4;co++) // [1p,2p,3p,4p]
630   {
631    if(fDiffCorrelationsPro[cs][co] && 0==nBins)
632    {
633     nBins = fDiffCorrelationsPro[cs][co]->GetNbinsX(); 
634    }
635   } // for(Int_t co=0;co<4;co++) // [1p,2p,3p,4p]
636  } // for(Int_t cs=0;cs<2;cs++) // [0=cos,1=sin]
637
638  // TBI: The lines below are genuine, most delicious, spaghetti ever... To be reimplemented (one day).
639  if(fCalculateDiffCos)
640  {
641  for(Int_t b=1;b<=nBins;b++)
642  {
643   fDiffBinNo = b-1;
644   // <2'>:  
645   Double_t num2 = TwoDiff(fDiffHarmonics[1][0],fDiffHarmonics[1][1]).Re();
646   Double_t den2 = TwoDiff(0,0).Re();
647   Double_t w2 = den2; // TBI add support for other options for the weight
648   if(den2>0.){fDiffCorrelationsPro[0][1]->Fill(fDiffCorrelationsPro[0][1]->GetBinCenter(b),num2/den2,w2);} 
649   // <3'>:  
650   Double_t num3 = ThreeDiff(fDiffHarmonics[2][0],fDiffHarmonics[2][1],fDiffHarmonics[2][2]).Re();
651   Double_t den3 = ThreeDiff(0,0,0).Re();
652   Double_t w3 = den3; // TBI add support for other options for the weight
653   if(den3>0.){fDiffCorrelationsPro[0][2]->Fill(fDiffCorrelationsPro[0][2]->GetBinCenter(b),num3/den3,w3);} 
654   // <4'>:  
655   Double_t num4 = FourDiff(fDiffHarmonics[3][0],fDiffHarmonics[3][1],fDiffHarmonics[3][2],fDiffHarmonics[3][3]).Re();
656   Double_t den4 = FourDiff(0,0,0,0).Re();
657   Double_t w4 = den4; // TBI add support for other options for the weight
658   if(den4>0.){fDiffCorrelationsPro[0][3]->Fill(fDiffCorrelationsPro[0][3]->GetBinCenter(b),num4/den4,w4);} 
659  } // for(Int_t b=1;b<=nBins;b++)
660  }
661  // TBI: The lines below are genuine, most delicious, spaghetti ever... To be reimplemented (one day).
662  if(fCalculateDiffSin)
663  {
664  for(Int_t b=1;b<=nBins;b++)
665  {
666   fDiffBinNo = b-1;
667   // <2'>:  
668   Double_t num2 = TwoDiff(fDiffHarmonics[1][0],fDiffHarmonics[1][1]).Im();
669   Double_t den2 = TwoDiff(0,0).Re();
670   Double_t w2 = den2; // TBI add support for other options for the weight
671   if(den2>0.){fDiffCorrelationsPro[1][1]->Fill(fDiffCorrelationsPro[1][1]->GetBinCenter(b),num2/den2,w2);} 
672   // <3'>:  
673   Double_t num3 = ThreeDiff(fDiffHarmonics[2][0],fDiffHarmonics[2][1],fDiffHarmonics[2][2]).Im();
674   Double_t den3 = ThreeDiff(0,0,0).Re();
675   Double_t w3 = den3; // TBI add support for other options for the weight
676   if(den3>0.){fDiffCorrelationsPro[1][2]->Fill(fDiffCorrelationsPro[1][2]->GetBinCenter(b),num3/den3,w3);} 
677   // <4'>:  
678   Double_t num4 = FourDiff(fDiffHarmonics[3][0],fDiffHarmonics[3][1],fDiffHarmonics[3][2],fDiffHarmonics[3][3]).Im();
679   Double_t den4 = FourDiff(0,0,0,0).Re();
680   Double_t w4 = den4; // TBI add support for other options for the weight
681   if(den4>0.){fDiffCorrelationsPro[1][3]->Fill(fDiffCorrelationsPro[1][3]->GetBinCenter(b),num4/den4,w4);} 
682  } // for(Int_t b=1;b<=nBins;b++)
683  }
684
685 } // void AliFlowAnalysisWithMultiparticleCorrelations::CalculateDiffCorrelations(AliFlowEventSimple *anEvent)
686
687 //=======================================================================================================================
688
689 Double_t AliFlowAnalysisWithMultiparticleCorrelations::CastStringToCorrelation(const char *string, Bool_t numerator)
690 {
691  // Cast string of the generic form Cos/Sin(-n_1,-n_2,...,n_{k-1},n_k) in the corresponding correlation value.
692  // If you issue a call to this method with setting numerator = kFALSE, then you are getting back for free
693  // the corresponding denumerator (a.k.a. weight 'number of combinations').
694
695  // TBI:
696  // a) add protection against cases a la:
697  //     string = Cos(-3,-4,5,6,5,6,-3)
698  //     method = Six(-3,-4,5,6,5,-3).Re()
699  // b) cross-check with nested loops this method 
700
701  Double_t dValue = 0.; // return value
702
703  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::CastStringToCorrelation(const char *string, Bool_t numerator)"; 
704
705  if(!(TString(string).BeginsWith("Cos") || TString(string).BeginsWith("Sin")))
706  {
707   cout<<Form("And the fatal string is... '%s'. Congratulations!!",string)<<endl; 
708   Fatal(sMethodName.Data(),"!(TString(string).BeginsWith(...");
709  }
710
711  Bool_t bRealPart = kTRUE;
712  if(TString(string).BeginsWith("Sin")){bRealPart = kFALSE;}
713
714  Int_t n[8] = {0,0,0,0,0,0,0,0}; // harmonics, supporting up to 8p correlations
715  UInt_t whichCorr = 0;   
716  for(Int_t t=0;t<=TString(string).Length();t++)
717  {
718   if(TString(string[t]).EqualTo(",") || TString(string[t]).EqualTo(")")) // TBI this is just ugly
719   {
720    n[whichCorr] = string[t-1] - '0';
721    if(TString(string[t-2]).EqualTo("-")){n[whichCorr] = -1*n[whichCorr];}
722    if(!(TString(string[t-2]).EqualTo("-") 
723       || TString(string[t-2]).EqualTo(",")
724       || TString(string[t-2]).EqualTo("("))) // TBI relax this eventually to allow two-digits harmonics
725    { 
726     cout<<Form("And the fatal string is... '%s'. Congratulations!!",string)<<endl; 
727     Fatal(sMethodName.Data(),"!(TString(string[t-2]).EqualTo(...");
728    }
729    whichCorr++;
730    if(whichCorr>=9){Fatal(sMethodName.Data(),"whichCorr>=9");} // not supporting corr. beyond 8p 
731   } // if(TString(string[t]).EqualTo(",") || TString(string[t]).EqualTo(")")) // TBI this is just ugly
732  } // for(UInt_t t=0;t<=TString(string).Length();t++)
733
734  switch(whichCorr)
735  {
736   case 1:
737    if(!numerator){dValue = One(0).Re();}
738    else if(bRealPart){dValue = One(n[0]).Re();} 
739    else{dValue = One(n[0]).Im();}
740   break;
741
742   case 2: 
743    if(!numerator){dValue = Two(0,0).Re();}
744    else if(bRealPart){dValue = Two(n[0],n[1]).Re();}
745    else{dValue = Two(n[0],n[1]).Im();}
746   break;
747
748   case 3: 
749    if(!numerator){dValue = Three(0,0,0).Re();}
750    else if(bRealPart){dValue = Three(n[0],n[1],n[2]).Re();}
751    else{dValue = Three(n[0],n[1],n[2]).Im();}
752   break;
753
754   case 4: 
755    if(!numerator){dValue = Four(0,0,0,0).Re();}
756    else if(bRealPart){dValue = Four(n[0],n[1],n[2],n[3]).Re();}
757    else{dValue = Four(n[0],n[1],n[2],n[3]).Im();}
758   break;
759
760   case 5: 
761    if(!numerator){dValue = Five(0,0,0,0,0).Re();}
762    else if(bRealPart){dValue = Five(n[0],n[1],n[2],n[3],n[4]).Re();}
763    else{dValue = Five(n[0],n[1],n[2],n[3],n[4]).Im();}
764   break;
765
766   case 6: 
767    if(!numerator){dValue = Six(0,0,0,0,0,0).Re();}
768    else if(bRealPart){dValue = Six(n[0],n[1],n[2],n[3],n[4],n[5]).Re();}
769    else{dValue = Six(n[0],n[1],n[2],n[3],n[4],n[5]).Im();}
770   break;
771
772   case 7: 
773    if(!numerator){dValue = Seven(0,0,0,0,0,0,0).Re();}
774    else if(bRealPart){dValue = Seven(n[0],n[1],n[2],n[3],n[4],n[5],n[6]).Re();}
775    else{dValue = Seven(n[0],n[1],n[2],n[3],n[4],n[5],n[6]).Im();}
776    break;
777
778   case 8: 
779    if(!numerator){dValue = Eight(0,0,0,0,0,0,0,0).Re();}
780    else if(bRealPart){dValue = Eight(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]).Re();} 
781    else{dValue = Eight(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]).Im();} 
782   break;
783
784   default:
785    cout<<Form("And the fatal 'whichCorr' value is... %d. Congratulations!!",whichCorr)<<endl; 
786    Fatal(sMethodName.Data(),"switch(whichCorr)"); 
787  } // switch(whichCorr)
788  
789  return dValue;
790
791 } // Double_t AliFlowAnalysisWithMultiparticleCorrelations::CastStringToCorrelation(const char *string, Bool_t numerator)
792
793 //=======================================================================================================================
794
795 void AliFlowAnalysisWithMultiparticleCorrelations::CalculateProductsOfCorrelations(AliFlowEventSimple *anEvent, TProfile2D *profile2D)
796 {
797  // Calculate products of multi-particle correlations (needed for error propagation).
798
799  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::CalculateProductsOfCorrelations(AliFlowEventSimple *anEvent, TProfile2D *profile2D)"; 
800  if(!anEvent){Fatal(sMethodName.Data(),"Sorry, 'anEvent' is on holidays.");} 
801  if(!profile2D){Fatal(sMethodName.Data(),"Sorry, 'profile2D' is on holidays.");} 
802
803  Int_t nBins = profile2D->GetXaxis()->GetNbins();
804  for(Int_t bx=2;bx<=nBins;bx++)
805  {
806   for(Int_t by=1;by<bx;by++)
807   {
808    const char *binLabelX = profile2D->GetXaxis()->GetBinLabel(bx);
809    const char *binLabelY = profile2D->GetYaxis()->GetBinLabel(by);
810    Double_t numX = this->CastStringToCorrelation(binLabelX,kTRUE); // numerator
811    Double_t denX = this->CastStringToCorrelation(binLabelX,kFALSE); // denominator
812    Double_t wX = denX; // weight TBI add support for other options
813    Double_t numY = this->CastStringToCorrelation(binLabelY,kTRUE); // numerator
814    Double_t denY = this->CastStringToCorrelation(binLabelY,kFALSE); // denominator
815    Double_t wY = denY; // weight TBI add support for other options
816    if(TMath::Abs(denX) > 0. && TMath::Abs(denY) > 0.)
817    {
818     profile2D->Fill(bx-0.5,by-0.5,(numX/denX)*(numY/denY),wX*wY);
819    } else
820      {
821       cout<<endl; 
822       cout<<"Cannot calculate product for:"<<endl;    
823       cout<<Form("binLabelX = %s",binLabelX)<<endl;
824       cout<<Form("binLabelY = %s",binLabelY)<<endl;
825       cout<<Form("anEvent->GetNumberOfRPs() = %d",anEvent->GetNumberOfRPs())<<endl; 
826       Fatal(sMethodName.Data(),"if(TMath::Abs(denX) > 0. && TMath::Abs(denY) > 0.)");
827      } // else
828   } // for(Int_t by=1;by<bx;by++)
829  } // for(Int_t bx=2;bx<=nBins;bx++)
830
831 } // void CalculateProductsOfCorrelations(AliFlowEventSimple *anEvent, TProfile2D *profile2D)
832
833 //=======================================================================================================================
834
835 void AliFlowAnalysisWithMultiparticleCorrelations::CalculateEbECumulants(AliFlowEventSimple *anEvent)
836 {
837  // Calculate e-b-e cumulants from Q-vector components.
838
839  // TBI this mathod is far (very far, in fact) from being finalized :'(
840
841  // a) Calculate and store e-b-e cumulants.
842
843  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::CalculateEbECumulants(AliFlowEventSimple *anEvent)"; 
844  if(!anEvent){Fatal(sMethodName.Data(),"'anEvent'!?!? You again!!!!");}
845
846  // a) Calculate and store e-b-e cumulants:
847  Double_t dMultRP = anEvent->GetNumberOfRPs(); // TBI shall I promote this variable into data member? 
848  Int_t binNo[8]; for(Int_t c=0;c<8;c++){binNo[c]=1;} 
849  // 1-p:
850  for(Int_t n1=-fMaxHarmonic;n1<=fMaxHarmonic;n1++) 
851  {
852   if(fSkipZeroHarmonics && 0==n1){continue;}
853   if(fCalculateAll)
854   {
855    TComplex oneN = One(n1); // numerator
856    Double_t oneD = One(0).Re(); // denominator
857    Double_t oneW = oneD; // weight TBI add other possibilities here for the weight
858    if(oneD>0. && dMultRP>=1) 
859    {
860     fEbECumulantsPro[0][0]->Fill(binNo[0]-.5,oneN.Re()/oneD,oneW);
861     fEbECumulantsPro[1][0]->Fill(binNo[0]++-.5,oneN.Im()/oneD,oneW);
862    } else {Warning(sMethodName.Data(),"if(oneD>0. && dMultRP>=1) ");}
863   } 
864   if(1==fDontGoBeyond){continue;}
865   // 2-p:
866   for(Int_t n2=n1;n2<=fMaxHarmonic;n2++) 
867   {
868    if(fSkipZeroHarmonics && 0==n2){continue;}
869    if(fCalculateAll 
870       || (fCalculateIsotropic && 0==n1+n2) 
871       || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2)) 
872       || (fCalculateSameIsotropic && 0==n1+n2 &&  TMath::Abs(n1)==TMath::Abs(n2)))
873    {
874     Double_t cumulants2pCos = Two(n1,n2).Re()/Two(0,0).Re() 
875                             - (One(n1).Re()/One(0).Re())*(One(n2).Re()/One(0).Re())
876                             + (One(n1).Im()/One(0).Re())*(One(n2).Im()/One(0).Re());
877                             
878     Double_t cumulants2pSin = Two(n1,n2).Im()/Two(0,0).Re() 
879                             - (One(n1).Re()/One(0).Re())*(One(n2).Im()/One(0).Re())
880                             - (One(n2).Re()/One(0).Re())*(One(n1).Im()/One(0).Re());
881
882     if(/*twoD>0. &&*/ dMultRP>=2) 
883     {
884      fEbECumulantsPro[0][1]->Fill(binNo[1]-.5,cumulants2pCos,1.);;
885      fEbECumulantsPro[1][1]->Fill(binNo[1]++-.5,cumulants2pSin,1.);;
886     } else {Warning(sMethodName.Data(),"/*twoD>0. &&*/ dMultRP>=2");} 
887    } 
888    if(2==fDontGoBeyond){continue;}
889    
890    /*
891
892    // 3-p:
893    for(Int_t n3=n2;n3<=fMaxHarmonic;n3++) 
894    {
895     if(fSkipZeroHarmonics && 0==n3){continue;}
896     if(fCalculateAll 
897        || (fCalculateIsotropic && 0==n1+n2+n3) 
898        || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3))
899        || (fCalculateSameIsotropic && 0==n1+n2+n3 && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3)))
900     {
901      TComplex threeN = Three(n1,n2,n3); // numerator
902      Double_t threeD = Three(0,0,0).Re(); // denominator
903      Double_t threeW = threeD; // weight TBI add other possibilities here for the weight
904      if(threeD>0. && dMultRP>=3) 
905      {
906       fEbECumulantsPro[0][2]->Fill(binNo[2]-.5,threeN.Re()/threeD,threeW);
907       fEbECumulantsPro[1][2]->Fill(binNo[2]++-.5,threeN.Im()/threeD,threeW);
908      } else {Warning(sMethodName.Data(),"threeD>0. && dMultRP>=3");} 
909     }
910     if(3==fDontGoBeyond){continue;}
911     // 4-p:
912     for(Int_t n4=n3;n4<=fMaxHarmonic;n4++) 
913     {
914      if(fSkipZeroHarmonics && 0==n4){continue;}
915      if(fCalculateAll 
916         || (fCalculateIsotropic && 0==n1+n2+n3+n4) 
917         || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) 
918             && TMath::Abs(n1)==TMath::Abs(n4))
919         || (fCalculateSameIsotropic && 0==n1+n2+n3+n4 && TMath::Abs(n1)==TMath::Abs(n2) 
920             && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4)))
921      { 
922       TComplex fourN = Four(n1,n2,n3,n4); // numerator
923       Double_t fourD = Four(0,0,0,0).Re(); // denominator
924       Double_t fourW = fourD; // weight TBI add other possibilities here for the weight
925       if(fourD>0. && dMultRP>=4) 
926       {
927        fEbECumulantsPro[0][3]->Fill(binNo[3]-.5,fourN.Re()/fourD,fourW);
928        fEbECumulantsPro[1][3]->Fill(binNo[3]++-.5,fourN.Im()/fourD,fourW);
929       } else {Warning(sMethodName.Data(),"fourD>0. && dMultRP>=4");}
930      }
931      if(4==fDontGoBeyond){continue;}
932      // 5-p:
933      for(Int_t n5=n4;n5<=fMaxHarmonic;n5++) 
934      {
935       if(fSkipZeroHarmonics && 0==n5){continue;}
936       if(fCalculateAll 
937          || (fCalculateIsotropic && 0==n1+n2+n3+n4+n5) 
938          || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) 
939              && TMath::Abs(n1)==TMath::Abs(n4) && TMath::Abs(n1)==TMath::Abs(n5))
940          || (fCalculateSameIsotropic && 0==n1+n2+n3+n4+n5 && TMath::Abs(n1)==TMath::Abs(n2) 
941              && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4) && TMath::Abs(n1)==TMath::Abs(n5)))
942       { 
943        TComplex fiveN = Five(n1,n2,n3,n4,n5); // numerator
944        Double_t fiveD = Five(0,0,0,0,0).Re(); // denominator
945        Double_t fiveW = fiveD; // weight TBI add other possibilities here for the weight
946        if(fiveD>0. && dMultRP>=5) 
947        {
948         fEbECumulantsPro[0][4]->Fill(binNo[4]-.5,fiveN.Re()/fiveD,fiveW);
949         fEbECumulantsPro[1][4]->Fill(binNo[4]++-.5,fiveN.Im()/fiveD,fiveW);
950        } else {Warning(sMethodName.Data(),"fiveD>0. && dMultRP>=5");}
951       } 
952       if(5==fDontGoBeyond){continue;}
953       // 6-p:  
954       for(Int_t n6=n5;n6<=fMaxHarmonic;n6++) 
955       {
956        if(fSkipZeroHarmonics && 0==n6){continue;}
957        if(fCalculateAll 
958           || (fCalculateIsotropic && 0==n1+n2+n3+n4+n5+n6)  
959           || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) 
960               && TMath::Abs(n1)==TMath::Abs(n4) && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6))
961           || (fCalculateSameIsotropic && 0==n1+n2+n3+n4+n5+n6 && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) 
962               && TMath::Abs(n1)==TMath::Abs(n4) && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6)))
963        { 
964         TComplex sixN = Six(n1,n2,n3,n4,n5,n6); // numerator
965         Double_t sixD = Six(0,0,0,0,0,0).Re(); // denominator
966         Double_t sixW = sixD; // weight TBI add other possibilities here for the weight
967         if(sixD>0. && dMultRP>=6) 
968         {
969          fEbECumulantsPro[0][5]->Fill(binNo[5]-.5,sixN.Re()/sixD,sixW);
970          fEbECumulantsPro[1][5]->Fill(binNo[5]++-.5,sixN.Im()/sixD,sixW);
971         } else {Warning(sMethodName.Data(),"sixD>0. && dMultRP>=6");}
972        } 
973        if(6==fDontGoBeyond){continue;}
974        // 7-p:
975        for(Int_t n7=n6;n7<=fMaxHarmonic;n7++) 
976        {
977         if(fSkipZeroHarmonics && 0==n7){continue;}
978         if(fCalculateAll 
979            || (fCalculateIsotropic && 0==n1+n2+n3+n4+n5+n6+n7) 
980            || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4) 
981                && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6) && TMath::Abs(n1)==TMath::Abs(n7))
982            || (fCalculateSameIsotropic && 0==n1+n2+n3+n4+n5+n6+n7 && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3)
983                && TMath::Abs(n1)==TMath::Abs(n4) && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6) 
984                && TMath::Abs(n1)==TMath::Abs(n7)))
985         { 
986          TComplex sevenN = Seven(n1,n2,n3,n4,n5,n6,n7); // numerator
987          Double_t sevenD = Seven(0,0,0,0,0,0,0).Re(); // denominator
988          Double_t sevenW = sevenD; // weight TBI add other possibilities here for the weight
989          if(sevenD>0. && dMultRP>=7) 
990          {
991           fEbECumulantsPro[0][6]->Fill(binNo[6]-.5,sevenN.Re()/sevenD,sevenW);
992           fEbECumulantsPro[1][6]->Fill(binNo[6]++-.5,sevenN.Im()/sevenD,sevenW);
993          } else {Warning(sMethodName.Data(),"sevenD>0. && dMultRP>=7");}
994         } 
995         if(7==fDontGoBeyond){continue;}
996         // 8-p:
997         for(Int_t n8=n7;n8<=fMaxHarmonic;n8++) 
998         {
999          if(fSkipZeroHarmonics && 0==n8){continue;}
1000          if(fCalculateAll 
1001             || (fCalculateIsotropic && 0==n1+n2+n3+n4+n5+n6+n7+n8) 
1002             || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4) 
1003                 && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6) && TMath::Abs(n1)==TMath::Abs(n7) 
1004                 && TMath::Abs(n1)==TMath::Abs(n8))
1005             || (fCalculateSameIsotropic && 0==n1+n2+n3+n4+n5+n6+n7+n8 && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) 
1006                 && TMath::Abs(n1)==TMath::Abs(n4) && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6) 
1007                 && TMath::Abs(n1)==TMath::Abs(n7) && TMath::Abs(n1)==TMath::Abs(n8)))
1008          { 
1009           TComplex eightN = Eight(n1,n2,n3,n4,n5,n6,n7,n8); // numerator
1010           Double_t eightD = Eight(0,0,0,0,0,0,0,0).Re(); // denominator
1011           Double_t eightW = eightD; // weight TBI add other possibilities here for the weight
1012           if(eightD>0. && dMultRP>=8) 
1013           {
1014            fEbECumulantsPro[0][7]->Fill(binNo[7]-.5,eightN.Re()/eightD,eightW);
1015            fEbECumulantsPro[1][7]->Fill(binNo[7]++-.5,eightN.Im()/eightD,eightW);
1016           }
1017          } 
1018         } // for(Int_t n8=n7;n8<=fMaxHarmonic;n8++)
1019        } // for(Int_t n7=n6;n7<=fMaxHarmonic;n7++) 
1020       } // for(Int_t n6=n5;n6<=fMaxHarmonic;n6++) 
1021      } // for(Int_t n5=n4;n5<=fMaxHarmonic;n5++) 
1022     } // for(Int_t n4=n3;n4<=fMaxHarmonic;n4++)   
1023    } // for(Int_t n3=n2;n3<=fMaxHarmonic;n3++) 
1024  
1025   */
1026
1027   } // for(Int_t n2=n1;n2<=fMaxHarmonic;n2++)
1028  } // for(Int_t n1=-fMaxHarmonic;n1<=fMaxHarmonic;n1++) 
1029
1030 } // void AliFlowAnalysisWithMultiparticleCorrelations::CalculateEbECumulants(AliFlowEventSimple *anEvent)
1031
1032 //=======================================================================================================================
1033
1034 void AliFlowAnalysisWithMultiparticleCorrelations::CrossCheckWithNestedLoops(AliFlowEventSimple *anEvent)
1035 {
1036  // Cross-check results for multi-particle correlations with nested loops.
1037
1038  // TBI add few comments here, there and over there
1039  // TBI this method is rather messy :'(
1040
1041  Int_t h1 = (Int_t)fNestedLoopsFlagsPro->GetBinContent(2);
1042  Int_t h2 = (Int_t)fNestedLoopsFlagsPro->GetBinContent(3);
1043  Int_t h3 = (Int_t)fNestedLoopsFlagsPro->GetBinContent(4);
1044  Int_t h4 = (Int_t)fNestedLoopsFlagsPro->GetBinContent(5);
1045  Int_t h5 = (Int_t)fNestedLoopsFlagsPro->GetBinContent(6);
1046  Int_t h6 = (Int_t)fNestedLoopsFlagsPro->GetBinContent(7);
1047  Int_t h7 = (Int_t)fNestedLoopsFlagsPro->GetBinContent(8);
1048  Int_t h8 = (Int_t)fNestedLoopsFlagsPro->GetBinContent(9);
1049
1050  this->ResetQvector();
1051  this->FillQvector(anEvent);
1052
1053  if(TMath::Abs(One(0).Re())>0.)
1054  {
1055   fNestedLoopsResultsCosPro->Fill(1.5,One(h1).Re()/One(0).Re(),One(0).Re()); 
1056   fNestedLoopsResultsSinPro->Fill(1.5,One(h1).Im()/One(0).Re(),One(0).Re());  
1057  } 
1058  if(TMath::Abs(Two(0,0).Re())>0.)
1059  {
1060   fNestedLoopsResultsCosPro->Fill(3.5,Two(h1,h2).Re()/Two(0,0).Re(),Two(0,0).Re()); 
1061   fNestedLoopsResultsSinPro->Fill(3.5,Two(h1,h2).Im()/Two(0,0).Re(),Two(0,0).Re()); 
1062  }
1063  if(TMath::Abs(Three(0,0,0).Re())>0.)
1064  {
1065   fNestedLoopsResultsCosPro->Fill(5.5,Three(h1,h2,h3).Re()/Three(0,0,0).Re(),Three(0,0,0).Re()); 
1066   fNestedLoopsResultsSinPro->Fill(5.5,Three(h1,h2,h3).Im()/Three(0,0,0).Re(),Three(0,0,0).Re()); 
1067  } 
1068  if(TMath::Abs(Four(0,0,0,0).Re())>0.)
1069  {
1070   fNestedLoopsResultsCosPro->Fill(7.5,Four(h1,h2,h3,h4).Re()/Four(0,0,0,0).Re(),Four(0,0,0,0).Re()); 
1071   fNestedLoopsResultsSinPro->Fill(7.5,Four(h1,h2,h3,h4).Im()/Four(0,0,0,0).Re(),Four(0,0,0,0).Re()); 
1072  } 
1073  if(TMath::Abs(Five(0,0,0,0,0).Re())>0.)
1074  {
1075   fNestedLoopsResultsCosPro->Fill(9.5,Five(h1,h2,h3,h4,h5).Re()/Five(0,0,0,0,0).Re(),Five(0,0,0,0,0).Re()); 
1076   fNestedLoopsResultsSinPro->Fill(9.5,Five(h1,h2,h3,h4,h5).Im()/Five(0,0,0,0,0).Re(),Five(0,0,0,0,0).Re()); 
1077  } 
1078  if(TMath::Abs(Six(0,0,0,0,0,0).Re())>0.)
1079  {
1080   fNestedLoopsResultsCosPro->Fill(11.5,Six(h1,h2,h3,h4,h5,h6).Re()/Six(0,0,0,0,0,0).Re(),Six(0,0,0,0,0,0).Re()); 
1081   fNestedLoopsResultsSinPro->Fill(11.5,Six(h1,h2,h3,h4,h5,h6).Im()/Six(0,0,0,0,0,0).Re(),Six(0,0,0,0,0,0).Re()); 
1082  }
1083  if(TMath::Abs(Seven(0,0,0,0,0,0,0).Re())>0.)
1084  {
1085   fNestedLoopsResultsCosPro->Fill(13.5,Seven(h1,h2,h3,h4,h5,h6,h7).Re()/Seven(0,0,0,0,0,0,0).Re(),Seven(0,0,0,0,0,0,0).Re()); 
1086   fNestedLoopsResultsSinPro->Fill(13.5,Seven(h1,h2,h3,h4,h5,h6,h7).Im()/Seven(0,0,0,0,0,0,0).Re(),Seven(0,0,0,0,0,0,0).Re()); 
1087  }
1088  if(TMath::Abs(Eight(0,0,0,0,0,0,0,0).Re())>0.)
1089  {
1090   fNestedLoopsResultsCosPro->Fill(15.5,Eight(h1,h2,h3,h4,h5,h6,h7,h8).Re()/Eight(0,0,0,0,0,0,0,0).Re(),Eight(0,0,0,0,0,0,0,0).Re()); 
1091   fNestedLoopsResultsSinPro->Fill(15.5,Eight(h1,h2,h3,h4,h5,h6,h7,h8).Im()/Eight(0,0,0,0,0,0,0,0).Re(),Eight(0,0,0,0,0,0,0,0).Re()); 
1092  }
1093
1094  Int_t nPrim = anEvent->NumberOfTracks(); 
1095  Double_t dMultRP = anEvent->GetNumberOfRPs(); // TBI shall I promote this variable into data member? 
1096  AliFlowTrackSimple *aftsTrack = NULL; 
1097  Double_t dPhi1=0.,dPhi2=0.,dPhi3=0.,dPhi4=0.,dPhi5=0.,dPhi6=0.,dPhi7=0.,dPhi8=0.; 
1098  Double_t wPhi1=1.,wPhi2=1.,wPhi3=1.,wPhi4=1.,wPhi5=1.,wPhi6=1.,wPhi7=1.,wPhi8=1.; 
1099
1100  // 1-particle stuff: TBI       
1101  if(dMultRP>=1)
1102  {
1103   for(Int_t i1=0;i1<nPrim;i1++)
1104   {
1105    aftsTrack = anEvent->GetTrack(i1);
1106    if(!(aftsTrack->InRPSelection())){continue;}
1107    dPhi1 = aftsTrack->Phi(); 
1108    if(fUseWeights[0][0]){wPhi1 = Weight(dPhi1,"RP","phi");}
1109    // Fill:
1110    fNestedLoopsResultsCosPro->Fill(0.5,TMath::Cos(h1*dPhi1),wPhi1); 
1111    fNestedLoopsResultsSinPro->Fill(0.5,TMath::Sin(h1*dPhi1),wPhi1); 
1112   } // end of for(Int_t i1=0;i1<nPrim;i1++)
1113  } // end of if(nPrim>=1) 
1114
1115  // 2-particle correlations:       
1116  if(dMultRP>=2)
1117  {
1118   for(Int_t i1=0;i1<nPrim;i1++)
1119   {
1120    aftsTrack = anEvent->GetTrack(i1);
1121    if(!(aftsTrack->InRPSelection())){continue;}
1122    dPhi1 = aftsTrack->Phi(); 
1123    if(fUseWeights[0][0]){wPhi1 = Weight(dPhi1,"RP","phi");}
1124    for(Int_t i2=0;i2<nPrim;i2++)
1125    {
1126     if(i2==i1){continue;}
1127     aftsTrack = anEvent->GetTrack(i2);
1128     if(!(aftsTrack->InRPSelection())){continue;}
1129     dPhi2 = aftsTrack->Phi();
1130     if(fUseWeights[0][0]){wPhi2 = Weight(dPhi2,"RP","phi");}
1131     // Fill:
1132     fNestedLoopsResultsCosPro->Fill(2.5,TMath::Cos(h1*dPhi1+h2*dPhi2),wPhi1*wPhi2); 
1133     fNestedLoopsResultsSinPro->Fill(2.5,TMath::Sin(h1*dPhi1+h2*dPhi2),wPhi1*wPhi2); 
1134    } // end of for(Int_t i2=0;i2<nPrim;i2++)
1135   } // end of for(Int_t i1=0;i1<nPrim;i1++)
1136  } // end of if(nPrim>=2)
1137
1138  // 3-particle correlations:         
1139  if(dMultRP>=3)
1140  {
1141   for(Int_t i1=0;i1<nPrim;i1++)
1142   {
1143    aftsTrack=anEvent->GetTrack(i1);
1144    if(!(aftsTrack->InRPSelection())){continue;}
1145    dPhi1=aftsTrack->Phi();
1146    if(fUseWeights[0][0]){wPhi1 = Weight(dPhi1,"RP","phi");}
1147    for(Int_t i2=0;i2<nPrim;i2++)
1148    {
1149     if(i2==i1){continue;}
1150     aftsTrack=anEvent->GetTrack(i2);
1151     if(!(aftsTrack->InRPSelection())){continue;}
1152     dPhi2=aftsTrack->Phi();
1153     if(fUseWeights[0][0]){wPhi2 = Weight(dPhi2,"RP","phi");}
1154     for(Int_t i3=0;i3<nPrim;i3++)
1155     {
1156      if(i3==i1||i3==i2){continue;}
1157      aftsTrack=anEvent->GetTrack(i3);
1158      if(!(aftsTrack->InRPSelection())){continue;}
1159      dPhi3=aftsTrack->Phi();
1160      if(fUseWeights[0][0]){wPhi3 = Weight(dPhi3,"RP","phi");}
1161      // Fill:
1162      fNestedLoopsResultsCosPro->Fill(4.5,TMath::Cos(h1*dPhi1+h2*dPhi2+h3*dPhi3),wPhi1*wPhi2*wPhi3);
1163      fNestedLoopsResultsSinPro->Fill(4.5,TMath::Sin(h1*dPhi1+h2*dPhi2+h3*dPhi3),wPhi1*wPhi2*wPhi3);
1164     } // end of for(Int_t i3=0;i3<nPrim;i3++)
1165    } // end of for(Int_t i2=0;i2<nPrim;i2++)
1166   } // end of for(Int_t i1=0;i1<nPrim;i1++)
1167  } // end of if(nPrim>=3)
1168
1169  // 4-particle correlations:
1170  if(dMultRP>=4)
1171  {       
1172   for(Int_t i1=0;i1<nPrim;i1++)
1173   { 
1174    aftsTrack=anEvent->GetTrack(i1);
1175    if(!(aftsTrack->InRPSelection())){continue;}
1176    dPhi1=aftsTrack->Phi();
1177    if(fUseWeights[0][0]){wPhi1 = Weight(dPhi1,"RP","phi");}
1178    for(Int_t i2=0;i2<nPrim;i2++)
1179    {
1180     if(i2==i1){continue;}
1181     aftsTrack=anEvent->GetTrack(i2);
1182     if(!(aftsTrack->InRPSelection())){continue;}
1183     dPhi2=aftsTrack->Phi();
1184     if(fUseWeights[0][0]){wPhi2 = Weight(dPhi2,"RP","phi");}
1185     for(Int_t i3=0;i3<nPrim;i3++)
1186     {
1187      if(i3==i1||i3==i2){continue;}
1188      aftsTrack=anEvent->GetTrack(i3);
1189      if(!(aftsTrack->InRPSelection())){continue;}
1190      dPhi3=aftsTrack->Phi();
1191      if(fUseWeights[0][0]){wPhi3 = Weight(dPhi3,"RP","phi");}
1192      for(Int_t i4=0;i4<nPrim;i4++)
1193      {
1194       if(i4==i1||i4==i2||i4==i3){continue;}
1195       aftsTrack=anEvent->GetTrack(i4);
1196       if(!(aftsTrack->InRPSelection())){continue;}
1197       dPhi4=aftsTrack->Phi();
1198       if(fUseWeights[0][0]){wPhi4 = Weight(dPhi4,"RP","phi");}
1199       // Fill:
1200       fNestedLoopsResultsCosPro->Fill(6.5,TMath::Cos(h1*dPhi1+h2*dPhi2+h3*dPhi3+h4*dPhi4),wPhi1*wPhi2*wPhi3*wPhi4);
1201       fNestedLoopsResultsSinPro->Fill(6.5,TMath::Sin(h1*dPhi1+h2*dPhi2+h3*dPhi3+h4*dPhi4),wPhi1*wPhi2*wPhi3*wPhi4);
1202      } // end of for(Int_t i4=0;i4<nPrim;i4++) 
1203     } // end of for(Int_t i3=0;i3<nPrim;i3++)
1204    } // end of for(Int_t i2=0;i2<nPrim;i2++)
1205   } // end of for(Int_t i1=0;i1<nPrim;i1++)
1206  } // end of if(nPrim>=)
1207
1208  // 5-particle correlations:      
1209  if(dMultRP>=5)
1210  {
1211   for(Int_t i1=0;i1<nPrim;i1++)
1212   {
1213    aftsTrack=anEvent->GetTrack(i1);
1214    if(!(aftsTrack->InRPSelection())){continue;}  
1215    dPhi1=aftsTrack->Phi();
1216    if(fUseWeights[0][0]){wPhi1 = Weight(dPhi1,"RP","phi");}
1217    for(Int_t i2=0;i2<nPrim;i2++)
1218    {
1219     if(i2==i1){continue;}
1220     aftsTrack=anEvent->GetTrack(i2);
1221     if(!(aftsTrack->InRPSelection())){continue;}
1222     dPhi2=aftsTrack->Phi();
1223     if(fUseWeights[0][0]){wPhi2 = Weight(dPhi2,"RP","phi");}
1224     for(Int_t i3=0;i3<nPrim;i3++)
1225     {
1226      if(i3==i1||i3==i2){continue;}
1227      aftsTrack=anEvent->GetTrack(i3);
1228      if(!(aftsTrack->InRPSelection())){continue;}
1229      dPhi3=aftsTrack->Phi();
1230      if(fUseWeights[0][0]){wPhi3 = Weight(dPhi3,"RP","phi");}
1231      for(Int_t i4=0;i4<nPrim;i4++)
1232      {
1233       if(i4==i1||i4==i2||i4==i3){continue;}
1234       aftsTrack=anEvent->GetTrack(i4);
1235       if(!(aftsTrack->InRPSelection())){continue;}
1236       dPhi4=aftsTrack->Phi();
1237       if(fUseWeights[0][0]){wPhi4 = Weight(dPhi4,"RP","phi");}
1238       for(Int_t i5=0;i5<nPrim;i5++)
1239       {
1240        if(i5==i1||i5==i2||i5==i3||i5==i4){continue;}
1241        aftsTrack=anEvent->GetTrack(i5);
1242        if(!(aftsTrack->InRPSelection())){continue;}
1243        dPhi5=aftsTrack->Phi();
1244        if(fUseWeights[0][0]){wPhi5 = Weight(dPhi5,"RP","phi");}
1245        // Fill:   
1246        fNestedLoopsResultsCosPro->Fill(8.5,TMath::Cos(h1*dPhi1+h2*dPhi2+h3*dPhi3+h4*dPhi4+h5*dPhi5),wPhi1*wPhi2*wPhi3*wPhi4*wPhi5);
1247        fNestedLoopsResultsSinPro->Fill(8.5,TMath::Sin(h1*dPhi1+h2*dPhi2+h3*dPhi3+h4*dPhi4+h5*dPhi5),wPhi1*wPhi2*wPhi3*wPhi4*wPhi5);
1248       } // end of for(Int_t i5=0;i5<nPrim;i5++)
1249      } // end of for(Int_t i4=0;i4<nPrim;i4++)  
1250     } // end of for(Int_t i3=0;i3<nPrim;i3++)
1251    } // end of for(Int_t i2=0;i2<nPrim;i2++)
1252   } // end of for(Int_t i1=0;i1<nPrim;i1++)
1253  } // end of if(nPrim>=5)
1254   
1255  // 6-particle correlations:
1256  if(dMultRP>=6)
1257  {
1258   for(Int_t i1=0;i1<nPrim;i1++)
1259   {
1260    aftsTrack=anEvent->GetTrack(i1);
1261    if(!(aftsTrack->InRPSelection())){continue;}
1262    dPhi1=aftsTrack->Phi();
1263    if(fUseWeights[0][0]){wPhi1 = Weight(dPhi1,"RP","phi");}
1264    for(Int_t i2=0;i2<nPrim;i2++)
1265    {
1266     if(i2==i1){continue;}
1267     aftsTrack=anEvent->GetTrack(i2);
1268     if(!(aftsTrack->InRPSelection())){continue;}
1269     dPhi2=aftsTrack->Phi();
1270     if(fUseWeights[0][0]){wPhi2 = Weight(dPhi2,"RP","phi");}
1271     for(Int_t i3=0;i3<nPrim;i3++)
1272     {
1273      if(i3==i1||i3==i2){continue;}
1274      aftsTrack=anEvent->GetTrack(i3);
1275      if(!(aftsTrack->InRPSelection())){continue;}
1276      dPhi3=aftsTrack->Phi();
1277      if(fUseWeights[0][0]){wPhi3 = Weight(dPhi3,"RP","phi");}
1278      for(Int_t i4=0;i4<nPrim;i4++)
1279      {
1280       if(i4==i1||i4==i2||i4==i3){continue;}
1281       aftsTrack=anEvent->GetTrack(i4);
1282       if(!(aftsTrack->InRPSelection())){continue;}
1283       dPhi4=aftsTrack->Phi();
1284       if(fUseWeights[0][0]){wPhi4 = Weight(dPhi4,"RP","phi");}
1285       for(Int_t i5=0;i5<nPrim;i5++)
1286       {
1287        if(i5==i1||i5==i2||i5==i3||i5==i4){continue;}
1288        aftsTrack=anEvent->GetTrack(i5);
1289        if(!(aftsTrack->InRPSelection())){continue;}
1290        dPhi5=aftsTrack->Phi();
1291        if(fUseWeights[0][0]){wPhi5=Weight(dPhi5,"RP","phi");}
1292        for(Int_t i6=0;i6<nPrim;i6++)
1293        {
1294         if(i6==i1||i6==i2||i6==i3||i6==i4||i6==i5){continue;}
1295         aftsTrack=anEvent->GetTrack(i6);
1296         if(!(aftsTrack->InRPSelection())){continue;}
1297         dPhi6=aftsTrack->Phi(); 
1298         if(fUseWeights[0][0]){wPhi6=Weight(dPhi6,"RP","phi");}
1299         // Fill:   
1300         fNestedLoopsResultsCosPro->Fill(10.5,TMath::Cos(h1*dPhi1+h2*dPhi2+h3*dPhi3+h4*dPhi4+h5*dPhi5+h6*dPhi6),wPhi1*wPhi2*wPhi3*wPhi4*wPhi5*wPhi6);
1301         fNestedLoopsResultsSinPro->Fill(10.5,TMath::Sin(h1*dPhi1+h2*dPhi2+h3*dPhi3+h4*dPhi4+h5*dPhi5+h6*dPhi6),wPhi1*wPhi2*wPhi3*wPhi4*wPhi5*wPhi6);
1302        } // end of for(Int_t i6=0;i6<nPrim;i6++)
1303       } // end of for(Int_t i5=0;i5<nPrim;i5++)
1304      } // end of for(Int_t i4=0;i4<nPrim;i4++)
1305     } // end of for(Int_t i3=0;i3<nPrim;i3++)
1306    } // end of for(Int_t i2=0;i2<nPrim;i2++)
1307   } // end of for(Int_t i1=0;i1<nPrim;i1++)
1308  } // end of if(nPrim>=6)
1309   
1310  // 7-particle correlations:
1311  if(dMultRP>=7)
1312  {
1313   for(Int_t i1=0;i1<nPrim;i1++)
1314   { 
1315    aftsTrack=anEvent->GetTrack(i1);
1316    if(!(aftsTrack->InRPSelection())){continue;}
1317    dPhi1=aftsTrack->Phi();
1318    if(fUseWeights[0][0]){wPhi1=Weight(dPhi1,"RP","phi");}
1319    for(Int_t i2=0;i2<nPrim;i2++)
1320    {
1321     if(i2==i1){continue;}
1322     aftsTrack=anEvent->GetTrack(i2);
1323     if(!(aftsTrack->InRPSelection())){continue;}
1324     dPhi2=aftsTrack->Phi();
1325     if(fUseWeights[0][0]){wPhi2=Weight(dPhi2,"RP","phi");}
1326     for(Int_t i3=0;i3<nPrim;i3++)
1327     {
1328      if(i3==i1||i3==i2){continue;}
1329      aftsTrack=anEvent->GetTrack(i3);
1330      if(!(aftsTrack->InRPSelection())){continue;}
1331      dPhi3=aftsTrack->Phi();
1332      if(fUseWeights[0][0]){wPhi3=Weight(dPhi3,"RP","phi");}
1333      for(Int_t i4=0;i4<nPrim;i4++)
1334      {
1335       if(i4==i1||i4==i2||i4==i3){continue;}
1336       aftsTrack=anEvent->GetTrack(i4);
1337       if(!(aftsTrack->InRPSelection())){continue;}
1338       dPhi4=aftsTrack->Phi();
1339       if(fUseWeights[0][0]){wPhi4=Weight(dPhi4,"RP","phi");}
1340       for(Int_t i5=0;i5<nPrim;i5++)
1341       {
1342        if(i5==i1||i5==i2||i5==i3||i5==i4){continue;}
1343        aftsTrack=anEvent->GetTrack(i5);
1344        if(!(aftsTrack->InRPSelection())){continue;}
1345        dPhi5=aftsTrack->Phi();
1346        if(fUseWeights[0][0]){wPhi5=Weight(dPhi5,"RP","phi");}
1347        for(Int_t i6=0;i6<nPrim;i6++)
1348        {
1349         if(i6==i1||i6==i2||i6==i3||i6==i4||i6==i5){continue;}
1350         aftsTrack=anEvent->GetTrack(i6);
1351         if(!(aftsTrack->InRPSelection())){continue;}
1352         dPhi6=aftsTrack->Phi(); 
1353         if(fUseWeights[0][0]){wPhi6=Weight(dPhi6,"RP","phi");}
1354         for(Int_t i7=0;i7<nPrim;i7++)
1355         {
1356          if(i7==i1||i7==i2||i7==i3||i7==i4||i7==i5||i7==i6){continue;}
1357          aftsTrack=anEvent->GetTrack(i7);
1358          if(!(aftsTrack->InRPSelection())){continue;}
1359          dPhi7=aftsTrack->Phi(); 
1360          if(fUseWeights[0][0]){wPhi7=Weight(dPhi7,"RP","phi");}
1361          // Fill:   
1362          fNestedLoopsResultsCosPro->Fill(12.5,TMath::Cos(h1*dPhi1+h2*dPhi2+h3*dPhi3+h4*dPhi4+h5*dPhi5+h6*dPhi6+h7*dPhi7),wPhi1*wPhi2*wPhi3*wPhi4*wPhi5*wPhi6*wPhi7);
1363          fNestedLoopsResultsSinPro->Fill(12.5,TMath::Sin(h1*dPhi1+h2*dPhi2+h3*dPhi3+h4*dPhi4+h5*dPhi5+h6*dPhi6+h7*dPhi7),wPhi1*wPhi2*wPhi3*wPhi4*wPhi5*wPhi6*wPhi7);
1364         } // end of for(Int_t i7=0;i7<nPrim;i7++)
1365        } // end of for(Int_t i6=0;i6<nPrim;i6++) 
1366       } // end of for(Int_t i5=0;i5<nPrim;i5++)
1367      } // end of for(Int_t i4=0;i4<nPrim;i4++)  
1368     } // end of for(Int_t i3=0;i3<nPrim;i3++)
1369    } // end of for(Int_t i2=0;i2<nPrim;i2++)
1370   } // end of for(Int_t i1=0;i1<nPrim;i1++)
1371  } // end of if(nPrim>=7)
1372  
1373  // 8-particle correlations:
1374  if(dMultRP>=8)
1375  {
1376   for(Int_t i1=0;i1<nPrim;i1++)
1377   {
1378    aftsTrack=anEvent->GetTrack(i1);
1379    if(!(aftsTrack->InRPSelection())){continue;}
1380    dPhi1=aftsTrack->Phi();
1381    if(fUseWeights[0][0]){wPhi1=Weight(dPhi1,"RP","phi");}
1382    for(Int_t i2=0;i2<nPrim;i2++)
1383    {
1384     if(i2==i1){continue;}
1385     aftsTrack=anEvent->GetTrack(i2);
1386     if(!(aftsTrack->InRPSelection())){continue;}
1387     dPhi2=aftsTrack->Phi();
1388     if(fUseWeights[0][0]){wPhi2=Weight(dPhi2,"RP","phi");}
1389     for(Int_t i3=0;i3<nPrim;i3++)
1390     {
1391      if(i3==i1||i3==i2){continue;}
1392      aftsTrack=anEvent->GetTrack(i3);
1393      if(!(aftsTrack->InRPSelection())){continue;}
1394      dPhi3=aftsTrack->Phi();
1395      if(fUseWeights[0][0]){wPhi3=Weight(dPhi3,"RP","phi");}
1396      for(Int_t i4=0;i4<nPrim;i4++)
1397      {
1398       if(i4==i1||i4==i2||i4==i3){continue;}
1399       aftsTrack=anEvent->GetTrack(i4);
1400       if(!(aftsTrack->InRPSelection())){continue;}
1401       dPhi4=aftsTrack->Phi();
1402       if(fUseWeights[0][0]){wPhi4=Weight(dPhi4,"RP","phi");}
1403       for(Int_t i5=0;i5<nPrim;i5++)
1404       {
1405        if(i5==i1||i5==i2||i5==i3||i5==i4){continue;}
1406        aftsTrack=anEvent->GetTrack(i5);
1407        if(!(aftsTrack->InRPSelection())){continue;}
1408        dPhi5=aftsTrack->Phi();
1409        if(fUseWeights[0][0]){wPhi5=Weight(dPhi5,"RP","phi");}
1410        for(Int_t i6=0;i6<nPrim;i6++)
1411        {
1412         if(i6==i1||i6==i2||i6==i3||i6==i4||i6==i5){continue;}
1413         aftsTrack=anEvent->GetTrack(i6);
1414         if(!(aftsTrack->InRPSelection())){continue;}
1415         dPhi6=aftsTrack->Phi();
1416         if(fUseWeights[0][0]){wPhi6=Weight(dPhi6,"RP","phi");}
1417         for(Int_t i7=0;i7<nPrim;i7++)
1418         {
1419          if(i7==i1||i7==i2||i7==i3||i7==i4||i7==i5||i7==i6){continue;}
1420          aftsTrack=anEvent->GetTrack(i7);
1421          if(!(aftsTrack->InRPSelection())){continue;}
1422          dPhi7=aftsTrack->Phi();
1423          if(fUseWeights[0][0]){wPhi7=Weight(dPhi7,"RP","phi");}
1424          for(Int_t i8=0;i8<nPrim;i8++)
1425          {
1426           if(i8==i1||i8==i2||i8==i3||i8==i4||i8==i5||i8==i6||i8==i7){continue;}
1427           aftsTrack=anEvent->GetTrack(i8);
1428           if(!(aftsTrack->InRPSelection())){continue;}
1429           dPhi8=aftsTrack->Phi();
1430           if(fUseWeights[0][0]){wPhi8=Weight(dPhi8,"RP","phi");}
1431           // Fill:   
1432           fNestedLoopsResultsCosPro->Fill(14.5,TMath::Cos(h1*dPhi1+h2*dPhi2+h3*dPhi3+h4*dPhi4+h5*dPhi5+h6*dPhi6+h7*dPhi7+h8*dPhi8),wPhi1*wPhi2*wPhi3*wPhi4*wPhi5*wPhi6*wPhi7*wPhi8);
1433           fNestedLoopsResultsSinPro->Fill(14.5,TMath::Sin(h1*dPhi1+h2*dPhi2+h3*dPhi3+h4*dPhi4+h5*dPhi5+h6*dPhi6+h7*dPhi7+h8*dPhi8),wPhi1*wPhi2*wPhi3*wPhi4*wPhi5*wPhi6*wPhi7*wPhi8);
1434          } // end of for(Int_t i8=0;i8<nPrim;i8++)
1435         } // end of for(Int_t i7=0;i7<nPrim;i7++) 
1436        } // end of for(Int_t i6=0;i6<nPrim;i6++) 
1437       } // end of for(Int_t i5=0;i5<nPrim;i5++)
1438      } // end of for(Int_t i4=0;i4<nPrim;i4++)  
1439     } // end of for(Int_t i3=0;i3<nPrim;i3++)
1440    } // end of for(Int_t i2=0;i2<nPrim;i2++)
1441   } // end of for(Int_t i1=0;i1<nPrim;i1++)
1442  } // end of if(nPrim>=8)
1443  
1444  // *) Printout: TBI move somewhere else
1445  printf("\n cosine:");
1446  printf("\n  1-p => Q-vector:     %.12f",fNestedLoopsResultsCosPro->GetBinContent(2));
1447  printf("\n  1-p => Nested loops: %.12f",fNestedLoopsResultsCosPro->GetBinContent(1));
1448  printf("\n  2-p => Q-vector:     %.12f",fNestedLoopsResultsCosPro->GetBinContent(4));
1449  printf("\n  2-p => Nested loops: %.12f",fNestedLoopsResultsCosPro->GetBinContent(3));
1450  printf("\n  3-p => Q-vector:     %.12f",fNestedLoopsResultsCosPro->GetBinContent(6));
1451  printf("\n  3-p => Nested loops: %.12f",fNestedLoopsResultsCosPro->GetBinContent(5));
1452  printf("\n  4-p => Q-vector:     %.12f",fNestedLoopsResultsCosPro->GetBinContent(8));
1453  printf("\n  4-p => Nested loops: %.12f",fNestedLoopsResultsCosPro->GetBinContent(7));
1454  printf("\n  5-p => Q-vector:     %.12f",fNestedLoopsResultsCosPro->GetBinContent(10));
1455  printf("\n  5-p => Nested loops: %.12f",fNestedLoopsResultsCosPro->GetBinContent(9));
1456  printf("\n  6-p => Q-vector:     %.12f",fNestedLoopsResultsCosPro->GetBinContent(12));
1457  printf("\n  6-p => Nested loops: %.12f",fNestedLoopsResultsCosPro->GetBinContent(11));
1458  printf("\n  7-p => Q-vector:     %.12f",fNestedLoopsResultsCosPro->GetBinContent(14));
1459  printf("\n  7-p => Nested loops: %.12f",fNestedLoopsResultsCosPro->GetBinContent(13));
1460  printf("\n  8-p => Q-vector:     %.12f",fNestedLoopsResultsCosPro->GetBinContent(16));
1461  printf("\n  8-p => Nested loops: %.12f",fNestedLoopsResultsCosPro->GetBinContent(15));
1462
1463  printf("\n\n sinus:");
1464  printf("\n  1-p => Q-vector:     %.12f",fNestedLoopsResultsSinPro->GetBinContent(2));
1465  printf("\n  1-p => Nested loops: %.12f",fNestedLoopsResultsSinPro->GetBinContent(1));
1466  printf("\n  2-p => Q-vector:     %.12f",fNestedLoopsResultsSinPro->GetBinContent(4));
1467  printf("\n  2-p => Nested loops: %.12f",fNestedLoopsResultsSinPro->GetBinContent(3));
1468  printf("\n  3-p => Q-vector:     %.12f",fNestedLoopsResultsSinPro->GetBinContent(6));
1469  printf("\n  3-p => Nested loops: %.12f",fNestedLoopsResultsSinPro->GetBinContent(5));
1470  printf("\n  4-p => Q-vector:     %.12f",fNestedLoopsResultsSinPro->GetBinContent(8));
1471  printf("\n  4-p => Nested loops: %.12f",fNestedLoopsResultsSinPro->GetBinContent(7));
1472  printf("\n  5-p => Q-vector:     %.12f",fNestedLoopsResultsSinPro->GetBinContent(10));
1473  printf("\n  5-p => Nested loops: %.12f",fNestedLoopsResultsSinPro->GetBinContent(9));
1474  printf("\n  6-p => Q-vector:     %.12f",fNestedLoopsResultsSinPro->GetBinContent(12));
1475  printf("\n  6-p => Nested loops: %.12f",fNestedLoopsResultsSinPro->GetBinContent(11));
1476  printf("\n  7-p => Q-vector:     %.12f",fNestedLoopsResultsSinPro->GetBinContent(14));
1477  printf("\n  7-p => Nested loops: %.12f",fNestedLoopsResultsSinPro->GetBinContent(13));
1478  printf("\n  8-p => Q-vector:     %.12f",fNestedLoopsResultsSinPro->GetBinContent(16));
1479  printf("\n  8-p => Nested loops: %.12f",fNestedLoopsResultsSinPro->GetBinContent(15));
1480
1481  printf("\n\n"); 
1482
1483 } // void AliFlowAnalysisWithMultiparticleCorrelations::CrossCheckWithNestedLoops(AliFlowEventSimple *anEvent)
1484
1485 //=======================================================================================================================
1486
1487 void AliFlowAnalysisWithMultiparticleCorrelations::CrossCheckDiffWithNestedLoops(AliFlowEventSimple *anEvent)
1488 {
1489  // Cross-check results for differential multi-particle correlations with nested loops.
1490
1491  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::CrossCheckDiffWithNestedLoops(AliFlowEventSimple *anEvent)";
1492
1493  Int_t nPrim = anEvent->NumberOfTracks(); 
1494  AliFlowTrackSimple *aftsTrack = NULL; 
1495  Double_t dPsi1=0.,dPhi2=0.,dPhi3=0.,dPhi4=0.; 
1496  Double_t wPsi1=1.,wPhi2=1.,wPhi3=1.,wPhi4=1.; 
1497
1498  Int_t cs = fCrossCheckDiffCSCOBN[0]; // cos/sin
1499
1500  // TBI reimplement lines below in a more civilised manner:
1501  Bool_t bCrossCheck2p = kFALSE;
1502  Bool_t bCrossCheck3p = kFALSE;
1503  Bool_t bCrossCheck4p = kFALSE;
1504
1505  if(fCrossCheckDiffCSCOBN[1] == 2){bCrossCheck2p = kTRUE;}
1506  else if(fCrossCheckDiffCSCOBN[1] == 3){bCrossCheck3p = kTRUE;}
1507  else if(fCrossCheckDiffCSCOBN[1] == 4){bCrossCheck4p = kTRUE;}
1508
1509  if(Int_t(bCrossCheck2p + bCrossCheck3p + bCrossCheck4p) > 1)
1510  {
1511   Fatal(sMethodName.Data(),"Int_t(bCrossCheck2p + bCrossCheck3p + bCrossCheck4p) > 1");
1512  }
1513  if(!(bCrossCheck2p || bCrossCheck3p || bCrossCheck4p))
1514  {
1515   Fatal(sMethodName.Data(),"!(bCrossCheck2p || bCrossCheck3p || bCrossCheck4p)");
1516  }
1517  Int_t nDiffBinNo = fCrossCheckDiffCSCOBN[2];
1518  Double_t dPt = 0., dEta = 0.;
1519
1520  // <2'>:
1521  for(Int_t i1=0;i1<nPrim;i1++) // Loop over particles in a differential bin 
1522  {
1523   aftsTrack=anEvent->GetTrack(i1);
1524   if(!(aftsTrack->InPOISelection())){continue;}
1525   dPsi1=aftsTrack->Phi();
1526   if(fCalculateDiffCorrelationsVsPt)
1527   {
1528    dPt=aftsTrack->Pt();
1529    if(fDiffCorrelationsPro[0][1]->FindBin(dPt) != nDiffBinNo){continue;} // TBI spaghetti again 
1530   } else 
1531     {
1532      dEta=aftsTrack->Eta();
1533      if(fDiffCorrelationsPro[0][1]->FindBin(dEta) != nDiffBinNo){continue;} // TBI spaghetti again 
1534     }
1535   if(fUseWeights[1][0]){wPsi1=Weight(dPsi1,"POI","phi");}
1536   for(Int_t i2=0;i2<nPrim;i2++) // Loop over particles in an event
1537   {
1538    if(i2==i1){continue;} // get rid of autocorrelations
1539    aftsTrack=anEvent->GetTrack(i2);
1540    if(!(aftsTrack->InRPSelection())){continue;}
1541    dPhi2=aftsTrack->Phi();
1542    if(fUseWeights[0][0]){wPhi2=Weight(dPhi2,"RP","phi");}
1543    // Fill profiles:
1544    if(bCrossCheck2p)
1545    {
1546     if(fCrossCheckDiffCSCOBN[0] == 0)
1547     {
1548      fNestedLoopsDiffResultsPro->Fill(0.5,TMath::Cos(fDiffHarmonics[1][0]*dPsi1+fDiffHarmonics[1][1]*dPhi2),wPsi1*wPhi2);
1549     } else {fNestedLoopsDiffResultsPro->Fill(0.5,TMath::Sin(fDiffHarmonics[1][0]*dPsi1+fDiffHarmonics[1][1]*dPhi2),wPsi1*wPhi2);}
1550    } // if(bCrossCheck2p) 
1551   } // for(Int_t i2=0;i2<nPrim;i2++)
1552  } // for(Int_t i1=0;i1<nPrim;i1++)
1553
1554  // <3'>:
1555  for(Int_t i1=0;i1<nPrim;i1++) // Loop over particles in a differential bin
1556  {
1557   aftsTrack=anEvent->GetTrack(i1);
1558   if(!(aftsTrack->InPOISelection())){continue;}
1559   dPsi1=aftsTrack->Phi();
1560   if(fCalculateDiffCorrelationsVsPt)
1561   {
1562    dPt=aftsTrack->Pt();
1563    if(fDiffCorrelationsPro[0][1]->FindBin(dPt) != nDiffBinNo){continue;} // TBI spaghetti again 
1564   } else 
1565     {
1566      dEta=aftsTrack->Eta();
1567      if(fDiffCorrelationsPro[0][1]->FindBin(dEta) != nDiffBinNo){continue;} // TBI spaghetti again 
1568     }
1569   if(fUseWeights[1][0]){wPsi1=Weight(dPsi1,"POI","phi");}
1570   for(Int_t i2=0;i2<nPrim;i2++) // Loop over particles in an event
1571   {
1572    if(i2==i1){continue;} // get rid of autocorrelations
1573    aftsTrack=anEvent->GetTrack(i2);
1574    if(!(aftsTrack->InRPSelection())){continue;}
1575    dPhi2=aftsTrack->Phi();
1576    if(fUseWeights[0][0]){wPhi2=Weight(dPhi2,"RP","phi");}
1577    for(Int_t i3=0;i3<nPrim;i3++)
1578    {
1579     if(i3==i1||i3==i2){continue;} // get rid of autocorrelations
1580     aftsTrack=anEvent->GetTrack(i3);
1581     if(!(aftsTrack->InRPSelection())){continue;}
1582     dPhi3=aftsTrack->Phi();
1583     if(fUseWeights[0][0]){wPhi3=Weight(dPhi3,"RP","phi");}
1584     // Fill the profiles:
1585     if(bCrossCheck3p)
1586     {
1587      if(fCrossCheckDiffCSCOBN[0] == 0)
1588      {
1589       fNestedLoopsDiffResultsPro->Fill(0.5,TMath::Cos(fDiffHarmonics[2][0]*dPsi1+fDiffHarmonics[2][1]*dPhi2+fDiffHarmonics[2][2]*dPhi3),wPsi1*wPhi2*wPhi3);  
1590      } else {fNestedLoopsDiffResultsPro->Fill(0.5,TMath::Sin(fDiffHarmonics[2][0]*dPsi1+fDiffHarmonics[2][1]*dPhi2+fDiffHarmonics[2][2]*dPhi3),wPsi1*wPhi2*wPhi3);}
1591     } // if(bCrossCheck3p)
1592    } // end of for(Int_t i3=0;i3<nPrim;i3++)  
1593   } // for(Int_t i2=0;i2<nPrim;i2++)
1594  } // for(Int_t i1=0;i1<nPrim;i1++)
1595
1596  // <4'>:
1597  for(Int_t i1=0;i1<nPrim;i1++) // Loop over particles in a differential bin
1598  {
1599   aftsTrack=anEvent->GetTrack(i1);
1600   if(!(aftsTrack->InPOISelection())){continue;}
1601   dPsi1=aftsTrack->Phi();
1602   if(fCalculateDiffCorrelationsVsPt)
1603   {
1604    dPt=aftsTrack->Pt();
1605    if(fDiffCorrelationsPro[0][1]->FindBin(dPt) != nDiffBinNo){continue;} // TBI spaghetti again 
1606   } else 
1607     {
1608      dEta=aftsTrack->Eta();
1609      if(fDiffCorrelationsPro[0][1]->FindBin(dEta) != nDiffBinNo){continue;} // TBI spaghetti again 
1610     }
1611   if(fUseWeights[1][0]){wPsi1=Weight(dPsi1,"POI","phi");}
1612   for(Int_t i2=0;i2<nPrim;i2++) // Loop over particles in an event
1613   {
1614    if(i2==i1){continue;} // get rid of autocorrelations
1615    aftsTrack=anEvent->GetTrack(i2);
1616    if(!(aftsTrack->InRPSelection())){continue;}
1617    dPhi2=aftsTrack->Phi();
1618    if(fUseWeights[0][0]){wPhi2=Weight(dPhi2,"RP","phi");}
1619    for(Int_t i3=0;i3<nPrim;i3++)
1620    {
1621     if(i3==i1||i3==i2){continue;} // get rid of autocorrelations
1622     aftsTrack=anEvent->GetTrack(i3);
1623     if(!(aftsTrack->InRPSelection())){continue;}
1624     dPhi3=aftsTrack->Phi();
1625     if(fUseWeights[0][0]){wPhi3=Weight(dPhi3,"RP","phi");}
1626     for(Int_t i4=0;i4<nPrim;i4++)
1627     {
1628      if(i4==i1||i4==i2||i4==i3){continue;} // get rid of autocorrelations
1629      aftsTrack=anEvent->GetTrack(i4);
1630      if(!(aftsTrack->InRPSelection())){continue;}
1631      dPhi4=aftsTrack->Phi();
1632      if(fUseWeights[0][0]){wPhi4=Weight(dPhi4,"RP","phi");}
1633      // Fill the profiles:
1634      if(bCrossCheck4p)
1635      {
1636       if(fCrossCheckDiffCSCOBN[0] == 0)
1637       {
1638        fNestedLoopsDiffResultsPro->Fill(0.5,TMath::Cos(fDiffHarmonics[3][0]*dPsi1+fDiffHarmonics[3][1]*dPhi2+fDiffHarmonics[3][2]*dPhi3+fDiffHarmonics[3][3]*dPhi4),wPsi1*wPhi2*wPhi3*wPhi4);
1639       } else {fNestedLoopsDiffResultsPro->Fill(0.5,TMath::Sin(fDiffHarmonics[3][0]*dPsi1+fDiffHarmonics[3][1]*dPhi2+fDiffHarmonics[3][2]*dPhi3+fDiffHarmonics[3][3]*dPhi4),wPsi1*wPhi2*wPhi3*wPhi4);} 
1640      } // if(bCrossCheck4p)
1641     } // end of for(Int_t i4=0;i4<nPrim;i4++) 
1642    } // end of for(Int_t i3=0;i3<nPrim;i3++)  
1643   } // for(Int_t i2=0;i2<nPrim;i2++)
1644  } // for(Int_t i1=0;i1<nPrim;i1++)
1645
1646  // Printout:
1647  // 2-p:
1648  if(bCrossCheck2p)
1649  {
1650   printf("\n  2-p => Q-vector:     %.12f",fDiffCorrelationsPro[cs][1]->GetBinContent(nDiffBinNo));
1651   printf("\n  2-p => Nested loops: %.12f\n",fNestedLoopsDiffResultsPro->GetBinContent(1));
1652  }
1653  // 3-p:
1654  if(bCrossCheck3p)
1655  {
1656   printf("\n  3-p => Q-vector:     %.12f",fDiffCorrelationsPro[cs][2]->GetBinContent(nDiffBinNo));
1657   printf("\n  3-p => Nested loops: %.12f\n",fNestedLoopsDiffResultsPro->GetBinContent(1));
1658  } 
1659  // 4-p:
1660  if(bCrossCheck4p)
1661  {
1662   printf("\n  4-p => Q-vector:     %.12f",fDiffCorrelationsPro[cs][3]->GetBinContent(nDiffBinNo));
1663   printf("\n  4-p => Nested loops: %.12f\n",fNestedLoopsDiffResultsPro->GetBinContent(1));
1664  }
1665
1666 } // void AliFlowAnalysisWithMultiparticleCorrelations::CrossCheckDiffWithNestedLoops(AliFlowEventSimple *anEvent)
1667
1668 //=======================================================================================================================
1669
1670 void AliFlowAnalysisWithMultiparticleCorrelations::FillQvector(AliFlowEventSimple *anEvent)
1671 {
1672  // Fill Q-vector components.
1673
1674  Int_t nTracks = anEvent->NumberOfTracks(); // TBI shall I promote this to data member?
1675  Double_t dPhi = 0., wPhi = 1.; // azimuthal angle and corresponding phi weight
1676  Double_t dPt = 0., wPt = 1.; // transverse momentum and corresponding pT weight
1677  Double_t dEta = 0., wEta = 1.; // pseudorapidity and corresponding eta weight
1678  Double_t wToPowerP = 1.; // weight raised to power p
1679  for(Int_t t=0;t<nTracks;t++) // loop over all tracks
1680  {
1681   AliFlowTrackSimple *pTrack = anEvent->GetTrack(t);
1682   if(!pTrack){printf("\n AAAARGH: pTrack is NULL in MPC::FillQvector(...) !!!!"); continue;}
1683   if(!(pTrack->InRPSelection() || pTrack->InPOISelection())){printf("\n AAAARGH: pTrack is neither RP nor POI !!!!"); continue;}
1684   if(pTrack->InRPSelection()) // fill Q-vector components only with reference particles
1685   {
1686    wPhi = 1.; wPt = 1.; wEta = 1.; wToPowerP = 1.; // TBI this shall go somewhere else, for performance sake
1687
1688    // Access kinematic variables for RP and corresponding weights:
1689    dPhi = pTrack->Phi(); // azimuthal angle
1690    if(fUseWeights[0][0]){wPhi = Weight(dPhi,"RP","phi");} // corresponding phi weight
1691    //if(dPhi < 0.){dPhi += TMath::TwoPi();} TBI
1692    //if(dPhi > TMath::TwoPi()){dPhi -= TMath::TwoPi();} TBI
1693    dPt = pTrack->Pt();
1694    if(fUseWeights[0][1]){wPt = Weight(dPt,"RP","pt");} // corresponding pT weight
1695    dEta = pTrack->Eta();
1696    if(fUseWeights[0][2]){wEta = Weight(dEta,"RP","eta");} // corresponding eta weight
1697    // Calculate Q-vector components:
1698    for(Int_t h=0;h<fMaxHarmonic*fMaxCorrelator+1;h++)
1699    {
1700     for(Int_t wp=0;wp<fMaxCorrelator+1;wp++) // weight power
1701     {
1702      if(fUseWeights[0][0]||fUseWeights[0][1]||fUseWeights[0][2]){wToPowerP = pow(wPhi*wPt*wEta,wp);} 
1703      fQvector[h][wp] += TComplex(wToPowerP*TMath::Cos(h*dPhi),wToPowerP*TMath::Sin(h*dPhi));
1704     } // for(Int_t wp=0;wp<fMaxCorrelator+1;wp++)
1705    } // for(Int_t h=0;h<fMaxHarmonic*fMaxCorrelator+1;h++)
1706   } // if(pTrack->InRPSelection()) // fill Q-vector components only with reference particles
1707
1708   // Differential Q-vectors (a.k.a. p-vector and q-vector):
1709   if(!fCalculateDiffQvectors){continue;}
1710   if(pTrack->InPOISelection()) 
1711   {
1712    wPhi = 1.; wPt = 1.; wEta = 1.; wToPowerP = 1.; // TBI this shall go somewhere else, for performance sake
1713
1714    // Access kinematic variables for POI and corresponding weights:
1715    dPhi = pTrack->Phi(); // azimuthal angle
1716    if(fUseWeights[1][0]){wPhi = Weight(dPhi,"POI","phi");} // corresponding phi weight
1717    //if(dPhi < 0.){dPhi += TMath::TwoPi();} TBI
1718    //if(dPhi > TMath::TwoPi()){dPhi -= TMath::TwoPi();} TBI
1719    dPt = pTrack->Pt();
1720    if(fUseWeights[1][1]){wPt = Weight(dPt,"POI","pt");} // corresponding pT weight
1721    dEta = pTrack->Eta();
1722    if(fUseWeights[1][2]){wEta = Weight(dEta,"POI","eta");} // corresponding eta weight
1723    // Determine bin:
1724    Int_t binNo = -44;
1725    if(fCalculateDiffCorrelationsVsPt)
1726    { 
1727     binNo = fDiffCorrelationsPro[0][0]->FindBin(dPt); // TBI: hardwired [0][0]
1728    } else
1729      {
1730       binNo = fDiffCorrelationsPro[0][0]->FindBin(dEta); // TBI: hardwired [0][0]
1731      }
1732    // Calculate p-vector components:
1733    for(Int_t h=0;h<fMaxHarmonic*fMaxCorrelator+1;h++)
1734    {
1735     for(Int_t wp=0;wp<fMaxCorrelator+1;wp++) // weight power
1736     {
1737      if(fUseWeights[1][0]||fUseWeights[1][1]||fUseWeights[1][2]){wToPowerP = pow(wPhi*wPt*wEta,wp);} 
1738      fpvector[binNo-1][h][wp] += TComplex(wToPowerP*TMath::Cos(h*dPhi),wToPowerP*TMath::Sin(h*dPhi));
1739
1740      if(pTrack->InRPSelection()) 
1741      {
1742       // Fill q-vector components:
1743       wPhi = 1.; wPt = 1.; wEta = 1.; wToPowerP = 1.; // TBI this shall go somewhere else, for performance sake
1744
1745       if(fUseWeights[0][0]){wPhi = Weight(dPhi,"RP","phi");} // corresponding phi weight
1746       //if(dPhi < 0.){dPhi += TMath::TwoPi();} TBI
1747       //if(dPhi > TMath::TwoPi()){dPhi -= TMath::TwoPi();} TBI
1748       if(fUseWeights[0][1]){wPt = Weight(dPt,"RP","pt");} // corresponding pT weight
1749       if(fUseWeights[0][2]){wEta = Weight(dEta,"RP","eta");} // corresponding eta weight
1750       if(fUseWeights[1][0]){wPhi = Weight(dPhi,"POI","phi");} // corresponding phi weight
1751       //if(dPhi < 0.){dPhi += TMath::TwoPi();} TBI
1752       //if(dPhi > TMath::TwoPi()){dPhi -= TMath::TwoPi();} TBI
1753       if(fUseWeights[1][1]){wPt = Weight(dPt,"POI","pt");} // corresponding pT weight
1754       if(fUseWeights[1][2]){wEta = Weight(dEta,"POI","eta");} // corresponding eta weight
1755       if(fUseWeights[0][0]||fUseWeights[0][1]||fUseWeights[0][2]||fUseWeights[1][0]||fUseWeights[1][1]||fUseWeights[1][2]){wToPowerP = pow(wPhi*wPt*wEta,wp);} 
1756       fqvector[binNo-1][h][wp] += TComplex(wToPowerP*TMath::Cos(h*dPhi),wToPowerP*TMath::Sin(h*dPhi));
1757      } // if(pTrack->InRPSelection()) 
1758
1759     } // for(Int_t wp=0;wp<fMaxCorrelator+1;wp++)
1760    } // for(Int_t h=0;h<fMaxHarmonic*fMaxCorrelator+1;h++)
1761   } // if(pTrack->InPOISelection()) 
1762
1763  } // for(Int_t t=0;t<nTracks;t++) // loop over all tracks
1764
1765 } // void AliFlowAnalysisWithMultiparticleCorrelations::FillQvector(AliFlowEventSimple *anEvent)
1766
1767 //=======================================================================================================================
1768
1769 void AliFlowAnalysisWithMultiparticleCorrelations::CrossCheckSettings()
1770 {
1771  // Cross-check all initial settings in this method. 
1772  
1773  // a) Few cross-checks for control histograms;
1774  // b) Few cross-checks for flags for correlations;
1775  // c) 'Standard candles';
1776  // d) Q-cumulants;
1777  // e) Weights;
1778  // f) Differential correlations;
1779  // g) Nested loops;
1780  // h) Dump the points.
1781
1782  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::CrossCheckSettings()";
1783
1784  // a) Few cross-checks for control histograms: TBI the lines below are not really what they are supposed to be...
1785  /*
1786  if(fFillKinematicsHist && !fFillControlHistograms){Fatal(sMethodName.Data(),"fFillKinematicsHist && !fFillControlHistograms");}
1787  if(fFillMultDistributionsHist && !fFillControlHistograms){Fatal(sMethodName.Data(),"fFillMultDistributionsHist && !fFillControlHistograms");}
1788  if(fFillMultCorrelationsHist && !fFillControlHistograms){Fatal(sMethodName.Data(),"fFillMultCorrelationsHist && !fFillControlHistograms");}
1789  */ 
1790
1791  // b) Few cross-checks for flags for correlations: // TBI the lines bellow can be civilized
1792  Int_t iSum = (Int_t)fCalculateIsotropic + (Int_t)fCalculateSame + (Int_t)fCalculateSameIsotropic;
1793  if(iSum>1){Fatal(sMethodName.Data(),"iSum is doing crazy things...");}
1794  if(fCalculateOnlyCos && fCalculateOnlySin){Fatal(sMethodName.Data(),"fCalculateOnlyCos && fCalculateOnlySin");}
1795
1796  // c) 'Standard candles':
1797  if(fCalculateStandardCandles && !fCalculateCorrelations)
1798  {
1799   Fatal(sMethodName.Data(),"fCalculateStandardCandles && !fCalculateCorrelations");
1800  }
1801  if(fCalculateStandardCandles && fCalculateCorrelations && fCalculateSameIsotropic)
1802  {
1803   Fatal(sMethodName.Data(),"fCalculateStandardCandles && fCalculateCorrelations && fCalculateSameIsotropic");
1804  }
1805  if(fCalculateStandardCandles && fCalculateOnlyForHarmonicQC)
1806  {
1807   Fatal(sMethodName.Data(),"fCalculateStandardCandles && fCalculateOnlyForHarmonicQC");
1808  }
1809  if(fCalculateStandardCandles && fCalculateOnlyForSC && (4!=fDontGoBeyond))
1810  {
1811   Fatal(sMethodName.Data(),"fCalculateStandardCandles && fCalculateOnlyForSC && (4!=fDontGoBeyond)");
1812  }
1813  if(fCalculateStandardCandles && !fPropagateErrorSC)
1814  {
1815   Warning(sMethodName.Data(),"fCalculateStandardCandles && !fPropagateErrorSC");
1816  }
1817  if(fCalculateStandardCandles && fCalculateOnlySin)
1818  {
1819   Fatal(sMethodName.Data(),"fCalculateStandardCandles && fCalculateOnlySin");
1820  }
1821  if(fCalculateStandardCandles && fDontGoBeyond < 3)
1822  {
1823   Fatal(sMethodName.Data(),"fCalculateStandardCandles && fDontGoBeyond < 3");
1824  }
1825
1826  // d) Q-cumulants:
1827  if(fCalculateQcumulants && !fCalculateCorrelations)
1828  {
1829   Fatal(sMethodName.Data(),"fCalculateQcumulants && !fCalculateCorrelations");
1830  }
1831  if(fCalculateQcumulants && !(fHarmonicQC > 0))
1832  {
1833   Fatal(sMethodName.Data(),"fCalculateQcumulants && !(fHarmonicQC > 0)");
1834  }
1835  if(fCalculateQcumulants && fCalculateOnlyForSC)
1836  {
1837   Fatal(sMethodName.Data(),"fCalculateQcumulants && fCalculateOnlyForSC");
1838  }
1839  if(fCalculateQcumulants && !fPropagateErrorQC)
1840  {
1841   Warning(sMethodName.Data(),"fCalculateQcumulants && !fPropagateErrorQC");
1842  }
1843  if(fCalculateQcumulants && fCalculateOnlySin)
1844  {
1845   Fatal(sMethodName.Data(),"fCalculateQcumulants && fCalculateOnlySin");
1846  }
1847  
1848  // e) Weights:
1849  for(Int_t rp=0;rp<2;rp++) // [RP,POI]
1850  {
1851   for(Int_t ppe=0;ppe<3;ppe++) // [phi,pt,eta]
1852   {
1853    if(fUseWeights[rp][ppe] && !fWeightsHist[rp][ppe])
1854    {
1855     Fatal(sMethodName.Data(),"fUseWeights[rp][ppe] && !fWeightsHist[rp][ppe], rp = %d, ppe = %d",rp,ppe);
1856    }
1857   }
1858  }
1859
1860  // f) Differential correlations:
1861  if(fCalculateDiffCorrelations && !fCalculateDiffQvectors)
1862  {
1863   Fatal(sMethodName.Data(),"fCalculateDiffCorrelations && !fCalculateDiffQvectors"); 
1864  }
1865  if(fCalculateDiffCorrelations && !fCalculateQvector)
1866  {
1867   Fatal(sMethodName.Data(),"fCalculateDiffCorrelations && !fCalculateQvector"); 
1868  }
1869  if(!fCalculateDiffCorrelations && fCalculateDiffQvectors)
1870  {
1871   Fatal(sMethodName.Data(),"!fCalculateDiffCorrelations && fCalculateDiffQvectors"); 
1872  }
1873  if(fCalculateDiffCorrelations && !fUseDefaultBinning && (fnDiffBins < 1 || !fRangesDiffBins))
1874  {
1875   Fatal(sMethodName.Data(),"fCalculateDiffCorrelations && !fUseDefaultBinning && (fnDiffBins < 1 || !fRangesDiffBins)"); 
1876  }
1877  if(fCalculateDiffCorrelations && !(fCalculateDiffCos || fCalculateDiffSin))
1878  {
1879   Fatal(sMethodName.Data(),"fCalculateDiffCorrelations && !(fCalculateDiffCos || fCalculateDiffSin)"); 
1880  }
1881  if(fCalculateDiffCorrelations && fDontFill[1])
1882  {
1883   Warning(sMethodName.Data(),"fCalculateDiffCorrelations && fDontFill[1]"); 
1884  }
1885
1886  // g) Nested loops:
1887  if(fCrossCheckDiffWithNestedLoops && (1 == fCrossCheckDiffCSCOBN[0] && !fCalculateDiffSin))
1888  {
1889   Fatal(sMethodName.Data(),"fCrossCheckDiffWithNestedLoops && (1 == fCrossCheckDiffCSCOBN[0] && !CalculateDiffSin)"); 
1890  }
1891  if(fCrossCheckDiffWithNestedLoops && (0 == fCrossCheckDiffCSCOBN[0] && !fCalculateDiffCos))
1892  {
1893   Fatal(sMethodName.Data(),"fCrossCheckDiffWithNestedLoops && (0 == fCrossCheckDiffCSCOBN[0] && !CalculateDiffCos)"); 
1894  }
1895
1896  // h) Dump the points:
1897  if(fDumpThePoints && !fFillMultDistributionsHist)
1898  {
1899   Fatal(sMethodName.Data(),"if(fDumpThePoints && !fFillMultDistributionsHist)"); 
1900  }
1901  if(fDumpThePoints && fMaxNoEventsPerFile <= 0)
1902  {
1903   Fatal(sMethodName.Data(),"if(fDumpThePoints && fMaxNoEventsPerFile <= 0)"); 
1904  }
1905
1906 } // end of void AliFlowAnalysisWithMultiparticleCorrelations::CrossCheckSettings()
1907
1908 //=======================================================================================================================
1909
1910 void AliFlowAnalysisWithMultiparticleCorrelations::BookAndNestAllLists()
1911 {
1912  // Book and nest all lists nested in the base list fHistList.
1913
1914  // a) Book and nest lists for control histograms;
1915  // b) Book and nest lists for Q-vectors;
1916  // c) Book and nest lists for correlations;
1917  // d) Book and nest lists for e-b-e cumulants;
1918  // e) Book and nest lists for weights;
1919  // f) Book and nest lists for nested loops;
1920  // g) Book and nest lists for 'standard candles';
1921  // h) Book and nest lists for Q-cumulants;
1922  // i) Book and nest lists for differential correlations.
1923
1924  // a) Book and nest lists for control histograms:
1925  fControlHistogramsList = new TList();
1926  fControlHistogramsList->SetName("Control Histograms");
1927  fControlHistogramsList->SetOwner(kTRUE);
1928  fHistList->Add(fControlHistogramsList);
1929
1930  // b) Book and nest lists for Q-vectors:
1931  fQvectorList = new TList();
1932  fQvectorList->SetName("Q-vectors");
1933  fQvectorList->SetOwner(kTRUE);
1934  fHistList->Add(fQvectorList);
1935
1936  // c) Book and nest lists for correlations:
1937  fCorrelationsList = new TList();
1938  fCorrelationsList->SetName("Correlations");
1939  fCorrelationsList->SetOwner(kTRUE);
1940  fHistList->Add(fCorrelationsList);
1941
1942  // d) Book and nest lists for e-b-e cumulants:
1943  fEbECumulantsList = new TList();
1944  fEbECumulantsList->SetName("E-b-e Cumulants");
1945  fEbECumulantsList->SetOwner(kTRUE);
1946  fHistList->Add(fEbECumulantsList);
1947
1948  // e) Book and nest lists for weights:
1949  fWeightsList = new TList();
1950  fWeightsList->SetName("Weights");
1951  fWeightsList->SetOwner(kTRUE);
1952  fHistList->Add(fWeightsList);
1953
1954  // f) Book and nest lists for nested loops:
1955  fNestedLoopsList = new TList();
1956  fNestedLoopsList->SetName("Nested Loops");
1957  fNestedLoopsList->SetOwner(kTRUE);
1958  fHistList->Add(fNestedLoopsList);
1959
1960  // g) Book and nest lists for 'standard candles':
1961  fStandardCandlesList = new TList();
1962  fStandardCandlesList->SetName("Standard Candles");
1963  fStandardCandlesList->SetOwner(kTRUE);
1964  fHistList->Add(fStandardCandlesList);
1965
1966  // h) Book and nest lists for Q-cumulants:
1967  fQcumulantsList = new TList();
1968  fQcumulantsList->SetName("Q-cumulants");
1969  fQcumulantsList->SetOwner(kTRUE);
1970  fHistList->Add(fQcumulantsList);
1971
1972  // i) Book and nest lists for differential correlations:
1973  fDiffCorrelationsList = new TList();
1974  fDiffCorrelationsList->SetName("Differential Correlations");
1975  fDiffCorrelationsList->SetOwner(kTRUE);
1976  fHistList->Add(fDiffCorrelationsList);
1977
1978 } // end of void AliFlowAnalysisWithMultiparticleCorrelations::BookAndNestAllLists()
1979
1980 //=======================================================================================================================
1981
1982 void AliFlowAnalysisWithMultiparticleCorrelations::WriteHistograms(TString outputFileName)
1983 {
1984  // Store the final results in output file <outputFileName>.root.
1985
1986  TFile *output = new TFile(outputFileName.Data(),"RECREATE");
1987  fHistList->Write(fHistList->GetName(),TObject::kSingleKey);
1988
1989  delete output;
1990
1991 } // end of void AliFlowAnalysisWithMultiparticleCorrelations::WriteHistograms(TString outputFileName)
1992
1993 //=======================================================================================================================
1994
1995 void AliFlowAnalysisWithMultiparticleCorrelations::WriteHistograms(TDirectoryFile *outputFileName)
1996 {
1997  // Store the final results in output file <outputFileName>.root.
1998
1999  outputFileName->Add(fHistList);
2000  outputFileName->Write(outputFileName->GetName(),TObject::kSingleKey);
2001
2002 } // end of void AliFlowAnalysisWithMultiparticleCorrelations::WriteHistograms(TDirectoryFile *outputFileName)
2003
2004 //=======================================================================================================================
2005
2006 void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForControlHistograms()
2007 {
2008  // Book all the stuff for control histograms.
2009
2010  // a) Book the profile holding all the flags for control histograms;
2011  // b) Book all control histograms;
2012  //  b0) Book TH1D *fKinematicsHist[2][3]; 
2013  //  b1) Book TH1D *fMultDistributionsHist[3];
2014  //  b2) Book TH2D *fMultCorrelationsHist[3].
2015
2016  // a) Book the profile holding all the flags for control histograms: TBI stil incomplete 
2017  fControlHistogramsFlagsPro = new TProfile("fControlHistogramsFlagsPro","Flags and settings for control histograms",7,0,7);
2018  fControlHistogramsFlagsPro->SetTickLength(-0.01,"Y");
2019  fControlHistogramsFlagsPro->SetMarkerStyle(25);
2020  fControlHistogramsFlagsPro->SetLabelSize(0.04);
2021  fControlHistogramsFlagsPro->SetLabelOffset(0.02,"Y");
2022  fControlHistogramsFlagsPro->SetStats(kFALSE);
2023  fControlHistogramsFlagsPro->SetFillColor(kGray);
2024  fControlHistogramsFlagsPro->SetLineColor(kBlack);
2025  fControlHistogramsFlagsPro->GetXaxis()->SetBinLabel(1,"fFillControlHistograms"); fControlHistogramsFlagsPro->Fill(0.5,fFillControlHistograms);
2026  fControlHistogramsFlagsPro->GetXaxis()->SetBinLabel(2,"fFillKinematicsHist"); fControlHistogramsFlagsPro->Fill(1.5,fFillKinematicsHist);
2027  fControlHistogramsFlagsPro->GetXaxis()->SetBinLabel(3,"fFillMultDistributionsHist"); fControlHistogramsFlagsPro->Fill(2.5,fFillMultDistributionsHist);
2028  fControlHistogramsFlagsPro->GetXaxis()->SetBinLabel(4,"fFillMultCorrelationsHist"); fControlHistogramsFlagsPro->Fill(3.5,fFillMultCorrelationsHist);
2029  fControlHistogramsFlagsPro->GetXaxis()->SetBinLabel(5,"fDontFill[0=RP]"); fControlHistogramsFlagsPro->Fill(4.5,fDontFill[0]);
2030  fControlHistogramsFlagsPro->GetXaxis()->SetBinLabel(6,"fDontFill[1=POI]"); fControlHistogramsFlagsPro->Fill(5.5,fDontFill[1]);
2031  fControlHistogramsFlagsPro->GetXaxis()->SetBinLabel(7,"fDontFill[2=REF]"); fControlHistogramsFlagsPro->Fill(6.5,fDontFill[2]);
2032  fControlHistogramsList->Add(fControlHistogramsFlagsPro);
2033
2034  if(!fFillControlHistograms){return;} // TBI is this safe? Well, perhaps it is if I can't implement it better...
2035
2036  // b) Book all control histograms: // TBI add setters for all these values
2037  //  b0) Book TH1D *fKinematicsHist[2][3]:
2038  TString name[2][3] = {{"RP,phi","RP,pt","RP,eta"},{"POI,phi","POI,pt","POI,eta"}}; // [RP,POI][phi,pt,eta]
2039  TString title[2] = {"Reference particles (RP)","Particles of interest (POI)"}; // [RP,POI]
2040  Int_t lineColor[2] = {kBlue,kRed}; // [RP,POI]
2041  Int_t fillColor[2] = {kBlue-10,kRed-10}; // [RP,POI]
2042  TString xAxisTitle[3] = {"#phi","p_{T}","#eta"}; // [phi,pt,eta]
2043  if(fFillKinematicsHist)
2044  {
2045   for(Int_t rp=0;rp<2;rp++) // [RP,POI]
2046   {
2047    if(fDontFill[rp]){continue;}
2048    for(Int_t ppe=0;ppe<3;ppe++) // [phi,pt,eta]
2049    {
2050     fKinematicsHist[rp][ppe] = new TH1D(name[rp][ppe].Data(),title[rp].Data(),fnBins[rp][ppe],fMin[rp][ppe],fMax[rp][ppe]);
2051     fKinematicsHist[rp][ppe]->GetXaxis()->SetTitle(xAxisTitle[ppe].Data());
2052     fKinematicsHist[rp][ppe]->SetLineColor(lineColor[rp]);
2053     fKinematicsHist[rp][ppe]->SetFillColor(fillColor[rp]);
2054     fKinematicsHist[rp][ppe]->SetMinimum(0.); 
2055     fControlHistogramsList->Add(fKinematicsHist[rp][ppe]);
2056    }
2057   }
2058  } // if(fFillKinematicsHist)
2059
2060  //  b1) Book TH1D *fMultDistributionsHist[3]: // TBI add setters for all these values
2061  TString nameMult[3] = {"Multiplicity (RP)","Multiplicity (POI)","Multiplicity (REF)"}; // [RP,POI,reference multiplicity]
2062  TString titleMult[3] = {"Reference particles (RP)","Particles of interest (POI)",""}; // [RP,POI,reference multiplicity]
2063  Int_t lineColorMult[3] = {kBlue,kRed,kGreen+2}; // [RP,POI,reference multiplicity]
2064  Int_t fillColorMult[3] = {kBlue-10,kRed-10,kGreen-10}; // [RP,POI,reference multiplicity]
2065  TString xAxisTitleMult[3] = {"Multiplicity (RP)","Multiplicity (POI)","Multiplicity (REF)"}; // [phi,pt,eta]
2066  if(fFillMultDistributionsHist)
2067  {
2068   for(Int_t rprm=0;rprm<3;rprm++) // [RP,POI,reference multiplicity]
2069   {
2070    if(fDontFill[rprm]){continue;}
2071    fMultDistributionsHist[rprm] = new TH1D(nameMult[rprm].Data(),titleMult[rprm].Data(),fnBinsMult[rprm],fMinMult[rprm],fMaxMult[rprm]);
2072    fMultDistributionsHist[rprm]->GetXaxis()->SetTitle(xAxisTitleMult[rprm].Data());
2073    fMultDistributionsHist[rprm]->SetLineColor(lineColorMult[rprm]);
2074    fMultDistributionsHist[rprm]->SetFillColor(fillColorMult[rprm]);
2075    fControlHistogramsList->Add(fMultDistributionsHist[rprm]);
2076   } // for(Int_t rprm=0;rprm<3;rprm++) // [RP,POI,reference multiplicity]
2077  } // if(fFillMultDistributionsHist)
2078
2079  //  b2) Book TH2I *fMultCorrelationsHist[3]: 
2080  if(fFillMultCorrelationsHist)
2081  {
2082   if(!fDontFill[0] && !fDontFill[1])
2083   {
2084    fMultCorrelationsHist[0] = new TH2I("Multiplicity (RP vs. POI)","Multiplicity (RP vs. POI)",fnBinsMult[0],fMinMult[0],fMaxMult[0],fnBinsMult[1],fMinMult[1],fMaxMult[1]);
2085    fMultCorrelationsHist[0]->GetXaxis()->SetTitle(xAxisTitleMult[0].Data());
2086    fMultCorrelationsHist[0]->GetYaxis()->SetTitle(xAxisTitleMult[1].Data());
2087    fControlHistogramsList->Add(fMultCorrelationsHist[0]);
2088   }
2089   if(!fDontFill[0] && !fDontFill[2])
2090   {
2091    fMultCorrelationsHist[1] = new TH2I("Multiplicity (RP vs. REF)","Multiplicity (RP vs. REF)",fnBinsMult[0],fMinMult[0],fMaxMult[0],fnBinsMult[2],fMinMult[2],fMaxMult[2]);
2092    fMultCorrelationsHist[1]->GetXaxis()->SetTitle(xAxisTitleMult[0].Data());
2093    fMultCorrelationsHist[1]->GetYaxis()->SetTitle(xAxisTitleMult[2].Data());
2094    fControlHistogramsList->Add(fMultCorrelationsHist[1]);
2095   }
2096   if(!fDontFill[1] && !fDontFill[2])
2097   {
2098    fMultCorrelationsHist[2] = new TH2I("Multiplicity (POI vs. REF)","Multiplicity (POI vs. REF)",fnBinsMult[1],fMinMult[1],fMaxMult[1],fnBinsMult[2],fMinMult[2],fMaxMult[2]);
2099    fMultCorrelationsHist[2]->GetXaxis()->SetTitle(xAxisTitleMult[1].Data());
2100    fMultCorrelationsHist[2]->GetYaxis()->SetTitle(xAxisTitleMult[2].Data());
2101    fControlHistogramsList->Add(fMultCorrelationsHist[2]);
2102   }
2103  } // if(fFillMultCorrelationsHist){
2104
2105 } // void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForControlHistograms()
2106
2107 //=======================================================================================================================
2108
2109 void AliFlowAnalysisWithMultiparticleCorrelations::FillControlHistograms(AliFlowEventSimple *anEvent)
2110 {
2111  // Fill control histograms. 
2112  // a) Fill TH1D *fKinematicsHist[2][3];
2113  // b) Fill TH1D *fMultDistributionsHist[3]; 
2114  // c) Fill TH2D *fMultCorrelationsHist[3].  
2115
2116  // a) Fill TH1D *fKinematicsHist[2][3]:
2117  if(fFillKinematicsHist)
2118  {
2119   Int_t nTracks = anEvent->NumberOfTracks(); // TBI shall I promote this to data member?
2120   for(Int_t t=0;t<nTracks;t++) // loop over all tracks
2121   {
2122    AliFlowTrackSimple *pTrack = anEvent->GetTrack(t);
2123    if(!pTrack){printf("\n AAAARGH: pTrack is NULL in MPC::FCH() !!!!");continue;}
2124    if(pTrack)
2125    {
2126     Double_t dPhi = pTrack->Phi(); 
2127     //if(dPhi < 0.){dPhi += TMath::TwoPi();} TBI
2128     //if(dPhi > TMath::TwoPi()){dPhi -= TMath::TwoPi();} TBI
2129     Double_t dPt = pTrack->Pt();
2130     Double_t dEta = pTrack->Eta();
2131     Double_t dPhiPtEta[3] = {dPhi,dPt,dEta};
2132     for(Int_t rp=0;rp<2;rp++) // [RP,POI]
2133     {
2134      for(Int_t ppe=0;ppe<3;ppe++) // [phi,pt,eta]
2135      {
2136       if((0==rp && pTrack->InRPSelection()) || (1==rp && pTrack->InPOISelection())) // TBI 
2137       { 
2138        if(fKinematicsHist[rp][ppe]){fKinematicsHist[rp][ppe]->Fill(dPhiPtEta[ppe]);}
2139       }
2140      } // for(Int_t ppe=0;ppe<3;ppe++) // [phi,pt,eta]
2141     } // for(Int_t rp=0;rp<2;rp++) // [RP,POI]
2142    } // if(pTrack)  
2143   } // for(Int_t t=0;t<nTracks;t++) // loop over all tracks
2144  } // if(fFillKinematicsHist)
2145
2146  // b) Fill TH1D *fMultDistributionsHist[3]: 
2147  Double_t dMultRP = anEvent->GetNumberOfRPs(); // TBI shall I promote these 3 variables into data members? 
2148  Double_t dMultPOI = anEvent->GetNumberOfPOIs();
2149  Double_t dMultREF = anEvent->GetReferenceMultiplicity();
2150  Double_t dMult[3] = {dMultRP,dMultPOI,dMultREF};
2151  for(Int_t rprm=0;rprm<3;rprm++) // [RP,POI,reference multiplicity]
2152  {
2153   if(fFillMultDistributionsHist && fMultDistributionsHist[rprm]){fMultDistributionsHist[rprm]->Fill(dMult[rprm]);}      
2154  } 
2155
2156  // c) Fill TH2I *fMultCorrelationsHist[3]:  
2157  if(fFillMultCorrelationsHist)
2158  {
2159   if(fMultCorrelationsHist[0]){fMultCorrelationsHist[0]->Fill((Int_t)dMultRP,(Int_t)dMultPOI);} // RP vs. POI
2160   if(fMultCorrelationsHist[1]){fMultCorrelationsHist[1]->Fill((Int_t)dMultRP,(Int_t)dMultREF);} // RP vs. refMult
2161   if(fMultCorrelationsHist[2]){fMultCorrelationsHist[2]->Fill((Int_t)dMultPOI,(Int_t)dMultREF);} // POI vs. refMult
2162  } // if(fFillMultCorrelationsHist)
2163
2164 } // void AliFlowAnalysisWithMultiparticleCorrelations::FillControlHistograms(AliFlowEventSimple *anEvent)
2165
2166 //=======================================================================================================================
2167
2168 void AliFlowAnalysisWithMultiparticleCorrelations::InitializeArraysForControlHistograms()
2169 {
2170  // Initialize all arrays for control histograms.
2171
2172  // a) Initialize TH1D *fKinematicsHist[2][3];
2173  // b) Initialize TH1D *fMultDistributionsHist[3]; 
2174  // c) Initialize TH2D *fMultCorrelationsHist[3];  
2175  // d) Initialize Bool_t fDontFill[3];   
2176  // e) Initialize default binning values for fKinematicsHist[2][3];
2177  // f) Initialize default binning values for fMultCorrelationsHist[3].
2178  
2179  // a) Initialize TH1D *fKinematicsHist[2][3]:
2180  for(Int_t rp=0;rp<2;rp++) // [RP,POI]
2181  {
2182   for(Int_t ppe=0;ppe<3;ppe++) // [phi,pt,eta]
2183   {
2184    fKinematicsHist[rp][ppe] = NULL;
2185   } 
2186  } 
2187
2188  // b) Initialize TH1D *fMultDistributionsHist[3]:
2189  for(Int_t rprm=0;rprm<3;rprm++) // [RP,POI,reference multiplicity]
2190  {
2191   fMultDistributionsHist[rprm] = NULL;      
2192  } 
2193
2194  // c) Initialize TH2I *fMultCorrelationsHist[3]: 
2195  for(Int_t r=0;r<3;r++) // [RP vs. POI, RP vs. refMult, POI vs. refMult]  
2196  {
2197   fMultCorrelationsHist[r] = NULL; 
2198  }
2199
2200  // d) Initialize Bool_t fDontFill[3]:
2201  for(Int_t rpr=0;rpr<3;rpr++) // [RP,POI,REF]
2202  {
2203   fDontFill[rpr] = kFALSE;
2204  }
2205
2206  // e) Initialize default binning values for fKinematicsHist[2][3]:
2207  // nBins:
2208  fnBins[0][0] = 360;  // [RP][phi]
2209  fnBins[0][1] = 1000; // [RP][pt]
2210  fnBins[0][2] = 1000; // [RP][eta]
2211  fnBins[1][0] = 360;  // [POI][phi]
2212  fnBins[1][1] = 1000; // [POI][pt]
2213  fnBins[1][2] = 1000; // [POI][eta]
2214  // Min:
2215  fMin[0][0] = 0.;  // [RP][phi]
2216  fMin[0][1] = 0.;  // [RP][pt]
2217  fMin[0][2] = -1.; // [RP][eta]
2218  fMin[1][0] = 0.;  // [POI][phi]
2219  fMin[1][1] = 0.;  // [POI][pt]
2220  fMin[1][2] = -1.; // [POI][eta]
2221  // Max:
2222  fMax[0][0] = TMath::TwoPi(); // [RP][phi]
2223  fMax[0][1] = 10.;            // [RP][pt]
2224  fMax[0][2] = 1.;             // [RP][eta]
2225  fMax[1][0] = TMath::TwoPi(); // [POI][phi]
2226  fMax[1][1] = 10.;            // [POI][pt]
2227  fMax[1][2] = 1.;             // [POI][eta]
2228
2229  // f) Initialize default binning values for fMultCorrelationsHist[3]:
2230  // nBins:
2231  fnBinsMult[0] = 3000; // [RP]
2232  fnBinsMult[1] = 3000; // [POI]
2233  fnBinsMult[2] = 3000; // [REF]
2234  // Min:
2235  fMinMult[0] = 0.; // [RP]
2236  fMinMult[1] = 0.; // [POI]
2237  fMinMult[2] = 0.; // [REF]
2238  // Max:
2239  fMaxMult[0] = 3000.; // [RP]
2240  fMaxMult[1] = 3000.; // [POI]
2241  fMaxMult[2] = 3000.; // [REF]
2242
2243 } // void AliFlowAnalysisWithMultiparticleCorrelations::InitializeArraysForControlHistograms()
2244
2245 //=======================================================================================================================
2246
2247 void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForQvector()
2248 {
2249  // Book all the stuff for Q-vector.
2250
2251  // a) Book the profile holding all the flags for Q-vector;
2252  // ...
2253
2254  // a) Book the profile holding all the flags for Q-vector:
2255  fQvectorFlagsPro = new TProfile("fQvectorFlagsPro","Flags for Q-vectors",2,0,2);
2256  fQvectorFlagsPro->SetTickLength(-0.01,"Y");
2257  fQvectorFlagsPro->SetMarkerStyle(25);
2258  fQvectorFlagsPro->SetLabelSize(0.03);
2259  fQvectorFlagsPro->SetLabelOffset(0.02,"Y");
2260  fQvectorFlagsPro->SetStats(kFALSE);
2261  fQvectorFlagsPro->SetFillColor(kGray);
2262  fQvectorFlagsPro->SetLineColor(kBlack);
2263  fQvectorFlagsPro->GetXaxis()->SetBinLabel(1,"fCalculateQvector"); fQvectorFlagsPro->Fill(0.5,fCalculateQvector); 
2264  fQvectorFlagsPro->GetXaxis()->SetBinLabel(2,"fCalculateDiffQvectors"); fQvectorFlagsPro->Fill(1.5,fCalculateDiffQvectors); 
2265  fQvectorList->Add(fQvectorFlagsPro);
2266
2267  // ...
2268
2269 } // void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForQvector()
2270
2271 //=======================================================================================================================
2272
2273 void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForCorrelations()
2274 {
2275  // Book all the stuff for correlations.
2276
2277  // TBI this method can be implemented in a much more civilised way. 
2278
2279  // a) Book the profile holding all the flags for correlations;
2280  // b) Book TProfile *fCorrelationsPro[2][8] ([0=cos,1=sin][1p,2p,...,8p]).
2281
2282  TString sMethodName = "void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForCorrelations()";
2283
2284  // a) Book the profile holding all the flags for correlations:
2285  fCorrelationsFlagsPro = new TProfile("fCorrelationsFlagsPro","Flags for correlations",13,0,13);
2286  fCorrelationsFlagsPro->SetTickLength(-0.01,"Y");
2287  fCorrelationsFlagsPro->SetMarkerStyle(25);
2288  fCorrelationsFlagsPro->SetLabelSize(0.03);
2289  fCorrelationsFlagsPro->SetLabelOffset(0.02,"Y");
2290  fCorrelationsFlagsPro->SetStats(kFALSE);
2291  fCorrelationsFlagsPro->SetFillColor(kGray);
2292  fCorrelationsFlagsPro->SetLineColor(kBlack);
2293  fCorrelationsFlagsPro->GetXaxis()->SetBinLabel(1,"fCalculateCorrelations"); fCorrelationsFlagsPro->Fill(0.5,fCalculateCorrelations); 
2294  fCorrelationsFlagsPro->GetXaxis()->SetBinLabel(2,"fMaxHarmonic"); fCorrelationsFlagsPro->Fill(1.5,fMaxHarmonic); 
2295  fCorrelationsFlagsPro->GetXaxis()->SetBinLabel(3,"fMaxCorrelator"); fCorrelationsFlagsPro->Fill(2.5,fMaxCorrelator); 
2296  fCorrelationsFlagsPro->GetXaxis()->SetBinLabel(4,"fCalculateIsotropic"); fCorrelationsFlagsPro->Fill(3.5,fCalculateIsotropic); 
2297  fCorrelationsFlagsPro->GetXaxis()->SetBinLabel(5,"fCalculateSame"); fCorrelationsFlagsPro->Fill(4.5,fCalculateSame); 
2298  fCorrelationsFlagsPro->GetXaxis()->SetBinLabel(6,"fSkipZeroHarmonics"); fCorrelationsFlagsPro->Fill(5.5,fSkipZeroHarmonics); 
2299  fCorrelationsFlagsPro->GetXaxis()->SetBinLabel(7,"fCalculateSameIsotropic"); fCorrelationsFlagsPro->Fill(6.5,fCalculateSameIsotropic); 
2300  fCorrelationsFlagsPro->GetXaxis()->SetBinLabel(8,"fCalculateAll"); fCorrelationsFlagsPro->Fill(7.5,fCalculateAll); 
2301  fCorrelationsFlagsPro->GetXaxis()->SetBinLabel(9,"fDontGoBeyond"); fCorrelationsFlagsPro->Fill(8.5,fDontGoBeyond); 
2302  fCorrelationsFlagsPro->GetXaxis()->SetBinLabel(10,"fCalculateOnlyForHarmonicQC"); fCorrelationsFlagsPro->Fill(9.5,fCalculateOnlyForHarmonicQC); 
2303  fCorrelationsFlagsPro->GetXaxis()->SetBinLabel(11,"fCalculateOnlyForSC"); fCorrelationsFlagsPro->Fill(10.5,fCalculateOnlyForSC); 
2304  fCorrelationsFlagsPro->GetXaxis()->SetBinLabel(12,"fCalculateOnlyCos"); fCorrelationsFlagsPro->Fill(11.5,fCalculateOnlyCos); 
2305  fCorrelationsFlagsPro->GetXaxis()->SetBinLabel(13,"fCalculateOnlySin"); fCorrelationsFlagsPro->Fill(12.5,fCalculateOnlySin);
2306  fCorrelationsList->Add(fCorrelationsFlagsPro);
2307
2308  if(!fCalculateCorrelations){return;} // TBI is this safe enough? 
2309
2310  // b) Book TProfile *fCorrelationsPro[2][8] ([0=cos,1=sin][1p,2p,...,8p]): // TBI hardwired 8, shall be fMaxCorrelator
2311  cout<<" => Booking TProfile *fCorrelationsPro[2][8]..."<<endl;
2312  TString sCosSin[2] = {"Cos","Sin"};
2313  Int_t markerColor[2] = {kBlue,kRed};
2314  Int_t markerStyle[2] = {kFullSquare,kFullSquare};
2315  Int_t nBins[8] = {1,1,1,1,1,1,1,1}; // TBI hardwired 8, shall be fMaxCorrelator
2316  Int_t nBinsTitle[8] = {1,1,1,1,1,1,1,1}; // TBI hardwired 8, shall be fMaxCorrelator
2317  Int_t nToBeFilled[8] = {0,0,0,0,0,0,0,0}; // TBI hardwired 8, shall be fMaxCorrelator
2318  for(Int_t c=0;c<fMaxCorrelator;c++) // [1p,2p,...,8p]
2319  {
2320   // Implementing \binom{n+k-1}{k}, which is the resulting number of sets obtained
2321   // after sampling n starting elements into k subsets, repetitions allowed.
2322   // In my case, n=2*fMaxHarmonic+1, k=c+1, hence:
2323   nBins[c] = (Int_t)(TMath::Factorial(2*fMaxHarmonic+1+c+1-1)
2324            / (TMath::Factorial(2*fMaxHarmonic+1-1)*TMath::Factorial(c+1)));
2325   nBinsTitle[c] = nBins[c];
2326   if(c>=fDontGoBeyond){nBins[c]=1;} // TBI is this really safe? 
2327  } // for(Int_t c=0;c<8;c++) // [1p,2p,...,8p]
2328  for(Int_t cs=0;cs<2;cs++) // [0=cos,1=sin]
2329  {
2330   if(fCalculateOnlyCos && 1==cs){continue;}
2331   else if(fCalculateOnlySin && 0==cs){continue;}
2332   for(Int_t c=0;c<fMaxCorrelator;c++) // [1p,2p,...,8p]
2333   {
2334    if(c==fDontGoBeyond){continue;}
2335    if(fCalculateOnlyForHarmonicQC && c%2==0){continue;}
2336    fCorrelationsPro[cs][c] = new TProfile(Form("%dpCorrelations%s",c+1,sCosSin[cs].Data()),"",nBins[c],0.,1.*nBins[c]);
2337    fCorrelationsPro[cs][c]->Sumw2();
2338    fCorrelationsPro[cs][c]->SetStats(kFALSE);
2339    fCorrelationsPro[cs][c]->SetMarkerColor(markerColor[cs]);
2340    fCorrelationsPro[cs][c]->SetMarkerStyle(markerStyle[cs]);
2341    fCorrelationsList->Add(fCorrelationsPro[cs][c]);
2342   } // for(Int_t c=0;c<8;c++) // [1p,2p,...,8p]
2343  } // for(Int_t cs=0;cs<2;cs++) // [0=cos,1=sin]
2344  // Set all bin labels: TBI this can be implemented better, most likely...
2345  Int_t binNo[2][8]; 
2346  for(Int_t cs=0;cs<2;cs++) // [0=cos,1=sin]
2347  {
2348   if(fCalculateOnlyCos && 1==cs){continue;}
2349   else if(fCalculateOnlySin && 0==cs){continue;}
2350   for(Int_t c=0;c<fMaxCorrelator;c++)
2351   {
2352    binNo[cs][c] = 1;
2353   } 
2354  } // for(Int_t cs=0;cs<2;cs++) // [0=cos,1=sin]
2355  
2356  for(Int_t n1=-fMaxHarmonic;n1<=fMaxHarmonic;n1++) 
2357  {
2358   cout<< Form("    Patience, this takes some time... n1 = %d/%d\r",n1+fMaxHarmonic,2*fMaxHarmonic)<<flush; // TBI
2359   if(fSkipZeroHarmonics && 0==n1){continue;}
2360   if(fCalculateOnlyForHarmonicQC && TMath::Abs(n1) != fHarmonicQC){continue;}
2361   if(fCalculateAll)
2362   {
2363    for(Int_t cs=0;cs<2;cs++) 
2364    {
2365     if(fCalculateOnlyCos && 1==cs){continue;}
2366     else if(fCalculateOnlySin && 0==cs){continue;}
2367     if(fCorrelationsPro[cs][0]){fCorrelationsPro[cs][0]->GetXaxis()->SetBinLabel(binNo[cs][0]++,Form("%s(%d)",sCosSin[cs].Data(),n1));}
2368    } // for(Int_t cs=0;cs<2;cs++) 
2369    nToBeFilled[0]++; 
2370   }
2371   if(1==fDontGoBeyond){continue;}
2372   for(Int_t n2=n1;n2<=fMaxHarmonic;n2++) 
2373   {
2374    if(fSkipZeroHarmonics && 0==n2){continue;}
2375    if(fCalculateOnlyForHarmonicQC && TMath::Abs(n2) != fHarmonicQC){continue;}
2376    if(fCalculateAll || (fCalculateIsotropic && 0==n1+n2) || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2)) 
2377       || (fCalculateSameIsotropic && 0==n1+n2 && TMath::Abs(n1)==TMath::Abs(n2)) 
2378       || (fCalculateOnlyForHarmonicQC && 0==n1+n2)
2379       || (fCalculateOnlyForSC && 0==n1+n2))
2380    {  
2381     for(Int_t cs=0;cs<2;cs++) 
2382     {
2383      if(fCalculateOnlyCos && 1==cs){continue;}
2384      else if(fCalculateOnlySin && 0==cs){continue;}
2385      if(fCorrelationsPro[cs][1]){fCorrelationsPro[cs][1]->GetXaxis()->SetBinLabel(binNo[cs][1]++,Form("%s(%d,%d)",sCosSin[cs].Data(),n1,n2));}
2386     } // for(Int_t cs=0;cs<2;cs++) 
2387     nToBeFilled[1]++; 
2388    }
2389    if(2==fDontGoBeyond){continue;}
2390    for(Int_t n3=n2;n3<=fMaxHarmonic;n3++) 
2391    {
2392     if(fSkipZeroHarmonics && 0==n3){continue;}
2393     if(fCalculateOnlyForHarmonicQC && TMath::Abs(n3) != fHarmonicQC){continue;}
2394     if(fCalculateAll || (fCalculateIsotropic && 0==n1+n2+n3) || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3))
2395        || (fCalculateSameIsotropic && 0==n1+n2+n3 && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3)) 
2396        || (fCalculateOnlyForHarmonicQC && 0==n1+n2+n3))
2397     {  
2398      for(Int_t cs=0;cs<2;cs++) 
2399      {
2400       if(fCalculateOnlyCos && 1==cs){continue;}
2401       else if(fCalculateOnlySin && 0==cs){continue;}
2402       if(fCorrelationsPro[cs][2]){fCorrelationsPro[cs][2]->GetXaxis()->SetBinLabel(binNo[cs][2]++,Form("%s(%d,%d,%d)",sCosSin[cs].Data(),n1,n2,n3));}
2403      } // for(Int_t cs=0;cs<2;cs++) 
2404      nToBeFilled[2]++; 
2405     }
2406     if(3==fDontGoBeyond){continue;}
2407     for(Int_t n4=n3;n4<=fMaxHarmonic;n4++) 
2408     {
2409      if(fSkipZeroHarmonics && 0==n4){continue;}
2410      if(fCalculateOnlyForHarmonicQC && TMath::Abs(n4) != fHarmonicQC){continue;}
2411      if(fCalculateAll || (fCalculateIsotropic && 0==n1+n2+n3+n4) || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4))
2412        || (fCalculateSameIsotropic && 0==n1+n2+n3+n4 && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4)) 
2413        || (fCalculateOnlyForHarmonicQC && 0==n1+n2+n3+n4)
2414        || (fCalculateOnlyForSC && (0==n1+n4 && 0==n2+n3 && n1 != n2 && n3 != n4)))
2415      {   
2416       for(Int_t cs=0;cs<2;cs++) 
2417       {
2418        if(fCalculateOnlyCos && 1==cs){continue;}
2419        else if(fCalculateOnlySin && 0==cs){continue;}
2420        if(fCorrelationsPro[cs][3]){fCorrelationsPro[cs][3]->GetXaxis()->SetBinLabel(binNo[cs][3]++,Form("%s(%d,%d,%d,%d)",sCosSin[cs].Data(),n1,n2,n3,n4));}
2421       } // for(Int_t cs=0;cs<2;cs++) 
2422       nToBeFilled[3]++; 
2423      } 
2424      if(4==fDontGoBeyond){continue;}
2425      for(Int_t n5=n4;n5<=fMaxHarmonic;n5++) 
2426      {
2427       if(fSkipZeroHarmonics && 0==n5){continue;}
2428       if(fCalculateOnlyForHarmonicQC && TMath::Abs(n5) != fHarmonicQC){continue;}
2429       if(fCalculateAll || (fCalculateIsotropic && 0==n1+n2+n3+n4+n5) 
2430          || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4) && TMath::Abs(n1)==TMath::Abs(n5))
2431          || (fCalculateSameIsotropic && 0==n1+n2+n3+n4+n5 && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4) && TMath::Abs(n1)==TMath::Abs(n5)) 
2432          || (fCalculateOnlyForHarmonicQC && 0==n1+n2+n3+n4+n5))
2433       {   
2434        for(Int_t cs=0;cs<2;cs++) 
2435        {
2436         if(fCalculateOnlyCos && 1==cs){continue;}
2437         else if(fCalculateOnlySin && 0==cs){continue;}
2438         if(fCorrelationsPro[cs][4]){fCorrelationsPro[cs][4]->GetXaxis()->SetBinLabel(binNo[cs][4]++,Form("%s(%d,%d,%d,%d,%d)",sCosSin[cs].Data(),n1,n2,n3,n4,n5));}
2439        } // for(Int_t cs=0;cs<2;cs++) 
2440        nToBeFilled[4]++; 
2441       }
2442       if(5==fDontGoBeyond){continue;}
2443       for(Int_t n6=n5;n6<=fMaxHarmonic;n6++) 
2444       {
2445        if(fSkipZeroHarmonics && 0==n6){continue;}
2446        if(fCalculateOnlyForHarmonicQC && TMath::Abs(n6) != fHarmonicQC){continue;}
2447        if(fCalculateAll || (fCalculateIsotropic && 0==n1+n2+n3+n4+n5+n6)  
2448           || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4) 
2449               && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6))
2450           || (fCalculateSameIsotropic && 0==n1+n2+n3+n4+n5+n6 && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) 
2451               && TMath::Abs(n1)==TMath::Abs(n4) && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6)) 
2452           || (fCalculateOnlyForHarmonicQC && 0==n1+n2+n3+n4+n5+n6))
2453        {   
2454         for(Int_t cs=0;cs<2;cs++) 
2455         {
2456          if(fCalculateOnlyCos && 1==cs){continue;}
2457          else if(fCalculateOnlySin && 0==cs){continue;}
2458          if(fCorrelationsPro[cs][5]){fCorrelationsPro[cs][5]->GetXaxis()->SetBinLabel(binNo[cs][5]++,Form("%s(%d,%d,%d,%d,%d,%d)",sCosSin[cs].Data(),n1,n2,n3,n4,n5,n6));}         
2459         } // for(Int_t cs=0;cs<2;cs++) 
2460         nToBeFilled[5]++; 
2461        }
2462        if(6==fDontGoBeyond){continue;}
2463        for(Int_t n7=n6;n7<=fMaxHarmonic;n7++) 
2464        {
2465         if(fSkipZeroHarmonics && 0==n7){continue;}
2466         if(fCalculateOnlyForHarmonicQC && TMath::Abs(n7) != fHarmonicQC){continue;}
2467         if(fCalculateAll || (fCalculateIsotropic && 0==n1+n2+n3+n4+n5+n6+n7) 
2468            || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4) 
2469                && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6) && TMath::Abs(n1)==TMath::Abs(n7))
2470            || (fCalculateSameIsotropic && 0==n1+n2+n3+n4+n5+n6+n7 && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4) 
2471                && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6) && TMath::Abs(n1)==TMath::Abs(n7)) 
2472            || (fCalculateOnlyForHarmonicQC && 0==n1+n2+n3+n4+n5+n6+n7))
2473         {   
2474          for(Int_t cs=0;cs<2;cs++) 
2475          {
2476           if(fCalculateOnlyCos && 1==cs){continue;}
2477           else if(fCalculateOnlySin && 0==cs){continue;}
2478           if(fCorrelationsPro[cs][6]){fCorrelationsPro[cs][6]->GetXaxis()->SetBinLabel(binNo[cs][6]++,Form("%s(%d,%d,%d,%d,%d,%d,%d)",sCosSin[cs].Data(),n1,n2,n3,n4,n5,n6,n7));}
2479          } // for(Int_t cs=0;cs<2;cs++) 
2480          nToBeFilled[6]++; 
2481         }
2482         if(7==fDontGoBeyond){continue;}
2483         for(Int_t n8=n7;n8<=fMaxHarmonic;n8++) 
2484         {
2485          if(fSkipZeroHarmonics && 0==n8){continue;}
2486          if(fCalculateOnlyForHarmonicQC && TMath::Abs(n8) != fHarmonicQC){continue;}
2487          if(fCalculateAll || (fCalculateIsotropic && 0==n1+n2+n3+n4+n5+n6+n7+n8) 
2488             || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4) 
2489                 && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6) && TMath::Abs(n1)==TMath::Abs(n7) && TMath::Abs(n1)==TMath::Abs(n8))
2490             || (fCalculateSameIsotropic && 0==n1+n2+n3+n4+n5+n6+n7+n8 && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) 
2491                 && TMath::Abs(n1)==TMath::Abs(n4) && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6) && TMath::Abs(n1)==TMath::Abs(n7) 
2492                 && TMath::Abs(n1)==TMath::Abs(n8))
2493             || (fCalculateOnlyForHarmonicQC && 0==n1+n2+n3+n4+n5+n6+n7+n8))
2494          {    
2495           for(Int_t cs=0;cs<2;cs++) 
2496           {
2497            if(fCalculateOnlyCos && 1==cs){continue;}
2498            else if(fCalculateOnlySin && 0==cs){continue;}
2499            if(fCorrelationsPro[cs][7]){fCorrelationsPro[cs][7]->GetXaxis()->SetBinLabel(binNo[cs][7]++,Form("%s(%d,%d,%d,%d,%d,%d,%d,%d)",sCosSin[cs].Data(),n1,n2,n3,n4,n5,n6,n7,n8));}
2500           } // for(Int_t cs=0;cs<2;cs++) 
2501           nToBeFilled[7]++; 
2502          }
2503         } // for(Int_t n8=n7;n8<=fMaxHarmonic;n8++)
2504        } // for(Int_t n7=n6;n7<=fMaxHarmonic;n7++) 
2505       } // for(Int_t n6=n5;n6<=fMaxHarmonic;n6++) 
2506      } // for(Int_t n5=n4;n5<=fMaxHarmonic;n5++) 
2507     } // for(Int_t n4=n3;n4<=fMaxHarmonic;n4++)   
2508    } // for(Int_t n3=n2;n3<=fMaxHarmonic;n3++) 
2509   } // for(Int_t n2=n1;n2<=fMaxHarmonic;n2++)
2510  } // for(Int_t n1=-fMaxHarmonic;n1<=fMaxHarmonic;n1++) 
2511
2512  for(Int_t cs=0;cs<2;cs++) // [0=cos,1=sin]
2513  {
2514   if(fCalculateOnlyCos && 1==cs){continue;}
2515   else if(fCalculateOnlySin && 0==cs){continue;}
2516   for(Int_t c=0;c<fMaxCorrelator;c++) // [1p,2p,...,8p]
2517   {
2518    if(!fCorrelationsPro[cs][c]){continue;}
2519    fCorrelationsPro[cs][c]->SetTitle(Form("%d-p correlations, %s terms, %d/%d in total",c+1,sCosSin[cs].Data(),nToBeFilled[c],nBinsTitle[c]));
2520    fCorrelationsPro[cs][c]->GetXaxis()->SetRangeUser(0.,fCorrelationsPro[cs][c]->GetBinLowEdge(nToBeFilled[c]+1));
2521   }
2522  } 
2523  cout<<"    Booked.                                           "<<endl; // TBI 
2524
2525 } // end of void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForCorrelations()
2526
2527 //=======================================================================================================================
2528
2529 void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForDiffCorrelations()
2530 {
2531  // Book all the stuff for differential correlations.
2532
2533  // a) Book the profile holding all the flags for differential correlations;
2534  // b) Book TProfile *fDiffCorrelationsPro[2][4] ([0=cos,1=sin][1p,2p,3p,4p]).
2535
2536  TString sMethodName = "void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForDiffCorrelations()";
2537
2538  // a) Book the profile holding all the flags for differential correlations:
2539  fDiffCorrelationsFlagsPro = new TProfile("fDiffCorrelationsFlagsPro","Flags for differential correlations",5,0,5);
2540  fDiffCorrelationsFlagsPro->SetTickLength(-0.01,"Y");
2541  fDiffCorrelationsFlagsPro->SetMarkerStyle(25);
2542  fDiffCorrelationsFlagsPro->SetLabelSize(0.03);
2543  fDiffCorrelationsFlagsPro->SetLabelOffset(0.02,"Y");
2544  fDiffCorrelationsFlagsPro->SetStats(kFALSE);
2545  fDiffCorrelationsFlagsPro->SetFillColor(kGray);
2546  fDiffCorrelationsFlagsPro->SetLineColor(kBlack);
2547  fDiffCorrelationsFlagsPro->GetXaxis()->SetBinLabel(1,"fCalculateDiffCorrelations"); fDiffCorrelationsFlagsPro->Fill(0.5,fCalculateDiffCorrelations); 
2548  fDiffCorrelationsFlagsPro->GetXaxis()->SetBinLabel(2,"fCalculateDiffCos"); fDiffCorrelationsFlagsPro->Fill(1.5,fCalculateDiffCos); 
2549  fDiffCorrelationsFlagsPro->GetXaxis()->SetBinLabel(3,"fCalculateDiffSin"); fDiffCorrelationsFlagsPro->Fill(2.5,fCalculateDiffSin); 
2550  fDiffCorrelationsFlagsPro->GetXaxis()->SetBinLabel(4,"fCalculateDiffCorrelationsVsPt"); fDiffCorrelationsFlagsPro->Fill(3.5,fCalculateDiffCorrelationsVsPt); 
2551  fDiffCorrelationsFlagsPro->GetXaxis()->SetBinLabel(5,"fUseDefaultBinning"); fDiffCorrelationsFlagsPro->Fill(4.5,fUseDefaultBinning); 
2552  fDiffCorrelationsList->Add(fDiffCorrelationsFlagsPro);
2553
2554  if(!fCalculateDiffCorrelations){return;}  
2555
2556  // b) Book TProfile *fDiffCorrelationsPro[2][4] ([0=cos,1=sin][1p,2p,3p,4p]):
2557  Bool_t fDiffStore[2][4] = {{0,1,1,1},{0,0,0,0}}; // store or not TBI promote to data member, and implement setter perhaps  
2558  Int_t markerColor[2] = {kRed,kGreen};
2559  Int_t markerStyle[2] = {kFullSquare,kOpenSquare};
2560  TString sCosSin[2] = {"Cos","Sin"};
2561  TString sLabel[4] = {Form("%d",fDiffHarmonics[0][0]),
2562                       Form("%d,%d",fDiffHarmonics[1][0],fDiffHarmonics[1][1]),
2563                       Form("%d,%d,%d",fDiffHarmonics[2][0],fDiffHarmonics[2][1],fDiffHarmonics[2][2]),
2564                       Form("%d,%d,%d,%d",fDiffHarmonics[3][0],fDiffHarmonics[3][1],fDiffHarmonics[3][2],fDiffHarmonics[3][3])};
2565
2566  for(Int_t cs=0;cs<2;cs++) // [0=cos,1=sin]
2567  {
2568   if(!fCalculateDiffCos && 0==cs){continue;}
2569   if(!fCalculateDiffSin && 1==cs){continue;}
2570
2571   for(Int_t c=0;c<4;c++) // [1p,2p,3p,4p]
2572   {
2573    if(fCalculateDiffCorrelationsVsPt)
2574    {
2575     if(fUseDefaultBinning)
2576     {
2577      // vs pt, default binning:  
2578      fDiffCorrelationsPro[cs][c] = new TProfile(Form("%s, %dp, %s",sCosSin[cs].Data(),c+1,"pt"),
2579                                                 Form("%s(%s)",sCosSin[cs].Data(),sLabel[c].Data()),
2580                                                 100,0.,10.);
2581     } else // if(fUseDefaultBinning)
2582       {
2583        // vs pt, non-default binning:
2584        fDiffCorrelationsPro[cs][c] = new TProfile(Form("%s, %dp, %s",sCosSin[cs].Data(),c+1,"pt"),
2585                                                   Form("%s(%s)",sCosSin[cs].Data(),sLabel[c].Data()),
2586                                                   fnDiffBins,fRangesDiffBins);
2587       }// else // if(fUseDefaultBinning) 
2588       fDiffCorrelationsPro[cs][c]->Sumw2();
2589       fDiffCorrelationsPro[cs][c]->SetStats(kFALSE);
2590       fDiffCorrelationsPro[cs][c]->SetMarkerColor(markerColor[cs]);
2591       fDiffCorrelationsPro[cs][c]->SetMarkerStyle(markerStyle[cs]);
2592       fDiffCorrelationsPro[cs][c]->GetXaxis()->SetTitle("p_{T}");
2593       if(fDiffStore[cs][c]){fDiffCorrelationsList->Add(fDiffCorrelationsPro[cs][c]);}
2594    } else // if(fCalculateDiffCorrelationsVsPt)
2595      {
2596       if(fUseDefaultBinning)
2597       {
2598        // vs eta, default binning:
2599        fDiffCorrelationsPro[cs][c] = new TProfile(Form("%s, %dp, %s",sCosSin[cs].Data(),c+1,"eta"),
2600                                                   Form("%s(%s)",sCosSin[cs].Data(),sLabel[c].Data()),
2601                                                   100,-1.,1.);
2602       } else // if(fUseDefaultBinning)
2603         {
2604          // vs eta, non-default binning:
2605          fDiffCorrelationsPro[cs][c] = new TProfile(Form("%s, %dp, %s",sCosSin[cs].Data(),c+1,"eta"),
2606                                                     Form("%s(%s)",sCosSin[cs].Data(),sLabel[c].Data()),
2607                                                     fnDiffBins,fRangesDiffBins);
2608         } // else // if(fUseDefaultBinning)
2609         fDiffCorrelationsPro[cs][c]->Sumw2();
2610         fDiffCorrelationsPro[cs][c]->SetStats(kFALSE);
2611         fDiffCorrelationsPro[cs][c]->SetMarkerColor(markerColor[cs]);
2612         fDiffCorrelationsPro[cs][c]->SetMarkerStyle(markerStyle[cs]);
2613         fDiffCorrelationsPro[cs][c]->GetXaxis()->SetTitle("#eta");
2614         if(fDiffStore[cs][c]){fDiffCorrelationsList->Add(fDiffCorrelationsPro[cs][c]);}
2615      } // else // if(fCalculateDiffCorrelationsVsPt)
2616   } // for(Int_t c=0;c<4;c++) // [1p,2p,3p,4p]
2617  } // for(Int_t cs=0;cs<2;cs++) // [0=cos,1=sin]
2618
2619 } // void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForDiffCorrelations()
2620
2621 //=======================================================================================================================
2622
2623 void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForEbECumulants()
2624 {
2625  // Book all the stuff for event-by-event cumulants.
2626
2627  // a) Book the profile holding all the flags for e-b-e cumulants;
2628  // b) Book TProfile *fEbECumulantsPro[2][8] ([0=cos,1=sin][1p,2p,...,8p]).
2629
2630  TString sMethodName = "void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForEbECumulants()";
2631
2632  // a) Book the profile holding all the flags for e-b-e cumulants:
2633  fEbECumulantsFlagsPro = new TProfile("fEbECumulantsFlagsPro","Flags for e-b-e cumulants",1,0,1);
2634  fEbECumulantsFlagsPro->SetTickLength(-0.01,"Y");
2635  fEbECumulantsFlagsPro->SetMarkerStyle(25);
2636  fEbECumulantsFlagsPro->SetLabelSize(0.03);
2637  fEbECumulantsFlagsPro->SetLabelOffset(0.02,"Y");
2638  fEbECumulantsFlagsPro->SetStats(kFALSE);
2639  fEbECumulantsFlagsPro->SetFillColor(kGray);
2640  fEbECumulantsFlagsPro->SetLineColor(kBlack);
2641  fEbECumulantsFlagsPro->GetXaxis()->SetBinLabel(1,"fCalculateEbECumulants"); fEbECumulantsFlagsPro->Fill(0.5,fCalculateEbECumulants); 
2642  fEbECumulantsList->Add(fEbECumulantsFlagsPro);
2643
2644  if(!fCalculateEbECumulants){return;} // TBI is this safe enough? 
2645
2646  // b) Book TProfile *fEbECumulantsPro[2][8] ([0=cos,1=sin][1p,2p,...,8p]):
2647  TString sCosSin[2] = {"Cos","Sin"};
2648  Int_t markerColor[2] = {kBlue,kRed};
2649  Int_t markerStyle[2] = {kFullSquare,kFullSquare};
2650  Int_t nBins[8] = {1,1,1,1,1,1,1,1}; // TBI hardwired 8, shall be fMaxCorrelator
2651  Int_t nBinsTitle[8] = {1,1,1,1,1,1,1,1}; // TBI hardwired 8, shall be fMaxCorrelator
2652  Int_t nToBeFilled[8] = {0,0,0,0,0,0,0,0}; // TBI hardwired 8, shall be fMaxCorrelator
2653  for(Int_t c=0;c<fMaxCorrelator;c++) // [1p,2p,...,8p]
2654  {
2655   // Implementing \binom{n+k-1}{k}, which is the resulting number of sets obtained
2656   // after sampling n starting elements into k subsets, repetitions allowed.
2657   // In my case, n=2*fMaxHarmonic+1, k=c+1, hence:
2658   nBins[c] = (Int_t)(TMath::Factorial(2*fMaxHarmonic+1+c+1-1)
2659            / (TMath::Factorial(2*fMaxHarmonic+1-1)*TMath::Factorial(c+1)));
2660   nBinsTitle[c] = nBins[c];
2661   if(c>=fDontGoBeyond){nBins[c]=1;} // TBI a bit of spaghetti here...
2662  } // for(Int_t c=0;c<8;c++) // [1p,2p,...,8p]
2663  for(Int_t cs=0;cs<2;cs++) // [0=cos,1=sin]
2664  {
2665   for(Int_t c=0;c<fMaxCorrelator;c++) // [1p,2p,...,8p]
2666   {
2667    fEbECumulantsPro[cs][c] = new TProfile(Form("%dpEbECumulants%s",c+1,sCosSin[cs].Data()),"",nBins[c],0.,1.*nBins[c]);
2668    fEbECumulantsPro[cs][c]->Sumw2();
2669    fEbECumulantsPro[cs][c]->SetStats(kFALSE);
2670    fEbECumulantsPro[cs][c]->SetMarkerColor(markerColor[cs]);
2671    fEbECumulantsPro[cs][c]->SetMarkerStyle(markerStyle[cs]);
2672    fEbECumulantsList->Add(fEbECumulantsPro[cs][c]);
2673   } // for(Int_t c=0;c<8;c++) // [1p,2p,...,8p]
2674  } // for(Int_t cs=0;cs<2;cs++) // [0=cos,1=sin]
2675  // Set all bin labels: TBI this can be implemented better, most likely...
2676  Int_t binNo[8]; for(Int_t c=0;c<fMaxCorrelator;c++){binNo[c]=1;} // TBI hardwired 8, shall be fMaxCorrelator
2677  for(Int_t n1=-fMaxHarmonic;n1<=fMaxHarmonic;n1++) 
2678  {
2679   if(fSkipZeroHarmonics && 0==n1){continue;}
2680   if(fCalculateAll)
2681   {
2682    fEbECumulantsPro[0][0]->GetXaxis()->SetBinLabel(binNo[0],Form("Cos(%d)",n1));
2683    fEbECumulantsPro[1][0]->GetXaxis()->SetBinLabel(binNo[0]++,Form("Sin(%d)",n1));
2684    nToBeFilled[0]++; 
2685   }
2686   if(1==fDontGoBeyond){continue;}
2687   for(Int_t n2=n1;n2<=fMaxHarmonic;n2++) 
2688   {
2689    if(fSkipZeroHarmonics && 0==n2){continue;}
2690    if(fCalculateAll || (fCalculateIsotropic && 0==n1+n2) || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2)) 
2691       || (fCalculateSameIsotropic && 0==n1+n2 &&  TMath::Abs(n1)==TMath::Abs(n2)))
2692    {  
2693     fEbECumulantsPro[0][1]->GetXaxis()->SetBinLabel(binNo[1],Form("Cos(%d,%d)",n1,n2));
2694     fEbECumulantsPro[1][1]->GetXaxis()->SetBinLabel(binNo[1]++,Form("Sin(%d,%d)",n1,n2));
2695     nToBeFilled[1]++; 
2696    }
2697    if(2==fDontGoBeyond){continue;}
2698    for(Int_t n3=n2;n3<=fMaxHarmonic;n3++) 
2699    {
2700     if(fSkipZeroHarmonics && 0==n3){continue;}
2701     if(fCalculateAll || (fCalculateIsotropic && 0==n1+n2+n3) || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3))
2702        || (fCalculateSameIsotropic && 0==n1+n2+n3 && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3)))
2703     {  
2704      fEbECumulantsPro[0][2]->GetXaxis()->SetBinLabel(binNo[2],Form("Cos(%d,%d,%d)",n1,n2,n3));
2705      fEbECumulantsPro[1][2]->GetXaxis()->SetBinLabel(binNo[2]++,Form("Sin(%d,%d,%d)",n1,n2,n3));
2706      nToBeFilled[2]++; 
2707     }
2708     if(3==fDontGoBeyond){continue;}
2709     for(Int_t n4=n3;n4<=fMaxHarmonic;n4++) 
2710     {
2711      if(fSkipZeroHarmonics && 0==n4){continue;}
2712      if(fCalculateAll || (fCalculateIsotropic && 0==n1+n2+n3+n4) || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4))
2713        || (fCalculateSameIsotropic && 0==n1+n2+n3+n4 && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4)))
2714      {   
2715       fEbECumulantsPro[0][3]->GetXaxis()->SetBinLabel(binNo[3],Form("Cos(%d,%d,%d,%d)",n1,n2,n3,n4));
2716       fEbECumulantsPro[1][3]->GetXaxis()->SetBinLabel(binNo[3]++,Form("Sin(%d,%d,%d,%d)",n1,n2,n3,n4)); 
2717       nToBeFilled[3]++; 
2718      } 
2719      if(4==fDontGoBeyond){continue;}
2720      for(Int_t n5=n4;n5<=fMaxHarmonic;n5++) 
2721      {
2722       if(fSkipZeroHarmonics && 0==n5){continue;}
2723       if(fCalculateAll || (fCalculateIsotropic && 0==n1+n2+n3+n4+n5) 
2724          || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4) && TMath::Abs(n1)==TMath::Abs(n5))
2725          || (fCalculateSameIsotropic && 0==n1+n2+n3+n4+n5 && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4) && TMath::Abs(n1)==TMath::Abs(n5)))
2726       {   
2727        fEbECumulantsPro[0][4]->GetXaxis()->SetBinLabel(binNo[4],Form("Cos(%d,%d,%d,%d,%d)",n1,n2,n3,n4,n5));
2728        fEbECumulantsPro[1][4]->GetXaxis()->SetBinLabel(binNo[4]++,Form("Sin(%d,%d,%d,%d,%d)",n1,n2,n3,n4,n5));
2729        nToBeFilled[4]++; 
2730       }
2731       if(5==fDontGoBeyond){continue;}
2732       for(Int_t n6=n5;n6<=fMaxHarmonic;n6++) 
2733       {
2734        if(fSkipZeroHarmonics && 0==n6){continue;}
2735        if(fCalculateAll || (fCalculateIsotropic && 0==n1+n2+n3+n4+n5+n6)  
2736           || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4) 
2737               && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6))
2738           || (fCalculateSameIsotropic && 0==n1+n2+n3+n4+n5+n6 && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) 
2739               && TMath::Abs(n1)==TMath::Abs(n4) && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6)))
2740        {   
2741         fEbECumulantsPro[0][5]->GetXaxis()->SetBinLabel(binNo[5],Form("Cos(%d,%d,%d,%d,%d,%d)",n1,n2,n3,n4,n5,n6));
2742         fEbECumulantsPro[1][5]->GetXaxis()->SetBinLabel(binNo[5]++,Form("Sin(%d,%d,%d,%d,%d,%d)",n1,n2,n3,n4,n5,n6));
2743         nToBeFilled[5]++; 
2744        }
2745        if(6==fDontGoBeyond){continue;}
2746        for(Int_t n7=n6;n7<=fMaxHarmonic;n7++) 
2747        {
2748         if(fSkipZeroHarmonics && 0==n7){continue;}
2749         if(fCalculateAll || (fCalculateIsotropic && 0==n1+n2+n3+n4+n5+n6+n7) 
2750            || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4) 
2751                && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6) && TMath::Abs(n1)==TMath::Abs(n7))
2752            || (fCalculateSameIsotropic && 0==n1+n2+n3+n4+n5+n6+n7 && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4) 
2753                && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6) && TMath::Abs(n1)==TMath::Abs(n7)))
2754         {   
2755          fEbECumulantsPro[0][6]->GetXaxis()->SetBinLabel(binNo[6],Form("Cos(%d,%d,%d,%d,%d,%d,%d)",n1,n2,n3,n4,n5,n6,n7));
2756          fEbECumulantsPro[1][6]->GetXaxis()->SetBinLabel(binNo[6]++,Form("Sin(%d,%d,%d,%d,%d,%d,%d)",n1,n2,n3,n4,n5,n6,n7));
2757          nToBeFilled[6]++; 
2758         }
2759         if(7==fDontGoBeyond){continue;}
2760         for(Int_t n8=n7;n8<=fMaxHarmonic;n8++) 
2761         {
2762          if(fSkipZeroHarmonics && 0==n8){continue;}
2763          if(fCalculateAll || (fCalculateIsotropic && 0==n1+n2+n3+n4+n5+n6+n7+n8) 
2764             || (fCalculateSame && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) && TMath::Abs(n1)==TMath::Abs(n4) 
2765                 && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6) && TMath::Abs(n1)==TMath::Abs(n7) && TMath::Abs(n1)==TMath::Abs(n8))
2766             || (fCalculateSameIsotropic && 0==n1+n2+n3+n4+n5+n6+n7+n8 && TMath::Abs(n1)==TMath::Abs(n2) && TMath::Abs(n1)==TMath::Abs(n3) 
2767                 && TMath::Abs(n1)==TMath::Abs(n4) && TMath::Abs(n1)==TMath::Abs(n5) && TMath::Abs(n1)==TMath::Abs(n6) && TMath::Abs(n1)==TMath::Abs(n7) 
2768                 && TMath::Abs(n1)==TMath::Abs(n8)))
2769          {    
2770           fEbECumulantsPro[0][7]->GetXaxis()->SetBinLabel(binNo[7],Form("Cos(%d,%d,%d,%d,%d,%d,%d,%d)",n1,n2,n3,n4,n5,n6,n7,n8));
2771           fEbECumulantsPro[1][7]->GetXaxis()->SetBinLabel(binNo[7]++,Form("Sin(%d,%d,%d,%d,%d,%d,%d,%d)",n1,n2,n3,n4,n5,n6,n7,n8));
2772           nToBeFilled[7]++; 
2773          }
2774         } // for(Int_t n8=n7;n8<=fMaxHarmonic;n8++)
2775        } // for(Int_t n7=n6;n7<=fMaxHarmonic;n7++) 
2776       } // for(Int_t n6=n5;n6<=fMaxHarmonic;n6++) 
2777      } // for(Int_t n5=n4;n5<=fMaxHarmonic;n5++) 
2778     } // for(Int_t n4=n3;n4<=fMaxHarmonic;n4++)   
2779    } // for(Int_t n3=n2;n3<=fMaxHarmonic;n3++) 
2780   } // for(Int_t n2=n1;n2<=fMaxHarmonic;n2++)
2781  } // for(Int_t n1=-fMaxHarmonic;n1<=fMaxHarmonic;n1++) 
2782
2783  for(Int_t cs=0;cs<2;cs++) // [0=cos,1=sin]
2784  {
2785   for(Int_t c=0;c<fMaxCorrelator;c++) // [1p,2p,...,8p]
2786   {
2787    fEbECumulantsPro[cs][c]->SetTitle(Form("%d-p e-b-e cumulants, %s terms, %d/%d in total",c+1,sCosSin[cs].Data(),nToBeFilled[c],nBinsTitle[c]));
2788    fEbECumulantsPro[cs][c]->GetXaxis()->SetRangeUser(0.,fEbECumulantsPro[cs][c]->GetBinLowEdge(nToBeFilled[c]+1));
2789   }
2790  } 
2791  
2792 } // end of void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForEbECumulants()
2793
2794 //=======================================================================================================================
2795
2796 void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForNestedLoops()
2797 {
2798  // Book all the stuff for nested loops.
2799
2800  // TBI this method is just ugly, who implemented it like this... 
2801
2802  // a) Set default harmonic values; 
2803  // b) Book the profile holding all the flags for nested loops;
2804  // c) Book the profile holding all results for nested loops (cosine);
2805  // d) Book the profile holding all results for nested loops (sinus);
2806  // e) Book the profile holding all results for differential nested loops.
2807
2808  // a) Set default harmonic values: 
2809  //delete gRandom; // TBI this is not safe here, 
2810  //gRandom = new TRandom3(0);
2811  Int_t h1 = (Int_t)pow(-1.,1.*gRandom->Integer(fMaxHarmonic+1))*gRandom->Integer(fMaxHarmonic+1); // TBI reimplement all these lines eventually 
2812  Int_t h2 = (Int_t)pow(-1.,1.*gRandom->Integer(fMaxHarmonic+1))*gRandom->Integer(fMaxHarmonic+1);
2813  Int_t h3 = (Int_t)pow(-1.,1.*gRandom->Integer(fMaxHarmonic+1))*gRandom->Integer(fMaxHarmonic+1);
2814  Int_t h4 = (Int_t)pow(-1.,1.*gRandom->Integer(fMaxHarmonic+1))*gRandom->Integer(fMaxHarmonic+1);
2815  Int_t h5 = (Int_t)pow(-1.,1.*gRandom->Integer(fMaxHarmonic+1))*gRandom->Integer(fMaxHarmonic+1);
2816  Int_t h6 = (Int_t)pow(-1.,1.*gRandom->Integer(fMaxHarmonic+1))*gRandom->Integer(fMaxHarmonic+1);
2817  Int_t h7 = (Int_t)pow(-1.,1.*gRandom->Integer(fMaxHarmonic+1))*gRandom->Integer(fMaxHarmonic+1);
2818  Int_t h8 = (Int_t)pow(-1.,1.*gRandom->Integer(fMaxHarmonic+1))*gRandom->Integer(fMaxHarmonic+1);
2819
2820  // REMARK: This values can be overriden in a steering macro via 
2821  // mpc->GetNestedLoopsFlagsPro()->SetBinContent(<binNo>,<value>);
2822
2823  // b) Book the profile holding all the flags for nested loops:
2824  fNestedLoopsFlagsPro = new TProfile("fNestedLoopsFlagsPro","Flags for nested loops",10,0,10);
2825  fNestedLoopsFlagsPro->SetTickLength(-0.01,"Y");
2826  fNestedLoopsFlagsPro->SetMarkerStyle(25);
2827  fNestedLoopsFlagsPro->SetLabelSize(0.03);
2828  fNestedLoopsFlagsPro->SetLabelOffset(0.02,"Y");
2829  fNestedLoopsFlagsPro->SetStats(kFALSE);
2830  fNestedLoopsFlagsPro->SetFillColor(kGray);
2831  fNestedLoopsFlagsPro->SetLineColor(kBlack);
2832  fNestedLoopsFlagsPro->GetXaxis()->SetBinLabel(1,"fCrossCheckWithNestedLoops"); fNestedLoopsFlagsPro->Fill(0.5,fCrossCheckWithNestedLoops);
2833  fNestedLoopsFlagsPro->GetXaxis()->SetBinLabel(2,"h_{1}"); fNestedLoopsFlagsPro->Fill(1.5,h1);
2834  fNestedLoopsFlagsPro->GetXaxis()->SetBinLabel(3,"h_{2}"); fNestedLoopsFlagsPro->Fill(2.5,h2);
2835  fNestedLoopsFlagsPro->GetXaxis()->SetBinLabel(4,"h_{3}"); fNestedLoopsFlagsPro->Fill(3.5,h3);
2836  fNestedLoopsFlagsPro->GetXaxis()->SetBinLabel(5,"h_{4}"); fNestedLoopsFlagsPro->Fill(4.5,h4);
2837  fNestedLoopsFlagsPro->GetXaxis()->SetBinLabel(6,"h_{5}"); fNestedLoopsFlagsPro->Fill(5.5,h5);
2838  fNestedLoopsFlagsPro->GetXaxis()->SetBinLabel(7,"h_{6}"); fNestedLoopsFlagsPro->Fill(6.5,h6);
2839  fNestedLoopsFlagsPro->GetXaxis()->SetBinLabel(8,"h_{7}"); fNestedLoopsFlagsPro->Fill(7.5,h7);
2840  fNestedLoopsFlagsPro->GetXaxis()->SetBinLabel(9,"h_{8}"); fNestedLoopsFlagsPro->Fill(8.5,h8);
2841  fNestedLoopsFlagsPro->GetXaxis()->SetBinLabel(10,"fCrossCheckDiffWithNestedLoops"); fNestedLoopsFlagsPro->Fill(9.5,fCrossCheckDiffWithNestedLoops);
2842  fNestedLoopsList->Add(fNestedLoopsFlagsPro);
2843
2844  // c) Book the profile holding all results for nested loops (cosine):
2845  fNestedLoopsResultsCosPro = new TProfile("fNestedLoopsResultsCosPro","Nested loops results (cosine)",16,0,16);
2846  fNestedLoopsResultsCosPro->SetTickLength(-0.01,"Y");
2847  fNestedLoopsResultsCosPro->SetMarkerStyle(25);
2848  fNestedLoopsResultsCosPro->SetLabelSize(0.02);
2849  fNestedLoopsResultsCosPro->SetLabelOffset(0.02,"Y");
2850  fNestedLoopsResultsCosPro->SetStats(kFALSE);
2851  fNestedLoopsResultsCosPro->GetXaxis()->SetBinLabel(1,Form("N: 1p(%d)",h1));
2852  fNestedLoopsResultsCosPro->GetXaxis()->SetBinLabel(2,Form("Q: 1p(%d)",h1));
2853  fNestedLoopsResultsCosPro->GetXaxis()->SetBinLabel(3,Form("N: 2p(%d,%d)",h1,h2));
2854  fNestedLoopsResultsCosPro->GetXaxis()->SetBinLabel(4,Form("Q: 2p(%d,%d)",h1,h2));
2855  fNestedLoopsResultsCosPro->GetXaxis()->SetBinLabel(5,Form("N: 3p(%d,%d,%d)",h1,h2,h3));
2856  fNestedLoopsResultsCosPro->GetXaxis()->SetBinLabel(6,Form("Q: 3p(%d,%d,%d)",h1,h2,h3));
2857  fNestedLoopsResultsCosPro->GetXaxis()->SetBinLabel(7,Form("N: 4p(%d,%d,%d,%d)",h1,h2,h3,h4));
2858  fNestedLoopsResultsCosPro->GetXaxis()->SetBinLabel(8,Form("Q: 4p(%d,%d,%d,%d)",h1,h2,h3,h4));
2859  fNestedLoopsResultsCosPro->GetXaxis()->SetBinLabel(9,Form("N: 5p(%d,%d,%d,%d,%d)",h1,h2,h3,h4,h5));
2860  fNestedLoopsResultsCosPro->GetXaxis()->SetBinLabel(10,Form("Q: 5p(%d,%d,%d,%d,%d)",h1,h2,h3,h4,h5));
2861  fNestedLoopsResultsCosPro->GetXaxis()->SetBinLabel(11,Form("N: 6p(%d,%d,%d,%d,%d,%d)",h1,h2,h3,h4,h5,h6));
2862  fNestedLoopsResultsCosPro->GetXaxis()->SetBinLabel(12,Form("Q: 6p(%d,%d,%d,%d,%d,%d)",h1,h2,h3,h4,h5,h6));
2863  fNestedLoopsResultsCosPro->GetXaxis()->SetBinLabel(13,Form("N: 7p(%d,%d,%d,%d,%d,%d,%d)",h1,h2,h3,h4,h5,h6,h7));
2864  fNestedLoopsResultsCosPro->GetXaxis()->SetBinLabel(14,Form("Q: 7p(%d,%d,%d,%d,%d,%d,%d)",h1,h2,h3,h4,h5,h6,h7));
2865  fNestedLoopsResultsCosPro->GetXaxis()->SetBinLabel(15,Form("N: 8p(%d,%d,%d,%d,%d,%d,%d,%d)",h1,h2,h3,h4,h5,h6,h7,h8));
2866  fNestedLoopsResultsCosPro->GetXaxis()->SetBinLabel(16,Form("Q: 8p(%d,%d,%d,%d,%d,%d,%d,%d)",h1,h2,h3,h4,h5,h6,h7,h8));
2867  if(fCrossCheckWithNestedLoops){fNestedLoopsList->Add(fNestedLoopsResultsCosPro);} else{delete fNestedLoopsResultsCosPro;}
2868
2869  // d) Book the profile holding all results for nested loops (sinus):
2870  fNestedLoopsResultsSinPro = new TProfile("fNestedLoopsResultsSinPro","Nested loops results (sinus)",16,0,16);
2871  fNestedLoopsResultsSinPro->SetTickLength(-0.01,"Y");
2872  fNestedLoopsResultsSinPro->SetMarkerStyle(25);
2873  fNestedLoopsResultsSinPro->SetLabelSize(0.02);
2874  fNestedLoopsResultsSinPro->SetLabelOffset(0.02,"Y");
2875  fNestedLoopsResultsSinPro->SetStats(kFALSE);
2876  fNestedLoopsResultsSinPro->GetXaxis()->SetBinLabel(1,Form("N: 1p(%d)",h1));
2877  fNestedLoopsResultsSinPro->GetXaxis()->SetBinLabel(2,Form("Q: 1p(%d)",h1));
2878  fNestedLoopsResultsSinPro->GetXaxis()->SetBinLabel(3,Form("N: 2p(%d,%d)",h1,h2));
2879  fNestedLoopsResultsSinPro->GetXaxis()->SetBinLabel(4,Form("Q: 2p(%d,%d)",h1,h2));
2880  fNestedLoopsResultsSinPro->GetXaxis()->SetBinLabel(5,Form("N: 3p(%d,%d,%d)",h1,h2,h3));
2881  fNestedLoopsResultsSinPro->GetXaxis()->SetBinLabel(6,Form("Q: 3p(%d,%d,%d)",h1,h2,h3));
2882  fNestedLoopsResultsSinPro->GetXaxis()->SetBinLabel(7,Form("N: 4p(%d,%d,%d,%d)",h1,h2,h3,h4));
2883  fNestedLoopsResultsSinPro->GetXaxis()->SetBinLabel(8,Form("Q: 4p(%d,%d,%d,%d)",h1,h2,h3,h4));
2884  fNestedLoopsResultsSinPro->GetXaxis()->SetBinLabel(9,Form("N: 5p(%d,%d,%d,%d,%d)",h1,h2,h3,h4,h5));
2885  fNestedLoopsResultsSinPro->GetXaxis()->SetBinLabel(10,Form("Q: 5p(%d,%d,%d,%d,%d)",h1,h2,h3,h4,h5));
2886  fNestedLoopsResultsSinPro->GetXaxis()->SetBinLabel(11,Form("N: 6p(%d,%d,%d,%d,%d,%d)",h1,h2,h3,h4,h5,h6));
2887  fNestedLoopsResultsSinPro->GetXaxis()->SetBinLabel(12,Form("Q: 6p(%d,%d,%d,%d,%d,%d)",h1,h2,h3,h4,h5,h6));
2888  fNestedLoopsResultsSinPro->GetXaxis()->SetBinLabel(13,Form("N: 7p(%d,%d,%d,%d,%d,%d,%d)",h1,h2,h3,h4,h5,h6,h7));
2889  fNestedLoopsResultsSinPro->GetXaxis()->SetBinLabel(14,Form("Q: 7p(%d,%d,%d,%d,%d,%d,%d)",h1,h2,h3,h4,h5,h6,h7));
2890  fNestedLoopsResultsSinPro->GetXaxis()->SetBinLabel(15,Form("N: 8p(%d,%d,%d,%d,%d,%d,%d,%d)",h1,h2,h3,h4,h5,h6,h7,h8));
2891  fNestedLoopsResultsSinPro->GetXaxis()->SetBinLabel(16,Form("Q: 8p(%d,%d,%d,%d,%d,%d,%d,%d)",h1,h2,h3,h4,h5,h6,h7,h8));
2892  if(fCrossCheckWithNestedLoops){fNestedLoopsList->Add(fNestedLoopsResultsSinPro);} else{delete fNestedLoopsResultsSinPro;}
2893
2894  // e) Book the profile holding all results for differential nested loops:
2895  fNestedLoopsDiffResultsPro = new TProfile("fNestedLoopsDiffResultsPro","Differential nested loops results",1,0.,1.);
2896  fNestedLoopsDiffResultsPro->SetStats(kFALSE);
2897  if(fCrossCheckDiffWithNestedLoops){fNestedLoopsList->Add(fNestedLoopsDiffResultsPro);} else{delete fNestedLoopsDiffResultsPro;}
2898
2899 } // void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForNestedLoops()
2900
2901 //=======================================================================================================================
2902
2903 void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForStandardCandles()
2904 {
2905  // Book all the stuff for 'standard candles'.
2906
2907  // a) Book the profile holding all the flags for 'standard candles';
2908  // b) Book the histogram holding all results for 'standard candles';
2909  // c) Book TProfile2D *fProductsSCPro. 
2910
2911  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForStandardCandles()";
2912
2913  // a) Book the profile holding all the flags for 'standard candles':
2914  fStandardCandlesFlagsPro = new TProfile("fStandardCandlesFlagsPro","Flags for standard candles",2,0,2);
2915  fStandardCandlesFlagsPro->SetTickLength(-0.01,"Y");
2916  fStandardCandlesFlagsPro->SetMarkerStyle(25);
2917  fStandardCandlesFlagsPro->SetLabelSize(0.03);
2918  fStandardCandlesFlagsPro->SetLabelOffset(0.02,"Y");
2919  fStandardCandlesFlagsPro->SetStats(kFALSE);
2920  fStandardCandlesFlagsPro->SetFillColor(kGray);
2921  fStandardCandlesFlagsPro->SetLineColor(kBlack);
2922  fStandardCandlesFlagsPro->GetXaxis()->SetBinLabel(1,"fCalculateStandardCandles"); fStandardCandlesFlagsPro->Fill(0.5,fCalculateStandardCandles);
2923  fStandardCandlesFlagsPro->GetXaxis()->SetBinLabel(2,"fPropagateErrorSC"); fStandardCandlesFlagsPro->Fill(1.5,fPropagateErrorSC);
2924  fStandardCandlesList->Add(fStandardCandlesFlagsPro);
2925
2926  if(!fCalculateStandardCandles){return;} // TBI is this safe like this? 
2927
2928  // b) Book the histogram holding all results for 'standard candles':
2929  Int_t nBins = fMaxHarmonic*(fMaxHarmonic-1)/2;
2930  fStandardCandlesHist = new TH1D("fStandardCandlesHist","Standard candles (SC)",nBins,0.,1.*nBins); 
2931  fStandardCandlesHist->SetStats(kFALSE);
2932  fStandardCandlesHist->SetMarkerStyle(kFullSquare);
2933  fStandardCandlesHist->SetMarkerColor(kBlue);
2934  fStandardCandlesHist->SetLineColor(kBlue);
2935  Int_t binNo = 1;
2936  for(Int_t n1=-fMaxHarmonic;n1<=-2;n1++)
2937  {
2938   for(Int_t n2=n1+1;n2<=-1;n2++)
2939   {
2940    fStandardCandlesHist->GetXaxis()->SetBinLabel(binNo++,Form("SC(%d,%d,%d,%d)",n1,n2,-1*n2,-1*n1));
2941   }
2942  }
2943  if(binNo-1 != nBins){Fatal(sMethodName.Data(),"Well, binNo-1 != nBins ... :'( ");}
2944  fStandardCandlesList->Add(fStandardCandlesHist);
2945
2946  if(!fPropagateErrorSC){return;} // TBI is this safe like this? 
2947
2948  // c) Book TProfile2D *fProductsSCPro:
2949  Int_t nBins2D = fMaxHarmonic + fMaxHarmonic*(fMaxHarmonic-1)/2; // #2-p + #4-p distinct correlators in SC context 
2950  if(nBins2D<=0){Fatal(sMethodName.Data(),"nBins2D<=0");} // well, just in case...
2951  fProductsSCPro = new TProfile2D("fProductsSCPro","Products of correlations",nBins2D,0.,nBins2D,nBins2D,0.,nBins2D);
2952  fProductsSCPro->SetStats(kFALSE);
2953  fProductsSCPro->Sumw2();
2954  for(Int_t b=1;b<=fMaxHarmonic;b++) // 2-p correlators
2955  {
2956   fProductsSCPro->GetXaxis()->SetBinLabel(b,Form("Cos(%d,%d)",-(fMaxHarmonic+1-b),(fMaxHarmonic+1-b)));
2957   fProductsSCPro->GetYaxis()->SetBinLabel(b,Form("Cos(%d,%d)",-(fMaxHarmonic+1-b),(fMaxHarmonic+1-b)));
2958  } // for(Int_t b=1;b<=fMaxHarmonic;b++) // 2-p correlators
2959  for(Int_t b=fMaxHarmonic+1;b<=nBins2D;b++) // 4-p correlators
2960  {
2961   TString sBinLabel = fStandardCandlesHist->GetXaxis()->GetBinLabel(b-fMaxHarmonic);
2962   if(sBinLabel.EqualTo("")){Fatal(sMethodName.Data(),"sBinLabel.EqualTo...");}
2963   fProductsSCPro->GetXaxis()->SetBinLabel(b,sBinLabel.ReplaceAll("SC","Cos").Data());
2964   fProductsSCPro->GetYaxis()->SetBinLabel(b,sBinLabel.ReplaceAll("SC","Cos").Data());
2965  } // for(Int_t b=fMaxHarmonic+1;b<=nBins2D;b++) // 4-p correlators
2966  fStandardCandlesList->Add(fProductsSCPro);
2967
2968 } // end of void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForStandardCandles()
2969
2970 //=======================================================================================================================
2971
2972 void AliFlowAnalysisWithMultiparticleCorrelations::GetOutputHistograms(TList *histList)
2973 {
2974  // Get pointers for everything and everywhere from the base list "fHistList". 
2975
2976  // a) Get pointer for base list fHistList;
2977  // b) Get pointer for profile holding internal flags and, well, set again all flags;
2978  // c) Get pointers for control histograms;
2979  // d) Get pointers for Q-vector;
2980  // e) Get pointers for correlations;
2981  // f) Get pointers for 'standard candles';
2982  // g) Get pointers for Q-cumulants;
2983  // h) Get pointers for differential correlations.
2984
2985  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::GetOutputHistograms(TList *histList)";
2986
2987  // a) Get pointer for base list fHistList and profile holding internal flags;
2988  fHistList = histList; 
2989  if(!fHistList){Fatal(sMethodName.Data(),"fHistList is malicious today...");}
2990
2991  // b) Get pointer for profile holding internal flags and, well, set again all flags:
2992  fInternalFlagsPro = dynamic_cast<TProfile*>(fHistList->FindObject("fInternalFlagsPro"));
2993  if(!fInternalFlagsPro){Fatal(sMethodName.Data(),"fInternalFlagsPro");}
2994  fUseInternalFlags = fInternalFlagsPro->GetBinContent(1);
2995  fMinNoRPs = (Int_t)fInternalFlagsPro->GetBinContent(2);
2996  fMaxNoRPs = (Int_t)fInternalFlagsPro->GetBinContent(3);
2997  fExactNoRPs = (Int_t)fInternalFlagsPro->GetBinContent(4);
2998  fPropagateError = (Bool_t)fInternalFlagsPro->GetBinContent(5);
2999
3000  // c) Get pointers for control histograms:
3001  this->GetPointersForControlHistograms(); 
3002
3003  // d) Get pointers for Q-vector:
3004  this->GetPointersForQvector(); 
3005
3006  // e) Get pointers for correlations:
3007  this->GetPointersForCorrelations(); 
3008
3009  // f) Get pointers for 'standard candles':
3010  this->GetPointersForStandardCandles(); 
3011
3012  // g) Get pointers for Q-cumulants:
3013  this->GetPointersForQcumulants(); 
3014
3015  // h) Get pointers for differential correlations:
3016  this->GetPointersForDiffCorrelations(); 
3017   
3018 } // void AliFlowAnalysisWithMultiparticleCorrelations::GetOutputHistograms(TList *histList)
3019
3020 //=======================================================================================================================
3021
3022 void AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForQvector()
3023 {
3024  // Get pointers for Q-vector objects.
3025
3026  // a) Get pointer for fQvectorList; 
3027  // b) Get pointer for fQvectorFlagsPro;
3028  // c) Set again all flags.
3029
3030  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForQvector()";
3031
3032  // a) Get pointer for fQvectorList: 
3033  fQvectorList = dynamic_cast<TList*>(fHistList->FindObject("Q-vectors")); 
3034  if(!fQvectorList){Fatal(sMethodName.Data(),"fQvectorList");}
3035
3036  // b) Get pointer for fQvectorFlagsPro: 
3037  fQvectorFlagsPro = dynamic_cast<TProfile*>(fQvectorList->FindObject("fQvectorFlagsPro"));
3038  if(!fQvectorFlagsPro){Fatal(sMethodName.Data(),"fQvectorFlagsPro");}
3039
3040  // c) Set again all flags:
3041  fCalculateQvector = (Bool_t)fQvectorFlagsPro->GetBinContent(1);
3042  fCalculateDiffQvectors = (Bool_t)fQvectorFlagsPro->GetBinContent(2);
3043
3044 } // void AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForQvector()
3045
3046 //=======================================================================================================================
3047
3048 void AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForStandardCandles()
3049 {
3050  // Get pointers for 'standard candles'.
3051
3052  // a) Get pointer for fStandardCandlesList; 
3053  // b) Get pointer for fStandardCandlesFlagsPro;
3054  // c) Set again all flags; 
3055  // d) Get pointer TH1D *fStandardCandlesHist;
3056  // e) Get pointer TProfile2D *fProductsSCPro.
3057
3058  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForStandardCandles()";
3059
3060  // a) Get pointer for fStandardCandlesList: 
3061  fStandardCandlesList = dynamic_cast<TList*>(fHistList->FindObject("Standard Candles"));
3062  if(!fStandardCandlesList){Fatal(sMethodName.Data(),"fStandardCandlesList");}
3063
3064  // b) Get pointer for fStandardCandlesFlagsPro: 
3065  fStandardCandlesFlagsPro = dynamic_cast<TProfile*>(fStandardCandlesList->FindObject("fStandardCandlesFlagsPro"));
3066  if(!fStandardCandlesFlagsPro){Fatal(sMethodName.Data(),"fStandardCandlesFlagsPro");}
3067
3068  // c) Set again all flags: 
3069  fCalculateStandardCandles = (Bool_t)fStandardCandlesFlagsPro->GetBinContent(1);
3070  fPropagateErrorSC = (Bool_t)fStandardCandlesFlagsPro->GetBinContent(2);
3071
3072  if(!fCalculateStandardCandles){return;} // TBI is this safe enough
3073
3074  // d) Get pointer TH1D *fStandardCandlesHist: 
3075  fStandardCandlesHist = dynamic_cast<TH1D*>(fStandardCandlesList->FindObject("fStandardCandlesHist"));
3076
3077  if(!fPropagateErrorSC){return;} // TBI is this safe enough
3078
3079  // e) Get pointer TProfile2D *fProductsSCPro:
3080  fProductsSCPro = dynamic_cast<TProfile2D*>(fStandardCandlesList->FindObject("fProductsSCPro"));
3081  
3082 } // void AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForStandardCandles()
3083
3084 //=======================================================================================================================
3085
3086 void AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForControlHistograms()
3087 {
3088  // Get pointers for control histograms.
3089
3090  // a) Get pointer for fControlHistogramsList; TBI
3091  // b) Get pointer for fControlHistogramsFlagsPro; TBI
3092  // c) Set again all flags; TBI
3093  // d) Get pointers to TH1D *fKinematicsHist[2][3]; TBI
3094  // e) Get pointers to TH1D *fMultDistributionsHist[3]; TBI
3095  // f) Get pointers to TH2D *fMultCorrelationsHist[3]. TBI
3096
3097  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForControlHistograms()";
3098
3099  // a) Get pointer for fControlHistogramsList: TBI
3100  fControlHistogramsList = dynamic_cast<TList*>(fHistList->FindObject("Control Histograms"));
3101  if(!fControlHistogramsList){Fatal(sMethodName.Data(),"fControlHistogramsList");}
3102
3103  // b) Get pointer for fControlHistogramsFlagsPro: TBI
3104  fControlHistogramsFlagsPro = dynamic_cast<TProfile*>(fControlHistogramsList->FindObject("fControlHistogramsFlagsPro"));
3105  if(!fControlHistogramsFlagsPro){Fatal(sMethodName.Data(),"fControlHistogramsFlagsPro");}
3106
3107  // c) Set again all flags:
3108  fFillControlHistograms = fControlHistogramsFlagsPro->GetBinContent(1);
3109  fFillKinematicsHist = fControlHistogramsFlagsPro->GetBinContent(2);
3110  fFillMultDistributionsHist = fControlHistogramsFlagsPro->GetBinContent(3);
3111  fFillMultCorrelationsHist = fControlHistogramsFlagsPro->GetBinContent(4);
3112  fDontFill[0] = fControlHistogramsFlagsPro->GetBinContent(5);
3113  fDontFill[1] = fControlHistogramsFlagsPro->GetBinContent(6);
3114  fDontFill[2] = fControlHistogramsFlagsPro->GetBinContent(7);
3115
3116  if(!fFillControlHistograms){return;} // TBI is this safe enough
3117
3118  // d) Get pointers to fKinematicsHist[2][3]: TBI
3119  TString name[2][3] = {{"RP,phi","RP,pt","RP,eta"},{"POI,phi","POI,pt","POI,eta"}}; // [RP,POI][phi,pt,eta]
3120  for(Int_t rp=0;rp<2;rp++) // [RP,POI]
3121  {
3122   if(fDontFill[rp]){continue;}
3123   for(Int_t ppe=0;ppe<3;ppe++) // [phi,pt,eta]
3124   {
3125    fKinematicsHist[rp][ppe] = dynamic_cast<TH1D*>(fControlHistogramsList->FindObject(name[rp][ppe].Data()));
3126    if(!fKinematicsHist[rp][ppe] && fFillKinematicsHist){Fatal(sMethodName.Data(),"%s",name[rp][ppe].Data());} // TBI 
3127   }
3128  }
3129
3130  // e) Get pointers to TH1D *fMultDistributionsHist[3]:
3131  TString nameMult[3] = {"Multiplicity (RP)","Multiplicity (POI)","Multiplicity (REF)"}; // [RP,POI,reference multiplicity]
3132  for(Int_t rprm=0;rprm<3;rprm++) // [RP,POI,reference multiplicity]
3133  {
3134   if(fDontFill[rprm]){continue;}
3135   fMultDistributionsHist[rprm] = dynamic_cast<TH1D*>(fControlHistogramsList->FindObject(nameMult[rprm].Data()));
3136   if(!fMultDistributionsHist[rprm] && fFillMultDistributionsHist){Fatal(sMethodName.Data(),"%s",nameMult[rprm].Data());} // TBI 
3137  } // for(Int_t rprm=0;rprm<3;rprm++) // [RP,POI,reference multiplicity]
3138
3139  // f) Get pointers to TH2I *fMultCorrelationsHist[3]: TBI automatize the things here (at some point...)...
3140  if(!fDontFill[0] && !fDontFill[1])
3141  {
3142   fMultCorrelationsHist[0] = dynamic_cast<TH2I*>(fControlHistogramsList->FindObject("Multiplicity (RP vs. POI)"));
3143   if(!fMultCorrelationsHist[0] && fFillMultCorrelationsHist){Fatal(sMethodName.Data(),"Multiplicity (RP vs. POI)");} // TBI 
3144  }
3145  if(!fDontFill[0] && !fDontFill[2])
3146  {
3147   fMultCorrelationsHist[1] = dynamic_cast<TH2I*>(fControlHistogramsList->FindObject("Multiplicity (RP vs. REF)"));
3148   if(!fMultCorrelationsHist[1] && fFillMultCorrelationsHist){Fatal(sMethodName.Data(),"Multiplicity (RP vs. REF)");} // TBI 
3149  }
3150  if(!fDontFill[1] && !fDontFill[2])
3151  {
3152   fMultCorrelationsHist[2] = dynamic_cast<TH2I*>(fControlHistogramsList->FindObject("Multiplicity (POI vs. REF)"));
3153   if(!fMultCorrelationsHist[2] && fFillMultCorrelationsHist){Fatal(sMethodName.Data(),"Multiplicity (POI vs. REF)");} // TBI 
3154  }
3155
3156 } // void AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForControlHistograms()
3157
3158 //=======================================================================================================================
3159
3160 void AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForCorrelations()
3161 {
3162  // Get pointers for correlations.
3163
3164  // a) Get pointer for fCorrelationsList; TBI
3165  // b) Get pointer for fCorrelationsFlagsPro; TBI
3166  // c) Set again all flags; TBI
3167  // d) Get pointers to TProfile *fCorrelationsPro[2][8].
3168
3169  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForCorrelations()";
3170
3171  // a) Get pointer for fCorrelationsList: TBI
3172  fCorrelationsList = dynamic_cast<TList*>(fHistList->FindObject("Correlations"));
3173  if(!fCorrelationsList){Fatal(sMethodName.Data(),"fCorrelationsList");}
3174
3175  // b) Get pointer for fCorrelationsFlagsPro: TBI
3176  fCorrelationsFlagsPro = dynamic_cast<TProfile*>(fCorrelationsList->FindObject("fCorrelationsFlagsPro"));
3177
3178  if(!fCorrelationsFlagsPro){Fatal(sMethodName.Data(),"fCorrelationsFlagsPro");}
3179
3180  // c) Set again all flags: 
3181  fCalculateCorrelations = fCorrelationsFlagsPro->GetBinContent(1);
3182  fMaxHarmonic = (Int_t)fCorrelationsFlagsPro->GetBinContent(2);
3183  fMaxCorrelator = (Int_t)fCorrelationsFlagsPro->GetBinContent(3);
3184  fCalculateIsotropic = (Bool_t)fCorrelationsFlagsPro->GetBinContent(4);
3185  fCalculateSame = (Bool_t)fCorrelationsFlagsPro->GetBinContent(5);
3186  fSkipZeroHarmonics = (Bool_t)fCorrelationsFlagsPro->GetBinContent(6);
3187  fCalculateSameIsotropic = (Bool_t)fCorrelationsFlagsPro->GetBinContent(7);
3188  fCalculateAll = (Bool_t)fCorrelationsFlagsPro->GetBinContent(8);
3189  fDontGoBeyond = (Int_t)fCorrelationsFlagsPro->GetBinContent(9);
3190  fCalculateOnlyForHarmonicQC = (Bool_t)fCorrelationsFlagsPro->GetBinContent(10);
3191  fCalculateOnlyForSC = (Bool_t)fCorrelationsFlagsPro->GetBinContent(11);
3192  fCalculateOnlyCos = (Bool_t)fCorrelationsFlagsPro->GetBinContent(12);
3193  fCalculateOnlySin = (Bool_t)fCorrelationsFlagsPro->GetBinContent(13);
3194
3195  if(!fCalculateCorrelations){return;} // TBI is this safe enough, that is the question...
3196
3197  // d) Get pointers to TProfile *fCorrelationsPro[2][8]:
3198  TString sCosSin[2] = {"Cos","Sin"}; 
3199  for(Int_t cs=0;cs<2;cs++)
3200  {
3201   if(fCalculateOnlyCos && 1==cs){continue;}
3202   else if(fCalculateOnlySin && 0==cs){continue;}
3203   for(Int_t c=0;c<fMaxCorrelator;c++)
3204   {
3205    if(c==fDontGoBeyond){continue;}
3206    if(fCalculateOnlyForHarmonicQC && c%2==0){continue;}
3207    fCorrelationsPro[cs][c] = dynamic_cast<TProfile*>(fCorrelationsList->FindObject(Form("%dpCorrelations%s",c+1,sCosSin[cs].Data())));
3208    if(!fCorrelationsPro[cs][c]){Fatal(sMethodName.Data(),"%dpCorrelations%s",c+1,sCosSin[cs].Data());} 
3209   }
3210  }
3211
3212 } // void AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForCorrelations()
3213
3214 //=======================================================================================================================
3215
3216 void AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForQcumulants()
3217 {
3218  // Get pointers for Q-cumulants.
3219
3220  // a) Get pointer for fQcumulantsList;
3221  // b) Get pointer for fQcumulantsFlagsPro;
3222  // c) Set again all flags; 
3223  // d) Get pointer for fQcumulantsHist;
3224  // e) Get pointer for fReferenceFlowHist;
3225  // f) Get pointer for fProductsQCPro.
3226
3227  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForQcumulants()";
3228
3229  // a) Get pointer for fQcumulantsList:
3230  fQcumulantsList = dynamic_cast<TList*>(fHistList->FindObject("Q-cumulants"));
3231  if(!fQcumulantsList){Fatal(sMethodName.Data(),"fQcumulantsList");}
3232
3233  // b) Get pointer for fQcumulantsFlagsPro:
3234  fQcumulantsFlagsPro = dynamic_cast<TProfile*>(fQcumulantsList->FindObject("fQcumulantsFlagsPro"));
3235  if(!fQcumulantsFlagsPro){Fatal(sMethodName.Data(),"fQcumulantsFlagsPro");}
3236
3237  // c) Set again all flags:
3238  fCalculateQcumulants = (Bool_t) fQcumulantsFlagsPro->GetBinContent(1);
3239  fHarmonicQC = (Int_t) fQcumulantsFlagsPro->GetBinContent(2);
3240  fPropagateErrorQC = (Bool_t) fQcumulantsFlagsPro->GetBinContent(3);
3241
3242  if(!fCalculateQcumulants){return;} // TBI is this safe enough
3243
3244  // d) Get pointer for fQcumulantsHist:
3245  fQcumulantsHist = dynamic_cast<TH1D*>(fQcumulantsList->FindObject("Q-cumulants"));
3246  if(!fQcumulantsHist){Fatal(sMethodName.Data(),"fQcumulantsHist");}
3247
3248  // e) Get pointer for fReferenceFlowHist:
3249  fReferenceFlowHist = dynamic_cast<TH1D*>(fQcumulantsList->FindObject("Reference Flow"));
3250  if(!fReferenceFlowHist){Fatal(sMethodName.Data(),"fReferenceFlowHist");}
3251
3252  if(!fPropagateErrorQC){return;} // TBI is this safe enough
3253
3254  // f) Get pointer for fProductsQCPro:
3255  fProductsQCPro = dynamic_cast<TProfile2D*>(fQcumulantsList->FindObject("fProductsQCPro"));
3256  if(!fProductsQCPro){Fatal(sMethodName.Data(),"fProductsQCPro");}
3257  
3258 } // void AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForQcumulants()
3259
3260 //=======================================================================================================================
3261
3262 void AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForDiffCorrelations()
3263 {
3264  // Get pointers for differential correlations.
3265
3266  // a) Get pointer for fDiffCorrelationsList; 
3267  // b) Get pointer for fDiffCorrelationsFlagsPro; 
3268  // c) Set again all flags; 
3269  // d) Get pointers to TProfile *fDiffCorrelationsPro[2][4].
3270
3271  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForDiffCorrelations()";
3272
3273  // a) Get pointer for fDiffCorrelationsList:
3274  fDiffCorrelationsList = dynamic_cast<TList*>(fHistList->FindObject("Differential Correlations"));
3275  if(!fDiffCorrelationsList){Fatal(sMethodName.Data(),"fDiffCorrelationsList");}
3276
3277  // b) Get pointer for fDiffCorrelationsFlagsPro: 
3278  fDiffCorrelationsFlagsPro = dynamic_cast<TProfile*>(fDiffCorrelationsList->FindObject("fDiffCorrelationsFlagsPro"));
3279  if(!fDiffCorrelationsFlagsPro){Fatal(sMethodName.Data(),"fDiffCorrelationsFlagsPro");}
3280
3281  // c) Set again all flags: 
3282  fCalculateDiffCorrelations = fDiffCorrelationsFlagsPro->GetBinContent(1);
3283
3284  if(!fCalculateDiffCorrelations){return;} 
3285
3286  // TBI get all pointers below for diff. stuff eventually, not needed for the time being. 
3287
3288  // d) Get pointers to TProfile *fDiffCorrelationsPro[2][4]: // TBI
3289  /*
3290  TString sCosSin[2] = {"Cos","Sin"}; 
3291  for(Int_t cs=0;cs<2;cs++)
3292  {
3293   if(fCalculateOnlyCos && 1==cs){continue;}
3294   else if(fCalculateOnlySin && 0==cs){continue;}
3295   for(Int_t c=0;c<fMaxCorrelator;c++)
3296   {
3297    fCorrelationsPro[cs][c] = dynamic_cast<TProfile*>(fCorrelationsList->FindObject(Form("%dpCorrelations%s",c+1,sCosSin[cs].Data())));
3298    if(!fCorrelationsPro[cs][c]){Fatal(sMethodName.Data(),"%dpCorrelations%s",c+1,sCosSin[cs].Data());} 
3299   }
3300  }
3301  */
3302
3303 } // void AliFlowAnalysisWithMultiparticleCorrelations::GetPointersForDiffCorrelations()
3304
3305 //=======================================================================================================================
3306
3307 void AliFlowAnalysisWithMultiparticleCorrelations::InitializeArraysForQvector()
3308 {
3309  // Initialize all arrays for Q-vector.
3310
3311  for(Int_t h=0;h<fMaxHarmonic*fMaxCorrelator+1;h++) 
3312  {
3313   for(Int_t wp=0;wp<fMaxCorrelator+1;wp++) // weight power
3314   {
3315    fQvector[h][wp] = TComplex(0.,0.);
3316    for(Int_t b=0;b<100;b++) // TBI hardwired 100 
3317    {  
3318     fpvector[b][h][wp] = TComplex(0.,0.); 
3319     fqvector[b][h][wp] = TComplex(0.,0.); 
3320    }
3321   }
3322  }
3323
3324 } // void AliFlowAnalysisWithMultiparticleCorrelations::InitializeArraysForQvector()
3325
3326 //=======================================================================================================================
3327
3328 void AliFlowAnalysisWithMultiparticleCorrelations::ResetQvector()
3329 {
3330  // Reset all Q-vector components to zero before starting a new event. 
3331
3332  for(Int_t h=0;h<fMaxHarmonic*fMaxCorrelator+1;h++) 
3333  {
3334   for(Int_t wp=0;wp<fMaxCorrelator+1;wp++) // weight powe
3335   {
3336    fQvector[h][wp] = TComplex(0.,0.);
3337    if(!fCalculateDiffQvectors){continue;}
3338    for(Int_t b=0;b<100;b++) // TBI hardwired 100 
3339    {  
3340     fpvector[b][h][wp] = TComplex(0.,0.); 
3341     fqvector[b][h][wp] = TComplex(0.,0.); 
3342    }
3343   } 
3344  } 
3345
3346 } // void AliFlowAnalysisWithMultiparticleCorrelations::ResetQvector()
3347
3348 //=======================================================================================================================
3349
3350 TComplex AliFlowAnalysisWithMultiparticleCorrelations::Q(Int_t n, Int_t wp)
3351 {
3352  // Using the fact that Q{-n,p} = Q{n,p}^*. 
3353  
3354  if(n>=0){return fQvector[n][wp];} 
3355  return TComplex::Conjugate(fQvector[-n][wp]);
3356  
3357 } // TComplex AliFlowAnalysisWithMultiparticleCorrelations::Q(Int_t n, Int_t wp)
3358
3359 //=======================================================================================================================
3360
3361 TComplex AliFlowAnalysisWithMultiparticleCorrelations::p(Int_t n, Int_t wp)
3362 {
3363  // Using the fact that p{-n,p} = p{n,p}^*.
3364  
3365  if(n>=0){return fpvector[fDiffBinNo][n][wp];} 
3366  return TComplex::Conjugate(fpvector[fDiffBinNo][-n][wp]);
3367
3368 } // TComplex AliFlowAnalysisWithMultiparticleCorrelations::p(Int_t n, Int_t p)
3369
3370 //=======================================================================================================================
3371
3372 TComplex AliFlowAnalysisWithMultiparticleCorrelations::q(Int_t n, Int_t wp)
3373 {
3374  // Using the fact that q{-n,p} = q{n,p}^*.
3375
3376  // When weights are used for RPs and not for POIs, and vice versa, some gymnastics is required here:
3377  // TBI rethink and reimplement the lines below:
3378  Int_t nUseWeightsForRP = (Int_t)(fUseWeights[0][0] || fUseWeights[0][1] || fUseWeights[0][2]); 
3379  Int_t nUseWeightsForPOI = (Int_t)(fUseWeights[1][0] || fUseWeights[1][1] || fUseWeights[1][2]); 
3380  if(nUseWeightsForPOI == 1 && nUseWeightsForRP == 0){wp=1;}
3381  else if(nUseWeightsForPOI == 0 && nUseWeightsForRP == 1){wp-=1;}
3382
3383  if(n>=0){return fqvector[fDiffBinNo][n][wp];} 
3384  return TComplex::Conjugate(fqvector[fDiffBinNo][-n][wp]);
3385
3386 } // TComplex AliFlowAnalysisWithMultiparticleCorrelations::q(Int_t n, Int_t wp)
3387
3388 //=======================================================================================================================
3389
3390 TComplex AliFlowAnalysisWithMultiparticleCorrelations::One(Int_t n1)
3391 {
3392  // Generic expression <exp[i(n1*phi1)]>. TBI comment
3393
3394  TComplex one = Q(n1,1);
3395
3396  return one;
3397
3398 } // TComplex AliFlowAnalysisWithMultiparticleCorrelations::One(Int_t n1)
3399
3400 //=======================================================================================================================
3401
3402 TComplex AliFlowAnalysisWithMultiparticleCorrelations::Two(Int_t n1, Int_t n2)
3403 {
3404  // Generic two-particle correlation <exp[i(n1*phi1+n2*phi2)]>.
3405
3406  TComplex two = Q(n1,1)*Q(n2,1)-Q(n1+n2,2);
3407
3408  return two;
3409
3410 } // TComplex AliFlowAnalysisWithMultiparticleCorrelations::Two(Int_t n1, Int_t n2)
3411
3412 //=======================================================================================================================
3413
3414 TComplex AliFlowAnalysisWithMultiparticleCorrelations::Three(Int_t n1, Int_t n2, Int_t n3)
3415 {
3416  // Generic three-particle correlation <exp[i(n1*phi1+n2*phi2+n3*phi3)]>.
3417
3418  TComplex three = Q(n1,1)*Q(n2,1)*Q(n3,1)-Q(n1+n2,2)*Q(n3,1)-Q(n2,1)*Q(n1+n3,2)
3419                 - Q(n1,1)*Q(n2+n3,2)+2.*Q(n1+n2+n3,3); 
3420
3421  return three;
3422
3423 } // TComplex AliFlowAnalysisWithMultiparticleCorrelations::Three(Int_t n1, Int_t n2, Int_t n3)
3424
3425 //=======================================================================================================================
3426
3427 TComplex AliFlowAnalysisWithMultiparticleCorrelations::Four(Int_t n1, Int_t n2, Int_t n3, Int_t n4)
3428 {
3429  // Generic four-particle correlation <exp[i(n1*phi1+n2*phi2+n3*phi3+n4*phi4)]>.
3430
3431  TComplex four = Q(n1,1)*Q(n2,1)*Q(n3,1)*Q(n4,1)-Q(n1+n2,2)*Q(n3,1)*Q(n4,1)-Q(n2,1)*Q(n1+n3,2)*Q(n4,1)
3432                - Q(n1,1)*Q(n2+n3,2)*Q(n4,1)+2.*Q(n1+n2+n3,3)*Q(n4,1)-Q(n2,1)*Q(n3,1)*Q(n1+n4,2)
3433                + Q(n2+n3,2)*Q(n1+n4,2)-Q(n1,1)*Q(n3,1)*Q(n2+n4,2)+Q(n1+n3,2)*Q(n2+n4,2)
3434                + 2.*Q(n3,1)*Q(n1+n2+n4,3)-Q(n1,1)*Q(n2,1)*Q(n3+n4,2)+Q(n1+n2,2)*Q(n3+n4,2)
3435                + 2.*Q(n2,1)*Q(n1+n3+n4,3)+2.*Q(n1,1)*Q(n2+n3+n4,3)-6.*Q(n1+n2+n3+n4,4);
3436
3437  return four;
3438
3439 } // TComplex AliFlowAnalysisWithMultiparticleCorrelations::Four(Int_t n1, Int_t n2, Int_t n3, Int_t n4)
3440
3441 //=======================================================================================================================
3442
3443 TComplex AliFlowAnalysisWithMultiparticleCorrelations::Five(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5)
3444 {
3445  // Generic five-particle correlation <exp[i(n1*phi1+n2*phi2+n3*phi3+n4*phi4+n5*phi5)]>.
3446
3447  TComplex five = Q(n1,1)*Q(n2,1)*Q(n3,1)*Q(n4,1)*Q(n5,1)-Q(n1+n2,2)*Q(n3,1)*Q(n4,1)*Q(n5,1)
3448                - Q(n2,1)*Q(n1+n3,2)*Q(n4,1)*Q(n5,1)-Q(n1,1)*Q(n2+n3,2)*Q(n4,1)*Q(n5,1)
3449                + 2.*Q(n1+n2+n3,3)*Q(n4,1)*Q(n5,1)-Q(n2,1)*Q(n3,1)*Q(n1+n4,2)*Q(n5,1)
3450                + Q(n2+n3,2)*Q(n1+n4,2)*Q(n5,1)-Q(n1,1)*Q(n3,1)*Q(n2+n4,2)*Q(n5,1)
3451                + Q(n1+n3,2)*Q(n2+n4,2)*Q(n5,1)+2.*Q(n3,1)*Q(n1+n2+n4,3)*Q(n5,1)
3452                - Q(n1,1)*Q(n2,1)*Q(n3+n4,2)*Q(n5,1)+Q(n1+n2,2)*Q(n3+n4,2)*Q(n5,1)
3453                + 2.*Q(n2,1)*Q(n1+n3+n4,3)*Q(n5,1)+2.*Q(n1,1)*Q(n2+n3+n4,3)*Q(n5,1)
3454                - 6.*Q(n1+n2+n3+n4,4)*Q(n5,1)-Q(n2,1)*Q(n3,1)*Q(n4,1)*Q(n1+n5,2)
3455                + Q(n2+n3,2)*Q(n4,1)*Q(n1+n5,2)+Q(n3,1)*Q(n2+n4,2)*Q(n1+n5,2)
3456                + Q(n2,1)*Q(n3+n4,2)*Q(n1+n5,2)-2.*Q(n2+n3+n4,3)*Q(n1+n5,2)
3457                - Q(n1,1)*Q(n3,1)*Q(n4,1)*Q(n2+n5,2)+Q(n1+n3,2)*Q(n4,1)*Q(n2+n5,2)
3458                + Q(n3,1)*Q(n1+n4,2)*Q(n2+n5,2)+Q(n1,1)*Q(n3+n4,2)*Q(n2+n5,2)
3459                - 2.*Q(n1+n3+n4,3)*Q(n2+n5,2)+2.*Q(n3,1)*Q(n4,1)*Q(n1+n2+n5,3)
3460                - 2.*Q(n3+n4,2)*Q(n1+n2+n5,3)-Q(n1,1)*Q(n2,1)*Q(n4,1)*Q(n3+n5,2)
3461                + Q(n1+n2,2)*Q(n4,1)*Q(n3+n5,2)+Q(n2,1)*Q(n1+n4,2)*Q(n3+n5,2)
3462                + Q(n1,1)*Q(n2+n4,2)*Q(n3+n5,2)-2.*Q(n1+n2+n4,3)*Q(n3+n5,2)
3463                + 2.*Q(n2,1)*Q(n4,1)*Q(n1+n3+n5,3)-2.*Q(n2+n4,2)*Q(n1+n3+n5,3)
3464                + 2.*Q(n1,1)*Q(n4,1)*Q(n2+n3+n5,3)-2.*Q(n1+n4,2)*Q(n2+n3+n5,3)
3465                - 6.*Q(n4,1)*Q(n1+n2+n3+n5,4)-Q(n1,1)*Q(n2,1)*Q(n3,1)*Q(n4+n5,2)
3466                + Q(n1+n2,2)*Q(n3,1)*Q(n4+n5,2)+Q(n2,1)*Q(n1+n3,2)*Q(n4+n5,2)
3467                + Q(n1,1)*Q(n2+n3,2)*Q(n4+n5,2)-2.*Q(n1+n2+n3,3)*Q(n4+n5,2)
3468                + 2.*Q(n2,1)*Q(n3,1)*Q(n1+n4+n5,3)-2.*Q(n2+n3,2)*Q(n1+n4+n5,3)
3469                + 2.*Q(n1,1)*Q(n3,1)*Q(n2+n4+n5,3)-2.*Q(n1+n3,2)*Q(n2+n4+n5,3)
3470                - 6.*Q(n3,1)*Q(n1+n2+n4+n5,4)+2.*Q(n1,1)*Q(n2,1)*Q(n3+n4+n5,3) 
3471                - 2.*Q(n1+n2,2)*Q(n3+n4+n5,3)-6.*Q(n2,1)*Q(n1+n3+n4+n5,4)
3472                - 6.*Q(n1,1)*Q(n2+n3+n4+n5,4)+24.*Q(n1+n2+n3+n4+n5,5);
3473  
3474  return five;
3475
3476 } // TComplex AliFlowAnalysisWithMultiparticleCorrelations::Five(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5)
3477
3478 //=======================================================================================================================
3479
3480 TComplex AliFlowAnalysisWithMultiparticleCorrelations::Six(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6)
3481 {
3482  // Generic six-particle correlation <exp[i(n1*phi1+n2*phi2+n3*phi3+n4*phi4+n5*phi5+n6*phi6)]>.
3483
3484  TComplex six = Q(n1,1)*Q(n2,1)*Q(n3,1)*Q(n4,1)*Q(n5,1)*Q(n6,1)-Q(n1+n2,2)*Q(n3,1)*Q(n4,1)*Q(n5,1)*Q(n6,1)
3485               - Q(n2,1)*Q(n1+n3,2)*Q(n4,1)*Q(n5,1)*Q(n6,1)-Q(n1,1)*Q(n2+n3,2)*Q(n4,1)*Q(n5,1)*Q(n6,1)
3486               + 2.*Q(n1+n2+n3,3)*Q(n4,1)*Q(n5,1)*Q(n6,1)-Q(n2,1)*Q(n3,1)*Q(n1+n4,2)*Q(n5,1)*Q(n6,1)
3487               + Q(n2+n3,2)*Q(n1+n4,2)*Q(n5,1)*Q(n6,1)-Q(n1,1)*Q(n3,1)*Q(n2+n4,2)*Q(n5,1)*Q(n6,1)
3488               + Q(n1+n3,2)*Q(n2+n4,2)*Q(n5,1)*Q(n6,1)+2.*Q(n3,1)*Q(n1+n2+n4,3)*Q(n5,1)*Q(n6,1)
3489               - Q(n1,1)*Q(n2,1)*Q(n3+n4,2)*Q(n5,1)*Q(n6,1)+Q(n1+n2,2)*Q(n3+n4,2)*Q(n5,1)*Q(n6,1)
3490               + 2.*Q(n2,1)*Q(n1+n3+n4,3)*Q(n5,1)*Q(n6,1)+2.*Q(n1,1)*Q(n2+n3+n4,3)*Q(n5,1)*Q(n6,1)
3491               - 6.*Q(n1+n2+n3+n4,4)*Q(n5,1)*Q(n6,1)-Q(n2,1)*Q(n3,1)*Q(n4,1)*Q(n1+n5,2)*Q(n6,1)
3492               + Q(n2+n3,2)*Q(n4,1)*Q(n1+n5,2)*Q(n6,1)+Q(n3,1)*Q(n2+n4,2)*Q(n1+n5,2)*Q(n6,1)
3493               + Q(n2,1)*Q(n3+n4,2)*Q(n1+n5,2)*Q(n6,1)-2.*Q(n2+n3+n4,3)*Q(n1+n5,2)*Q(n6,1)
3494               - Q(n1,1)*Q(n3,1)*Q(n4,1)*Q(n2+n5,2)*Q(n6,1)+Q(n1+n3,2)*Q(n4,1)*Q(n2+n5,2)*Q(n6,1)
3495               + Q(n3,1)*Q(n1+n4,2)*Q(n2+n5,2)*Q(n6,1)+Q(n1,1)*Q(n3+n4,2)*Q(n2+n5,2)*Q(n6,1)
3496               - 2.*Q(n1+n3+n4,3)*Q(n2+n5,2)*Q(n6,1)+2.*Q(n3,1)*Q(n4,1)*Q(n1+n2+n5,3)*Q(n6,1)
3497               - 2.*Q(n3+n4,2)*Q(n1+n2+n5,3)*Q(n6,1)-Q(n1,1)*Q(n2,1)*Q(n4,1)*Q(n3+n5,2)*Q(n6,1)
3498               + Q(n1+n2,2)*Q(n4,1)*Q(n3+n5,2)*Q(n6,1)+Q(n2,1)*Q(n1+n4,2)*Q(n3+n5,2)*Q(n6,1)
3499               + Q(n1,1)*Q(n2+n4,2)*Q(n3+n5,2)*Q(n6,1)-2.*Q(n1+n2+n4,3)*Q(n3+n5,2)*Q(n6,1)
3500               + 2.*Q(n2,1)*Q(n4,1)*Q(n1+n3+n5,3)*Q(n6,1)-2.*Q(n2+n4,2)*Q(n1+n3+n5,3)*Q(n6,1)
3501               + 2.*Q(n1,1)*Q(n4,1)*Q(n2+n3+n5,3)*Q(n6,1)-2.*Q(n1+n4,2)*Q(n2+n3+n5,3)*Q(n6,1)
3502               - 6.*Q(n4,1)*Q(n1+n2+n3+n5,4)*Q(n6,1)-Q(n1,1)*Q(n2,1)*Q(n3,1)*Q(n4+n5,2)*Q(n6,1)
3503               + Q(n1+n2,2)*Q(n3,1)*Q(n4+n5,2)*Q(n6,1)+Q(n2,1)*Q(n1+n3,2)*Q(n4+n5,2)*Q(n6,1)
3504               + Q(n1,1)*Q(n2+n3,2)*Q(n4+n5,2)*Q(n6,1)-2.*Q(n1+n2+n3,3)*Q(n4+n5,2)*Q(n6,1)
3505               + 2.*Q(n2,1)*Q(n3,1)*Q(n1+n4+n5,3)*Q(n6,1)-2.*Q(n2+n3,2)*Q(n1+n4+n5,3)*Q(n6,1)
3506               + 2.*Q(n1,1)*Q(n3,1)*Q(n2+n4+n5,3)*Q(n6,1)-2.*Q(n1+n3,2)*Q(n2+n4+n5,3)*Q(n6,1)
3507               - 6.*Q(n3,1)*Q(n1+n2+n4+n5,4)*Q(n6,1)+2.*Q(n1,1)*Q(n2,1)*Q(n3+n4+n5,3)*Q(n6,1)
3508               - 2.*Q(n1+n2,2)*Q(n3+n4+n5,3)*Q(n6,1)-6.*Q(n2,1)*Q(n1+n3+n4+n5,4)*Q(n6,1)
3509               - 6.*Q(n1,1)*Q(n2+n3+n4+n5,4)*Q(n6,1)+24.*Q(n1+n2+n3+n4+n5,5)*Q(n6,1)
3510               - Q(n2,1)*Q(n3,1)*Q(n4,1)*Q(n5,1)*Q(n1+n6,2)+Q(n2+n3,2)*Q(n4,1)*Q(n5,1)*Q(n1+n6,2)
3511               + Q(n3,1)*Q(n2+n4,2)*Q(n5,1)*Q(n1+n6,2)+Q(n2,1)*Q(n3+n4,2)*Q(n5,1)*Q(n1+n6,2)
3512               - 2.*Q(n2+n3+n4,3)*Q(n5,1)*Q(n1+n6,2)+Q(n3,1)*Q(n4,1)*Q(n2+n5,2)*Q(n1+n6,2)
3513               - Q(n3+n4,2)*Q(n2+n5,2)*Q(n1+n6,2)+Q(n2,1)*Q(n4,1)*Q(n3+n5,2)*Q(n1+n6,2)
3514               - Q(n2+n4,2)*Q(n3+n5,2)*Q(n1+n6,2)-2.*Q(n4,1)*Q(n2+n3+n5,3)*Q(n1+n6,2)
3515               + Q(n2,1)*Q(n3,1)*Q(n4+n5,2)*Q(n1+n6,2)-Q(n2+n3,2)*Q(n4+n5,2)*Q(n1+n6,2)
3516               - 2.*Q(n3,1)*Q(n2+n4+n5,3)*Q(n1+n6,2)-2.*Q(n2,1)*Q(n3+n4+n5,3)*Q(n1+n6,2)
3517               + 6.*Q(n2+n3+n4+n5,4)*Q(n1+n6,2)-Q(n1,1)*Q(n3,1)*Q(n4,1)*Q(n5,1)*Q(n2+n6,2)
3518               + Q(n1+n3,2)*Q(n4,1)*Q(n5,1)*Q(n2+n6,2)+Q(n3,1)*Q(n1+n4,2)*Q(n5,1)*Q(n2+n6,2)
3519               + Q(n1,1)*Q(n3+n4,2)*Q(n5,1)*Q(n2+n6,2)-2.*Q(n1+n3+n4,3)*Q(n5,1)*Q(n2+n6,2)
3520               + Q(n3,1)*Q(n4,1)*Q(n1+n5,2)*Q(n2+n6,2)-Q(n3+n4,2)*Q(n1+n5,2)*Q(n2+n6,2)
3521               + Q(n1,1)*Q(n4,1)*Q(n3+n5,2)*Q(n2+n6,2)-Q(n1+n4,2)*Q(n3+n5,2)*Q(n2+n6,2)
3522               - 2.*Q(n4,1)*Q(n1+n3+n5,3)*Q(n2+n6,2)+Q(n1,1)*Q(n3,1)*Q(n4+n5,2)*Q(n2+n6,2)
3523               - Q(n1+n3,2)*Q(n4+n5,2)*Q(n2+n6,2)-2.*Q(n3,1)*Q(n1+n4+n5,3)*Q(n2+n6,2)
3524               - 2.*Q(n1,1)*Q(n3+n4+n5,3)*Q(n2+n6,2)+6.*Q(n1+n3+n4+n5,4)*Q(n2+n6,2)
3525               + 2.*Q(n3,1)*Q(n4,1)*Q(n5,1)*Q(n1+n2+n6,3)-2.*Q(n3+n4,2)*Q(n5,1)*Q(n1+n2+n6,3)
3526               - 2.*Q(n4,1)*Q(n3+n5,2)*Q(n1+n2+n6,3)-2.*Q(n3,1)*Q(n4+n5,2)*Q(n1+n2+n6,3)
3527               + 4.*Q(n3+n4+n5,3)*Q(n1+n2+n6,3)-Q(n1,1)*Q(n2,1)*Q(n4,1)*Q(n5,1)*Q(n3+n6,2)
3528               + Q(n1+n2,2)*Q(n4,1)*Q(n5,1)*Q(n3+n6,2)+Q(n2,1)*Q(n1+n4,2)*Q(n5,1)*Q(n3+n6,2)
3529               + Q(n1,1)*Q(n2+n4,2)*Q(n5,1)*Q(n3+n6,2)-2.*Q(n1+n2+n4,3)*Q(n5,1)*Q(n3+n6,2)
3530               + Q(n2,1)*Q(n4,1)*Q(n1+n5,2)*Q(n3+n6,2)-Q(n2+n4,2)*Q(n1+n5,2)*Q(n3+n6,2)
3531               + Q(n1,1)*Q(n4,1)*Q(n2+n5,2)*Q(n3+n6,2)-Q(n1+n4,2)*Q(n2+n5,2)*Q(n3+n6,2)
3532               - 2.*Q(n4,1)*Q(n1+n2+n5,3)*Q(n3+n6,2)+Q(n1,1)*Q(n2,1)*Q(n4+n5,2)*Q(n3+n6,2)
3533               - Q(n1+n2,2)*Q(n4+n5,2)*Q(n3+n6,2)-2.*Q(n2,1)*Q(n1+n4+n5,3)*Q(n3+n6,2)
3534               - 2.*Q(n1,1)*Q(n2+n4+n5,3)*Q(n3+n6,2)+6.*Q(n1+n2+n4+n5,4)*Q(n3+n6,2)
3535               + 2.*Q(n2,1)*Q(n4,1)*Q(n5,1)*Q(n1+n3+n6,3)-2.*Q(n2+n4,2)*Q(n5,1)*Q(n1+n3+n6,3)
3536               - 2.*Q(n4,1)*Q(n2+n5,2)*Q(n1+n3+n6,3)-2.*Q(n2,1)*Q(n4+n5,2)*Q(n1+n3+n6,3)
3537               + 4.*Q(n2+n4+n5,3)*Q(n1+n3+n6,3)+2.*Q(n1,1)*Q(n4,1)*Q(n5,1)*Q(n2+n3+n6,3)
3538               - 2.*Q(n1+n4,2)*Q(n5,1)*Q(n2+n3+n6,3)-2.*Q(n4,1)*Q(n1+n5,2)*Q(n2+n3+n6,3)
3539               - 2.*Q(n1,1)*Q(n4+n5,2)*Q(n2+n3+n6,3)+4.*Q(n1+n4+n5,3)*Q(n2+n3+n6,3)
3540               - 6.*Q(n4,1)*Q(n5,1)*Q(n1+n2+n3+n6,4)+6.*Q(n4+n5,2)*Q(n1+n2+n3+n6,4)
3541               - Q(n1,1)*Q(n2,1)*Q(n3,1)*Q(n5,1)*Q(n4+n6,2)+Q(n1+n2,2)*Q(n3,1)*Q(n5,1)*Q(n4+n6,2)
3542               + Q(n2,1)*Q(n1+n3,2)*Q(n5,1)*Q(n4+n6,2)+Q(n1,1)*Q(n2+n3,2)*Q(n5,1)*Q(n4+n6,2)
3543               - 2.*Q(n1+n2+n3,3)*Q(n5,1)*Q(n4+n6,2)+Q(n2,1)*Q(n3,1)*Q(n1+n5,2)*Q(n4+n6,2)
3544               - Q(n2+n3,2)*Q(n1+n5,2)*Q(n4+n6,2)+Q(n1,1)*Q(n3,1)*Q(n2+n5,2)*Q(n4+n6,2)
3545               - Q(n1+n3,2)*Q(n2+n5,2)*Q(n4+n6,2)-2.*Q(n3,1)*Q(n1+n2+n5,3)*Q(n4+n6,2)
3546               + Q(n1,1)*Q(n2,1)*Q(n3+n5,2)*Q(n4+n6,2)-Q(n1+n2,2)*Q(n3+n5,2)*Q(n4+n6,2)
3547               - 2.*Q(n2,1)*Q(n1+n3+n5,3)*Q(n4+n6,2)-2.*Q(n1,1)*Q(n2+n3+n5,3)*Q(n4+n6,2)
3548               + 6.*Q(n1+n2+n3+n5,4)*Q(n4+n6,2)+2.*Q(n2,1)*Q(n3,1)*Q(n5,1)*Q(n1+n4+n6,3)
3549               - 2.*Q(n2+n3,2)*Q(n5,1)*Q(n1+n4+n6,3)-2.*Q(n3,1)*Q(n2+n5,2)*Q(n1+n4+n6,3)
3550               - 2.*Q(n2,1)*Q(n3+n5,2)*Q(n1+n4+n6,3)+4.*Q(n2+n3+n5,3)*Q(n1+n4+n6,3)
3551               + 2.*Q(n1,1)*Q(n3,1)*Q(n5,1)*Q(n2+n4+n6,3)-2.*Q(n1+n3,2)*Q(n5,1)*Q(n2+n4+n6,3)
3552               - 2.*Q(n3,1)*Q(n1+n5,2)*Q(n2+n4+n6,3)-2.*Q(n1,1)*Q(n3+n5,2)*Q(n2+n4+n6,3)
3553               + 4.*Q(n1+n3+n5,3)*Q(n2+n4+n6,3)-6.*Q(n3,1)*Q(n5,1)*Q(n1+n2+n4+n6,4)
3554               + 6.*Q(n3+n5,2)*Q(n1+n2+n4+n6,4)+2.*Q(n1,1)*Q(n2,1)*Q(n5,1)*Q(n3+n4+n6,3)
3555               - 2.*Q(n1+n2,2)*Q(n5,1)*Q(n3+n4+n6,3)-2.*Q(n2,1)*Q(n1+n5,2)*Q(n3+n4+n6,3)
3556               - 2.*Q(n1,1)*Q(n2+n5,2)*Q(n3+n4+n6,3)+4.*Q(n1+n2+n5,3)*Q(n3+n4+n6,3)
3557               - 6.*Q(n2,1)*Q(n5,1)*Q(n1+n3+n4+n6,4)+6.*Q(n2+n5,2)*Q(n1+n3+n4+n6,4)
3558               - 6.*Q(n1,1)*Q(n5,1)*Q(n2+n3+n4+n6,4)+6.*Q(n1+n5,2)*Q(n2+n3+n4+n6,4)
3559               + 24.*Q(n5,1)*Q(n1+n2+n3+n4+n6,5)-Q(n1,1)*Q(n2,1)*Q(n3,1)*Q(n4,1)*Q(n5+n6,2)
3560               + Q(n1+n2,2)*Q(n3,1)*Q(n4,1)*Q(n5+n6,2)+Q(n2,1)*Q(n1+n3,2)*Q(n4,1)*Q(n5+n6,2)
3561               + Q(n1,1)*Q(n2+n3,2)*Q(n4,1)*Q(n5+n6,2)-2.*Q(n1+n2+n3,3)*Q(n4,1)*Q(n5+n6,2)
3562               + Q(n2,1)*Q(n3,1)*Q(n1+n4,2)*Q(n5+n6,2)-Q(n2+n3,2)*Q(n1+n4,2)*Q(n5+n6,2)
3563               + Q(n1,1)*Q(n3,1)*Q(n2+n4,2)*Q(n5+n6,2)-Q(n1+n3,2)*Q(n2+n4,2)*Q(n5+n6,2)
3564               - 2.*Q(n3,1)*Q(n1+n2+n4,3)*Q(n5+n6,2)+Q(n1,1)*Q(n2,1)*Q(n3+n4,2)*Q(n5+n6,2)
3565               - Q(n1+n2,2)*Q(n3+n4,2)*Q(n5+n6,2)-2.*Q(n2,1)*Q(n1+n3+n4,3)*Q(n5+n6,2)
3566               - 2.*Q(n1,1)*Q(n2+n3+n4,3)*Q(n5+n6,2)+6.*Q(n1+n2+n3+n4,4)*Q(n5+n6,2)
3567               + 2.*Q(n2,1)*Q(n3,1)*Q(n4,1)*Q(n1+n5+n6,3)-2.*Q(n2+n3,2)*Q(n4,1)*Q(n1+n5+n6,3)
3568               - 2.*Q(n3,1)*Q(n2+n4,2)*Q(n1+n5+n6,3)-2.*Q(n2,1)*Q(n3+n4,2)*Q(n1+n5+n6,3)
3569               + 4.*Q(n2+n3+n4,3)*Q(n1+n5+n6,3)+2.*Q(n1,1)*Q(n3,1)*Q(n4,1)*Q(n2+n5+n6,3)
3570               - 2.*Q(n1+n3,2)*Q(n4,1)*Q(n2+n5+n6,3)-2.*Q(n3,1)*Q(n1+n4,2)*Q(n2+n5+n6,3)
3571               - 2.*Q(n1,1)*Q(n3+n4,2)*Q(n2+n5+n6,3)+4.*Q(n1+n3+n4,3)*Q(n2+n5+n6,3)
3572               - 6.*Q(n3,1)*Q(n4,1)*Q(n1+n2+n5+n6,4)+6.*Q(n3+n4,2)*Q(n1+n2+n5+n6,4)
3573               + 2.*Q(n1,1)*Q(n2,1)*Q(n4,1)*Q(n3+n5+n6,3)-2.*Q(n1+n2,2)*Q(n4,1)*Q(n3+n5+n6,3)
3574               - 2.*Q(n2,1)*Q(n1+n4,2)*Q(n3+n5+n6,3)-2.*Q(n1,1)*Q(n2+n4,2)*Q(n3+n5+n6,3)
3575               + 4.*Q(n1+n2+n4,3)*Q(n3+n5+n6,3)-6.*Q(n2,1)*Q(n4,1)*Q(n1+n3+n5+n6,4)
3576               + 6.*Q(n2+n4,2)*Q(n1+n3+n5+n6,4)-6.*Q(n1,1)*Q(n4,1)*Q(n2+n3+n5+n6,4)
3577               + 6.*Q(n1+n4,2)*Q(n2+n3+n5+n6,4)+24.*Q(n4,1)*Q(n1+n2+n3+n5+n6,5)
3578               + 2.*Q(n1,1)*Q(n2,1)*Q(n3,1)*Q(n4+n5+n6,3)-2.*Q(n1+n2,2)*Q(n3,1)*Q(n4+n5+n6,3)
3579               - 2.*Q(n2,1)*Q(n1+n3,2)*Q(n4+n5+n6,3)-2.*Q(n1,1)*Q(n2+n3,2)*Q(n4+n5+n6,3)
3580               + 4.*Q(n1+n2+n3,3)*Q(n4+n5+n6,3)-6.*Q(n2,1)*Q(n3,1)*Q(n1+n4+n5+n6,4)
3581               + 6.*Q(n2+n3,2)*Q(n1+n4+n5+n6,4)-6.*Q(n1,1)*Q(n3,1)*Q(n2+n4+n5+n6,4)
3582               + 6.*Q(n1+n3,2)*Q(n2+n4+n5+n6,4)+24.*Q(n3,1)*Q(n1+n2+n4+n5+n6,5)
3583               - 6.*Q(n1,1)*Q(n2,1)*Q(n3+n4+n5+n6,4)+6.*Q(n1+n2,2)*Q(n3+n4+n5+n6,4)
3584               + 24.*Q(n2,1)*Q(n1+n3+n4+n5+n6,5)+24.*Q(n1,1)*Q(n2+n3+n4+n5+n6,5)
3585               - 120.*Q(n1+n2+n3+n4+n5+n6,6);
3586
3587  return six;
3588
3589 } // TComplex AliFlowAnalysisWithMultiparticleCorrelations::Six(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6)
3590
3591 //=======================================================================================================================
3592
3593 TComplex AliFlowAnalysisWithMultiparticleCorrelations::Seven(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6, Int_t n7)
3594 {
3595  // Generic seven-particle correlation <exp[i(n1*phi1+n2*phi2+n3*phi3+n4*phi4+n5*phi5+n6*phi6+n7*phi7)]>.
3596
3597  Int_t harmonic[7] = {n1,n2,n3,n4,n5,n6,n7};
3598
3599  TComplex seven = Recursion(7,harmonic); 
3600
3601  return seven;
3602
3603 } // end of TComplex AliFlowAnalysisWithMultiparticleCorrelations::Seven(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6, Int_t n7)
3604
3605 //=======================================================================================================================
3606
3607 TComplex AliFlowAnalysisWithMultiparticleCorrelations::Eight(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6, Int_t n7, Int_t n8)
3608 {
3609  // Generic eight-particle correlation <exp[i(n1*phi1+n2*phi2+n3*phi3+n4*phi4+n5*phi5+n6*phi6+n7*phi7+n8*phi8)]>.
3610
3611  Int_t harmonic[8] = {n1,n2,n3,n4,n5,n6,n7,n8};
3612
3613  TComplex eight = Recursion(8,harmonic); 
3614
3615  return eight;
3616
3617 } // end of TComplex AliFlowAnalysisWithMultiparticleCorrelations::Eight(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6, Int_t n7, Int_t n8)
3618
3619 //=======================================================================================================================
3620
3621 void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForWeights()
3622 {
3623  // Book all objects for calculations with weights. 
3624
3625  // a) Book profile to hold all flags for weights;
3626  // b) Store histograms holding phi, pt and eta weights.
3627     
3628  // a) Book profile to hold all flags for weights:
3629  fWeightsFlagsPro = new TProfile("fWeightsFlagsPro","0 = weight not used, 1 = weight used ",6,0,6);
3630  fWeightsFlagsPro->SetLabelSize(0.06);
3631  fWeightsFlagsPro->SetStats(kFALSE);
3632  fWeightsFlagsPro->SetFillColor(kGray);
3633  fWeightsFlagsPro->SetLineColor(kBlack);
3634  fWeightsFlagsPro->GetXaxis()->SetBinLabel(1,"RP: w_{#phi}"); fWeightsFlagsPro->Fill(0.5,fUseWeights[0][0]);
3635  fWeightsFlagsPro->GetXaxis()->SetBinLabel(2,"RP: w_{p_{T}}"); fWeightsFlagsPro->Fill(1.5,fUseWeights[0][1]);
3636  fWeightsFlagsPro->GetXaxis()->SetBinLabel(3,"RP: w_{#eta}"); fWeightsFlagsPro->Fill(2.5,fUseWeights[0][2]);
3637  fWeightsFlagsPro->GetXaxis()->SetBinLabel(4,"POI: w_{#phi}"); fWeightsFlagsPro->Fill(3.5,fUseWeights[1][0]);
3638  fWeightsFlagsPro->GetXaxis()->SetBinLabel(5,"POI: w_{p_{T}}"); fWeightsFlagsPro->Fill(4.5,fUseWeights[1][1]);
3639  fWeightsFlagsPro->GetXaxis()->SetBinLabel(6,"POI: w_{#eta}"); fWeightsFlagsPro->Fill(5.5,fUseWeights[1][2]);
3640  fWeightsList->Add(fWeightsFlagsPro); 
3641   
3642  // b) Store histograms holding phi, pt and eta weights:
3643  //    REMARK: It is assumed that these histos are accessed from external file "weights.root" 
3644  for(Int_t rp=0;rp<2;rp++) // [RP,POI]
3645  {
3646   for(Int_t ppe=0;ppe<3;ppe++) // [phi,pt,eta]
3647   {
3648    if(fWeightsHist[rp][ppe]){fWeightsList->Add(fWeightsHist[rp][ppe]);}
3649   }
3650  }
3651
3652 } // void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForWeights()
3653
3654 //=======================================================================================================================
3655
3656 Double_t AliFlowAnalysisWithMultiparticleCorrelations::Weight(const Double_t &value, const char *type, const char *variable) // value, [RP,POI], [phi,pt,eta]
3657 {
3658  // Determine particle weight. 
3659
3660  TString sMethodName = "Double_t AliFlowAnalysisWithMultiparticleCorrelations::Weight(const Double_t &value, const char *type, const char *variable)"; 
3661
3662  // Basic protection:
3663  if(!(TString(type).EqualTo("RP") || TString(type).EqualTo("POI"))){Fatal(sMethodName.Data(),"!(TString(type).EqualTo...");}
3664  if(!(TString(variable).EqualTo("phi") || TString(variable).EqualTo("pt") || TString(variable).EqualTo("eta"))){Fatal(sMethodName.Data(),"!(TString(variable).EqualTo...");}
3665
3666  Int_t rp = 0; // [RP,POI]
3667  if(TString(type).EqualTo("POI")){rp=1;} 
3668
3669  Int_t ppe = 0; // [phi,pt,eta]
3670  if(TString(variable).EqualTo("pt")){ppe=1;} 
3671  if(TString(variable).EqualTo("eta")){ppe=2;} 
3672
3673  if(!fWeightsHist[rp][ppe]){Fatal(sMethodName.Data(),"!fWeightsHist[rp][ppe]");}
3674
3675  Double_t weight = fWeightsHist[rp][ppe]->GetBinContent(fWeightsHist[rp][ppe]->FindBin(value));
3676
3677  return weight;
3678
3679 } // Double_t AliFlowAnalysisWithMultiparticleCorrelations::Weight(const Double_t &value, const char *type, const char *variable)
3680
3681 //=======================================================================================================================
3682
3683 /*
3684 Double_t AliFlowAnalysisWithMultiparticleCorrelations::PhiWeight(const Double_t &dPhi, const char *type)
3685 {
3686  // Determine phi weight for a given phi. 
3687
3688  TString sMethodName = "Double_t AliFlowAnalysisWithMultiparticleCorrelations::PhiWeight(const Double_t &dPhi, const char *type)"; 
3689
3690  // Basic protection:
3691  if(!(TString(type)::EqualTo("RP") || TString(type)::EqualTo("POI"))){Fatal(sMethodName.Data(),"!(TString(type)::EqualTo...");}
3692
3693  Int_t rp = 0; // RP or POI
3694  if(TString(type)::EqualTo("POI")){rp=1;} 
3695  
3696  if(!fWeightsHist[rp][0]){Fatal("AliFlowAnalysisWithMultiparticleCorrelations::PhiWeight(const Double_t &dPhi)","fPhiWeightsHist");}
3697   
3698
3699
3700
3701
3702
3703
3704
3705
3706  Double_t wPhi = fPhiWeightsHist->GetBinContent(fPhiWeightsHist->FindBin(dPhi));
3707  
3708
3709  wPhi = 0.;
3710
3711  return wPhi;
3712
3713 } // Double_t AliFlowAnalysisWithMultiparticleCorrelations::PhiWeight(const Double_t &dPhi)
3714
3715 //=======================================================================================================================
3716
3717 Double_t AliFlowAnalysisWithMultiparticleCorrelations::PtWeight(const Double_t &dPt, const char *type)
3718 {
3719  // Determine pt weight for a given pt. 
3720
3721  if(!fPtWeightsHist){Fatal("AliFlowAnalysisWithMultiparticleCorrelations::PtWeight(const Double_t &dPt)","fPtWeightsHist");}
3722
3723  Double_t wPt = fPtWeightsHist->GetBinContent(fPtWeightsHist->FindBin(dPt));
3724
3725  return wPt;
3726
3727 } // Double_t AliFlowAnalysisWithMultiparticleCorrelations::PtWeight(const Double_t &dPt)
3728
3729 //=======================================================================================================================
3730
3731 Double_t AliFlowAnalysisWithMultiparticleCorrelations::EtaWeight(const Double_t &dEta, const char *type)
3732 {
3733  // Determine eta weight for a given eta. 
3734
3735  if(!fEtaWeightsHist){Fatal("AliFlowAnalysisWithMultiparticleCorrelations::EtaWeight(const Double_t &dEta)","fEtaWeightsHist");}
3736
3737  Double_t wEta = fEtaWeightsHist->GetBinContent(fEtaWeightsHist->FindBin(dEta));
3738
3739  return wEta;
3740
3741 } // Double_t AliFlowAnalysisWithMultiparticleCorrelations::EtaWeight(const Double_t &dEta)
3742
3743 */
3744
3745
3746 //=======================================================================================================================
3747
3748 void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForBase()
3749 {
3750  // Book all base objects. 
3751
3752  fInternalFlagsPro = new TProfile("fInternalFlagsPro","Internal flags and settings",8,0,8);
3753  fInternalFlagsPro->SetLabelSize(0.05);
3754  fInternalFlagsPro->SetStats(kFALSE);
3755  fInternalFlagsPro->SetFillColor(kGray);
3756  fInternalFlagsPro->SetLineColor(kBlack);
3757  fInternalFlagsPro->GetXaxis()->SetBinLabel(1,"fUseInternalFlags"); fInternalFlagsPro->Fill(0.5,fUseInternalFlags);  
3758  fInternalFlagsPro->GetXaxis()->SetBinLabel(2,"fMinNoRPs"); fInternalFlagsPro->Fill(1.5,fMinNoRPs);  
3759  fInternalFlagsPro->GetXaxis()->SetBinLabel(3,"fMaxNoRPs"); fInternalFlagsPro->Fill(2.5,fMaxNoRPs); 
3760  fInternalFlagsPro->GetXaxis()->SetBinLabel(4,"fExactNoRPs"); fInternalFlagsPro->Fill(3.5,fExactNoRPs);  
3761  fInternalFlagsPro->GetXaxis()->SetBinLabel(5,"fPropagateError"); fInternalFlagsPro->Fill(4.5,fPropagateError);  
3762  fInternalFlagsPro->GetXaxis()->SetBinLabel(6,Form("fAnalysisTag = %s",fAnalysisTag.Data())); 
3763  fInternalFlagsPro->GetXaxis()->SetBinLabel(7,"fDumpThePoints"); fInternalFlagsPro->Fill(6.5,fDumpThePoints);  
3764  fInternalFlagsPro->GetXaxis()->SetBinLabel(8,"fMaxNoEventsPerFile"); fInternalFlagsPro->Fill(7.5,fMaxNoEventsPerFile);  
3765
3766  fHistList->Add(fInternalFlagsPro); 
3767
3768 } // void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForBase()
3769
3770 //=======================================================================================================================
3771
3772 Bool_t AliFlowAnalysisWithMultiparticleCorrelations::CrossCheckInternalFlags(AliFlowEventSimple *anEvent)
3773 {
3774  // Cross-check in this method wether "anEvent" passes internal flags. 
3775
3776  // a) Cross-check min. and max. number of RPs; 
3777  // b) Cross-check exact number of RPs. 
3778
3779  Bool_t bPassesInternalFlags = kTRUE;
3780
3781  // a) Cross-check min. and max. number of RPs: 
3782  if(-44 != fMinNoRPs)
3783  {
3784   fMinNoRPs <= anEvent->GetNumberOfRPs() ? 1 : bPassesInternalFlags = kFALSE; 
3785   if(!bPassesInternalFlags){return bPassesInternalFlags;}
3786  }
3787  if(-44 != fMaxNoRPs)
3788  {
3789   anEvent->GetNumberOfRPs() < fMaxNoRPs ? 1 : bPassesInternalFlags = kFALSE;  
3790   if(!bPassesInternalFlags){return bPassesInternalFlags;}
3791  }
3792
3793  // b) Cross-check exact number of RPs:
3794  if(-44 != fExactNoRPs)
3795  {
3796   anEvent->GetNumberOfRPs() == fExactNoRPs ? 1 : bPassesInternalFlags = kFALSE;  
3797   if(!bPassesInternalFlags){return bPassesInternalFlags;}
3798  }
3799
3800  return bPassesInternalFlags; 
3801
3802 } // Bool_t AliFlowAnalysisWithMultiparticleCorrelations::CrossCheckInternalFlags(AliFlowEventSimple *anEvent)
3803
3804 //=======================================================================================================================
3805
3806 void AliFlowAnalysisWithMultiparticleCorrelations::DumpPointsForDurham(TGraphErrors *ge)
3807 {
3808  // Dump points from TGraphErrors object into Durham database format. 
3809
3810  // Remark 1: format is <binCenter>  <value>  +-<stat.error>
3811  // Remark 2: the default precision is 6 significant digits
3812
3813  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::DumpPointsForDurham(TGraphErrors *ge)"; 
3814
3815  if(!ge){Fatal(sMethodName.Data(),"ge is NULL, for one reason or another...");}
3816
3817  ge->Draw("ap");
3818
3819  Int_t nPoints = ge->GetN();
3820  Double_t x = 0.;
3821  //Double_t xErr = 0.;
3822  Double_t y = 0.;
3823  Double_t yErr = 0.;
3824  printf("\nbinCenter value     +-stat.error\n");
3825  for(Int_t p=0;p<nPoints;p++)
3826  { 
3827   ge->GetPoint(p,x,y);
3828   //xErr = ge->GetErrorX(p); 
3829   yErr = ge->GetErrorY(p); 
3830   printf("%f  %f  +-%f\n",x,y,yErr);
3831  } // end of for(Int_t p=0;p<nPoints;p++)
3832  cout<<endl;
3833
3834 } // void AliFlowAnalysisWithMultiparticleCorrelations::DumpPointsForDurham(TGraphErrors *ge)
3835
3836 //=======================================================================================================================
3837
3838 void AliFlowAnalysisWithMultiparticleCorrelations::DumpPointsForDurham(TH1D *h)
3839 {
3840  // Dump points from TH1D object into Durham database format.
3841
3842  // Remark 1: format is <binCenter>  <value>  +-<stat.error>
3843  // Remark 2: the default precision is 6 significant digits
3844
3845  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::DumpPointsForDurham(TH1D *h)"; 
3846
3847  if(!h){Fatal(sMethodName.Data(),"h is NULL, for one reason or another...");}
3848
3849  h->Draw();
3850
3851  Int_t nPoints = h->GetXaxis()->GetNbins();
3852  Double_t x = 0.;
3853  Double_t y = 0.;
3854  Double_t yErr = 0.;
3855  printf("\nbinCenter value     +-stat.error\n");
3856  for(Int_t p=1;p<=nPoints;p++)
3857  { 
3858   x = h->GetBinCenter(p);
3859   y = h->GetBinContent(p);
3860   yErr = h->GetBinError(p); 
3861   //printf("%f  %f  +-%f\n",x,y,yErr); 
3862   printf("%e  %e  +-%e\n",x,y,yErr); 
3863  } // end of for(Int_t p=0;p<nPoints;p++)
3864  cout<<endl;
3865
3866 } // void AliFlowAnalysisWithMultiparticleCorrelations::DumpPointsForDurham(TH1D *h)
3867
3868 //=======================================================================================================================
3869
3870 void AliFlowAnalysisWithMultiparticleCorrelations::DumpPointsForDurham(TH1F *h)
3871 {
3872  // Dump points from TH1F object into Durham database format.
3873
3874  // Remark 1: format is <binCenter>  <value>  +-<stat.error>
3875  // Remark 2: the default precision is 6 significant digits
3876
3877  TString sMethodName = "AliFlowAnalysisWithMultiparticleCorrelations::DumpPointsForDurham(TH1F *h)"; 
3878
3879  if(!h){Fatal(sMethodName.Data(),"h is NULL, for one reason or another...");}
3880
3881  h->Draw();
3882
3883  Int_t nPoints = h->GetXaxis()->GetNbins();
3884  Double_t x = 0.;
3885  Double_t y = 0.;
3886  Double_t yErr = 0.;
3887  printf("\nbinCenter value     +-stat.error\n");
3888  for(Int_t p=1;p<=nPoints;p++)
3889  { 
3890   x = h->GetBinCenter(p);
3891   y = h->GetBinContent(p);
3892   yErr = h->GetBinError(p); 
3893   printf("%f  %f  +-%f\n",x,y,yErr);
3894  } // end of for(Int_t p=0;p<nPoints;p++)
3895  cout<<endl;
3896
3897 } // void AliFlowAnalysisWithMultiparticleCorrelations::DumpPointsForDurham(TH1F *h)
3898
3899 //=======================================================================================================================
3900
3901 void AliFlowAnalysisWithMultiparticleCorrelations::InitializeArraysForQcumulants()
3902 {
3903  // Initialize all arrays for Q-cumulants.
3904
3905  // ... TBI 
3906
3907 } // void AliFlowAnalysisWithMultiparticleCorrelations::InitializeArraysForQcumulants()
3908
3909 //=======================================================================================================================
3910
3911 void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForQcumulants()
3912 {
3913  // Book all the stuff for Q-cumulants.
3914
3915  // a) Book the profile holding all the flags for Q-cumulants;
3916  // b) Book TH1D *fQcumulantsHist;
3917  // c) Book TH1D *fReferenceFlowHist;
3918  // d) Book TProfile2D *fProductsQCPro.
3919
3920  TString sMethodName = "void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForQcumulants()";
3921
3922  // a) Book the profile holding all the flags for Q-cumulants:
3923  fQcumulantsFlagsPro = new TProfile("fQcumulantsFlagsPro","Flags for Q-cumulants",3,0,3);
3924  fQcumulantsFlagsPro->SetTickLength(-0.01,"Y");
3925  fQcumulantsFlagsPro->SetMarkerStyle(25);
3926  fQcumulantsFlagsPro->SetLabelSize(0.03);
3927  fQcumulantsFlagsPro->SetLabelOffset(0.02,"Y");
3928  fQcumulantsFlagsPro->SetStats(kFALSE);
3929  fQcumulantsFlagsPro->SetFillColor(kGray);
3930  fQcumulantsFlagsPro->SetLineColor(kBlack);
3931  fQcumulantsFlagsPro->GetXaxis()->SetBinLabel(1,"fCalculateQcumulants"); fQcumulantsFlagsPro->Fill(0.5,fCalculateQcumulants); 
3932  fQcumulantsFlagsPro->GetXaxis()->SetBinLabel(2,"fHarmonicQC"); fQcumulantsFlagsPro->Fill(1.5,fHarmonicQC); 
3933  fQcumulantsFlagsPro->GetXaxis()->SetBinLabel(3,"fPropagateErrorQC"); fQcumulantsFlagsPro->Fill(2.5,fPropagateErrorQC); 
3934  fQcumulantsList->Add(fQcumulantsFlagsPro);
3935
3936  if(!fCalculateQcumulants){return;} // TBI is this safe enough? 
3937
3938  // b) Book TH1D *fQcumulantsHist:
3939  fQcumulantsHist = new TH1D("Q-cumulants",Form("Q-cumulants (n = %d)",fHarmonicQC),4,0.,4.);
3940  fQcumulantsHist->SetStats(kFALSE);
3941  fQcumulantsHist->SetMarkerColor(kBlack);
3942  fQcumulantsHist->SetMarkerStyle(kFullSquare);
3943  fQcumulantsHist->GetXaxis()->SetLabelSize(0.045);
3944  fQcumulantsHist->GetXaxis()->SetLabelOffset(0.01);
3945  for(Int_t qc=1;qc<=4;qc++) // [QC{2},QC{4},QC{6},QC{8}]
3946  {
3947   fQcumulantsHist->GetXaxis()->SetBinLabel(qc,Form("QC{%d}",2*qc));
3948  } 
3949  fQcumulantsList->Add(fQcumulantsHist);
3950
3951  // c) Book TH1D *fReferenceFlowHist:
3952  fReferenceFlowHist = new TH1D("Reference Flow","Reference flow from Q-cumulants",4,0.,4.);
3953  fReferenceFlowHist->SetStats(kFALSE);
3954  fReferenceFlowHist->SetMarkerColor(kBlack);
3955  fReferenceFlowHist->SetMarkerStyle(kFullSquare);
3956  fReferenceFlowHist->GetXaxis()->SetLabelSize(0.045);
3957  fReferenceFlowHist->GetXaxis()->SetLabelOffset(0.01);
3958  for(Int_t qc=1;qc<=4;qc++) // [vn{2},vn{4},vn{6},vn{8}]
3959  {
3960   fReferenceFlowHist->GetXaxis()->SetBinLabel(qc,Form("v_{%d}{%d}",fHarmonicQC,2*qc));
3961  } 
3962  fQcumulantsList->Add(fReferenceFlowHist);
3963
3964  if(!fPropagateErrorQC){return;} // TBI is this safe enough? 
3965
3966  // d) Book TProfile2D *fProductsQCPro:
3967  const Int_t nCorrelations = 4;
3968  Int_t n = fHarmonicQC; 
3969  TString sCorrelations[nCorrelations] = {Form("Cos(-%d,%d)",n,n),
3970                                          Form("Cos(-%d,-%d,%d,%d)",n,n,n,n),
3971                                          Form("Cos(-%d,-%d,-%d,%d,%d,%d)",n,n,n,n,n,n),
3972                                          Form("Cos(-%d,-%d,-%d,-%d,%d,%d,%d,%d)",n,n,n,n,n,n,n,n)}; 
3973  Int_t nBins2D = (Int_t)TMath::Floor(fDontGoBeyond/2.);
3974  if(fDontGoBeyond > 8){nBins2D = 4;}
3975  if(nBins2D < 1 || nBins2D > 4)
3976  {
3977   cout<<Form("nBins2D = %d",nBins2D)<<endl;
3978   cout<<Form("fDontGoBeyond = %d",fDontGoBeyond)<<endl;
3979   Fatal(sMethodName.Data(),"nBins2D < 1 || nBins2D > 4");
3980  }
3981  fProductsQCPro = new TProfile2D("fProductsQCPro","Products of correlations",nBins2D,0.,nBins2D,nBins2D,0.,nBins2D);
3982  fProductsQCPro->SetStats(kFALSE);
3983  fProductsQCPro->Sumw2();
3984  for(Int_t b=1;b<=nBins2D;b++)
3985  {
3986   fProductsQCPro->GetXaxis()->SetBinLabel(b,sCorrelations[b-1].Data());
3987   fProductsQCPro->GetYaxis()->SetBinLabel(b,sCorrelations[b-1].Data());
3988  } // for(Int_t b=1;b<=nBins2D;b++)
3989  fQcumulantsList->Add(fProductsQCPro);
3990  
3991 } // end of void AliFlowAnalysisWithMultiparticleCorrelations::BookEverythingForQcumulants()
3992
3993 //=======================================================================================================================
3994
3995 void AliFlowAnalysisWithMultiparticleCorrelations::CalculateQcumulants()
3996 {
3997  // Calculate Q-cumulants.
3998
3999  TString sMethodName = "void AliFlowAnalysisWithMultiparticleCorrelations::CalculateQcumulants()";
4000
4001  fPropagateError = kTRUE;
4002  Int_t n = fHarmonicQC;
4003  fQcumulantsHist->SetTitle(Form("Q-cumulants (n = %d)",n));
4004
4005  TString sCorrelations[4] = {Form("Cos(-%d,%d)",n,n),
4006                              Form("Cos(-%d,-%d,%d,%d)",n,n,n,n),
4007                              Form("Cos(-%d,-%d,-%d,%d,%d,%d)",n,n,n,n,n,n),
4008                              Form("Cos(-%d,-%d,-%d,-%d,%d,%d,%d,%d)",n,n,n,n,n,n,n,n)};
4009
4010  Int_t nBins[4] = {fCorrelationsPro[0][1]->GetNbinsX(),fCorrelationsPro[0][3]->GetNbinsX(),
4011                    fCorrelationsPro[0][5]->GetNbinsX(),fCorrelationsPro[0][7]->GetNbinsX()};
4012
4013  Double_t dCorrelation[4] = {0.};
4014  Double_t dCorrelationErr[4] = {0.};
4015
4016  for(Int_t c=0;c<4;c++) // [<<2>>,<<4>>,<<6>>,<<8>>]
4017  {
4018   if(2*(c+1)>fDontGoBeyond){break;}
4019   for(Int_t b=1;b<=nBins[c];b++)
4020   {
4021    if(sCorrelations[c].EqualTo(fCorrelationsPro[0][2*c+1]->GetXaxis()->GetBinLabel(b)))   
4022    {
4023     dCorrelation[c] = fCorrelationsPro[0][2*c+1]->GetBinContent(b);
4024     dCorrelationErr[c] = fCorrelationsPro[0][2*c+1]->GetBinError(b);
4025     break; 
4026    }
4027   } // for(Int_t b=1;b<=nBins[c];b++)
4028  } // for(Int_t c=0;c<4;c++) // [<<2>>,<<4>>,<<6>>,<<8>>]
4029
4030  // Correlations:
4031  Double_t two = dCorrelation[0]; // <<2>>
4032  Double_t four = dCorrelation[1]; // <<4>>  
4033  Double_t six = dCorrelation[2]; // <<6>> 
4034  Double_t eight = dCorrelation[3]; // <<8>>  
4035
4036  // Q-cumulants: 
4037  Double_t qc2 = 0.; // QC{2}
4038  Double_t qc4 = 0.; // QC{4}
4039  Double_t qc6 = 0.; // QC{6}
4040  Double_t qc8 = 0.; // QC{8}
4041  if(TMath::Abs(two) > 0. && !(fDontGoBeyond < 2)){qc2 = two;} 
4042  if(TMath::Abs(four) > 0. && !(fDontGoBeyond < 4)){qc4 = four-2.*pow(two,2.);} 
4043  if(TMath::Abs(six) > 0. && !(fDontGoBeyond < 6)){qc6 = six-9.*two*four+12.*pow(two,3.);} 
4044  if(TMath::Abs(eight) > 0. && !(fDontGoBeyond < 8)){qc8 = eight-16.*two*six-18.*pow(four,2.)+144.*pow(two,2.)*four-144.*pow(two,4.);} 
4045
4046  // Store the results for Q-cumulants:
4047  if(TMath::Abs(qc2)>0.)
4048  {
4049   fQcumulantsHist->SetBinContent(1,qc2);
4050  }
4051  if(TMath::Abs(qc4)>0.)
4052  {
4053   fQcumulantsHist->SetBinContent(2,qc4);
4054  }
4055  if(TMath::Abs(qc6)>0.)
4056  {
4057   fQcumulantsHist->SetBinContent(3,qc6);
4058  }
4059  if(TMath::Abs(qc8)>0.)
4060  {
4061   fQcumulantsHist->SetBinContent(4,qc8); 
4062  }
4063
4064  if(!fPropagateErrorQC)
4065  {
4066   fQcumulantsHist->SetBinError(1,0.); 
4067   fQcumulantsHist->SetBinError(2,0.); 
4068   fQcumulantsHist->SetBinError(3,0.); 
4069   fQcumulantsHist->SetBinError(4,0.); 
4070   return;
4071  } // if(!fPropagateErrorQC)
4072
4073  // Statistical errors of average 2-, 4-, 6- and 8-particle azimuthal correlations:
4074  Double_t twoError = dCorrelationErr[0]; // statistical error of <2>  
4075  Double_t fourError = dCorrelationErr[1]; // statistical error of <4>   
4076  Double_t sixError = dCorrelationErr[2]; // statistical error of <6> 
4077  Double_t eightError = dCorrelationErr[3]; // statistical error of <8> 
4078
4079  // Covariances multiplied by a prefactor depending on weights: 
4080  Double_t wCov24 = 0.; // Cov(<2>,<4>) * prefactor(w_<2>,w_<4>) 
4081  Double_t wCov26 = 0.; // Cov(<2>,<6>) * prefactor(w_<2>,w_<6>)
4082  Double_t wCov28 = 0.; // Cov(<2>,<8>) * prefactor(w_<2>,w_<8>)
4083  Double_t wCov46 = 0.; // Cov(<4>,<6>) * prefactor(w_<4>,w_<6>)
4084  Double_t wCov48 = 0.; // Cov(<4>,<8>) * prefactor(w_<4>,w_<8>)
4085  Double_t wCov68 = 0.; // Cov(<6>,<8>) * prefactor(w_<6>,w_<8>)  
4086  if(!(fDontGoBeyond < 4)){wCov24 = Covariance(sCorrelations[0].Data(),sCorrelations[1].Data(),fProductsQCPro);} // Cov(<2>,<4>) * prefactor(w_<2>,w_<4>) 
4087  if(!(fDontGoBeyond < 6)){wCov26 = Covariance(sCorrelations[0].Data(),sCorrelations[2].Data(),fProductsQCPro);} // Cov(<2>,<6>) * prefactor(w_<2>,w_<6>)
4088  if(!(fDontGoBeyond < 8)){wCov28 = Covariance(sCorrelations[0].Data(),sCorrelations[3].Data(),fProductsQCPro);} // Cov(<2>,<8>) * prefactor(w_<2>,w_<8>)
4089  if(!(fDontGoBeyond < 6)){wCov46 = Covariance(sCorrelations[1].Data(),sCorrelations[2].Data(),fProductsQCPro);} // Cov(<4>,<6>) * prefactor(w_<4>,w_<6>)
4090  if(!(fDontGoBeyond < 8)){wCov48 = Covariance(sCorrelations[1].Data(),sCorrelations[3].Data(),fProductsQCPro);} // Cov(<4>,<8>) * prefactor(w_<4>,w_<8>)
4091  if(!(fDontGoBeyond < 8)){wCov68 = Covariance(sCorrelations[2].Data(),sCorrelations[3].Data(),fProductsQCPro);} // Cov(<6>,<8>) * prefactor(w_<6>,w_<8>)  
4092
4093  // Statistical errors of Q-cumulants:       
4094  Double_t qc2Error = 0.;
4095  Double_t qc4Error = 0.;
4096  Double_t qc6Error = 0.;
4097  Double_t qc8Error = 0.; 
4098  // Squared statistical errors of Q-cumulants:       
4099  //Double_t qc2ErrorSquared = 0.;
4100  Double_t qc4ErrorSquared = 0.;
4101  Double_t qc6ErrorSquared = 0.;
4102  Double_t qc8ErrorSquared = 0.;        
4103  // Statistical error of QC{2}:              
4104  if(!(fDontGoBeyond < 2)){qc2Error = twoError;}                                                 
4105  // Statistical error of QC{4}:              
4106  qc4ErrorSquared = 16.*pow(two,2.)*pow(twoError,2)+pow(fourError,2.)
4107                  - 8.*two*wCov24;                     
4108  if(qc4ErrorSquared > 0. && !(fDontGoBeyond < 4))
4109  {
4110   qc4Error = pow(qc4ErrorSquared,0.5);
4111  } else{Warning(sMethodName.Data(),"Statistical error of QC{4} is imaginary !!!!"); fPropagateError = kFALSE;}
4112                                            
4113  // Statistical error of QC{6}:              
4114  qc6ErrorSquared = 81.*pow(4.*pow(two,2.)-four,2.)*pow(twoError,2.)
4115                  + 81.*pow(two,2.)*pow(fourError,2.)
4116                  + pow(sixError,2.)
4117                  - 162.*two*(4.*pow(two,2.)-four)*wCov24
4118                  + 18.*(4.*pow(two,2.)-four)*wCov26
4119                  - 18.*two*wCov46;                     
4120  if(qc6ErrorSquared > 0. && !(fDontGoBeyond < 6))
4121  {
4122   qc6Error = pow(qc6ErrorSquared,0.5);
4123  } else{Warning(sMethodName.Data(),"Statistical error of QC{6} is imaginary !!!!"); fPropagateError = kFALSE;}
4124
4125  // Statistical error of QC{8}:              
4126  qc8ErrorSquared = 256.*pow(36.*pow(two,3.)-18.*four*two+six,2.)*pow(twoError,2.)
4127                  + 1296.*pow(4.*pow(two,2.)-four,2.)*pow(fourError,2.)
4128                  + 256.*pow(two,2.)*pow(sixError,2.)
4129                  + pow(eightError,2.)
4130                  - 1152.*(36.*pow(two,3.)-18.*four*two+six)*(4.*pow(two,2.)-four)*wCov24
4131                  + 512.*two*(36.*pow(two,3.)-18.*four*two+six)*wCov26
4132                  - 32.*(36.*pow(two,3.)-18.*four*two+six)*wCov28
4133                  - 1152.*two*(4.*pow(two,2.)-four)*wCov46
4134                  + 72.*(4.*pow(two,2.)-four)*wCov48
4135                  - 32.*two*wCov68;       
4136  if(qc8ErrorSquared > 0. && !(fDontGoBeyond < 8))
4137  {
4138   qc8Error = pow(qc8ErrorSquared,0.5);
4139  } else{Warning(sMethodName.Data(),"Statistical error of QC{8} is imaginary !!!!"); fPropagateError = kFALSE;}
4140
4141  if(!fPropagateError){fPropagateError = kTRUE; return;}
4142
4143  // Store the statistical errors for Q-cumulants:
4144  if(TMath::Abs(qc2)>0.)
4145  {
4146   fQcumulantsHist->SetBinError(1,qc2Error);
4147  }
4148  if(TMath::Abs(qc4)>0.)
4149  {
4150   fQcumulantsHist->SetBinError(2,qc4Error);
4151  }
4152  if(TMath::Abs(qc6)>0.)
4153  {
4154   fQcumulantsHist->SetBinError(3,qc6Error);
4155  }
4156  if(TMath::Abs(qc8)>0.)
4157  {
4158   fQcumulantsHist->SetBinError(4,qc8Error);
4159  }
4160
4161 } // void AliFlowAnalysisWithMultiparticleCorrelations::CalculateQcumulants()
4162
4163 //=======================================================================================================================
4164
4165 void AliFlowAnalysisWithMultiparticleCorrelations::CalculateReferenceFlow()
4166 {
4167  // Calculate reference flow from Q-cumulants.
4168
4169  TString sMethodName = "void AliFlowAnalysisWithMultiparticleCorrelations::CalculateReferenceFlow()";
4170
4171  Int_t n = fHarmonicQC;
4172
4173  // Reference flow estimates:
4174  Double_t v2 = 0.; // v{2}  
4175  Double_t v4 = 0.; // v{4}  
4176  Double_t v6 = 0.; // v{6}  
4177  Double_t v8 = 0.; // v{8}
4178
4179  // Reference flow's statistical errors:
4180  Double_t v2Error = 0.; // v{2} stat. error 
4181  Double_t v4Error = 0.; // v{4} stat. error
4182  Double_t v6Error = 0.; // v{6} stat. error
4183  Double_t v8Error = 0.; // v{8} stat. error
4184   
4185  // Q-cumulants:
4186  Double_t qc2 = fQcumulantsHist->GetBinContent(1); // QC{2}  
4187  Double_t qc4 = fQcumulantsHist->GetBinContent(2); // QC{4}  
4188  Double_t qc6 = fQcumulantsHist->GetBinContent(3); // QC{6}  
4189  Double_t qc8 = fQcumulantsHist->GetBinContent(4); // QC{8}
4190
4191  // Q-cumulants's statistical errors: 
4192  Double_t qc2Error = fQcumulantsHist->GetBinError(1); // QC{2} stat. error  
4193  Double_t qc4Error = fQcumulantsHist->GetBinError(2); // QC{4} stat. error  
4194  Double_t qc6Error = fQcumulantsHist->GetBinError(3); // QC{6} stat. error  
4195  Double_t qc8Error = fQcumulantsHist->GetBinError(4); // QC{8} stat. error
4196
4197  // Calculate reference flow estimates from Q-cumulants: 
4198  if(qc2>=0.){v2 = pow(qc2,0.5);} 
4199  if(qc4<=0.){v4 = pow(-1.*qc4,1./4.);} 
4200  if(qc6>=0.){v6 = pow((1./4.)*qc6,1./6.);}
4201  if(qc8<=0.){v8 = pow((-1./33.)*qc8,1./8.);}  
4202
4203  // Calculate stat. error for reference flow estimates from stat. error of Q-cumulants:  
4204  if(qc2>0. && qc2Error>0.){v2Error = (1./2.)*pow(qc2,-0.5)*qc2Error;} 
4205  if(qc4<0. && qc4Error>0.){v4Error = (1./4.)*pow(-qc4,-3./4.)*qc4Error;} 
4206  if(qc6>0. && qc6Error>0.){v6Error = (1./6.)*pow(2.,-1./3.)*pow(qc6,-5./6.)*qc6Error;}   
4207  if(qc8<0. && qc8Error>0.){v8Error = (1./8.)*pow(33.,-1./8.)*pow(-qc8,-7./8.)*qc8Error;}   
4208
4209  // Print warnings for the 'wrong sign' cumulants: 
4210  if(TMath::Abs(v2)<1.e-44){Warning(sMethodName.Data(),"Wrong sign QC{2}, couldn't calculate v{2} !!!!");}
4211  if(TMath::Abs(v4)<1.e-44){Warning(sMethodName.Data(),"Wrong sign QC{4}, couldn't calculate v{4} !!!!");} 
4212  if(TMath::Abs(v6)<1.e-44){Warning(sMethodName.Data(),"Wrong sign QC{6}, couldn't calculate v{6} !!!!");}
4213  if(TMath::Abs(v8)<1.e-44){Warning(sMethodName.Data(),"Wrong sign QC{8}, couldn't calculate v{8} !!!!");}                       
4214
4215  // Store the results and statistical errors of reference flow estimates:
4216  for(Int_t qc=1;qc<=4;qc++) // [vn{2},vn{4},vn{6},vn{8}]
4217  {
4218   fReferenceFlowHist->GetXaxis()->SetBinLabel(qc,Form("v_{%d}{%d}",n,2*qc));
4219  } 
4220  fReferenceFlowHist->SetBinContent(1,v2);
4221  fReferenceFlowHist->SetBinError(1,v2Error);
4222  fReferenceFlowHist->SetBinContent(2,v4);
4223  fReferenceFlowHist->SetBinError(2,v4Error);
4224  fReferenceFlowHist->SetBinContent(3,v6);
4225  fReferenceFlowHist->SetBinError(3,v6Error);
4226  fReferenceFlowHist->SetBinContent(4,v8);
4227  fReferenceFlowHist->SetBinError(4,v8Error);  
4228
4229  // Final printout:
4230  cout<<endl;
4231  cout<<"*************************************"<<endl;
4232  cout<<"*************************************"<<endl;
4233  cout<<" flow estimates from Q-cumulants"<<endl;
4234  TString sWhichWeights = "no weights";
4235  if(fUseWeights[0][0]){sWhichWeights = "phi weights";} 
4236  else if(fUseWeights[0][1]){sWhichWeights = "pt weights";}
4237  else if(fUseWeights[0][2]){sWhichWeights = "eta weights";}
4238  cout<<Form("  (MPC class, RPs, %s)",sWhichWeights.Data())<<endl; 
4239  cout<<endl;
4240  for(Int_t co=0;co<4;co++) // cumulant order
4241  {
4242   cout<<Form("  v_%d{%d} = %.8f +/- %.8f",fHarmonicQC,2*(co+1),fReferenceFlowHist->GetBinContent(co+1),fReferenceFlowHist->GetBinError(co+1))<<endl;
4243  }
4244  cout<<endl;
4245  Int_t nEvts = 0;
4246  Double_t dAvM = 0.;
4247  if(fMultDistributionsHist[0])
4248  {
4249   nEvts = (Int_t)fMultDistributionsHist[0]->GetEntries();
4250   dAvM = fMultDistributionsHist[0]->GetMean();
4251  } else{Warning(sMethodName.Data(),"fMultDistributionsHist[0] is NULL !!!!");}
4252  cout<<Form("     nEvts = %d, <M> = %.2f",nEvts,dAvM)<<endl;
4253  cout<<"*************************************"<<endl;
4254  cout<<"*************************************"<<endl;
4255  cout<<endl;
4256
4257 } // void AliFlowAnalysisWithMultiparticleCorrelations::CalculateReferenceFlow()
4258
4259 //=======================================================================================================================
4260
4261 Double_t AliFlowAnalysisWithMultiparticleCorrelations::Covariance(const char *x, const char *y, TProfile2D *profile2D, Bool_t bUnbiasedEstimator)
4262 {
4263  // Calculate covariance (multiplied by a weight dependent factor).
4264
4265  // Remark: wCov = Cov(<x>,<y>) * (sum_{i=1}^{N} w_{<x>}_i w_{<y>}_i )/[(sum_{i=1}^{N} w_{<x>}_i) * (sum_{j=1}^{N} w_{<y>}_j)],  
4266  //         where Cov(<x>,<y>) is biased or unbiased estimator (specified via bUnbiasedEstimator) for the covariance.
4267  //         An unbiased estimator is given for instance in Eq. (C.12) on page 131 of my thesis. 
4268
4269  Double_t wCov = 0.; // return value
4270
4271  TString sMethodName = "void AliFlowAnalysisWithMultiparticleCorrelations::Covariance(const char *x, const char *y, TProfile2D *profile2D, Bool_t bBiasedEstimator)";
4272  if(!profile2D){Fatal(sMethodName.Data(),"Sorry, 'profile2D' is on holidays.");}
4273
4274  // Basic protection:
4275  if(!(TString(x).BeginsWith("Cos") || TString(x).BeginsWith("Sin")))
4276  {
4277   cout<<Form("And the fatal x is... '%s'. Congratulations!!",x)<<endl; 
4278   Fatal(sMethodName.Data(),"!(TString(x).BeginsWith(...");
4279  }
4280  if(!(TString(y).BeginsWith("Cos") || TString(y).BeginsWith("Sin")))
4281  {
4282   cout<<Form("And the fatal y is... '%s'. Congratulations!!",y)<<endl; 
4283   Fatal(sMethodName.Data(),"!(TString(y).BeginsWith(...");
4284  }
4285
4286  // Determine 'cs' (cosine or sinus) indices for x and y:
4287  Int_t csx = 0; if(TString(x).BeginsWith("Sin")){csx = 1;}
4288  Int_t csy = 0; if(TString(y).BeginsWith("Sin")){csy = 1;}
4289
4290  // Determine 'c' (order of correlator) indices for x and y:
4291  Int_t cx = -1;   
4292  for(Int_t t=0;t<=TString(x).Length();t++)
4293  {
4294   if(TString(x[t]).EqualTo(",") || TString(x[t]).EqualTo(")")) // TBI this is just ugly
4295   {
4296    cx++;
4297    if(cx>=8){Fatal(sMethodName.Data(),"cx>=8");} // not supporting corr. beyond 8p 
4298   } // if(TString(x[t]).EqualTo(",") || TString(x[t]).EqualTo(")")) // TBI this is just ugly
4299  } // for(Int_t t=0;t<=TString(x).Length();t++)
4300  Int_t cy = -1;   
4301  for(Int_t t=0;t<=TString(y).Length();t++)
4302  {
4303   if(TString(y[t]).EqualTo(",") || TString(y[t]).EqualTo(")")) // TBI this is just ugly
4304   {
4305    cy++;
4306    if(cy>=8){Fatal(sMethodName.Data(),"cy>=8");} // not supporting corr. beyond 8p 
4307   } // if(TString(y[t]).EqualTo(",") || TString(y[t]).EqualTo(")")) // TBI this is just ugly
4308  } // for(Int_t t=0;t<=TString(y).Length();t++)
4309
4310  // Correlations corresponding to x and y:
4311  // x:
4312  Double_t dx = 0.; // <<x>>
4313  Double_t wx = 0.; // \sum w_x
4314  Int_t nbx = fCorrelationsPro[csx][cx]->GetNbinsX();
4315  for(Int_t b=1;b<=nbx;b++)
4316  {
4317   TString sBinLabel = fCorrelationsPro[csx][cx]->GetXaxis()->GetBinLabel(b);
4318   if(sBinLabel.EqualTo(x))
4319   {
4320    //cout<<Form("b = %d, binLabel = %s",b,sBinLabel.Data())<<endl;
4321    dx = fCorrelationsPro[csx][cx]->GetBinContent(b);
4322    wx = fCorrelationsPro[csx][cx]->GetBinEntries(b);
4323    break;
4324   } // if(sBinLabel.EqualTo(x))
4325   if(sBinLabel.EqualTo("")){break;}
4326  } // for(Int_t b=1;b<=nbx;b++)
4327  if(TMath::Abs(dx)<1.e-44)
4328  {
4329   Warning(sMethodName.Data(),"TMath::Abs(dx)<1.e-44, %s",x);
4330   fPropagateError = kFALSE;
4331   return wCov;
4332  } 
4333  if(TMath::Abs(wx)<1.e-44)
4334  {
4335   Warning(sMethodName.Data(),"TMath::Abs(wx)<1.e-44, %s",x);
4336   fPropagateError = kFALSE;
4337   return wCov;
4338  }
4339
4340  // y:
4341  Double_t dy = 0.; // <<y>> 
4342  Double_t wy = 0.; // \sum w_y
4343  Int_t nby = fCorrelationsPro[csy][cy]->GetNbinsX();
4344  for(Int_t b=1;b<=nby;b++)
4345  {
4346   TString sBinLabel = fCorrelationsPro[csy][cy]->GetXaxis()->GetBinLabel(b);
4347   if(sBinLabel.EqualTo(y))
4348   {
4349    //cout<<Form("b = %d, binLabel = %s",b,sBinLabel.Data())<<endl;
4350    dy = fCorrelationsPro[csy][cy]->GetBinContent(b);
4351    wy = fCorrelationsPro[csy][cy]->GetBinEntries(b);
4352    break;
4353   } // if(sBinLabel.EqualTo(y))
4354   if(sBinLabel.EqualTo("")){break;}
4355  } // for(Int_t b=1;b<=nby;b++)
4356  if(TMath::Abs(dy)<1.e-44)
4357  {
4358   Warning(sMethodName.Data(),"TMath::Abs(dy)<1.e-44, %s",y);
4359   fPropagateError = kFALSE;
4360   return wCov; 
4361  }
4362  if(TMath::Abs(wy)<1.e-44)
4363  {
4364   Warning(sMethodName.Data(),"TMath::Abs(wy)<1.e-44, %s",y);
4365   fPropagateError = kFALSE;
4366   return wCov; 
4367  } 
4368
4369  // Product: 
4370  Double_t dxy = 0.; // <<xy>>
4371  Double_t wxy = 0.; // \sum w_x*w_y
4372  // x:
4373  Int_t nBinsX = profile2D->GetNbinsX();
4374  Int_t gbx = 0; // generic bin for x 
4375  for(Int_t b=1;b<=nBinsX;b++)
4376  {
4377   TString sBinLabel = profile2D->GetXaxis()->GetBinLabel(b);
4378   if(sBinLabel.EqualTo(x))
4379   {
4380    gbx = b; break;
4381   } 
4382  } // for(Int_t b=1;b<=nBins2D;b++)
4383  if(0==gbx){Fatal(sMethodName.Data(),"0==gbx, %s",x);} 
4384  // y:
4385  Int_t nBinsY = profile2D->GetNbinsY();
4386  Int_t gby = 0; // generic bin for y 
4387  for(Int_t b=1;b<=nBinsY;b++)
4388  {
4389   TString sBinLabel = profile2D->GetYaxis()->GetBinLabel(b);
4390   if(sBinLabel.EqualTo(y))
4391   {
4392    gby = b; break;
4393   } 
4394  } // for(Int_t b=1;b<=nBinsY;b++)
4395  if(0==gby){Fatal(sMethodName.Data(),"0==gby, %s",y);} 
4396
4397  if(gbx>gby)
4398  {
4399   dxy = profile2D->GetBinContent(profile2D->GetBin(gbx,gby));
4400   wxy = profile2D->GetBinEntries(profile2D->GetBin(gbx,gby));
4401  }
4402  else if(gbx<gby)
4403  {
4404   dxy = profile2D->GetBinContent(profile2D->GetBin(gby,gbx));
4405   wxy = profile2D->GetBinEntries(profile2D->GetBin(gby,gbx));
4406  } else{Fatal(sMethodName.Data(),"gbx==gby, %s, %s",x,y);}
4407  if(TMath::Abs(dxy)<1.e-44)
4408  {
4409   Warning(sMethodName.Data(),"TMath::Abs(dxy)<1.e-44, %s, %s",x,y);
4410   fPropagateError = kFALSE;
4411   return wCov; 
4412  } 
4413  if(TMath::Abs(wxy)<1.e-44)
4414  {
4415   Warning(sMethodName.Data(),"TMath::Abs(wxy)<1.e-44, %s, %s",x,y);
4416   fPropagateError = kFALSE;
4417   return wCov; 
4418  } 
4419
4420  // Finally:
4421  if(bUnbiasedEstimator)
4422  {
4423   Double_t num = dxy-dx*dy; // numerator of Eq. (C.12) on page 131 of my thesis
4424   Double_t den = 1.-wxy/(wx*wy); // denominator of Eq. (C.12) on page 131 of my thesis 
4425   Double_t pre = wxy/(wx*wy); // prefactor
4426   if(TMath::Abs(den)<1.e-44)
4427   {
4428    Warning(sMethodName.Data(),"TMath::Abs(den)<1.e-44, %s, %s",x,y);
4429    fPropagateError = kFALSE;
4430    return wCov; 
4431   }
4432   wCov = pre*num/den;  
4433   if(TMath::Abs(wCov)<1.e-44)
4434   {
4435    Warning(sMethodName.Data(),"TMath::Abs(wCov)<1.e-44, %s, %s",x,y);
4436    fPropagateError = kFALSE;
4437    return wCov; 
4438   }
4439  } else
4440    {
4441     // TBI check if this is a correct formula for the biased estimator
4442     Double_t num = dxy-dx*dy; // numerator of Eq. (C.12) on page 131 of my thesis
4443     Double_t den = 1.; 
4444     Double_t pre = wxy/(wx*wy); // prefactor
4445     if(TMath::Abs(den)<1.e-44)
4446     {
4447      Warning(sMethodName.Data(),"TMath::Abs(den)<1.e-44, %s, %s",x,y);
4448      fPropagateError = kFALSE;
4449      return wCov; 
4450     }
4451     wCov = pre*num/den;  
4452     if(TMath::Abs(wCov)<1.e-44)
4453     {
4454      Warning(sMethodName.Data(),"TMath::Abs(wCov)<1.e-44, %s, %s",x,y);
4455      fPropagateError = kFALSE;
4456      return wCov; 
4457     }
4458    } 
4459
4460  return wCov;
4461
4462 } // Double_t AliFlowAnalysisWithMultiparticleCorrelations::Covariance(const char *x, const char *y, TProfile2D *profile2D, Bool_t bUnbiasedEstimator = kFALSE)
4463
4464 //=======================================================================================================================
4465
4466 /*
4467 TComplex AliFlowAnalysisWithMultiparticleCorrelations::Recursion(Int_t n, Int_t* harmonic, Int_t* mult)
4468 {
4469  // Calculate multi-particle correlators by using recursion originally developed by 
4470  // Kristjan Gulbrandsen (gulbrand@nbi.dk). 
4471
4472  TComplex c = Q(harmonic[n-1], mult[n-1]);
4473  if (n == 1) return c;
4474  c *= Recursion(n-1, harmonic, mult);
4475  if (mult[n-1]>1) return c;
4476  for (Int_t i=0; i<(n-1); i++) {
4477     harmonic[i] += harmonic[n-1];
4478     mult[i]++;
4479     c -= (mult[i]-1.)*Recursion(n-1, harmonic, mult);
4480     mult[i]--;
4481     harmonic[i] -= harmonic[n-1];
4482   }
4483
4484  return c;
4485
4486 } // TComplex AliFlowAnalysisWithMultiparticleCorrelations::Recursion(Int_t n, Int_t* harmonic, Int_t* mult)
4487 */
4488
4489 //=======================================================================================================================
4490
4491 TComplex AliFlowAnalysisWithMultiparticleCorrelations::Recursion(Int_t n, Int_t* harmonic, Int_t mult, Int_t skip) 
4492 {
4493  // Calculate multi-particle correlators by using recursion (an improved faster version) originally developed by 
4494  // Kristjan Gulbrandsen (gulbrand@nbi.dk). 
4495
4496   Int_t nm1 = n-1;
4497   TComplex c(Q(harmonic[nm1], mult));
4498   if (nm1 == 0) return c;
4499   c *= Recursion(nm1, harmonic);
4500   if (nm1 == skip) return c;
4501
4502   Int_t multp1 = mult+1;
4503   Int_t nm2 = n-2;
4504   Int_t counter1 = 0;
4505   Int_t hhold = harmonic[counter1];
4506   harmonic[counter1] = harmonic[nm2];
4507   harmonic[nm2] = hhold + harmonic[nm1];
4508   TComplex c2(Recursion(nm1, harmonic, multp1, nm2));
4509   Int_t counter2 = n-3;
4510   while (counter2 >= skip) {
4511     harmonic[nm2] = harmonic[counter1];
4512     harmonic[counter1] = hhold;
4513     ++counter1;
4514     hhold = harmonic[counter1];
4515     harmonic[counter1] = harmonic[nm2];
4516     harmonic[nm2] = hhold + harmonic[nm1];
4517     c2 += Recursion(nm1, harmonic, multp1, counter2);
4518     --counter2;
4519   }
4520   harmonic[nm2] = harmonic[counter1];
4521   harmonic[counter1] = hhold;
4522
4523   if (mult == 1) return c-c2;
4524   return c-Double_t(mult)*c2;
4525
4526 } // TComplex AliFlowAnalysisWithMultiparticleCorrelations::Recursion(Int_t n, Int_t* harmonic, Int_t mult, Int_t skip) 
4527
4528 //=======================================================================================================================
4529
4530 TComplex AliFlowAnalysisWithMultiparticleCorrelations::OneDiff(Int_t n1)
4531 {
4532  // Generic differential one-particle correlation <exp[i(n1*psi1)]>.
4533  // (psi labels POI, phi labels RPs)  
4534
4535  TComplex one = p(n1,1);
4536
4537  return one;
4538
4539 } // TComplex AliFlowAnalysisWithMultiparticleCorrelations::OneDiff(Int_t n1)
4540
4541 //=======================================================================================================================
4542
4543 TComplex AliFlowAnalysisWithMultiparticleCorrelations::TwoDiff(Int_t n1, Int_t n2)
4544 {
4545  // Generic differential two-particle correlation <exp[i(n1*psi1+n2*phi2)]>.
4546  // (psi labels POI, phi labels RPs)  
4547
4548  TComplex two = p(n1,1)*Q(n2,1)-q(n1+n2,2);
4549
4550  return two;
4551
4552 } // TComplex AliFlowAnalysisWithMultiparticleCorrelations::TwoDiff(Int_t n1, Int_t n2)
4553
4554 //=======================================================================================================================
4555
4556 TComplex AliFlowAnalysisWithMultiparticleCorrelations::ThreeDiff(Int_t n1, Int_t n2, Int_t n3)
4557 {
4558  // Generic differential three-particle correlation <exp[i(n1*psi1+n2*phi2+n3*phi3)]>.
4559  // (psi labels POI, phi labels RPs)  
4560
4561  TComplex three = p(n1,1)*Q(n2,1)*Q(n3,1)-q(n1+n2,2)*Q(n3,1)-q(n1+n3,2)*Q(n2,1)
4562                 - p(n1,1)*Q(n2+n3,2)+2.*q(n1+n2+n3,3); 
4563
4564  return three;
4565
4566 } // TComplex AliFlowAnalysisWithMultiparticleCorrelations::ThreeDiff(Int_t n1, Int_t n2, Int_t n3)
4567
4568 //=======================================================================================================================
4569
4570 TComplex AliFlowAnalysisWithMultiparticleCorrelations::FourDiff(Int_t n1, Int_t n2, Int_t n3, Int_t n4)
4571 {
4572  // Generic differential four-particle correlation <exp[i(n1*psi1+n2*phi2+n3*phi3+n4*phi4)]>.
4573  // (psi labels POI, phi labels RPs)  
4574
4575  TComplex four = p(n1,1)*Q(n2,1)*Q(n3,1)*Q(n4,1)-q(n1+n2,2)*Q(n3,1)*Q(n4,1)-Q(n2,1)*q(n1+n3,2)*Q(n4,1)
4576                - p(n1,1)*Q(n2+n3,2)*Q(n4,1)+2.*q(n1+n2+n3,3)*Q(n4,1)-Q(n2,1)*Q(n3,1)*q(n1+n4,2)
4577                + Q(n2+n3,2)*q(n1+n4,2)-p(n1,1)*Q(n3,1)*Q(n2+n4,2)+q(n1+n3,2)*Q(n2+n4,2)
4578                + 2.*Q(n3,1)*q(n1+n2+n4,3)-p(n1,1)*Q(n2,1)*Q(n3+n4,2)+q(n1+n2,2)*Q(n3+n4,2)
4579                + 2.*Q(n2,1)*q(n1+n3+n4,3)+2.*p(n1,1)*Q(n2+n3+n4,3)-6.*q(n1+n2+n3+n4,4);
4580
4581  return four;
4582
4583 } // TComplex AliFlowAnalysisWithMultiparticleCorrelations::FourDiff(Int_t n1, Int_t n2, Int_t n3, Int_t n4)
4584
4585 //=======================================================================================================================
4586
4587 void AliFlowAnalysisWithMultiparticleCorrelations::SetDiffHarmonics(Int_t order, Int_t *harmonics)
4588 {
4589  // Set harmonics for all differential correlators. 
4590
4591  TString sMethodName = "void AliFlowAnalysisWithMultiparticleCorrelations::SetDiffHarmonics(Int_t order, Int_t *harmonics)";
4592
4593  // Basic protection:
4594  if(order<=0||order>4){Fatal(sMethodName.Data(),"order<=0||order>4");}
4595  if(!harmonics){Fatal(sMethodName.Data(),"!harmonics");}
4596
4597  for(Int_t o=0;o<order;o++)
4598  {
4599   fDiffHarmonics[order-1][o] = harmonics[o];
4600  }
4601  
4602  fCalculateDiffCorrelations = kTRUE;
4603
4604 } // void AliFlowAnalysisWithMultiparticleCorrelations::SetDiffHarmonics(Int_t order, Int_t *harmonics)
4605
4606 //=======================================================================================================================
4607
4608 void AliFlowAnalysisWithMultiparticleCorrelations::SetWeightsHist(TH1D* const hist, const char *type, const char *variable)
4609 {
4610  // Pass histogram holding weights from an external file to the corresponding data member. 
4611  
4612  TString sMethodName = "void AliFlowAnalysisWithMultiparticleCorrelations::SetWeightsHist(TH1D* const hist, const char *type, const char *variable)";
4613  
4614  // Basic protection:
4615  if(!hist){Fatal(sMethodName.Data(),"hist");}
4616  if(!(TString(type).EqualTo("RP") || TString(type).EqualTo("POI"))){Fatal(sMethodName.Data(),"!(TString(type).EqualTo... type = %s ",type);}
4617  if(!(TString(variable).EqualTo("phi") || TString(variable).EqualTo("pt") || TString(variable).EqualTo("eta"))){Fatal(sMethodName.Data(),"!(TString(variable).EqualTo... variable = %s ",variable);}
4618
4619  Int_t rp = 0; // [RP,POI]
4620  if(TString(type).EqualTo("POI")){rp=1;} 
4621
4622  Int_t ppe = 0; // [phi,pt,eta]
4623  if(TString(variable).EqualTo("pt")){ppe=1;} 
4624  if(TString(variable).EqualTo("eta")){ppe=2;} 
4625
4626  // Finally:
4627  hist->SetDirectory(0);
4628  fWeightsHist[rp][ppe] = (TH1D*)hist->Clone();
4629  if(!fWeightsHist[rp][ppe]){Fatal(sMethodName.Data(),"fWeightsHist[%d][%d]",rp,ppe);}
4630
4631  // Cosmetics:
4632  TString sType[2] = {"RP","POI"};
4633  TString sVariable[3] = {"phi","pt","eta"};
4634  fWeightsHist[rp][ppe]->SetName(Form("%s weights (%s)",sVariable[ppe].Data(),sType[rp].Data()));
4635  //fWeightsHist[rp][ppe]->SetTitle(Form("%s weights (%s)",sVariable[ppe].Data(),sType[rp].Data()));
4636
4637  // Flag:
4638  fUseWeights[rp][ppe] = kTRUE; 
4639
4640 } // void AliFlowAnalysisWithMultiparticleCorrelations::SetWeightsHist(TH1D* const hwh, const char *type, const char *variable)
4641
4642 //=======================================================================================================================
4643
4644 void AliFlowAnalysisWithMultiparticleCorrelations::InitializeArraysForWeights()
4645 {
4646  // Initialize all arrays for weights. 
4647
4648  for(Int_t rp=0;rp<2;rp++) // [RP,POI]
4649  {
4650   for(Int_t ppe=0;ppe<3;ppe++) // [phi,pt,eta]
4651   {
4652    fUseWeights[rp][ppe] = kFALSE;
4653    fWeightsHist[rp][ppe] = NULL; 
4654   }
4655  }
4656
4657 } // void AliFlowAnalysisWithMultiparticleCorrelations::InitializeArraysForWeights()
4658
4659 //=======================================================================================================================
4660
4661 void AliFlowAnalysisWithMultiparticleCorrelations::SetnBins(const char *type, const char *variable, Int_t nBins)
4662 {
4663  // Set number of bins for histograms fKinematicsHist[2][3].
4664
4665  TString sMethodName = "void AliFlowAnalysisWithMultiparticleCorrelations::SetnBins(const char *type, const char *variable, Int_t nBins)";
4666  
4667  // Basic protection:
4668  if(!(TString(type).EqualTo("RP") || TString(type).EqualTo("POI")))
4669  {
4670   cout<<"Well, it would be better for you to use RP or POI here..."<<endl;
4671   Fatal(sMethodName.Data(),"!(TString(type).EqualTo... type = %s ",type);
4672  }
4673  if(!(TString(variable).EqualTo("phi") || TString(variable).EqualTo("pt") || TString(variable).EqualTo("eta")))
4674  {
4675   cout<<"phi, pt or eta, please!"<<endl;
4676   Fatal(sMethodName.Data(),"!(TString(variable).EqualTo... variable = %s ",variable);
4677  }
4678
4679  Int_t rp = 0; // [RP,POI]
4680  if(TString(type).EqualTo("POI")){rp=1;} 
4681
4682  Int_t ppe = 0; // [phi,pt,eta]
4683  if(TString(variable).EqualTo("pt")){ppe=1;} 
4684  if(TString(variable).EqualTo("eta")){ppe=2;} 
4685
4686  fnBins[rp][ppe] = nBins;
4687
4688 } // void AliFlowAnalysisWithMultiparticleCorrelations::SetnBins(const char *type, const char *variable, Int_t nBins)
4689
4690 //=======================================================================================================================
4691
4692 void AliFlowAnalysisWithMultiparticleCorrelations::SetMin(const char *type, const char *variable, Double_t min)
4693 {
4694  // Set min bin range for histograms fKinematicsHist[2][3].
4695
4696  TString sMethodName = "void AliFlowAnalysisWithMultiparticleCorrelations::SetMin(const char *type, const char *variable, Double_t min)";
4697  
4698  // Basic protection:
4699  if(!(TString(type).EqualTo("RP") || TString(type).EqualTo("POI")))
4700  {
4701   cout<<"Well, it would be better for you to use RP or POI here..."<<endl;
4702   Fatal(sMethodName.Data(),"!(TString(type).EqualTo... type = %s ",type);
4703  }
4704  if(!(TString(variable).EqualTo("phi") || TString(variable).EqualTo("pt") || TString(variable).EqualTo("eta")))
4705  {
4706   cout<<"phi, pt or eta, please!"<<endl;
4707   Fatal(sMethodName.Data(),"!(TString(variable).EqualTo... variable = %s ",variable);
4708  }
4709
4710  Int_t rp = 0; // [RP,POI]
4711  if(TString(type).EqualTo("POI")){rp=1;} 
4712
4713  Int_t ppe = 0; // [phi,pt,eta]
4714  if(TString(variable).EqualTo("pt")){ppe=1;} 
4715  if(TString(variable).EqualTo("eta")){ppe=2;} 
4716
4717  fMin[rp][ppe] = min;
4718
4719 } // void AliFlowAnalysisWithMultiparticleCorrelations::SetMin(const char *type, const char *variable, Double_t min)
4720
4721 //=======================================================================================================================
4722
4723 void AliFlowAnalysisWithMultiparticleCorrelations::SetMax(const char *type, const char *variable, Double_t max)
4724 {
4725  // Set max bin range for histograms fKinematicsHist[2][3].
4726
4727  TString sMethodName = "void AliFlowAnalysisWithMultiparticleCorrelations::SetMax(const char *type, const char *variable, Double_t max)";
4728  
4729  // Basic protection:
4730  if(!(TString(type).EqualTo("RP") || TString(type).EqualTo("POI")))
4731  {
4732   cout<<"Well, it would be better for you to use RP or POI here..."<<endl;
4733   Fatal(sMethodName.Data(),"!(TString(type).EqualTo... type = %s ",type);
4734  }
4735  if(!(TString(variable).EqualTo("phi") || TString(variable).EqualTo("pt") || TString(variable).EqualTo("eta")))
4736  {
4737   cout<<"phi, pt or eta, please!"<<endl;
4738   Fatal(sMethodName.Data(),"!(TString(variable).EqualTo... variable = %s ",variable);
4739  }
4740
4741  Int_t rp = 0; // [RP,POI]
4742  if(TString(type).EqualTo("POI")){rp=1;} 
4743
4744  Int_t ppe = 0; // [phi,pt,eta]
4745  if(TString(variable).EqualTo("pt")){ppe=1;} 
4746  if(TString(variable).EqualTo("eta")){ppe=2;} 
4747
4748  fMax[rp][ppe] = max;
4749
4750 } // void AliFlowAnalysisWithMultiparticleCorrelations::SetMax(const char *type, const char *variable, Double_t min)
4751
4752 //=======================================================================================================================
4753
4754 void AliFlowAnalysisWithMultiparticleCorrelations::SetnBinsMult(const char *type, Int_t nBinsMult)
4755 {
4756  // Set number of bins for histograms fMultDistributionsHist[3].
4757
4758  TString sMethodName = "void AliFlowAnalysisWithMultiparticleCorrelations::SetnBinsMult(const char *type, Int_t nBinsMult)";
4759  
4760  // Basic protection:
4761  if(!(TString(type).EqualTo("RP") || TString(type).EqualTo("POI") || TString(type).EqualTo("REF")))
4762  {
4763   cout<<"Well, it would be better for you to use RP, POI or REF here..."<<endl;
4764   Fatal(sMethodName.Data(),"!(TString(type).EqualTo... type = %s ",type);
4765  }
4766
4767  Int_t rpr = 0; // [RP,POI,REF]
4768  if(TString(type).EqualTo("POI")){rpr=1;} 
4769  else if(TString(type).EqualTo("REF")){rpr=2;} 
4770
4771  fnBinsMult[rpr] = nBinsMult;
4772
4773 } // void AliFlowAnalysisWithMultiparticleCorrelations::SetnBinsMult(const char *type, Int_t nBinsMult)
4774
4775 //=======================================================================================================================
4776
4777 void AliFlowAnalysisWithMultiparticleCorrelations::SetMinMult(const char *type, Double_t minMult)
4778 {
4779  // Set min bin range for histograms fMultDistributionsHist[3].
4780
4781  TString sMethodName = "void AliFlowAnalysisWithMultiparticleCorrelations::SetMinMult(const char *type, Double_t minMult)";
4782  
4783  // Basic protection:
4784  if(!(TString(type).EqualTo("RP") || TString(type).EqualTo("POI") || TString(type).EqualTo("REF")))
4785  {
4786   cout<<"Well, it would be better for you to use RP, POI or REF here..."<<endl;
4787   Fatal(sMethodName.Data(),"!(TString(type).EqualTo... type = %s ",type);
4788  }
4789
4790  Int_t rpr = 0; // [RP,POI,REF]
4791  if(TString(type).EqualTo("POI")){rpr=1;} 
4792  else if(TString(type).EqualTo("REF")){rpr=2;} 
4793
4794  fMinMult[rpr] = minMult;
4795
4796 } // void AliFlowAnalysisWithMultiparticleCorrelations::SetMinMult(const char *type, Double_t minMult)
4797
4798 //=======================================================================================================================
4799
4800 void AliFlowAnalysisWithMultiparticleCorrelations::SetMaxMult(const char *type, Double_t maxMult)
4801 {
4802  // Set max bin range for histograms fMultDistributionsHist[3].
4803
4804  TString sMethodName = "void AliFlowAnalysisWithMultiparticleCorrelations::SetMaxMult(const char *type, Double_t maxMult)";
4805  
4806  // Basic protection:
4807  if(!(TString(type).EqualTo("RP") || TString(type).EqualTo("POI") || TString(type).EqualTo("REF")))
4808  {
4809   cout<<"Well, it would be better for you to use RP, POI or REF here..."<<endl;
4810   Fatal(sMethodName.Data(),"!(TString(type).EqualTo... type = %s ",type);
4811  }
4812
4813  Int_t rpr = 0; // [RP,POI,REF]
4814  if(TString(type).EqualTo("POI")){rpr=1;} 
4815  else if(TString(type).EqualTo("REF")){rpr=2;} 
4816
4817  fMaxMult[rpr] = maxMult;
4818
4819 } // void AliFlowAnalysisWithMultiparticleCorrelations::SetMaxMult(const char *type, Double_t minMult)
4820
4821 //=======================================================================================================================
4822
4823 void AliFlowAnalysisWithMultiparticleCorrelations::DumpThePoints(AliFlowEventSimple *anEvent)
4824 {
4825  // Dump the points into the external file. 
4826  
4827  // Dumping format: 
4828  // Event <eventNo> Multiplicity <multRP> 
4829  // phi pt eta
4830
4831  TString sMethodName = "void AliFlowAnalysisWithMultiparticleCorrelations::DumpThePoints(AliFlowEventSimple *anEvent)";
4832
4833  // Basic protection:
4834  if(!anEvent){Fatal(sMethodName.Data(),"if(!anEvent)");} 
4835  if(!fMultDistributionsHist[0]){Fatal(sMethodName.Data(),"if(!fMultDistributionsHist[0])");} 
4836  if(fMaxNoEventsPerFile<=0){Fatal(sMethodName.Data(),"if(fMaxNoEventsPerFile<=0)");} 
4837
4838  // Determine event number and multiplicity:
4839  Int_t eventNo = (Int_t) fMultDistributionsHist[0]->GetEntries(); // TBI this is a little bit shaky...
4840  Int_t multRP = (Int_t) anEvent->GetNumberOfRPs(); // TBI shall I promote this variable into data member? 
4841
4842  // Determine external file name:
4843  Int_t fileCounter = (Int_t)((eventNo-1)/fMaxNoEventsPerFile);
4844  TString filename = Form("%s_%d.dat",fAnalysisTag.Data(),fileCounter);
4845
4846  // Open external file and dump:
4847  ofstream myfile;
4848  myfile.open(filename.Data(),ios::app); 
4849  myfile << Form("Event %d Multiplicity %d\n",eventNo,multRP);   
4850  Int_t nTracks = (Int_t) anEvent->NumberOfTracks();
4851  Double_t dPhi = 0., dPt = 0., dEta = 0.;
4852  for(Int_t t=0;t<nTracks;t++) // loop over all tracks
4853  {
4854   AliFlowTrackSimple *pTrack = anEvent->GetTrack(t);
4855   if(!pTrack){printf("\n AAAARGH: pTrack is NULL in MPC::DumpThePoints(AliFlowEventSimple *anEvent) !!!!"); continue;}
4856   if(pTrack->InRPSelection()) 
4857   {
4858    dPhi = pTrack->Phi(); 
4859    dPt = pTrack->Pt();
4860    dEta = pTrack->Eta();
4861    myfile<<Form("%f %f %f\n",dPhi,dPt,dEta);
4862    //cout<<Form("%f %f %f",dPhi,dPt,dEta)<<endl;
4863   }
4864  } // for(Int_t t=0;t<nTracks;t++) // loop over all tracks
4865  myfile<<"\n";
4866  myfile.close();
4867
4868 } // void AliFlowAnalysisWithMultiparticleCorrelations::DumpThePoints(AliFlowEventSimple *anEvent)
4869
4870 //=======================================================================================================================
4871
4872 TH1D *AliFlowAnalysisWithMultiparticleCorrelations::GetHistogramWithWeights(const char *filePath, const char *listName, const char *type, const char *variable, const char *production)
4873 {
4874  // Access from external ROOT file the desired histogram with weights. 
4875
4876  // a) Return value; 
4877  // b) Method name; 
4878  // c) Basic protection for arguments; 
4879  // d) Check if the external ROOT file exists at specified path; 
4880  // e) Access the external ROOT file and fetch the desired histogram with weights;
4881  // f) Close the external ROOT file. 
4882
4883  // a) Return value:
4884  TH1D *hist = NULL; 
4885
4886  // b) Method name: 
4887  TString sMethodName = "Double_t AliFlowAnalysisWithMultiparticleCorrelations::GetHistogramWithWeights(const char *filePath, const char *listName, const char *type, const char *variable, const char *production)"; 
4888
4889  // c) Basic protection for arguments:
4890  if(!(TString(type).EqualTo("RP") || TString(type).EqualTo("POI"))){Fatal(sMethodName.Data(),"!(TString(type).EqualTo...");}
4891  if(!(TString(variable).EqualTo("phi") || TString(variable).EqualTo("pt") || TString(variable).EqualTo("eta"))){Fatal(sMethodName.Data(),"!(TString(variable).EqualTo...");}
4892  if(!(TString(production).EqualTo("data") || TString(production).BeginsWith("LHC"))){Fatal(sMethodName.Data(),"!(TString(production).EqualTo...");}
4893
4894  // d) Check if the external ROOT file exists at specified path:
4895  if(gSystem->AccessPathName(filePath,kFileExists))
4896  {
4897   Fatal(sMethodName.Data(),"if(gSystem->AccessPathName(filePath,kFileExists)), filePath = %s",filePath);
4898  }
4899
4900  // e) Access the external ROOT file and fetch the desired histogram with weights:
4901  TFile *weightsFile = TFile::Open(filePath,"READ");
4902  TList *weightsFileLOK = weightsFile->GetListOfKeys(); 
4903  if(!weightsFileLOK || weightsFileLOK->GetEntries() != 1) // TBI get rid of the 2nd condition at some point...
4904  {
4905   //printf("\n => if(!weightsFileLOK || weightsFileLOK->GetEntries() != 1)\n\n"); 
4906   Fatal(sMethodName.Data(),"if(!weightsFileLOK || weightsFileLOK->GetEntries() != 1)");
4907  } 
4908  // Access TDirectoryFile "weightsMPCanalysis":
4909  TDirectoryFile *directoryFile = dynamic_cast<TDirectoryFile*>(weightsFile->Get("weightsMPCanalysis"));
4910  if(!directoryFile)
4911  {
4912   //printf("\n => if(!directoryFile)\n\n");   
4913   Fatal(sMethodName.Data(),"if(!directoryFile)");
4914  } 
4915  // Access the specified list:
4916  TList *list = dynamic_cast<TList*>(directoryFile->Get(listName));
4917  if(!list)
4918  {
4919   cout<<Form("listName = %s",listName)<<endl;
4920   Warning(sMethodName.Data(),"if(!list)"); 
4921   return NULL;
4922  }
4923  // Finally, access the desired histogram:
4924  hist = dynamic_cast<TH1D*>(list->FindObject(Form("%s,%s,%s",type,variable,production)));
4925  if(!hist)
4926  {
4927   //printf("\n => if(!hist)\n\n");   
4928   Warning(sMethodName.Data(),"if(!hist)");
4929   return NULL;
4930  } else { hist->SetDirectory(0); }
4931
4932  // f) Close the external ROOT file: 
4933  weightsFile->Close(); delete weightsFile;
4934
4935  return hist;
4936
4937 } // TH1D *AliFlowAnalysisWithMultiparticleCorrelations::GetHistogramWithWeights(const char *filePath, const char *listName, const char *type, const char *variable, const char *production)
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959