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