]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
First CVS version of the flow analysis code (Emanuele)
authorhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 12 Dec 2006 14:01:31 +0000 (14:01 +0000)
committerhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 12 Dec 2006 14:01:31 +0000 (14:01 +0000)
14 files changed:
PWG2/FLOW/AliFlowAnalysisMaker.cxx [new file with mode: 0644]
PWG2/FLOW/AliFlowAnalysisMaker.h [new file with mode: 0644]
PWG2/FLOW/AliFlowConstants.cxx [new file with mode: 0644]
PWG2/FLOW/AliFlowConstants.h [new file with mode: 0644]
PWG2/FLOW/AliFlowEvent.cxx [new file with mode: 0644]
PWG2/FLOW/AliFlowEvent.h [new file with mode: 0644]
PWG2/FLOW/AliFlowSelection.cxx [new file with mode: 0644]
PWG2/FLOW/AliFlowSelection.h [new file with mode: 0644]
PWG2/FLOW/AliFlowTrack.cxx [new file with mode: 0644]
PWG2/FLOW/AliFlowTrack.h [new file with mode: 0644]
PWG2/FLOW/AliFlowV0.cxx [new file with mode: 0644]
PWG2/FLOW/AliFlowV0.h [new file with mode: 0644]
PWG2/FLOW/AliSelectorFlow.cxx [new file with mode: 0644]
PWG2/FLOW/AliSelectorFlow.h [new file with mode: 0644]

diff --git a/PWG2/FLOW/AliFlowAnalysisMaker.cxx b/PWG2/FLOW/AliFlowAnalysisMaker.cxx
new file mode 100644 (file)
index 0000000..cb6cf38
--- /dev/null
@@ -0,0 +1,3776 @@
+//////////////////////////////////////////////////////////////////////
+//
+// $Id$
+//
+// Author: Emanuele Simili
+//
+//////////////////////////////////////////////////////////////////////
+//_____________________________________________________________
+//
+// Description: 
+//         the AliFlowAnalysisMaker class loops over AliFlowEvents, 
+// calculates/extracts interesting observables, produces and fills the 
+// related histograms for flow analysis. 
+// Set AliFlowEvents file via SetInputFileName("file.root"), and the 
+// histograms file via SetHistFileName("hist.root"), defalts are given. 
+// It also calculates the phi weights to make the event plane isotropic 
+// in the lab, and the bayesian weight for p.id. calculation, and saves 
+// them in a file (set it via SetPhiWgtFileName("flowPhiWgt.hist.root")). 
+// Those weights, if enabled, will be used only in the next run of the 
+// analysis. In the first run or whenever the wgt file is missing, all 
+// weights (phi & bayesian) are set to 1 .
+// The most important features of the Flow Analysis are:
+//  - Reaction Plane calculation: for different harmonics and selections
+//   the R.P. is simply extracted via the appropriate AliFlowEvent methods.
+//  - Correlation Analysis: particles are related to the R.P. and Vn 
+//   coefficient are extracted. The AliFlowAnalysisMaker also removes 
+//   auto-correlations of each particle with respect to the event plane, 
+//   by subtracting track by track from the Q vector before the correlation 
+//   study. Observable Flow is plotted.
+//  - Differential Flow: for each harmonic and selection, flow values 
+//   (Vn) are plotted versus rapidity/pseudorapidity and pT. 
+//  - Resulution Estimate: event plane resolution is estimated via the 
+//   sub-event method (res ~ sqrt(cos(psi1-psi2))), and flow values are 
+//   then corrected for it. "True" Flow is plotted. 
+//  - Integrated Flow: for the doubly-integrated (pT & eta) Vn values 
+//   the error on the event plane resolution is folded in to the error. 
+//  - Phi and Baiesian weights calculation (from event observables). 
+//
+// The AliFlowAnalysisMaker Class is adapted from the original 
+// StFlowAnalysisMaker, succesfully used to study flow in the 
+// STAR experiment at RICH.
+// Original Authors:                 Raimond Snellings & Art Poskanzer
+//
+
+#include "AliFlowAnalysisMaker.h"
+#include "AliFlowConstants.h"
+#include "TVector2.h"
+#include <iostream>
+#include <cmath>     //PK: <cmath> needed for fabs() and fmod() on some systems.
+using namespace std; //required for resolving the 'cout' symbol
+
+ClassImp(AliFlowAnalysisMaker)
+//-----------------------------------------------------------------------
+AliFlowAnalysisMaker::AliFlowAnalysisMaker(const Char_t* name)
+{
+ // default constructor 
+
+ pFlowSelect = new AliFlowSelection();
+ mName = name ;
+ InitDefault() ;
+ cout << FlowAnalysis << " !!! No flowSelection defined .  Will use default cuts  (class AliFlowSelection) !!! " << endl ;
+}
+//-----------------------------------------------------------------------
+AliFlowAnalysisMaker::AliFlowAnalysisMaker(const Char_t* name, const AliFlowSelection& flowSelect)
+{
+ //copy constructor
+
+ pFlowSelect = new AliFlowSelection(flowSelect);  
+ mName = name ;
+ InitDefault() ;
+}
+//-----------------------------------------------------------------------
+AliFlowAnalysisMaker::~AliFlowAnalysisMaker() 
+{
+ // default distructor (no actions) 
+}
+//-----------------------------------------------------------------------
+void AliFlowAnalysisMaker::InitDefault()
+{
+ // sets some defaults for the analysis
+ SetDebugg(1) ;  // Debug options (1,2,3)
+ if(Debug0) { cout << FlowAnalysis << "Constructor" << endl ; }
+ // input-output file (default output is given via the name given to the AliFlowAnalysis Object)
+ SetInputFileName("AliFlowEVT.root") ;
+ TString histfilename = mName ; histfilename += "Plot"  ; histfilename += ".root" ; 
+ SetHistFileName(histfilename.Data());
+ fFileNames.Clear() ;
+
+ // internal settings (for event loop & printing purpose)
+ FlowAnalysis = " [" ; FlowAnalysis += mName ; FlowAnalysis += "] - " ;
+ spaces = " " ; for(Int_t s=0;s<(FlowAnalysis.Length()-1);s++) { spaces += " " ; }
+ evtN = 0 ;
+ pFlowEventsFile = 0 ;
+ pFlowEvent      = 0 ;
+ for(Int_t ii=0;ii<3;ii++){ vertex[ii] = 0 ; }
+ // for labels histogram
+ mLabelling = kTRUE ; 
+ mLabellingFirst = kTRUE ;
+ maxLabel = 0 ;
+
+ // analysis settings 
+ SetPhiWgtFileName("flowPhiWgt.hist.root");
+ mV0           = kTRUE ;  // correlation analysis is done also for neutral secundary vertex
+ mShuffle      = kFALSE ; // randomly reshuffles tracks
+ mV1Ep1Ep2     = kFALSE ; // disabled by default
+ mEtaSub       = kFALSE ; // eta subevents
+ mPhiWgt       = kTRUE ;  // if flowPhiWgt file is there -> Phi Weights are used
+ mBayWgt       = kFALSE ; // Bayesian Weights for P.Id. not used  
+ mRePid        = kFALSE ; // recalculates the P.Id. (becomes kTRUE if new bayesian weights are plugged in)  
+
+ mPtWgt        = kFALSE ; // pT as a weight
+ mEtaWgt       = kFALSE ; // eta as a weight
+ mOnePhiWgt    = kTRUE  ; // one/three phi-wgt histogram(s)
+
+ mRedoWgt      = kFALSE ; // to recalculate Wgt histograms (even if flowPhi.hist.root exist)
+ mMakeAll      = kTRUE ;  // claculates all events vars in one shoot (should run faster) 
+}
+//------------------------------------------------------------------------
+// ###
+//------------------------------------------------------------------------
+Int_t AliFlowAnalysisMaker::Init()                    
+{
+ // Opens input, output and wgt files, books histograms, sets limits & bin 
+ if(Debug0) { cout << FlowAnalysis << "Init() . " << endl ; }
+
+ // Check for Read/Write weights ... if weight file is there, wgt arrays are filled (phiwgt & bayesian)
+ WgtChk() ;  // -> FillWgtArrays(wgtFile)
+ // Open output files (->plots)
+ histFile = new TFile(GetHistFileName().Data(), "RECREATE");
+ histFile->cd() ;
+
+ // Variable setting
+ float ptMaxPart = 5. ;      if(pFlowSelect->PtMaxPart())  { ptMaxPart = pFlowSelect->PtMaxPart() ; }
+ int nPtBinsPart = 40  ;     if(pFlowSelect->PtBinsPart()) { nPtBinsPart = pFlowSelect->PtBinsPart() ; }
+ xLabel = "Pseudorapidity" ; if(strlen(pFlowSelect->PidPart()) != 0) { xLabel = "Rapidity"; }
+ // -                       
+ const float etaMin  = Flow::fEtaMin ; 
+ const float etaMax  = Flow::fEtaMax ; 
+ const float ptMin   = Flow::fPtMin ;       
+ const float ptMax   = Flow::fPtMax ;       
+ const int   EtaBins  = Flow::nEtaBins ;      
+ const int   nPtBins  = Flow::nPtBins ;      
+ const int   nPhiBins = Flow::nPhiBins ;     
+ // -
+ SetHistoRanges(etaMin, etaMax, EtaBins);
+ SetPtRange_for_vEta(1.,0.);   //(ptMin, ptMax);
+ SetEtaRange_for_vPt(1.,0.);   //(etaMin, etaMax);
+ // -
+ const float triggerMin      =  -1.5;
+ const float triggerMax      =  10.5;
+ const float chargeMin       =  -2.5;
+ const float chargeMax       =   2.5; 
+ const float dcaMin         =   0.0;
+ const float dcaMax         =  10.0; //  0.5; 
+ const float glDcaMax       =  50.0; 
+ const float chi2Min        =    0.;
+ const float chi2Max        =  500.; 
+ const float chi2normMax     =   50.; 
+ const float chi2MaxC       =   30.; 
+ const float chi2MaxI       =   60.; 
+ const float fitPtsMin       =  -0.5;
+ const float fitPtsMaxTpc    = 160.5;
+ const float fitPtsMaxIts    =   6.5;
+ const float fitPtsMaxTrd    = 130.5;
+ const float fitPtsMaxTof    =   1.5;
+ const float fitOverMaxMin   =    0.;
+ const float fitOverMaxMax   =   1.1;
+ const float multOverOrigMin =    0.;
+ const float multOverOrigMax =    1.;
+ const float vertexZMin      =  -10.;
+ const float vertexZMax      =   10.; 
+ const float vertexXYMin     =  -0.1;
+ const float vertexXYMax     =   0.1; 
+ const float etaSymMinPart   =   -1.;
+ const float etaSymMaxPart   =    1.;
+ const float etaSymMin       =   -2.;
+ const float etaSymMax       =    2.;
+ const float phiMin         =    0.;
+ const float phiMax         = 2*TMath::Pi() ; 
+ const float psiMin         =    0.;
+ const float psiMax         = 2*TMath::Pi() ; 
+ const float multMin        =    0. ;
+ const float multMax        =25000. ;
+ const float multV0         = 5000. ;
+ const float qMin           =    0. ;
+ const float qMax           =   20. ;
+ const float pidMin         =    0. ;
+ const float pidMax         =    1. ;
+ const float centMin        =  -0.5 ;
+ const float centMax        =   9.5 ;
+ const float logpMin        =   -2.5 ;
+ const float logpMax        =    2.5 ;
+ const float pMin           =     0. ;
+ const float pMax           =   100. ;
+ const float dEdxMax        =  1000. ;
+ const float dEdxMaxTPC             =  1500. ;
+ const float TOFmin         =  10000. ;
+ const float TOFmax         =  50000. ;
+ const float TRDmax         =  2000. ;
+ const float lgMin          =  -1000. ;
+ const float lgMax          =  1000. ;
+ const float lgMinV0        =  0. ;
+ const float lgMaxV0        =  50. ;
+ const float massMin        =  -0.1 ;
+ const float massMax        =  2.1 ;
+ const float ZDCpartMin      = -0.5 ;
+ const float ZDCpartMax             =  1000.5 ;
+ const float ZDCeMin        =  0. ;
+ const float ZDCeMax         =  10000. ;
+ // - 
+ enum { nTriggerBins     = 12,
+       nChargeBins       = 5,
+       nDcaBins          = 1000,
+       nChi2Bins         = 150,
+       nFitPtsBinsTpc    = 161,
+       nFitPtsBinsIts    = 7,
+       nFitPtsBinsTrd    = 131,
+       nFitPtsBinsTof    = 2,
+       nFitOverMaxBins   = 55,
+       nMultOverOrigBins =100,
+       nVertexZBins      = 200,
+       nVertexXYBins     = 1000,
+       nEtaSymBins       = 200,
+       nPhi3DBins        = nPhiBins/6 ,
+       nPsiBins          = 36,
+       nMultBins         = 250,
+       nPidBins          = 100,
+        nCentBins        = 10,
+       nDedxBins        = 1000,
+       nTofBins         = 1000,
+       nTrdBins         = 100,
+       nMomenBins       = 500,
+       n_qBins          =  50,
+       nLgBins          = 500,
+       nMassBins        = 2200,
+       nZDCpartBins     = 1001,
+       nZDCeBins        = 200
+      } ;
+
+// *temp*   
+  int maxMaxLabel = maxLabel ;
+  if(Debug1) { cout << spaces << " Creating Labels hist at the beginning ( max bin by hand = " << maxMaxLabel << " ) . " << endl ; }
+  TString* labTitle = new TString("TracksLabel_full") ; 
+  mLabHist = new TH2F(labTitle->Data(),labTitle->Data(),Flow::nSels+4,0.,Flow::nSels+4.,maxMaxLabel+1,0.,maxMaxLabel+1.) ;
+  if(Flow::nSels==2) { mLabHist->SetXTitle("tracks , sel0 , sel1 , selPart , v0s , selV0s ") ; }
+  else  { mLabHist->SetXTitle("tracks , sel... , selPart , v0s , selV0s ") ; }
+  mLabHist->SetYTitle("MC label") ;
+  delete labTitle ;
+  mLabellingFirst = kFALSE ; 
+// *temp* 
+
+ // Histograms Booking ...
+ // Trigger
+ mHistTrigger = new TH1F("Flow_Trigger", "Flow_Trigger", nTriggerBins, triggerMin, triggerMax);
+ mHistTrigger->SetXTitle("Trigger: 1 minbias, 2 central, 3 laser, 10 other");
+ mHistTrigger->SetYTitle("Counts");
+
+ // Charge
+ mHistCharge = new TH1F("Flow_Charge", "Flow_Charge", nChargeBins, chargeMin, chargeMax);
+ mHistCharge->SetXTitle("Charge");
+ mHistCharge->SetYTitle("Counts");
+
+ // Reconstructed Momentum (constrained, if so)
+ mHistPtot = new TH1F("Flow_totalP","Flow_totalP", nPtBins, ptMin, ptMax);
+ mHistPtot->Sumw2();
+ mHistPtot->SetXTitle("P (GeV/c)");
+ mHistPtot->SetYTitle("Counts");
+
+ // Reconstructed pT (constrained, if so)
+ mHistPt = new TH1F("Flow_Pt","Flow_Pt", nMomenBins, pMin, pMax);
+ mHistPt->Sumw2();
+ mHistPt->SetXTitle("Pt (GeV/c)");
+ mHistPt->SetYTitle("Counts");
+   
+ // Reconstructed P.id vs pT 
+ mHistPidPt = new TH2F("Flow_PidPt","Flow_PidPt", 12, 0., 12., nPtBins, ptMin, ptMax);
+ mHistPidPt->Sumw2();
+ mHistPidPt->SetXTitle("e-, e+, mu-, mu+, pi-, pi+, K-, K+, pr-, pr+, d-, d+");
+ mHistPidPt->SetYTitle("Pt (GeV/c)");
+   
+ // Distance of closest approach - Transverse, Unsigned
+ mHistDca = new TH1F("Flow_TransDCA", "Flow_TransverseDCA", nDcaBins, dcaMin, dcaMax);
+ mHistDca->Sumw2();
+ mHistDca->SetXTitle("|Track's Signed dca (cm)|");
+ mHistDca->SetYTitle("Counts");
+
+ // Distance of closest approach - Transverse
+ mHistTransDca = new TH1F("Flow_TransDCA_Signed", "Flow_TransverseDCA_Signed", nDcaBins, -dcaMax, dcaMax);
+ mHistTransDca->Sumw2();
+ mHistTransDca->SetXTitle("Track's Transverse dca (cm)");
+ mHistTransDca->SetYTitle("Counts");
+
+ // Distance of closest approach - 3d
+ mHistDcaGlobal = new TH1F("Flow_3dDcaGlobal", "Flow_3dDcaGlobal", nDcaBins, dcaMin, glDcaMax);
+ mHistDcaGlobal->Sumw2();
+ mHistDcaGlobal->SetXTitle("|3d Global Track's dca to Vertex (cm)|");
+ mHistDcaGlobal->SetYTitle("Counts");
+
+ // Distance of closest approach for particles correlated with the event plane - 3d
+ mHistDcaGlobalPart = new TH1F("Flow_3dDcaGlobalPart", "Flow_3dDcaGlobalPart", nDcaBins, dcaMin, glDcaMax);
+ mHistDcaGlobalPart->Sumw2();
+ mHistDcaGlobalPart->SetXTitle("|3d Global Track's dca to Vertex (cm)|");
+ mHistDcaGlobalPart->SetYTitle("Counts");
+
+ // Distance of closest approach for particles NOT SELECTED for correlation with the event plane - 3d
+ mHistDcaGlobalOut = new TH1F("Flow_3dDcaGlobalOut", "Flow_3dDcaGlobalOut", nDcaBins, dcaMin, glDcaMax);
+ mHistDcaGlobalOut->Sumw2();
+ mHistDcaGlobalOut->SetXTitle("|3d Global Track's dca to Vertex (cm)|");
+ mHistDcaGlobalOut->SetYTitle("Counts");
+
+ // Yield Pt-Phi for constrained tracks
+ mHistPhiPtCon = new TH2D("Flow_PtPhi_Con", "Flow_PtPhi_Con", nPhiBins, phiMin, phiMax, nPtBins, ptMin, ptMax);
+ mHistPhiPtCon->Sumw2();
+ mHistPhiPtCon->SetXTitle("Phi");
+ mHistPhiPtCon->SetYTitle("Pt (GeV/c)");
+ // Yield Pt-Phi for UNconstrained tracks
+ mHistPhiPtUnc = new TH2D("Flow_PtPhi_Unc", "Flow_PtPhi_Unc", nPhiBins, phiMin, phiMax, nPtBins, ptMin, ptMax);
+ mHistPhiPtUnc->Sumw2();
+ mHistPhiPtUnc->SetXTitle("Phi");
+ mHistPhiPtUnc->SetYTitle("Pt (GeV/c)");
+ // Chi2 
+ // at the main vertex
+ mHistChi2 = new TH1F("Flow_Chi2", "Flow_Chi2", nChi2Bins, chi2Min, chi2MaxC);
+ mHistChi2->SetXTitle("Chi square at Main Vertex");
+ mHistChi2->SetYTitle("Counts");
+ // TPC
+ mHistChi2TPC = new TH1F("Flow_Chi2_TPC", "Flow_Chi2_TPC", nChi2Bins, chi2Min, chi2Max);
+ mHistChi2TPC->SetXTitle("Chi square for TPC");
+ mHistChi2TPC->SetYTitle("Counts");
+ // ITS
+ mHistChi2ITS = new TH1F("Flow_Chi2_ITS", "Flow_Chi2_ITS", nChi2Bins, chi2Min, chi2MaxI);
+ mHistChi2ITS->SetXTitle("Chi square for ITS");
+ mHistChi2ITS->SetYTitle("Counts");
+ // TRD
+ mHistChi2TRD = new TH1F("Flow_Chi2_TRD", "Flow_Chi2_TRD", nChi2Bins, chi2Min, chi2Max);
+ mHistChi2TRD->SetXTitle("Chi square for TRD");
+ mHistChi2TRD->SetYTitle("Counts");
+ // TOF
+ mHistChi2TOF = new TH1F("Flow_Chi2_TOF", "Flow_Chi2_TOF", nChi2Bins, chi2Min, chi2Max);
+ mHistChi2TOF->SetXTitle("Chi square for TOF");
+ mHistChi2TOF->SetYTitle("Counts");
+
+ // Chi2 normalized
+ // TPC
+ mHistChi2normTPC = new TH1F("Flow_Chi2norm_TPC", "Flow_Chi2norm_TPC", nChi2Bins, chi2Min, chi2normMax);
+ mHistChi2normTPC->SetXTitle("Normalized #Chi^{2} for TPC");
+ mHistChi2normTPC->SetYTitle("Counts");
+ // ITS
+ mHistChi2normITS = new TH1F("Flow_Chi2norm_ITS", "Flow_Chi2norm_ITS", nChi2Bins, chi2Min, chi2normMax);
+ mHistChi2normITS->SetXTitle("Normalized #Chi^{2} for ITS");
+ mHistChi2normITS->SetYTitle("Counts");
+ // TRD
+ mHistChi2normTRD = new TH1F("Flow_Chi2norm_TRD", "Flow_Chi2norm_TRD", nChi2Bins, chi2Min, chi2normMax);
+ mHistChi2normTRD->SetXTitle("Normalized #Chi^{2} for TRD");
+ mHistChi2normTRD->SetYTitle("Counts");
+ // TOF
+ mHistChi2normTOF = new TH1F("Flow_Chi2norm_TOF", "Flow_Chi2norm_TOF", nChi2Bins, chi2Min, chi2normMax);
+ mHistChi2normTOF->SetXTitle("Normalized #Chi^{2} for TOF");
+ mHistChi2normTOF->SetYTitle("Counts");
+ // FitPts
+ // TPC
+ mHistFitPtsTPC = new TH1F("Flow_FitPts_TPC", "Flow_FitPts_TPC", nFitPtsBinsTpc, fitPtsMin, fitPtsMaxTpc);
+ mHistFitPtsTPC->SetXTitle("Fit Points");
+ mHistFitPtsTPC->SetYTitle("Counts");
+ // ITS
+ mHistFitPtsITS = new TH1F("Flow_HitPts_ITS", "Flow_HitPts_ITS", nFitPtsBinsIts, fitPtsMin, fitPtsMaxIts);
+ mHistFitPtsITS->SetXTitle("Fit Points");
+ mHistFitPtsITS->SetYTitle("Counts");
+ // TRD
+ mHistFitPtsTRD = new TH1F("Flow_FitPts_TRD", "Flow_FitPts_TRD", nFitPtsBinsTrd, fitPtsMin, fitPtsMaxTrd);
+ mHistFitPtsTRD->SetXTitle("Fit Points");
+ mHistFitPtsTRD->SetYTitle("Counts");
+ // TOF
+ mHistFitPtsTOF = new TH1F("Flow_HitPts_TOF", "Flow_HitPts_TOF", nFitPtsBinsTof, fitPtsMin, fitPtsMaxTof);
+ mHistFitPtsTOF->SetXTitle("Fit Points");
+ mHistFitPtsTOF->SetYTitle("Counts");
+
+ // MaxPts 
+ // TPC
+ mHistMaxPtsTPC = new TH1F("Flow_MaxPts_TPC", "Flow_MaxPts_TPC", nFitPtsBinsTpc, fitPtsMin, fitPtsMaxTpc);
+ mHistMaxPtsTPC->SetXTitle("Max Points");
+ mHistMaxPtsTPC->SetYTitle("Counts");
+ // ITS
+ mHistMaxPtsITS = new TH1F("Flow_MaxPts_ITS", "Flow_MaxPts_ITS", nFitPtsBinsIts, fitPtsMin, fitPtsMaxIts);
+ mHistMaxPtsITS->SetXTitle("Max Points");
+ mHistMaxPtsITS->SetYTitle("Counts");
+ // TRD
+ mHistMaxPtsTRD = new TH1F("Flow_MaxPts_TRD", "Flow_MaxPts_TRD", nFitPtsBinsTrd, fitPtsMin, fitPtsMaxTrd);
+ mHistMaxPtsTRD->SetXTitle("Max Points");
+ mHistMaxPtsTRD->SetYTitle("Counts");
+ // TOF
+ mHistMaxPtsTOF = new TH1F("Flow_MaxPts_TOF", "Flow_MaxPts_TOF", nFitPtsBinsTof, fitPtsMin, fitPtsMaxTof);
+ mHistMaxPtsTOF->SetXTitle("Max Points");
+ mHistMaxPtsTOF->SetYTitle("Counts");
+
+ // FitOverMax 
+ // Tpc
+ mHistFitOverMaxTPC = new TH1F("Flow_FitOverMax_TPC", "Flow_FitOverMax_TPC", nFitOverMaxBins, fitOverMaxMin, fitOverMaxMax);
+ mHistFitOverMaxTPC->SetXTitle("(Fit Points - 1) / Max Points");
+ mHistFitOverMaxTPC->SetYTitle("Counts");  
+ // All
+ mHistFitOverMax = new TH1F("Flow_FitOverMax", "Flow_FitOverMax", nFitOverMaxBins, fitOverMaxMin, fitOverMaxMax);
+ mHistFitOverMax->SetXTitle("(Fit Points - 1) / Max Points");
+ mHistFitOverMax->SetYTitle("Counts");  
+
+ // lenght
+ mHistLenght = new TH1F("Flow_TrackLenght", "Flow_TrackLenght", nLgBins, lgMin, lgMax);
+ mHistLenght->SetXTitle("Lenght of the Track (cm)");
+ mHistLenght->SetYTitle("Counts");
+
+  // OrigMult
+ mHistOrigMult = new TH1F("Flow_OrigMult", "Flow_OrigMult", nMultBins, multMin, multMax);
+ mHistOrigMult->SetXTitle("Original Mult");
+ mHistOrigMult->SetYTitle("Counts");
+
+ // MultEta
+ mHistMultEta = new TH1F("Flow_MultEta", "Flow_MultEta", nMultBins, multMin, multMax);
+ mHistMultEta->SetXTitle("Mult for Centrality");
+ mHistMultEta->SetYTitle("Counts");
+   
+ // Mult
+ mHistMult = new TH1F("Flow_Mult", "Flow_Mult", nMultBins, multMin, multMax);
+ mHistMult->SetXTitle("Mult");
+ mHistMult->SetYTitle("Counts");
+
+ // V0s multiplicity
+ mHistV0Mult = new TH1F("FlowV0_Mult","FlowV0_Mult", nMultBins, multMin, multV0);
+ mHistV0Mult->SetXTitle("V0s Multiplicity");
+ mHistV0Mult->SetYTitle("Counts");
+   
+ // MultOverOrig
+ mHistMultOverOrig = new TH1F("Flow_MultOverOrig", "Flow_MultOverOrig", nMultOverOrigBins, multOverOrigMin, multOverOrigMax);
+ mHistMultOverOrig->SetXTitle("Mult / Orig. Mult");
+ mHistMultOverOrig->SetYTitle("Counts");
+   
+ // Mult correlated with the event planes
+ mHistMultPart = new TH1F("Flow_MultPart", "Flow_MultPart", 2*nMultBins, multMin, multMax);
+ mHistMultPart->SetXTitle("Mult of Correlated Particles");
+ mHistMultPart->SetYTitle("Counts");
+   
+ // Mult correlated with the event planes in 1 unit rapidity
+ mHistMultPartUnit = new TH1F("Flow_MultPartUnit", "Flow_MultPartUnit", 2*nMultBins, multMin, multMax/2);
+ mHistMultPartUnit->SetXTitle("Mult of Correlated Particles (-0.5 < eta < 0.5)");
+ mHistMultPartUnit->SetYTitle("Counts");
+   
+ // Mult of V0s correlated with the event planes
+ mHistV0MultPart = new TH1F("FlowV0_MultPart", "FlowV0_MultPart", nMultBins, multMin, multV0);
+ mHistV0MultPart->SetXTitle("Mult of Correlated V0s");
+ mHistV0MultPart->SetYTitle("Counts");
+   
+ // VertexZ
+ mHistVertexZ = new TH1F("Flow_VertexZ", "Flow_VertexZ", nVertexZBins, vertexZMin, vertexZMax);
+ mHistVertexZ->SetXTitle("Vertex Z (cm)");
+ mHistVertexZ->SetYTitle("Counts");
+   
+ // VertexXY
+ mHistVertexXY2D = new TH2F("Flow_VertexXY2D", "Flow_VertexXY2D", nVertexXYBins, vertexXYMin, vertexXYMax, nVertexXYBins, vertexXYMin, vertexXYMax);
+ mHistVertexXY2D->SetXTitle("Vertex X (cm)");
+ mHistVertexXY2D->SetYTitle("Vertex Y (cm)");
+   
+ // EtaSym vs. Vertex Z Tpc
+ mHistEtaSymVerZ2D = new TH2F("Flow_EtaSymVerZ2D", "Flow_EtaSymVerZ2D", nVertexZBins, vertexZMin, vertexZMax, nEtaSymBins, etaSymMin, etaSymMax);
+ mHistEtaSymVerZ2D->SetXTitle("Vertex Z (cm)");
+ mHistEtaSymVerZ2D->SetYTitle("Eta Symmetry TPC");
+
+ // EtaSym Tpc
+ mHistEtaSym = new TH1F("Flow_EtaSym_TPC", "Flow_EtaSym_TPC", nEtaSymBins, etaSymMin, etaSymMax);
+ mHistEtaSym->SetXTitle("Eta Symmetry Ratio TPC");
+ mHistEtaSym->SetYTitle("Counts");
+   
+ // EtaSym vs. Vertex Z Tpc - correlation analysis
+ mHistEtaSymVerZ2DPart = new TH2F("Flow_EtaSymVerZ2D_part", "Flow_EtaSymVerZ2D_part", nVertexZBins, vertexZMin, vertexZMax, nEtaSymBins, etaSymMinPart, etaSymMaxPart);
+ mHistEtaSymVerZ2DPart->SetXTitle("Vertex Z (cm)");
+ mHistEtaSymVerZ2DPart->SetYTitle("Eta Symmetry TPC");
+
+ // EtaSym Tpc - correlation analysis
+ mHistEtaSymPart = new TH1F("Flow_EtaSym_TPC_part", "Flow_EtaSym_TPC_part", nEtaSymBins, etaSymMinPart, etaSymMaxPart);
+ mHistEtaSymPart->SetXTitle("Eta Symmetry Ratio TPC");
+ mHistEtaSymPart->SetYTitle("Counts");
+   
+ // phi , whatever
+ mHistPhi = new TH1F("Flow_xPhi", "Flow_xPhi (all)", nPhiBins, phiMin, phiMax);
+ mHistPhi->SetXTitle("Phi (rad)");
+ mHistPhi->SetYTitle("Counts");
+
+ // phi constrained
+ mHistPhiCons = new TH1F("Flow_cPhi", "Flow_cPhi", nPhiBins, phiMin, phiMax);
+ mHistPhiCons->SetXTitle("cPhi (rad)");
+ mHistPhiCons->SetYTitle("Counts");
+   
+ // EtaPtPhi , whatever
+ mHistAllEtaPtPhi3D = new TH3F("Flow_EtaPtPhi3Dall", "Flow_EtaPtPhi3Dall (whatever)", mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax, nPhi3DBins, phiMin, phiMax);
+ mHistAllEtaPtPhi3D->SetXTitle("Eta");
+ mHistAllEtaPtPhi3D->SetYTitle("Pt (GeV/c)");
+ mHistAllEtaPtPhi3D->SetZTitle("Phi (rad)");
+   
+ // Constrained EtaPtPhi
+ mHistConsEtaPtPhi3D = new TH3F("Flow_consEtaPtPhi3D", "Flow_consEtaPtPhi3D (constrainable)", mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax, nPhi3DBins, phiMin, phiMax);
+ mHistConsEtaPtPhi3D->SetXTitle("cEta");
+ mHistConsEtaPtPhi3D->SetYTitle("cPt (GeV/c)");
+ mHistConsEtaPtPhi3D->SetZTitle("cPhi (rad)");
+   
+ // Global EtaPtPhi
+ mHistGlobEtaPtPhi3D = new TH3F("Flow_globEtaPtPhi3D", "Flow_globEtaPtPhi3D (constrainable)", mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax, nPhi3DBins, phiMin, phiMax);
+ mHistGlobEtaPtPhi3D->SetXTitle("gEta");
+ mHistGlobEtaPtPhi3D->SetYTitle("gPt (GeV/c)");
+ mHistGlobEtaPtPhi3D->SetZTitle("gPhi (rad)");
+
+ // UnConstrained EtaPtPhi
+ mHistUncEtaPtPhi3D = new TH3F("Flow_uncEtaPtPhi3D", "Flow_uncEtaPtPhi3D (un-constrainable)", mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax, nPhi3DBins, phiMin, phiMax);
+ mHistUncEtaPtPhi3D->SetXTitle("gEta");
+ mHistUncEtaPtPhi3D->SetYTitle("gPt (GeV/c)");
+ mHistUncEtaPtPhi3D->SetZTitle("gPhi (rad)");
+   
+ // EtaPtPhi for particles correlated with the event plane
+ mHistEtaPtPhi3DPart = new TH3F("Flow_EtaPtPhi3Dpart", "Flow_EtaPtPhi3Dpart (selected part)", mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax, nPhi3DBins, phiMin, phiMax);
+ mHistEtaPtPhi3DPart->SetXTitle("Eta");
+ mHistEtaPtPhi3DPart->SetYTitle("Pt (GeV/c)");
+ mHistEtaPtPhi3DPart->SetZTitle("Phi (rad)");
+   
+ // EtaPtPhi for particles NOT SELECTED for correlation with the event plane
+ mHistEtaPtPhi3DOut = new TH3F("Flow_EtaPtPhi3Dout", "Flow_EtaPtPhi3Dout (NOT selected part)", mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax, nPhi3DBins, phiMin, phiMax);
+ mHistEtaPtPhi3DOut->SetXTitle("Eta");
+ mHistEtaPtPhi3DOut->SetYTitle("Pt (GeV/c)");
+ mHistEtaPtPhi3DOut->SetZTitle("Phi (rad)");
+   
+ // Yield Pt-Phi for all positive
+ mHistPtPhiPos = new TH2D("Flow_PtPhi_Plus", "Flow_PtPhi_Plus", nPhiBins, phiMin, phiMax, 50, ptMin, ptMax);
+ mHistPtPhiPos->Sumw2();
+ mHistPtPhiPos->SetXTitle("Phi");
+ mHistPtPhiPos->SetYTitle("Pt (GeV/c)");
+
+ // Yield Pt-Phi for all negative
+ mHistPtPhiNeg = new TH2D("Flow_PtPhi_Minus", "Flow_PtPhi_Minus", nPhiBins, phiMin, phiMax, 50, ptMin, ptMax);
+ mHistPtPhiNeg->Sumw2();
+ mHistPtPhiNeg->SetXTitle("Phi");
+ mHistPtPhiNeg->SetYTitle("Pt (GeV/c)");
+   
+ // Yield for all particles
+ mHistYieldAll2D = new TH2D("Flow_YieldAll2D", "Flow_YieldAll2D", mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax);
+ mHistYieldAll2D->Sumw2();
+ mHistYieldAll2D->SetXTitle("Pseudorapidty");
+ mHistYieldAll2D->SetYTitle("Pt (GeV/c)");
+
+ // Yield for constrainable tracks
+ mHistYieldCon2D = new TH2D("Flow_YieldCons2D", "Flow_YieldCons2D", mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax);
+ mHistYieldCon2D->Sumw2();
+ mHistYieldCon2D->SetXTitle("Pseudorapidty");
+ mHistYieldCon2D->SetYTitle("Pt (GeV/c)");
+
+ // Yield for un-constrainable tracks
+ mHistYieldUnc2D = new TH2D("Flow_YieldUnc2D", "Flow_YieldUnc2D", mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax);
+ mHistYieldUnc2D->Sumw2();
+ mHistYieldUnc2D->SetXTitle("Pseudorapidty");
+ mHistYieldUnc2D->SetYTitle("Pt (GeV/c)");
+
+ // Yield for particles correlated with the event plane
+ mHistYieldPart2D = new TH2D("Flow_YieldPart2D", "Flow_YieldPart2D (selected part)", mNEtaBins, mEtaMin, mEtaMax, nPtBinsPart, ptMin, ptMaxPart);
+ mHistYieldPart2D->Sumw2();
+ mHistYieldPart2D->SetXTitle((char*)xLabel.Data());
+ mHistYieldPart2D->SetYTitle("Pt (GeV/c)");
+
+ // Yield for particles NOT SELECTED for correlation with the event plane
+ mHistYieldOut2D = new TH2D("Flow_YieldOut2D", "Flow_YieldOut2D (NOT selected part)", mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax);
+ mHistYieldOut2D->Sumw2();
+ mHistYieldOut2D->SetXTitle("Pseudorapidty");
+ mHistYieldOut2D->SetYTitle("Pt (GeV/c)");
+ // invariant Mass for all particles (from TOF)
+ mHistInvMass = new TH1F("Flow_InvMass", "Flow_InvMass (tof)", nMassBins, massMin, massMax);
+ mHistInvMass->SetXTitle("Invariant Mass (GeV)");
+ mHistInvMass->SetYTitle("Counts");
+ // invariant Mass for particles correlated with the event plane (from TOF)
+ mHistInvMassPart = new TH1F("Flow_InvMassPart", "Flow_InvMassPart (tof)", nMassBins, massMin, massMax);
+ mHistInvMassPart->SetXTitle("Invariant Mass (GeV)");
+ mHistInvMassPart->SetYTitle("Counts");
+ // invariant Mass for particles NOT SELECTED for correlation with the event plane (from TOF)
+ mHistInvMassOut = new TH1F("Flow_InvMassOut", "Flow_InvMassOut (tof)", nMassBins, massMin, massMax);
+ mHistInvMassOut->SetXTitle("Invariant Mass (GeV)");
+ mHistInvMassOut->SetYTitle("Counts");
+
+ // Mean Eta in each bin for particles correlated with the event plane
+ mHistBinEta = new TProfile("Flow_Bin_Eta", "Flow_Bin_Eta_part (selected part)", mNEtaBins, mEtaMin, mEtaMax, mEtaMin, mEtaMax, "");
+ mHistBinEta->SetXTitle((char*)xLabel.Data());
+ mHistBinEta->SetYTitle((char*)xLabel.Data());
+ // Mean Pt in each bin for particles correlated with the event plane
+ mHistBinPt = new TProfile("Flow_Bin_Pt", "Flow_Bin_Pt_part (selected part)", nPtBinsPart, ptMin, ptMaxPart, ptMin, ptMaxPart, "");
+ mHistBinPt->SetXTitle("Pt (GeV/c)");
+ mHistBinPt->SetYTitle("<Pt> (GeV/c)");
+ // cos(n*phiLab)
+ mHistCosPhi = new TProfile("Flow_CosPhiLab", "Flow_CosPhiLab", Flow::nHars, 0.5, (float)(Flow::nHars) + 0.5, -100., 100., "");
+ mHistCosPhi->SetXTitle("Harmonic");
+ mHistCosPhi->SetYTitle("<cos(n*PhiLab)> (%)");
+   
+ // PID pi+
+ mHistPidPiPlus = new TH1F("Flow_PidPiPlus", "Flow_PidPiPlus", nPidBins, pidMin, pidMax);
+ mHistPidPiPlus->SetXTitle("ALICE P.Id.");
+ mHistPidPiPlus->SetYTitle("Counts");
+   
+ // PID pi-
+ mHistPidPiMinus = new TH1F("Flow_PidPiMinus", "Flow_PidPiMinus", nPidBins, pidMin, pidMax);
+ mHistPidPiMinus->SetXTitle("ALICE P.Id.");
+ mHistPidPiMinus->SetYTitle("Counts");
+   
+ // PID proton
+ mHistPidProton = new TH1F("Flow_PidProton", "Flow_PidProton", nPidBins, pidMin, pidMax);
+ mHistPidProton->SetXTitle("ALICE P.Id.");
+ mHistPidProton->SetYTitle("Counts");
+
+ // PID anti proton
+ mHistPidAntiProton = new TH1F("Flow_PidAntiProton", "Flow_PidAntiProton", nPidBins, pidMin, pidMax);
+ mHistPidAntiProton->SetXTitle("ALICE P.Id.");
+ mHistPidAntiProton->SetYTitle("Counts");
+
+ // PID Kplus
+ mHistPidKplus = new TH1F("Flow_PidKplus", "Flow_PidKplus", nPidBins, pidMin, pidMax);
+ mHistPidKplus->SetXTitle("ALICE P.Id.");
+ mHistPidKplus->SetYTitle("Counts");
+
+ // PID Kminus
+ mHistPidKminus = new TH1F("Flow_PidKminus", "Flow_PidKminus", nPidBins, pidMin, pidMax);
+ mHistPidKminus->SetXTitle("ALICE P.Id.");
+ mHistPidKminus->SetYTitle("Counts");
+
+ // PID deuteron
+ mHistPidDeuteron = new TH1F("Flow_PidDeuteron", "Flow_PidDeuteron", nPidBins, pidMin, pidMax);
+ mHistPidDeuteron->SetXTitle("ALICE P.Id.");
+ mHistPidDeuteron->SetYTitle("Counts");
+
+ // PID anti deuteron
+ mHistPidAntiDeuteron = new TH1F("Flow_PidAntiDeuteron", "Flow_PidAntiDeuteron", nPidBins, pidMin, pidMax);
+ mHistPidAntiDeuteron->SetXTitle("ALICE P.Id.");
+ mHistPidAntiDeuteron->SetYTitle("Counts");
+
+ // PID electron
+ mHistPidElectron = new TH1F("Flow_PidElectron", "Flow_PidElectron", nPidBins, pidMin, pidMax);
+ mHistPidElectron->SetXTitle("ALICE P.Id.");
+ mHistPidElectron->SetYTitle("Counts");
+
+ // PID positron
+ mHistPidPositron = new TH1F("Flow_PidPositron", "Flow_PidPositron", nPidBins, pidMin, pidMax);
+ mHistPidPositron->SetXTitle("ALICE P.Id.");
+ mHistPidPositron->SetYTitle("Counts");
+
+ // PID Muon+
+ mHistPidMuonPlus = new TH1F("Flow_PidMuonPlus", "Flow_PidMuonPlus", nPidBins, pidMin, pidMax);
+ mHistPidMuonPlus->SetXTitle("ALICE P.Id.");
+ mHistPidMuonPlus->SetYTitle("Counts");
+
+ // PID Muon-
+ mHistPidMuonMinus = new TH1F("Flow_PidMuonMinus", "Flow_PidMuonMinus", nPidBins, pidMin, pidMax);
+ mHistPidMuonMinus->SetXTitle("ALICE P.Id.");
+ mHistPidMuonMinus->SetYTitle("Counts");
+
+ // PID pi+ selected
+ mHistPidPiPlusPart = new TH1F("Flow_PidPiPlusPart", "Flow_PidPiPlusPart", nPidBins, pidMin, pidMax);
+ mHistPidPiPlusPart->SetXTitle("ALICE P.Id. (pid = pi+)");
+ mHistPidPiPlusPart->SetYTitle("Counts");
+   
+ // PID pi- selected
+ mHistPidPiMinusPart = new TH1F("Flow_PidPiMinusPart", "Flow_PidPiMinusPart", nPidBins, pidMin, pidMax);
+ mHistPidPiMinusPart->SetXTitle("ALICE P.Id. (pid = pi-)");
+ mHistPidPiMinusPart->SetYTitle("Counts");
+   
+ // PID proton selected
+ mHistPidProtonPart = new TH1F("Flow_PidProtonPart", "Flow_PidProtonPart", nPidBins, pidMin, pidMax);
+ mHistPidProtonPart->SetXTitle("ALICE P.Id. (pid = p)");
+ mHistPidProtonPart->SetYTitle("Counts");
+
+ // PID anti proton selected
+ mHistPidAntiProtonPart = new TH1F("Flow_PidAntiProtonPart", "Flow_PidAntiProtonPart", nPidBins, pidMin, pidMax);
+ mHistPidAntiProtonPart->SetXTitle("ALICE P.Id. (pid = p-)");
+ mHistPidAntiProtonPart->SetYTitle("Counts");
+
+ // PID Kplus selected
+ mHistPidKplusPart = new TH1F("Flow_PidKplusPart", "Flow_PidKplusPart", nPidBins, pidMin, pidMax);
+ mHistPidKplusPart->SetXTitle("ALICE P.Id. (pid = K+)");
+ mHistPidKplusPart->SetYTitle("Counts");
+
+ // PID Kminus selected
+ mHistPidKminusPart = new TH1F("Flow_PidKminusPart", "Flow_PidKminusPart", nPidBins, pidMin, pidMax);
+ mHistPidKminusPart->SetXTitle("ALICE P.Id. (pid = K-)");
+ mHistPidKminusPart->SetYTitle("Counts");
+
+ // PID deuteron selected
+ mHistPidDeuteronPart = new TH1F("Flow_PidDeuteronPart", "Flow_PidDeuteronPart", nPidBins, pidMin, pidMax);
+ mHistPidDeuteronPart->SetXTitle("ALICE P.Id. (pid = d)");
+ mHistPidDeuteronPart->SetYTitle("Counts");
+
+ // PID anti deuteron selected
+ mHistPidAntiDeuteronPart = new TH1F("Flow_PidAntiDeuteronPart", "Flow_PidAntiDeuteronPart", nPidBins, pidMin, pidMax);
+ mHistPidAntiDeuteronPart->SetXTitle("ALICE P.Id. (pid = d--)");
+ mHistPidAntiDeuteronPart->SetYTitle("Counts");
+
+ // PID electron selected
+ mHistPidElectronPart = new TH1F("Flow_PidElectronPart", "Flow_PidElectronPart", nPidBins, pidMin, pidMax);
+ mHistPidElectronPart->SetXTitle("ALICE P.Id. (pid = e-)");
+ mHistPidElectronPart->SetYTitle("Counts");
+
+ // PID positron selected
+ mHistPidPositronPart = new TH1F("Flow_PidPositronPart", "Flow_PidPositronPart", nPidBins, pidMin, pidMax);
+ mHistPidPositronPart->SetXTitle("ALICE P.Id. (pid = e+)");
+ mHistPidPositronPart->SetYTitle("Counts");
+
+ // PID Muon+ selected
+ mHistPidMuonPlusPart = new TH1F("Flow_PidMuonPlusPart", "Flow_PidMuonPlusPart", nPidBins, pidMin, pidMax);
+ mHistPidMuonPlusPart->SetXTitle("ALICE P.Id. (pid = mu+)");
+ mHistPidMuonPlusPart->SetYTitle("Counts");
+
+ // PID Muon- selected
+ mHistPidMuonMinusPart = new TH1F("Flow_PidMuonMinusPart", "Flow_PidMuonMinusPart", nPidBins, pidMin, pidMax);
+ mHistPidMuonMinusPart->SetXTitle("ALICE P.Id. (pid = mu-)");
+ mHistPidMuonMinusPart->SetYTitle("Counts");
+
+ // PID multiplicities (all)
+ mHistPidMult = new TProfile("Flow_PidMult", "Flow_PidMult", 15, 0.5, 15.5, "");
+ mHistPidMult->SetXTitle("all, h+, h-, pi+, pi-, pr+, pr-, K+, K-, d+, d-, e-, e+, mu-, mu+");
+ mHistPidMult->SetYTitle("Multiplicity");
+
+ // PID for all tracks
+ mHistBayPidMult = new TH1F("Flow_BayPidMult","Flow_BayPidMult",Flow::nPid,-0.5,((float)Flow::nPid-0.5));
+ mHistBayPidMult->Sumw2() ;
+ mHistBayPidMult->SetXTitle("e+/- , mu+/- , pi+/- , K+/- , p+/- , d+/- ");
+ mHistBayPidMult->SetYTitle("Counts");
+   
+ // PID for particles correlated with the event plane
+ mHistBayPidMultPart = new TH1F("Flow_BayPidMult_Part","Flow_BayPidMult_Part",Flow::nPid,-0.5,((float)Flow::nPid-0.5));
+ mHistBayPidMultPart->Sumw2() ;
+ mHistBayPidMultPart->SetXTitle("e+/- , mu+/- , pi+/- , K+/- , p+/- , d+/- ");
+ mHistBayPidMultPart->SetYTitle("Counts");
+
+ // Centrality
+ mHistCent = new TH1F("Flow_Cent", "Flow_Cent", nCentBins, centMin, centMax);
+ mHistCent->SetXTitle("Centrality Bin");
+ mHistCent->SetYTitle("Counts");
+   
+ // Deposited Energy in ZDC
+ mHistEnergyZDC = new TH2F("Flow_ZDC_E", "Flow_ZDC_E", 3, 0., 3., nZDCeBins, ZDCeMin, ZDCeMax);
+ mHistEnergyZDC->SetXTitle("neutron , proton , e.m.");
+ mHistEnergyZDC->SetYTitle("ZDC energy");
+
+ // Part. versus Energy in ZDC
+ mHistPartZDC = new TH1F("Flow_ZDC_Participants", "Flow_ZDC_Participants", nZDCpartBins, ZDCpartMin, ZDCpartMax);
+ mHistPartZDC->SetXTitle("ZDC part");
+ mHistPartZDC->SetYTitle("Counts");
+
+ // MeanDedxPos TPC
+ mHistMeanDedxPos2D = new TH2F("Flow_MeanDedxPos2D_TPC","Flow_MeanDedxPos2D_TPC", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMaxTPC);
+ mHistMeanDedxPos2D->SetXTitle("log(momentum) (GeV/c)");
+ mHistMeanDedxPos2D->SetYTitle("mean dEdx (+)");
+ // MeanDedxNeg TPC
+ mHistMeanDedxNeg2D = new TH2F("Flow_MeanDedxNeg2D_TPC","Flow_MeanDedxNeg2D_TPC", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMaxTPC);
+ mHistMeanDedxNeg2D->SetXTitle("log(momentum) (GeV/c)");
+ mHistMeanDedxNeg2D->SetYTitle("mean dEdx (-)");
+
+ // MeanDedxPos ITS
+ mHistMeanDedxPos2DITS = new TH2F("Flow_MeanDedxPos2D_ITS","Flow_MeanDedxPos2D_ITS", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMax);
+ mHistMeanDedxPos2DITS->SetXTitle("log(momentum) (GeV/c)");
+ mHistMeanDedxPos2DITS->SetYTitle("mean dEdx (+)");
+ // MeanDedxNeg ITS
+ mHistMeanDedxNeg2DITS = new TH2F("Flow_MeanDedxNeg2D_ITS","Flow_MeanDedxNeg2D_ITS", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMax);
+ mHistMeanDedxNeg2DITS->SetXTitle("log(momentum) (GeV/c)");
+ mHistMeanDedxNeg2DITS->SetYTitle("mean dEdx (-)");
+
+ // MeanDedxPos TPC 3D selected Part
+ mHistMeanDedxPos3DPart = new TH3F("Flow_MeanDedxPos3DPart_TPC","Flow_MeanDedxPos3DPart_TPC", nMomenBins, logpMin, logpMax, nDedxBins, 0., dEdxMaxTPC, Flow::nPid, 0., Flow::nPid);
+ mHistMeanDedxPos3DPart->SetXTitle("log(momentum) (GeV/c)");
+ mHistMeanDedxPos3DPart->SetYTitle("mean dEdx (+)");
+ mHistMeanDedxPos3DPart->SetZTitle("e , mu , pi , k , p , d");
+ // MeanDedxNeg TPC 3D selected Part
+ mHistMeanDedxNeg3DPart = new TH3F("Flow_MeanDedxNeg3DPart_TPC","Flow_MeanDedxNeg3DPart_TPC", nMomenBins, logpMin, logpMax, nDedxBins, 0., dEdxMaxTPC, Flow::nPid, 0., Flow::nPid);
+ mHistMeanDedxNeg3DPart->SetXTitle("log(momentum) (GeV/c)");
+ mHistMeanDedxNeg3DPart->SetYTitle("mean dEdx (-)");
+ mHistMeanDedxNeg3DPart->SetZTitle("e , mu , pi , k , p , d");
+
+ // MeanDedxPos ITS 3D selected Part
+ mHistMeanDedxPos3DPartITS = new TH3F("Flow_MeanDedxPos3DPart_ITS","Flow_MeanDedxPos3DPart_ITS", nMomenBins, logpMin, logpMax, nDedxBins, 0., dEdxMax, Flow::nPid, 0., Flow::nPid);
+ mHistMeanDedxPos3DPartITS->SetXTitle("log(momentum) (GeV/c)");
+ mHistMeanDedxPos3DPartITS->SetYTitle("mean dEdx (+)");
+ mHistMeanDedxPos3DPartITS->SetZTitle("e , mu , pi , k , p , d");
+ // MeanDedxNeg ITS 3D selected Part
+ mHistMeanDedxNeg3DPartITS = new TH3F("Flow_MeanDedxNeg3DPart_ITS","Flow_MeanDedxNeg3DPart_ITS", nMomenBins, logpMin, logpMax, nDedxBins, 0., dEdxMax, Flow::nPid, 0., Flow::nPid);
+ mHistMeanDedxNeg3DPartITS->SetXTitle("log(momentum) (GeV/c)");
+ mHistMeanDedxNeg3DPartITS->SetYTitle("mean dEdx (-)");
+ mHistMeanDedxNeg3DPartITS->SetZTitle("e , mu , pi , k , p , d");
+
+ // MeanSignalPos TRD
+ mHistMeanDedxPos2DTRD = new TH2F("Flow_MeanSignalPos2D_TRD","Flow_MeanSignalPos2D_TRD", nMomenBins, logpMin, logpMax, nTrdBins, 0, TRDmax);
+ mHistMeanDedxPos2DTRD->SetXTitle("log(momentum) (GeV/c)");
+ mHistMeanDedxPos2DTRD->SetYTitle("mean TRD (+)");
+ // MeanSignalNeg TRD
+ mHistMeanDedxNeg2DTRD = new TH2F("Flow_MeanSignalNeg2D_TRD","Flow_MeanSignalNeg2D_TRD", nMomenBins, logpMin, logpMax, nTrdBins, 0, TRDmax);
+ mHistMeanDedxNeg2DTRD->SetXTitle("log(momentum) (GeV/c)");
+ mHistMeanDedxNeg2DTRD->SetYTitle("mean TRD (-)");
+
+ // MeanTimePos TOF
+ mHistMeanDedxPos2DTOF = new TH2F("Flow_MeanTimePos2D_TOF","Flow_MeanTimePos2D_TOF", nMomenBins, logpMin, logpMax, nTofBins, TOFmin, TOFmax);
+ mHistMeanDedxPos2DTOF->SetXTitle("log(momentum) (GeV/c)");
+ mHistMeanDedxPos2DTOF->SetYTitle("mean Time of Flight (+)");
+ // MeanTimeNeg TOF
+ mHistMeanDedxNeg2DTOF = new TH2F("Flow_MeanTimeNeg2D_TOF","Flow_MeanTimeNeg2D_TOF", nMomenBins, logpMin, logpMax, nTofBins, TOFmin, TOFmax);
+ mHistMeanDedxNeg2DTOF->SetXTitle("log(momentum) (GeV/c)");
+ mHistMeanDedxNeg2DTOF->SetYTitle("mean Time of Flight (-)");
+ // Detector response for each particle { ... 
+ // MeanDedx PiPlus - TPC
+ mHistMeanTPCPiPlus = new TH2F("Flow_MeanDedxPiPlusTPC", "Flow_MeanDedxPiPlusTPC", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMaxTPC);
+ mHistMeanTPCPiPlus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTPCPiPlus->SetYTitle("mean dEdx (pi+)");
+ // MeanDedx PiMinus
+ mHistMeanTPCPiMinus = new TH2F("Flow_MeanDedxPiMinusTPC", "Flow_MeanDedxPiMinusTPC", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMaxTPC);
+ mHistMeanTPCPiMinus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTPCPiMinus->SetYTitle("mean dEdx (pi-)");
+ // MeanDedx Proton
+ mHistMeanTPCProton = new TH2F("Flow_MeanDedxProtonTPC", "Flow_MeanDedxProtonTPC", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMaxTPC);
+ mHistMeanTPCProton->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTPCProton->SetYTitle("mean dEdx (pr+)");
+ // MeanDedx Pbar
+ mHistMeanTPCPbar = new TH2F("Flow_MeanDedxPbarTPC", "Flow_MeanDedxPbarTPC", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMaxTPC);
+ mHistMeanTPCPbar->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTPCPbar->SetYTitle("mean dEdx (pr-)");
+ // MeanDedx Kplus
+ mHistMeanTPCKplus = new TH2F("Flow_MeanDedxKplusTPC", "Flow_MeanDedxKplusTPC", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMaxTPC);
+ mHistMeanTPCKplus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTPCKplus->SetYTitle("mean dEdx (K+)");
+ // MeanDedx Kminus
+ mHistMeanTPCKminus = new TH2F("Flow_MeanDedxKminusTPC", "Flow_MeanDedxKminusTPC", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMaxTPC);
+ mHistMeanTPCKminus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTPCKminus->SetYTitle("mean dEdx (K-)");
+ // MeanDedx Deuteron
+ mHistMeanTPCDeuteron = new TH2F("Flow_MeanDedxDeuteronTPC", "Flow_MeanDedxDeuteronTPC", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMaxTPC);
+ mHistMeanTPCDeuteron->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTPCDeuteron->SetYTitle("mean dEdx (d+)");
+ // MeanDedx AntiDeuteron
+ mHistMeanTPCAntiDeuteron = new TH2F("Flow_MeanDedxAntiDeuteronTPC", "Flow_MeanDedxAntiDeuteronTPC", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMaxTPC);
+ mHistMeanTPCAntiDeuteron->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTPCAntiDeuteron->SetYTitle("mean dEdx (d-)");
+ // MeanDedxElectron
+ mHistMeanTPCElectron = new TH2F("Flow_MeanDedxElectronTPC", "Flow_MeanDedxElectronTPC", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMaxTPC);
+ mHistMeanTPCElectron->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTPCElectron->SetYTitle("mean dEdx (e-)");
+ // MeanDedx Positron
+ mHistMeanTPCPositron = new TH2F("Flow_MeanDedxPositronTPC", "Flow_MeanDedxPositronTPC", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMaxTPC);
+ mHistMeanTPCPositron->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTPCPositron->SetYTitle("mean dEdx (e+)");
+ // MeanDedx MuonPlus
+ mHistMeanTPCMuonPlus = new TH2F("Flow_MeanDedxMuonPlusTPC", "Flow_MeanDedxMuonPlusTPC", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMaxTPC);
+ mHistMeanTPCMuonPlus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTPCMuonPlus->SetYTitle("mean dEdx (mu+)");
+ // MeanDedx MuonMinus
+ mHistMeanTPCMuonMinus = new TH2F("Flow_MeanDedxMuonMinusTPC", "Flow_MeanDedxMuonMinusTPC", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMaxTPC);
+ mHistMeanTPCMuonMinus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTPCMuonMinus->SetYTitle("mean dEdx (mu-)");
+ // MeanDedx PiPlus - ITS
+ mHistMeanITSPiPlus = new TH2F("Flow_MeanDedxPiPlusITS", "Flow_MeanDedxPiPlusITS", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMax);
+ mHistMeanITSPiPlus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanITSPiPlus->SetYTitle("mean dEdx (pi+)");
+ // MeanDedx PiMinus
+ mHistMeanITSPiMinus = new TH2F("Flow_MeanDedxPiMinusITS", "Flow_MeanDedxPiMinusITS", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMax);
+ mHistMeanITSPiMinus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanITSPiMinus->SetYTitle("mean dEdx (pi-)");
+ // MeanDedx Proton
+ mHistMeanITSProton = new TH2F("Flow_MeanDedxProtonITS", "Flow_MeanDedxProtonITS", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMax);
+ mHistMeanITSProton->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanITSProton->SetYTitle("mean dEdx (pr+)");
+ // MeanDedx Pbar
+ mHistMeanITSPbar = new TH2F("Flow_MeanDedxPbarITS", "Flow_MeanDedxPbarITS", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMax);
+ mHistMeanITSPbar->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanITSPbar->SetYTitle("mean dEdx (pr-)");
+ // MeanDedx Kplus
+ mHistMeanITSKplus = new TH2F("Flow_MeanDedxKplusITS", "Flow_MeanDedxKplusITS", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMax);
+ mHistMeanITSKplus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanITSKplus->SetYTitle("mean dEdx (K+)");
+ // MeanDedx Kminus
+ mHistMeanITSKminus = new TH2F("Flow_MeanDedxKminusITS", "Flow_MeanDedxKminusITS", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMax);
+ mHistMeanITSKminus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanITSKminus->SetYTitle("mean dEdx (K-)");
+ // MeanDedx Deuteron
+ mHistMeanITSDeuteron = new TH2F("Flow_MeanDedxDeuteronITS", "Flow_MeanDedxDeuteronITS", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMax);
+ mHistMeanITSDeuteron->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanITSDeuteron->SetYTitle("mean dEdx (d+)");
+ // MeanDedx AntiDeuteron
+ mHistMeanITSAntiDeuteron = new TH2F("Flow_MeanDedxAntiDeuteronITS", "Flow_MeanDedxAntiDeuteronITS", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMax);
+ mHistMeanITSAntiDeuteron->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanITSAntiDeuteron->SetYTitle("mean dEdx (d-)");
+ // MeanDedx Electron
+ mHistMeanITSElectron = new TH2F("Flow_MeanDedxElectronITS", "Flow_MeanDedxElectronITS", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMax);
+ mHistMeanITSElectron->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanITSElectron->SetYTitle("mean dEdx (e-)");
+ // MeanDedx Positron
+ mHistMeanITSPositron = new TH2F("Flow_MeanDedxPositronITS", "Flow_MeanDedxPositronITS", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMax);
+ mHistMeanITSPositron->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanITSPositron->SetYTitle("mean dEdx (e+)");
+ // MeanDedx MuonPlus
+ mHistMeanITSMuonPlus = new TH2F("Flow_MeanDedxMuonPlusITS", "Flow_MeanDedxMuonPlusITS", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMax);
+ mHistMeanITSMuonPlus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanITSMuonPlus->SetYTitle("mean dEdx (mu+)");
+ // MeanDedx MuonMinus
+ mHistMeanITSMuonMinus = new TH2F("Flow_MeanDedxMuonMinusITS", "Flow_MeanDedxMuonMinusITS", nMomenBins, logpMin, logpMax, nDedxBins, 0, dEdxMax);
+ mHistMeanITSMuonMinus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanITSMuonMinus->SetYTitle("mean dEdx (mu-)");
+ // MeanTrd PiPlus - TRD
+ mHistMeanTRDPiPlus = new TH2F("Flow_MeanTrdPiPlusTRD", "Flow_MeanTrdPiPlusTRD", nMomenBins, logpMin, logpMax, nTrdBins, 0, TRDmax);
+ mHistMeanTRDPiPlus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTRDPiPlus->SetYTitle("mean t.r.[] (pi+)");
+ // MeanTrd PiMinus
+ mHistMeanTRDPiMinus = new TH2F("Flow_MeanTrdPiMinusTRD", "Flow_MeanTrdPiMinusTRD", nMomenBins, logpMin, logpMax, nTrdBins, 0, TRDmax);
+ mHistMeanTRDPiMinus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTRDPiMinus->SetYTitle("mean t.r.[] (pi-)");
+ // MeanTrd Proton
+ mHistMeanTRDProton = new TH2F("Flow_MeanTrdProtonTRD", "Flow_MeanTrdProtonTRD", nMomenBins, logpMin, logpMax, nTrdBins, 0, TRDmax);
+ mHistMeanTRDProton->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTRDProton->SetYTitle("mean t.r.[] (pr+)");
+ // MeanTrd Pbar
+ mHistMeanTRDPbar = new TH2F("Flow_MeanTrdPbarTRD", "Flow_MeanTrdPbarTRD", nMomenBins, logpMin, logpMax, nTrdBins, 0, TRDmax);
+ mHistMeanTRDPbar->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTRDPbar->SetYTitle("mean t.r.[] (pr-)");
+ // MeanTrd Kplus
+ mHistMeanTRDKplus = new TH2F("Flow_MeanTrdKplusTRD", "Flow_MeanTrdKplusTRD", nMomenBins, logpMin, logpMax, nTrdBins, 0, TRDmax);
+ mHistMeanTRDKplus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTRDKplus->SetYTitle("mean t.r.[] (K+)");
+ // MeanTrd Kminus
+ mHistMeanTRDKminus = new TH2F("Flow_MeanTrdKminusTRD", "Flow_MeanTrdKminusTRD", nMomenBins, logpMin, logpMax, nTrdBins, 0, TRDmax);
+ mHistMeanTRDKminus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTRDKminus->SetYTitle("mean t.r.[] (K-)");
+ // MeanTrd Deuteron
+ mHistMeanTRDDeuteron = new TH2F("Flow_MeanTrdDeuteronTRD", "Flow_MeanTrdDeuteronTRD", nMomenBins, logpMin, logpMax, nTrdBins, 0, TRDmax);
+ mHistMeanTRDDeuteron->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTRDDeuteron->SetYTitle("mean t.r.[] (d+)");
+ // MeanTrd AntiDeuteron
+ mHistMeanTRDAntiDeuteron = new TH2F("Flow_MeanTrdAntiDeuteronTRD", "Flow_MeanTrdAntiDeuteronTRD", nMomenBins, logpMin, logpMax, nTrdBins, 0, TRDmax);
+ mHistMeanTRDAntiDeuteron->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTRDAntiDeuteron->SetYTitle("mean t.r.[] (d-)");
+ // MeanTrd Electron
+ mHistMeanTRDElectron = new TH2F("Flow_MeanTrdElectronTRD", "Flow_MeanTrdElectronTRD", nMomenBins, logpMin, logpMax, nTrdBins, 0, TRDmax);
+ mHistMeanTRDElectron->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTRDElectron->SetYTitle("mean t.r.[] (e-)");
+ // MeanTrd Positron
+ mHistMeanTRDPositron = new TH2F("Flow_MeanTrdPositronTRD", "Flow_MeanTrdPositronTRD", nMomenBins, logpMin, logpMax, nTrdBins, 0, TRDmax);
+ mHistMeanTRDPositron->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTRDPositron->SetYTitle("mean t.r.[] (e+)");
+ // MeanTrd MuonPlus
+ mHistMeanTRDMuonPlus = new TH2F("Flow_MeanTrdMuonPlusTRD", "Flow_MeanTrdMuonPlusTRD", nMomenBins, logpMin, logpMax, nTrdBins, 0, TRDmax);
+ mHistMeanTRDMuonPlus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTRDMuonPlus->SetYTitle("mean t.r.[] (mu+)");
+ // MeanTrd MuonMinus
+ mHistMeanTRDMuonMinus = new TH2F("Flow_MeanTrdMuonMinusTRD", "Flow_MeanTrdMuonMinusTRD", nMomenBins, logpMin, logpMax, nTrdBins, 0, TRDmax);
+ mHistMeanTRDMuonMinus->SetXTitle("Log10(p) (GeV/c)");
+ mHistMeanTRDMuonMinus->SetYTitle("mean t.r.[] (mu-)");
+ // T.O.F. PiPlus - TOF
+ mHistMeanTOFPiPlus = new TH2F("Flow_MeanTofPiPlusTOF", "Flow_MeanTofPiPlusTOF", nMassBins, massMin, massMax, nTofBins, TOFmin, TOFmax);
+ mHistMeanTOFPiPlus->SetXTitle("invariant mass (GeV)");
+ mHistMeanTOFPiPlus->SetYTitle("mean t.o.f.[psec] (pi+)");
+ // MeanTof PiMinus
+ mHistMeanTOFPiMinus = new TH2F("Flow_MeanTofPiMinusTOF", "Flow_MeanTofPiMinusTOF", nMassBins, massMin, massMax, nTofBins, TOFmin, TOFmax);
+ mHistMeanTOFPiMinus->SetXTitle("invariant mass (GeV)");
+ mHistMeanTOFPiMinus->SetYTitle("mean t.o.f.[psec] (pi-)");
+ // MeanTof Proton
+ mHistMeanTOFProton = new TH2F("Flow_MeanTofProtonTOF", "Flow_MeanTofProtonTOF", nMassBins, massMin, massMax, nTofBins, TOFmin, TOFmax);
+ mHistMeanTOFProton->SetXTitle("invariant mass (GeV)");
+ mHistMeanTOFProton->SetYTitle("mean t.o.f.[psec] (pr+)");
+ // Mean TofPbar
+ mHistMeanTOFPbar = new TH2F("Flow_MeanTofPbarTOF", "Flow_MeanTofPbarTOF", nMassBins, massMin, massMax, nTofBins, TOFmin, TOFmax);
+ mHistMeanTOFPbar->SetXTitle("invariant mass (GeV)");
+ mHistMeanTOFPbar->SetYTitle("mean t.o.f.[psec] (pr-)");
+ // mean t.o.f.[psec]Kplus
+ mHistMeanTOFKplus = new TH2F("Flow_MeanTofKplusTOF", "Flow_MeanTofKplusTOF", nMassBins, massMin, massMax, nTofBins, TOFmin, TOFmax);
+ mHistMeanTOFKplus->SetXTitle("invariant mass (GeV)");
+ mHistMeanTOFKplus->SetYTitle("mean t.o.f.[psec] (K+)");
+ // mean t.o.f.[psec]Kminus
+ mHistMeanTOFKminus = new TH2F("Flow_MeanTofKminusTOF", "Flow_MeanTofKminusTOF", nMassBins, massMin, massMax, nTofBins, TOFmin, TOFmax);
+ mHistMeanTOFKminus->SetXTitle("invariant mass (GeV)");
+ mHistMeanTOFKminus->SetYTitle("mean t.o.f.[psec] (K-)");
+ // MeanTof Deuteron
+ mHistMeanTOFDeuteron = new TH2F("Flow_MeanTofDeuteronTOF", "Flow_MeanTofDeuteronTOF", nMassBins, massMin, massMax, nTofBins, TOFmin, TOFmax);
+ mHistMeanTOFDeuteron->SetXTitle("invariant mass (GeV)");
+ mHistMeanTOFDeuteron->SetYTitle("mean t.o.f.[psec] (d+)");
+ // MeanTof AntiDeuteron
+ mHistMeanTOFAntiDeuteron = new TH2F("Flow_MeanTofAntiDeuteronTOF", "Flow_MeanTofAntiDeuteronTOF", nMassBins, massMin, massMax, nTofBins, TOFmin, TOFmax);
+ mHistMeanTOFAntiDeuteron->SetXTitle("invariant mass (GeV)");
+ mHistMeanTOFAntiDeuteron->SetYTitle("mean t.o.f.[psec] (d-)");
+ // MeanTof Electron
+ mHistMeanTOFElectron = new TH2F("Flow_MeanTofElectronTOF", "Flow_MeanTofElectronTOF", nMassBins, massMin, massMax, nTofBins, TOFmin, TOFmax);
+ mHistMeanTOFElectron->SetXTitle("invariant mass (GeV)");
+ mHistMeanTOFElectron->SetYTitle("mean t.o.f.[psec] (e-)");
+ // MeanTof Positron
+ mHistMeanTOFPositron = new TH2F("Flow_MeanTofPositronTOF", "Flow_MeanTofPositronTOF", nMassBins, massMin, massMax, nTofBins, TOFmin, TOFmax);
+ mHistMeanTOFPositron->SetXTitle("invariant mass (GeV)");
+ mHistMeanTOFPositron->SetYTitle("mean t.o.f.[psec] (e+)");
+ // MeanTof MuonPlus
+ mHistMeanTOFMuonPlus = new TH2F("Flow_MeanTofMuonPlusTOF", "Flow_MeanTofMuonPlusTOF", nMassBins, massMin, massMax, nTofBins, TOFmin, TOFmax);
+ mHistMeanTOFMuonPlus->SetXTitle("invariant mass (GeV)");
+ mHistMeanTOFMuonPlus->SetYTitle("mean t.o.f.[psec] (mu+)");
+ // MeanTof MuonMinus
+ mHistMeanTOFMuonMinus = new TH2F("Flow_MeanTofMuonMinusTOF", "Flow_MeanTofMuonMinusTOF", nMassBins, massMin, massMax, nTofBins, TOFmin, TOFmax);
+ mHistMeanTOFMuonMinus->SetXTitle("invariant mass (GeV)");
+ mHistMeanTOFMuonMinus->SetYTitle("mean t.o.f.[psec] (mu-)");
+ // ... }
+
+ TString* histTitle;
+ for (int n = 0; n < Flow::nSubs; n++) // for sub-events
+ {
+  for (int k = 0; k < Flow::nSels; k++) 
+  {
+   for (int j = 0; j < Flow::nHars; j++) 
+   {
+    float order = (float)(j + 1);
+    int i = Flow::nSubs * k + n ;
+
+    // event planes
+    histTitle = new TString("Flow_Psi_Sub");
+    *histTitle += n+1;
+    histTitle->Append("_Sel");
+    *histTitle += k+1;
+    histTitle->Append("_Har");
+    *histTitle += j+1;
+    histSub[i].histSubHar[j].mHistPsiSubs = new TH1F(histTitle->Data(),histTitle->Data(), nPsiBins, psiMin, (psiMax / order));
+    histSub[i].histSubHar[j].mHistPsiSubs->SetXTitle("Event Plane Angle (rad)");
+    histSub[i].histSubHar[j].mHistPsiSubs->SetYTitle("Counts");
+    delete histTitle;
+   }
+  }
+ }
+ if(mV0)            // All V0s (if there, if flag on)
+ {
+ // Mass
+  mHistV0Mass = new TH1F("FlowV0_InvMass", "FlowV0_InvMass", nMassBins, massMin, massMax);
+  mHistV0Mass->SetXTitle("Invariant Mass (GeV)");
+  mHistV0Mass->SetYTitle("Counts");
+ // Distance of closest approach
+  mHistV0Dca = new TH1F("FlowV0_Dca", "FlowV0_Dca", nDcaBins, dcaMin, glDcaMax);
+  mHistV0Dca->SetXTitle("dca between tracks (cm)");
+  mHistV0Dca->SetYTitle("Counts");
+ // lenght
+  mHistV0Lenght = new TH1F("FlowV0_Lenght", "FlowV0_Lenght", nLgBins, lgMinV0, lgMaxV0);
+  mHistV0Lenght->SetXTitle("Distance of V0s (cm)");
+  mHistV0Lenght->SetYTitle("Counts");
+ // Sigma for all particles
+  mHistV0Sigma = new TH1F("FlowV0_Sigma", "FlowV0_Sigma", nLgBins, lgMinV0, lgMaxV0 );
+  mHistV0Sigma->SetXTitle("Sigma");
+  mHistV0Sigma->SetYTitle("Counts");
+ // Chi2 
+  mHistV0Chi2 = new TH1F("FlowV0_Chi2", "FlowV0_Chi2", nChi2Bins, chi2Min, chi2MaxC);
+  mHistV0Chi2->SetXTitle("Chi square at Main Vertex");
+  mHistV0Chi2->SetYTitle("Counts");
+ // EtaPtPhi
+  mHistV0EtaPtPhi3D = new TH3F("FlowV0_EtaPtPhi3D", "FlowV0_EtaPtPhi3D", mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax, nPhi3DBins, phiMin, phiMax);
+  mHistV0EtaPtPhi3D->SetXTitle("Eta");
+  mHistV0EtaPtPhi3D->SetYTitle("Pt (GeV/c)");
+  mHistV0EtaPtPhi3D->SetZTitle("Phi (rad)");
+ // Yield for all v0s
+  mHistV0YieldAll2D = new TH2D("FlowV0_YieldAll2D", "FlowV0_YieldAll2D", mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax);
+  mHistV0YieldAll2D->Sumw2();
+  mHistV0YieldAll2D->SetXTitle("Pseudorapidty");
+  mHistV0YieldAll2D->SetYTitle("Pt (GeV/c)");
+ // Mass slices on pT
+  mHistV0MassPtSlices = new TH2D("FlowV0_MassPtSlices", "FlowV0_MassPtSlices", nMassBins, massMin, massMax, nPtBins, ptMin, ptMax);
+  mHistV0MassPtSlices->Sumw2();
+  mHistV0MassPtSlices->SetXTitle("Invariant Mass (GeV)");
+  mHistV0MassPtSlices->SetYTitle("Pt (GeV/c)");
+
+ // Selected V0s ...  
+ // Yield 
+  mHistV0YieldPart2D = new TH2D("FlowV0_Yield2Dsel", "FlowV0_Yield2Dsel", mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax);
+  mHistV0YieldPart2D->Sumw2();
+  mHistV0YieldPart2D->SetXTitle("Pseudorapidty");
+  mHistV0YieldPart2D->SetYTitle("Pt (GeV/c)");
+ // Mass Window
+  mHistV0MassWin = new TH1F("FlowV0_MassWinPart", "FlowV0_MassWinPart", nMassBins, massMin, massMax);
+  mHistV0MassWin->SetXTitle("Invariant Mass (GeV)");
+  mHistV0MassWin->SetYTitle("Counts");
+ // EtaPtPhi
+  mHistV0EtaPtPhi3DPart = new TH3F("FlowV0_EtaPtPhi3Dpart", "FlowV0_EtaPtPhi3Dpart", mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax, nPhi3DBins, phiMin, phiMax);
+  mHistV0EtaPtPhi3DPart->SetXTitle("Eta");
+  mHistV0EtaPtPhi3DPart->SetYTitle("Pt (GeV/c)");
+  mHistV0EtaPtPhi3DPart->SetZTitle("Phi (rad)");
+ // Distance of closest approach
+  mHistV0DcaPart = new TH1F("FlowV0_DcaPart", "FlowV0_DcaPart", nDcaBins, dcaMin, dcaMax);
+  mHistV0DcaPart->Sumw2();
+  mHistV0DcaPart->SetXTitle("dca between tracks (cm)");
+  mHistV0DcaPart->SetYTitle("Counts");
+ // lenght
+  mHistV0LenghtPart = new TH1F("FlowV0_LenghtPart", "FlowV0_LenghtPart", nLgBins, lgMinV0, lgMaxV0);
+  mHistV0LenghtPart->SetXTitle("Distance of V0s (cm)");
+  mHistV0LenghtPart->SetYTitle("Counts");
+ // SideBand Mass (sidebands)
+  mHistV0sbMassSide = new TH1F("FlowV0sb_MassWinSideBands", "FlowV0sb_MassWinSideBands", nMassBins, massMin, massMax);
+  mHistV0sbMassSide->SetXTitle("Invariant Mass (GeV)");
+  mHistV0sbMassSide->SetYTitle("Counts");
+ // EtaPtPhi (sidebands)
+  mHistV0sbEtaPtPhi3DPart = new TH3F("FlowV0sb_EtaPtPhi3D", "FlowV0sb_EtaPtPhi3D", mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax, nPhi3DBins, phiMin, phiMax);
+  mHistV0sbEtaPtPhi3DPart->SetXTitle("Eta");
+  mHistV0sbEtaPtPhi3DPart->SetYTitle("Pt (GeV/c)");
+  mHistV0sbEtaPtPhi3DPart->SetZTitle("Phi (rad)");
+ // Distance of closest approach (sidebands)
+  mHistV0sbDcaPart = new TH1F("FlowV0sb_Dca", "FlowV0sb_Dca", nDcaBins, dcaMin, dcaMax);
+  mHistV0sbDcaPart->Sumw2();
+  mHistV0sbDcaPart->SetXTitle("dca between tracks (cm)");
+  mHistV0sbDcaPart->SetYTitle("Counts");
+ // lenght (sidebands)
+  mHistV0sbLenghtPart = new TH1F("FlowV0sb_Lenght", "FlowV0sb_Lenght", nLgBins, lgMinV0, lgMaxV0);
+  mHistV0sbLenghtPart->SetXTitle("Distance of V0s (cm)");
+  mHistV0sbLenghtPart->SetYTitle("Counts");
+
+ // Mean Eta in each bin
+  mHistV0BinEta = new TProfile("FlowV0_Bin_Eta", "FlowV0_Bin_Eta", mNEtaBins, mEtaMin, mEtaMax, mEtaMin, mEtaMax, "");
+  mHistV0BinEta->SetXTitle((char*)xLabel.Data());
+  mHistV0BinEta->SetYTitle("<Eta>");
+ // Mean Pt in each bin
+  mHistV0BinPt = new TProfile("FlowV0_Bin_Pt", "FlowV0_Bin_Pt", nPtBinsPart, ptMin, ptMaxPart, ptMin, ptMaxPart, "");
+  mHistV0BinPt->SetXTitle("Pt (GeV/c)");
+  mHistV0BinPt->SetYTitle("<Pt> (GeV/c)");
+ // Mean Eta in each bin (sidebands)
+  mHistV0sbBinEta = new TProfile("FlowV0sb_Bin_Eta", "FlowV0sb_Bin_Eta", mNEtaBins, mEtaMin, mEtaMax, mEtaMin, mEtaMax, "");
+  mHistV0sbBinEta->SetXTitle((char*)xLabel.Data());
+  mHistV0sbBinEta->SetYTitle("<Eta>");
+ // Mean Pt in each bin (sidebands)
+  mHistV0sbBinPt = new TProfile("FlowV0sb_Bin_Pt", "FlowV0sb_Bin_Pt", nPtBinsPart, ptMin, ptMaxPart, ptMin, ptMaxPart, "");
+  mHistV0sbBinPt->SetXTitle("Pt (GeV/c)");
+  mHistV0sbBinPt->SetYTitle("<Pt> (GeV/c)");
+ }
+
+ for (int k = 0; k < Flow::nSels; k++) // for each selection
+ {
+  // cos(n*delta_Psi)
+  histTitle = new TString("Flow_Cos_Sel");
+  *histTitle += k+1;
+  histFull[k].mHistCos = new TProfile(histTitle->Data(), histTitle->Data(), Flow::nHars, 0.5, (float)(Flow::nHars) + 0.5, -1., 1., "");
+  histFull[k].mHistCos->SetXTitle("Harmonic");
+  histFull[k].mHistCos->SetYTitle("<cos(n*delta_Psi)>");
+  delete histTitle;
+   
+  // resolution
+  histTitle = new TString("Flow_Res_Sel");
+  *histTitle += k+1;
+  histFull[k].mHistRes = new TH1F(histTitle->Data(), histTitle->Data(), Flow::nHars, 0.5, (float)(Flow::nHars) + 0.5);
+  histFull[k].mHistRes->SetXTitle("Harmonic");
+  histFull[k].mHistRes->SetYTitle("Resolution");
+  delete histTitle;
+
+  // vObs
+  histTitle = new TString("Flow_vObs_Sel");
+  *histTitle += k+1;
+  histFull[k].mHist_vObs = new TProfile(histTitle->Data(), histTitle->Data(), Flow::nHars, 0.5, (float)(Flow::nHars) + 0.5, -100., 100., "");
+  histFull[k].mHist_vObs->SetXTitle("Harmonic");
+  histFull[k].mHist_vObs->SetYTitle("vObs (%)");
+  delete histTitle;
+
+  // vObs V0
+  histTitle = new TString("FlowV0_vObs_Sel");
+  *histTitle += k+1;
+  histFull[k].mHistV0_vObs = new TProfile(histTitle->Data(), histTitle->Data(), Flow::nHars, 0.5, (float)(Flow::nHars) + 0.5, -100., 100., "");
+  histFull[k].mHistV0_vObs->SetXTitle("Harmonic");
+  histFull[k].mHistV0_vObs->SetYTitle("vObs (%)");
+  delete histTitle;
+   
+  // vObs V0 sideband SX
+  histTitle = new TString("FlowV0sb_vObs_sx_Sel");
+  *histTitle += k+1;
+  histFull[k].mHistV0sb_vObs_sx = new TProfile(histTitle->Data(), histTitle->Data(), Flow::nHars, 0.5, (float)(Flow::nHars) + 0.5, -100., 100., "");
+  histFull[k].mHistV0sb_vObs_sx->SetXTitle("Harmonic");
+  histFull[k].mHistV0sb_vObs_sx->SetYTitle("vObs (%)");
+  delete histTitle;
+   
+  // vObs V0 sideband DX
+  histTitle = new TString("FlowV0sb_vObs_dx_Sel");
+  *histTitle += k+1;
+  histFull[k].mHistV0sb_vObs_dx = new TProfile(histTitle->Data(), histTitle->Data(), Flow::nHars, 0.5, (float)(Flow::nHars) + 0.5, -100., 100., "");
+  histFull[k].mHistV0sb_vObs_dx->SetXTitle("Harmonic");
+  histFull[k].mHistV0sb_vObs_dx->SetYTitle("vObs (%)");
+  delete histTitle;
+   
+  // PID for tracks used in R.P.
+  histTitle = new TString("Flow_BayPidMult_Sel");
+  *histTitle += k+1;
+  histFull[k].mHistBayPidMult = new TH1F(histTitle->Data(), histTitle->Data(),Flow::nPid,-0.5,((float)Flow::nPid-0.5));
+  histFull[k].mHistBayPidMult->Sumw2() ;
+  histFull[k].mHistBayPidMult->SetXTitle("e+/-  ,  mu+/-  ,  pi+/-  ,  K+/-  ,  p+/-  ,  d+/- ");
+  histFull[k].mHistBayPidMult->SetYTitle("Counts");
+  delete histTitle;
+
+  for (int j = 0; j < Flow::nHars; j++)   // for each harmonic
+  {
+   float order  = (float)(j+1);
+
+   // multiplicity
+   histTitle = new TString("Flow_Mul_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistMult = new TH1F(histTitle->Data(),histTitle->Data(), nMultBins, multMin, multMax);
+   histFull[k].histFullHar[j].mHistMult->SetXTitle("Multiplicity");
+   histFull[k].histFullHar[j].mHistMult->SetYTitle("Counts");
+   delete histTitle;
+
+   // event plane
+   histTitle = new TString("Flow_Psi_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistPsi = new TH1F(histTitle->Data(), histTitle->Data(), nPsiBins, psiMin, psiMax / order);
+   histFull[k].histFullHar[j].mHistPsi->SetXTitle("Event Plane Angle (rad)");
+   histFull[k].histFullHar[j].mHistPsi->SetYTitle("Counts");
+   delete histTitle;
+     
+   // event plane difference of two selections
+   histTitle = new TString("Flow_Psi_Diff_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   if (k == 0 ) 
+   {
+    Int_t my_order = 1;
+    if (j == 1) { my_order = 2 ; }
+    histFull[k].histFullHar[j].mHistPsi_Diff = new TH1F(histTitle->Data(), histTitle->Data(), nPsiBins, -psiMax/my_order/2., psiMax/my_order/2.);
+   } 
+   else 
+   {
+    histFull[k].histFullHar[j].mHistPsi_Diff = new TH1F(histTitle->Data(), histTitle->Data(), nPsiBins, -psiMax/2., psiMax/2.);
+   }
+   if (k == 0) 
+   {
+    if (j == 0) 
+    {
+     histFull[k].histFullHar[j].mHistPsi_Diff->SetXTitle("#Psi_{1,Sel1} - #Psi_{1,Sel2}(rad)");
+    } 
+    else if (j == 1) 
+    {
+     histFull[k].histFullHar[j].mHistPsi_Diff->SetXTitle("#Psi_{2,Sel1} - #Psi_{2,Sel2}(rad)");
+    }
+   } 
+   else if (k == 1) 
+   {
+    if (j == 0) 
+    {  
+     histFull[k].histFullHar[j].mHistPsi_Diff->SetXTitle("#Psi_{1,Sel1} - #Psi_{2,Sel2}(rad)");
+    } 
+    else if (j == 1) 
+    {
+     histFull[k].histFullHar[j].mHistPsi_Diff->SetXTitle("#Psi_{1,Sel1} - #Psi_{2,Sel1}(rad)");
+    }
+   }
+   histFull[k].histFullHar[j].mHistPsi_Diff->SetYTitle("Counts");
+   delete histTitle;
+
+   // correlation of sub-event planes
+   histTitle = new TString("Flow_Psi_Sub_Corr_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistPsiSubCorr = new TH1F(histTitle->Data(), histTitle->Data(), nPsiBins, psiMin, psiMax / order);
+   histFull[k].histFullHar[j].mHistPsiSubCorr->Sumw2();
+   histFull[k].histFullHar[j].mHistPsiSubCorr->SetXTitle("Sub-Event Correlation (rad)");
+   histFull[k].histFullHar[j].mHistPsiSubCorr->SetYTitle("Counts");
+   delete histTitle;
+     
+   // correlation of sub-event planes of different order
+   histTitle = new TString("Flow_Psi_Sub_Corr_Diff_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistPsiSubCorrDiff = new TH1F(histTitle->Data(), histTitle->Data(), nPsiBins, psiMin, psiMax / (order+1.));
+   histFull[k].histFullHar[j].mHistPsiSubCorrDiff->Sumw2();
+   histFull[k].histFullHar[j].mHistPsiSubCorrDiff->SetXTitle("Sub-Event Correlation (rad)");
+   histFull[k].histFullHar[j].mHistPsiSubCorrDiff->SetYTitle("Counts");
+   delete histTitle;
+     
+   // q
+   histTitle = new TString("Flow_NormQ_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHist_q = new TH1F(histTitle->Data(), histTitle->Data(), n_qBins, qMin, qMax);
+   histFull[k].histFullHar[j].mHist_q->Sumw2();
+   histFull[k].histFullHar[j].mHist_q->SetXTitle("q = |Q|/sqrt(Mult)");
+   histFull[k].histFullHar[j].mHist_q->SetYTitle("Counts");
+   delete histTitle;
+
+    // particle-plane azimuthal correlation
+   histTitle = new TString("Flow_Phi_Corr_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistPhiCorr = new TH1F(histTitle->Data(), histTitle->Data(), nPhiBins, phiMin, phiMax / order);
+   histFull[k].histFullHar[j].mHistPhiCorr->Sumw2();
+   histFull[k].histFullHar[j].mHistPhiCorr->SetXTitle("Particle-Plane Correlation (rad)");
+   histFull[k].histFullHar[j].mHistPhiCorr->SetYTitle("Counts");
+   delete histTitle;
+     
+   // neutral particle-plane azimuthal correlation
+   histTitle = new TString("FlowV0_Phi_Corr_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0PhiCorr = new TH1F(histTitle->Data(), histTitle->Data(), nPhiBins, phiMin, phiMax / order);
+   histFull[k].histFullHar[j].mHistV0PhiCorr->Sumw2();
+   histFull[k].histFullHar[j].mHistV0PhiCorr->SetXTitle("V0-Plane Correlation (rad)");
+   histFull[k].histFullHar[j].mHistV0PhiCorr->SetYTitle("Counts");
+   delete histTitle;
+
+   // neutral sidebands-plane azimuthal correlation
+   histTitle = new TString("FlowV0sb_Phi_Corr_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0sbPhiCorr = new TH1F(histTitle->Data(), histTitle->Data(), nPhiBins, phiMin, phiMax / order);
+   histFull[k].histFullHar[j].mHistV0sbPhiCorr->Sumw2();
+   histFull[k].histFullHar[j].mHistV0sbPhiCorr->SetXTitle("V0sideBands-Plane Correlation (rad)");
+   histFull[k].histFullHar[j].mHistV0sbPhiCorr->SetYTitle("Counts");
+   delete histTitle;
+
+   // Yield(pt)
+   histTitle = new TString("Flow_YieldPt_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistYieldPt = new TH1F(histTitle->Data(), histTitle->Data(), nPtBins, ptMin, ptMax);
+   histFull[k].histFullHar[j].mHistYieldPt->Sumw2();
+   histFull[k].histFullHar[j].mHistYieldPt->SetXTitle("Pt (GeV/c)");
+   histFull[k].histFullHar[j].mHistYieldPt->SetYTitle("Yield");
+   delete histTitle;
+     
+   // EtaPtPhi 
+   histTitle = new TString("Flow_EtaPtPhi3D_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistEtaPtPhi3D = new TH3F(histTitle->Data(), histTitle->Data(), mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax, nPhi3DBins, phiMin, phiMax);
+   histFull[k].histFullHar[j].mHistEtaPtPhi3D->SetXTitle("Eta");
+   histFull[k].histFullHar[j].mHistEtaPtPhi3D->SetYTitle("Pt (GeV/c)");
+   histFull[k].histFullHar[j].mHistEtaPtPhi3D->SetZTitle("Phi (rad)");
+   delete histTitle;
+
+   // Yield(eta,pt)
+   histTitle = new TString("Flow_Yield2D_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistYield2D = new TH2D(histTitle->Data(), histTitle->Data(), mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax);
+   histFull[k].histFullHar[j].mHistYield2D->Sumw2();
+   histFull[k].histFullHar[j].mHistYield2D->SetXTitle("Pseudorapidty");
+   histFull[k].histFullHar[j].mHistYield2D->SetYTitle("Pt (GeV/c)");
+   delete histTitle;
+
+   // Dca - 3D
+   histTitle = new TString("Flow_3dDca_Sel") ;
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistDcaGlob = new TH1F(histTitle->Data(), histTitle->Data(), nDcaBins, dcaMin, glDcaMax);
+   histFull[k].histFullHar[j].mHistDcaGlob->Sumw2();
+   histFull[k].histFullHar[j].mHistDcaGlob->SetXTitle("|3d Global Track's dca to Vertex (cm)|");
+   delete histTitle;
+
+   // Yield(pt) - excluded from R.P.
+   histTitle = new TString("Flow_YieldPt_outSel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistYieldPtout = new TH1F(histTitle->Data(), histTitle->Data(), nPtBins, ptMin, ptMax);
+   histFull[k].histFullHar[j].mHistYieldPtout->Sumw2();
+   histFull[k].histFullHar[j].mHistYieldPtout->SetXTitle("Pt (GeV/c)");
+   histFull[k].histFullHar[j].mHistYieldPtout->SetYTitle("Yield");
+   delete histTitle;
+     
+   // EtaPtPhi - excluded from R.P. 
+   histTitle = new TString("Flow_EtaPtPhi3D_outSel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistEtaPtPhi3Dout = new TH3F(histTitle->Data(), histTitle->Data(), mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax, nPhi3DBins, phiMin, phiMax);
+   histFull[k].histFullHar[j].mHistEtaPtPhi3Dout->SetXTitle("Eta");
+   histFull[k].histFullHar[j].mHistEtaPtPhi3Dout->SetYTitle("Pt (GeV/c)");
+   histFull[k].histFullHar[j].mHistEtaPtPhi3Dout->SetZTitle("Phi (rad)");
+   delete histTitle;
+
+   // Yield(eta,pt) - excluded from R.P.
+   histTitle = new TString("Flow_Yield2D_outSel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistYield2Dout = new TH2D(histTitle->Data(), histTitle->Data(), mNEtaBins, mEtaMin, mEtaMax, nPtBins, ptMin, ptMax);
+   histFull[k].histFullHar[j].mHistYield2Dout->Sumw2();
+   histFull[k].histFullHar[j].mHistYield2Dout->SetXTitle("Pseudorapidty");
+   histFull[k].histFullHar[j].mHistYield2Dout->SetYTitle("Pt (GeV/c)");
+   delete histTitle;
+
+   // Dca - 3D - excluded from R.P.
+   histTitle = new TString("Flow_3dDca_outSel") ;
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistDcaGlobout = new TH1F(histTitle->Data(), histTitle->Data(), nDcaBins, dcaMin, glDcaMax);
+   histFull[k].histFullHar[j].mHistDcaGlobout->Sumw2();
+   histFull[k].histFullHar[j].mHistDcaGlobout->SetXTitle("|3d Global Track's dca to Vertex (cm)|");
+   delete histTitle;
+
+   // Flow observed - v_obs,Pt,Eta
+   histTitle = new TString("Flow_vObs2D_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHist_vObs2D = new TProfile2D(histTitle->Data(), histTitle->Data(), mNEtaBins, mEtaMin, mEtaMax, nPtBinsPart, ptMin, ptMaxPart, -100., 100., "");
+   histFull[k].histFullHar[j].mHist_vObs2D->SetXTitle((char*)xLabel.Data());
+   histFull[k].histFullHar[j].mHist_vObs2D->SetYTitle("Pt (GeV/c)");
+   delete histTitle;
+
+   // v_obs,Eta
+   histTitle = new TString("Flow_vObsEta_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHist_vObsEta = new TProfile(histTitle->Data(), histTitle->Data(), mNEtaBins, mEtaMin, mEtaMax, -100., 100., "");
+   histFull[k].histFullHar[j].mHist_vObsEta->SetXTitle((char*)xLabel.Data());
+   histFull[k].histFullHar[j].mHist_vObsEta->SetYTitle("v (%)");
+   delete histTitle;
+
+   // v_obs,Pt
+   histTitle = new TString("Flow_vObsPt_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHist_vObsPt = new TProfile(histTitle->Data(), histTitle->Data(), nPtBinsPart, ptMin, ptMaxPart, -100., 100., "");
+   histFull[k].histFullHar[j].mHist_vObsPt->SetXTitle("Pt (GeV/c)");
+   histFull[k].histFullHar[j].mHist_vObsPt->SetYTitle("v (%)");
+   delete histTitle;
+
+   // neutral Flow observed - Pt,Eta
+   histTitle = new TString("FlowV0_vObs2D_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0_vObs2D = new TProfile2D(histTitle->Data(), histTitle->Data(), mNEtaBins, mEtaMin, mEtaMax, nPtBinsPart, ptMin, ptMaxPart, -100., 100., "");
+   histFull[k].histFullHar[j].mHistV0_vObs2D->SetXTitle((char*)xLabel.Data());
+   histFull[k].histFullHar[j].mHistV0_vObs2D->SetYTitle("Pt (GeV/c)");
+   delete histTitle;
+
+   // neutral Flow observed - Eta
+   histTitle = new TString("FlowV0_vObsEta_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0_vObsEta = new TProfile(histTitle->Data(), histTitle->Data(), mNEtaBins, mEtaMin, mEtaMax, -100., 100., "");
+   histFull[k].histFullHar[j].mHistV0_vObsEta->SetXTitle((char*)xLabel.Data());
+   histFull[k].histFullHar[j].mHistV0_vObsEta->SetYTitle("v (%)");
+   delete histTitle;
+
+   // neutral Flow observed - Pt
+   histTitle = new TString("FlowV0_vObsPt_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0_vObsPt = new TProfile(histTitle->Data(), histTitle->Data(), nPtBinsPart, ptMin, ptMaxPart, -100., 100., "");
+   histFull[k].histFullHar[j].mHistV0_vObsPt->SetXTitle("Pt (GeV/c)");
+   histFull[k].histFullHar[j].mHistV0_vObsPt->SetYTitle("v (%)");
+   delete histTitle;
+
+   // neutral sidebands Flow observed - Pt,Eta
+   histTitle = new TString("FlowV0sb_vObs2D_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0sb_vObs2D = new TProfile2D(histTitle->Data(), histTitle->Data(), mNEtaBins, mEtaMin, mEtaMax, nPtBinsPart, ptMin, ptMaxPart, -100., 100., "");
+   histFull[k].histFullHar[j].mHistV0sb_vObs2D->SetXTitle((char*)xLabel.Data());
+   histFull[k].histFullHar[j].mHistV0sb_vObs2D->SetYTitle("Pt (GeV/c)");
+   delete histTitle;
+
+   // neutral sidebands Flow observed - Eta
+   histTitle = new TString("FlowV0sb_vObsEta_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0sb_vObsEta = new TProfile(histTitle->Data(), histTitle->Data(), mNEtaBins, mEtaMin, mEtaMax, -100., 100., "");
+   histFull[k].histFullHar[j].mHistV0sb_vObsEta->SetXTitle((char*)xLabel.Data());
+   histFull[k].histFullHar[j].mHistV0sb_vObsEta->SetYTitle("v (%)");
+   delete histTitle;
+
+   // neutral sidebands Flow observed - Pt
+   histTitle = new TString("FlowV0sb_vObsPt_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0sb_vObsPt = new TProfile(histTitle->Data(), histTitle->Data(), nPtBinsPart, ptMin, ptMaxPart, -100., 100., "");
+   histFull[k].histFullHar[j].mHistV0sb_vObsPt->SetXTitle("Pt (GeV/c)");
+   histFull[k].histFullHar[j].mHistV0sb_vObsPt->SetYTitle("v (%)");
+   delete histTitle;
+
+   // SX neutral sidebands Flow observed - Eta
+   histTitle = new TString("FlowV0sb_vObsEta_sx_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0sb_vObsEta_sx = new TProfile(histTitle->Data(), histTitle->Data(), mNEtaBins, mEtaMin, mEtaMax, -100., 100., "");
+   histFull[k].histFullHar[j].mHistV0sb_vObsEta_sx->SetXTitle((char*)xLabel.Data());
+   histFull[k].histFullHar[j].mHistV0sb_vObsEta_sx->SetYTitle("v (%)");
+   delete histTitle;
+
+   // SX neutral sidebands Flow observed - Pt
+   histTitle = new TString("FlowV0sb_vObsPt_sx_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0sb_vObsPt_sx = new TProfile(histTitle->Data(), histTitle->Data(), nPtBinsPart, ptMin, ptMaxPart, -100., 100., "");
+   histFull[k].histFullHar[j].mHistV0sb_vObsPt_sx->SetXTitle("Pt (GeV/c)");
+   histFull[k].histFullHar[j].mHistV0sb_vObsPt_sx->SetYTitle("v (%)");
+   delete histTitle;
+
+   // DX neutral sidebands Flow observed - Eta
+   histTitle = new TString("FlowV0sb_vObsEta_dx_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0sb_vObsEta_dx = new TProfile(histTitle->Data(), histTitle->Data(), mNEtaBins, mEtaMin, mEtaMax, -100., 100., "");
+   histFull[k].histFullHar[j].mHistV0sb_vObsEta_dx->SetXTitle((char*)xLabel.Data());
+   histFull[k].histFullHar[j].mHistV0sb_vObsEta_dx->SetYTitle("v (%)");
+   delete histTitle;
+
+   // DX neutral sidebands Flow observed - Pt
+   histTitle = new TString("FlowV0sb_vObsPt_dx_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0sb_vObsPt_dx = new TProfile(histTitle->Data(), histTitle->Data(), nPtBinsPart, ptMin, ptMaxPart, -100., 100., "");
+   histFull[k].histFullHar[j].mHistV0sb_vObsPt_dx->SetXTitle("Pt (GeV/c)");
+   histFull[k].histFullHar[j].mHistV0sb_vObsPt_dx->SetYTitle("v (%)");
+   delete histTitle;
+
+   // Phi lab
+   // Tpc (plus)
+   histTitle = new TString("Flow_Phi_TPCplus_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistPhiPlus = new TH1D(histTitle->Data(), histTitle->Data(), nPhiBins, phiMin, phiMax);
+   histFull[k].histFullHar[j].mHistPhiPlus->SetXTitle("Azimuthal Angles (rad)");
+   histFull[k].histFullHar[j].mHistPhiPlus->SetYTitle("Counts");
+   delete histTitle;
+
+   // Tpc (minus)
+   histTitle = new TString("Flow_Phi_TPCminus_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistPhiMinus = new TH1D(histTitle->Data(), histTitle->Data(), nPhiBins, phiMin, phiMax);
+   histFull[k].histFullHar[j].mHistPhiMinus->SetXTitle("Azimuthal Angles (rad)");
+   histFull[k].histFullHar[j].mHistPhiMinus->SetYTitle("Counts");
+   delete histTitle;
+  
+   // Tpc (cross)
+   histTitle = new TString("Flow_Phi_TPCcross_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistPhiAll = new TH1D(histTitle->Data(), histTitle->Data(), nPhiBins, phiMin, phiMax);
+   histFull[k].histFullHar[j].mHistPhiAll->SetXTitle("Azimuthal Angles (rad)");
+   histFull[k].histFullHar[j].mHistPhiAll->SetYTitle("Counts");
+   delete histTitle;
+  
+   // Tpc
+   histTitle = new TString("Flow_Phi_TPC_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistPhi = new TH1D(histTitle->Data(), histTitle->Data(), nPhiBins, phiMin, phiMax);
+   histFull[k].histFullHar[j].mHistPhi->SetXTitle("Azimuthal Angles (rad)");
+   histFull[k].histFullHar[j].mHistPhi->SetYTitle("Counts");
+   delete histTitle;
+  
+   // Phi lab flattened
+   // Tpc (Plus)
+   histTitle = new TString("Flow_Phi_Flat_TPCplus_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistPhiFlatPlus = new TH1D(histTitle->Data(), histTitle->Data(), nPhiBins, phiMin, phiMax);
+   histFull[k].histFullHar[j].mHistPhiFlatPlus->SetXTitle("Azimuthal Angles (rad)");
+   histFull[k].histFullHar[j].mHistPhiFlatPlus->SetYTitle("Counts");
+   delete histTitle;
+
+   // Tpc (Minus)
+   histTitle = new TString("Flow_Phi_Flat_TPCminus_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistPhiFlatMinus = new TH1D(histTitle->Data(), histTitle->Data(), nPhiBins, phiMin, phiMax);
+   histFull[k].histFullHar[j].mHistPhiFlatMinus->SetXTitle("Azimuthal Angles (rad)");
+   histFull[k].histFullHar[j].mHistPhiFlatMinus->SetYTitle("Counts");
+   delete histTitle;
+
+   // Tpc (cross)
+   histTitle = new TString("Flow_Phi_Flat_TPCcross_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistPhiFlatAll = new TH1D(histTitle->Data(), histTitle->Data(), nPhiBins, phiMin, phiMax);
+   histFull[k].histFullHar[j].mHistPhiFlatAll->SetXTitle("Azimuthal Angles (rad)");
+   histFull[k].histFullHar[j].mHistPhiFlatAll->SetYTitle("Counts");
+   delete histTitle;
+
+   // Tpc
+   histTitle = new TString("Flow_Phi_Flat_TPC_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistPhiFlat = new TH1D(histTitle->Data(), histTitle->Data(), nPhiBins, phiMin, phiMax);
+   histFull[k].histFullHar[j].mHistPhiFlat->SetXTitle("Azimuthal Angles (rad)");
+   histFull[k].histFullHar[j].mHistPhiFlat->SetYTitle("Counts");
+   delete histTitle;
+  }
+ }
+ if(Debug1)  { cout << spaces << "Histograms booked" << endl ; }
+ if(fOneInputFile)
+ {
+  if(Open(GetInputFileName().Data()))  { if(Debug1)  { cout << spaces << "Events File Opened" << endl ; } }
+  else                                        { cout << FlowAnalysis << "ERROR OPENING THE FILE!" << endl ; return 0 ; }
+ }
+ else
+ {
+  if(Debug1)  
+  { 
+   cout << spaces << "Events Files : " << endl ; 
+   Int_t tot = fFileNames.GetEntries() ;
+   for(Int_t jj=0;jj<tot;jj++) 
+   { 
+    cout << spaces << "          " << jj << " : " << ((TObjString*)fFileNames.At(jj))->GetString().Data() << endl ;  
+   }
+   cout << spaces << " tot : " << tot << " . " << endl ; 
+  }
+ }
+
+ if(Debug1)  { cout << FlowAnalysis << "Initialized" << endl ; }
+ return 1 ;
+}
+//-----------------------------------------------------------------------
+Int_t AliFlowAnalysisMaker::Make()                   
+{
+ // Performs the event loop (0..nEvents) and makes call to : 
+ //  - get the event and checks it with AliFlowSelection (dummy) ,
+ //  - plugs in the Phi and the Bayesian weights from file (if there) ,
+ //  - re-sets the r.p. calculation cuts and re-does the tracks' selection loop (*) ,
+ //  - re-shuffles the tracks' array and re-devide in sub-events (*) ,
+ //  - fills event histograms (FillEventHistograms()) ,
+ //  - fills particle histograms (FillParticleHistograms()) ,
+ //  - fills v0 histograms (FillV0Histograms()) (*) .
+ // Then makes call to:
+ //  - calculate the global resolution and correct flow coefficients (Resolution()) ,
+ //  - calculate Phi & Bayesian weights and fill the weight histograms (Weightening()) .
+ if(Debug0) { cout << FlowAnalysis << "Make (starting events loop) . " << endl ; cout << endl ; }
+
+ Int_t succEv = 0 ;
+ Int_t tot = 1 ;
+ if(!fOneInputFile) { tot = fFileNames.GetEntries() ; }
+ for(Int_t ll=0;ll<tot;ll++)
+ {
+  if(!fOneInputFile) 
+  { 
+   TString nextFile = ((TObjString*)fFileNames.At(ll))->GetString().Data() ;
+   if(Open(nextFile.Data()))  { if(Debug0)  { cout << spaces << "Just Opened : " << nextFile.Data() << endl ; } }
+   else                      { cout << FlowAnalysis << "ERROR OPENING THE FILE: " << nextFile.Data() << endl ; continue ; }
+  }
+  for(int ie=0;ie<nEvents;ie++)
+  {
+   evtN = ie ;
+   pFlowEvent = GetEvt(evtN) ;
+   if(pFlowEvent) 
+   {
+    if(Analyze(pFlowEvent)) { cout << FlowAnalysis << " ev. " << evtN << " taken" << endl ; succEv++ ; } 
+    else                    { cout << FlowAnalysis << " ev. " << evtN << " discarded" << endl ; }
+   }
+   else 
+   {
+    if(Debug1) { cout << FlowAnalysis << "Problem opening  ev" << evtN << " . " << endl ; }
+    delete pFlowEvent  ; pFlowEvent = 0 ; 
+    continue ;
+   }
+   delete pFlowEvent  ; pFlowEvent = 0 ; 
+   pFlowTracks = 0 ;
+   pFlowV0s = 0 ;   
+  }
+  if(!fOneInputFile) 
+  {
+   pFlowEventsFile->Close() ; 
+   if(Debug1) { cout << spaces << "...going for next    " << ll << endl ; } 
+  }
+ }
+ if(!succEv) 
+ { 
+  if(Debug0) { cout << FlowAnalysis << "NO EVENT HAS BEEN PROCESSED !!!" << endl ; } 
+  return kFALSE ; 
+ }
+ Resolution() ;                                                 // calculates the resolution (and corrected v's)
+ if(mWritePhiWgt || mRedoWgt) { Weightening() ; }       // calculates the phi weights 
+ if(Debug1) { cout << FlowAnalysis << "Made" << endl ; }
+  
+ return 1 ;
+}
+//-----------------------------------------------------------------------
+Int_t AliFlowAnalysisMaker::Finish()                   
+{
+ // Close the analysis and saves the histograms on the histFile .
+
+ if(Debug0) { cout << FlowAnalysis << "Finish . " << endl ; } 
+ cout << FlowAnalysis << "Output File :  " << GetHistFileName() << endl ;
+ cout << endl ;
+
+ // Write all histograms
+ histFile->cd() ; histFile->Write() ; 
+ histFile->cd() ; mVnResHistList->Write();
+
+// *temp*  --  !uncomment!
+ // if(mLabelling) { histFile->cd() ; mLabHist->Write(); delete mLabHist ; }
+// *temp*  --  !uncomment!
+
+ histFile->Close() ;
+  
+ delete mVnResHistList ;
+ delete pFlowSelect ;
+ if(Debug1) { cout << FlowAnalysis << "Finished" << endl ; } 
+ return 1 ;
+}
+//-----------------------------------------------------------------------
+// ###
+//------------------------------------------------------------------------
+void AliFlowAnalysisMaker::WgtChk()
+{
+ // Check for Read/Write weights ...
+ TFile* wgtFile = new TFile(GetPhiWgtFileName().Data(),"READ");
+ // In case the file does not exist or is not a valid ROOT file, it is made a Zombie. 
+ // One can detect this situation with a code like:  f.IsZombie()
+ if(wgtFile->IsZombie()) 
+ {
+  if(Debug0) { cout << spaces << "Weights File ( " << GetPhiWgtFileName().Data() << " ) not present . A new one will be created ." << endl ; }
+  mReadPhiWgt = kFALSE ; mWritePhiWgt = kTRUE  ; mRedoWgt = kFALSE ; 
+ }
+ else 
+ { 
+  if(Debug0) { cout << spaces << "Reading Weights from File : " << GetPhiWgtFileName().Data() << " . " << endl ; }
+  mReadPhiWgt = kTRUE  ; mWritePhiWgt = kFALSE ; 
+  FillWgtArrays(wgtFile) ;                     
+  if(Debug2) { cout << spaces << "PhiWgt Arrays filled . " << endl ; } 
+ }
+ wgtFile->Close() ;
+}
+//-----------------------------------------------------------------------
+void AliFlowAnalysisMaker::FillWgtArrays(TFile* wgtFile)
+{
+ // Loads PhiWeights & Bayesian particles' abundance from file (default: 
+ // flowPhiWgt.hist.root). Weights are stored in some AliFlowAnalysisMaker 
+ // static data member, ready to be plugged into the AliFlowEvent .
+ // This is called at the beginning of the analysis (if wgt file is there).
+ TString* histTitle ;
+ TH1D* TPC_all ; TH1D* TPC_plus ; TH1D* TPC_minus ; TH1D* TPC_cross ;
+ TH1D* PID_bay ;
+ const int nPhiBins = Flow::nPhiBins ;
+
+ for(int k=0;k<Flow::nSels;k++)
+ {
+  for(int j=0;j<Flow::nHars;j++) 
+  {
+   // Tpc (plus)
+   histTitle = new TString("Flow_Phi_Weight_TPCplus_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   TPC_plus = (TH1D*)wgtFile->Get(histTitle->Data());
+   delete histTitle;
+   // Tpc (minus)
+   histTitle = new TString("Flow_Phi_Weight_TPCminus_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   TPC_minus = (TH1D*)wgtFile->Get(histTitle->Data());
+   delete histTitle;
+   // Tpc (cross)
+   histTitle = new TString("Flow_Phi_Weight_TPCcross_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   TPC_cross = (TH1D*)wgtFile->Get(histTitle->Data());
+   delete histTitle;
+
+   // Tpc
+   histTitle = new TString("Flow_Phi_Weight_TPC_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   TPC_all = (TH1D*)wgtFile->Get(histTitle->Data());
+   delete histTitle;
+  
+   for (int n=0;n<nPhiBins;n++) 
+   { 
+    nPhiWgtPlus[k][j][n]  = TPC_plus->GetBinContent(n+1) ;
+    nPhiWgtMinus[k][j][n] = TPC_minus->GetBinContent(n+1) ;
+    nPhiWgtCross[k][j][n] = TPC_cross->GetBinContent(n+1) ;
+    nPhiWgt[k][j][n]     = TPC_all->GetBinContent(n+1) ;
+    if(Debug2) { cout << "Weights: " << nPhiWgt[k][j][n] << " ; " << nPhiWgtPlus[k][j][n] << " | " << nPhiWgtMinus[k][j][n] << " | " << nPhiWgtCross[k][j][n] << endl ; }
+   } 
+  }
+  // Bayesian weights
+  histTitle = new TString("Flow_BayPidMult_Sel");
+  *histTitle += k+1;
+  PID_bay = (TH1D*)wgtFile->Get(histTitle->Data());
+  delete histTitle;
+  Double_t totCount = PID_bay->GetSumOfWeights() ;
+  for (int n=0;n<Flow::nPid;n++) 
+  { 
+   if(totCount) { nBayWgt[k][n] = PID_bay->GetBinContent(n+1) / totCount ; }
+   else        { nBayWgt[k][n] = 1. ; }
+   if(Debug2)  { cout << "Bayesian Weights (" << n << ") : " << nBayWgt[k][n] << endl ; }
+  }
+ }
+ delete TPC_all ; delete TPC_plus ; delete TPC_minus ; delete TPC_cross ;
+ delete PID_bay ;
+}
+//-----------------------------------------------------------------------
+void AliFlowAnalysisMaker::FillEvtPhiWgt()
+{
+ // Plugs Wgt arrays into the current AliFlowEvent.
+ pFlowEvent->SetPhiWeight(nPhiWgt);
+ pFlowEvent->SetPhiWeightPlus(nPhiWgtPlus);
+ pFlowEvent->SetPhiWeightMinus(nPhiWgtMinus);
+ pFlowEvent->SetPhiWeightCross(nPhiWgtCross); 
+}
+//-----------------------------------------------------------------------
+void AliFlowAnalysisMaker::FillBayesianWgt(int sel)
+{
+ // Plugs Bayesian particle abundance into the current AliFlowEvent.
+ // In principle a bayesian vector is stored for each selection and each
+ // harmonic. In practice just the 1st one is then plugged into the event
+ // (AliFlowEvent::mBayesianCs[6] is a 1-dimensional array).
+
+ Double_t bayes[Flow::nPid] ; 
+ Double_t bayCheck = 0. ;
+ for (int n=0;n<Flow::nPid;n++) 
+ {
+  bayes[n] = nBayWgt[sel][n] ;
+  bayCheck += bayes[n] ;   
+  if(Debug2) { cout << "Bayesian V[" << n << "]  =  " << nBayWgt[sel][n] << endl ; } 
+ }
+ if(bayCheck)   { pFlowEvent->SetBayesian(bayes) ; }
+ else          { cout << "An empty bayesian vector is stored !!! - Bayesian weights = {1,1,1,1,1,1} " << endl ; }
+ mRePid = kTRUE ;
+}
+//-----------------------------------------------------------------------
+void AliFlowAnalysisMaker::Weightening()
+{
+ // Calculates weights, and fills PhiWgt histograms and saves them into
+ // the PhiWgt file (by default: flowPhiWgt.hist.root) .
+ // This is called at the end of the analysis.
+ if(Debug0) { cout << FlowAnalysis << "Calculating/Filling weights . " << endl ; } 
+ cout << endl ;
+ // PhiWgt histogram collection
+ mPhiWgtHistList = new TOrdCollection(Flow::nSels*Flow::nHars) ;
+ const float phiMin   = 0. ;
+ const float phiMax   = 2*TMath::Pi() ; 
+ const int   nPhiBins = Flow::nPhiBins ;  // 120 
+ TString* histTitle ;
+
+ for(int k = 0; k < Flow::nSels; k++)
+ {
+  for(int j = 0; j < Flow::nHars; j++) 
+  {
+   // Creates PhiWgt Histograms
+
+   // Tpc (plus)
+   histTitle = new TString("Flow_Phi_Weight_TPCplus_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistPhiWgtPlus = new TH1D(histTitle->Data(),histTitle->Data(), nPhiBins, phiMin, phiMax);
+   histFull[k].histFullHar[j].mHistPhiWgtPlus->Sumw2();
+   histFull[k].histFullHar[j].mHistPhiWgtPlus->SetXTitle("Azimuthal Angles (rad)");
+   histFull[k].histFullHar[j].mHistPhiWgtPlus->SetYTitle("PhiWgt");
+   delete histTitle;
+   // Tpc (minus)
+   histTitle = new TString("Flow_Phi_Weight_TPCminus_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistPhiWgtMinus = new TH1D(histTitle->Data(),histTitle->Data(), nPhiBins, phiMin, phiMax);
+   histFull[k].histFullHar[j].mHistPhiWgtMinus->Sumw2();
+   histFull[k].histFullHar[j].mHistPhiWgtMinus->SetXTitle("Azimuthal Angles (rad)");
+   histFull[k].histFullHar[j].mHistPhiWgtMinus->SetYTitle("PhiWgt");
+   delete histTitle;
+   // Tpc (cross)
+   histTitle = new TString("Flow_Phi_Weight_TPCcross_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistPhiWgtAll = new TH1D(histTitle->Data(),histTitle->Data(), nPhiBins, phiMin, phiMax);
+   histFull[k].histFullHar[j].mHistPhiWgtAll->Sumw2();
+   histFull[k].histFullHar[j].mHistPhiWgtAll->SetXTitle("Azimuthal Angles (rad)");
+   histFull[k].histFullHar[j].mHistPhiWgtAll->SetYTitle("PhiWgt");
+   delete histTitle;
+
+   // Tpc
+   histTitle = new TString("Flow_Phi_Weight_TPC_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistPhiWgt = new TH1D(histTitle->Data(),histTitle->Data(), nPhiBins, phiMin, phiMax);
+   histFull[k].histFullHar[j].mHistPhiWgt->Sumw2();
+   histFull[k].histFullHar[j].mHistPhiWgt->SetXTitle("Azimuthal Angles (rad)");
+   histFull[k].histFullHar[j].mHistPhiWgt->SetYTitle("PhiWgt");
+   delete histTitle;
+
+   // Calculate PhiWgt
+   double meanPlus  = histFull[k].histFullHar[j].mHistPhiPlus->Integral() / (double)nPhiBins ;
+   double meanMinus = histFull[k].histFullHar[j].mHistPhiMinus->Integral() / (double)nPhiBins ;
+   double meanCross = histFull[k].histFullHar[j].mHistPhiAll->Integral() / (double)nPhiBins ;
+
+   double meanTPC = histFull[k].histFullHar[j].mHistPhi->Integral() / (double)nPhiBins ;
+
+   // Tpc
+   for (int i=0;i<nPhiBins;i++) 
+   {
+    histFull[k].histFullHar[j].mHistPhiWgtPlus->SetBinContent(i+1,meanPlus);
+    histFull[k].histFullHar[j].mHistPhiWgtPlus->SetBinError(i+1, 0.);
+    histFull[k].histFullHar[j].mHistPhiWgtMinus->SetBinContent(i+1,meanMinus);
+    histFull[k].histFullHar[j].mHistPhiWgtMinus->SetBinError(i+1, 0.);
+    histFull[k].histFullHar[j].mHistPhiWgtAll->SetBinContent(i+1,meanCross);
+    histFull[k].histFullHar[j].mHistPhiWgtAll->SetBinError(i+1, 0.);
+
+    histFull[k].histFullHar[j].mHistPhiWgt->SetBinContent(i+1,meanTPC);
+    histFull[k].histFullHar[j].mHistPhiWgt->SetBinError(i+1, 0.);
+   }
+   histFull[k].histFullHar[j].mHistPhiWgtPlus->Divide(histFull[k].histFullHar[j].mHistPhiPlus);
+   mPhiWgtHistList->AddLast(histFull[k].histFullHar[j].mHistPhiWgtPlus);
+   histFull[k].histFullHar[j].mHistPhiWgtMinus->Divide(histFull[k].histFullHar[j].mHistPhiMinus);
+   mPhiWgtHistList->AddLast(histFull[k].histFullHar[j].mHistPhiWgtMinus);
+   histFull[k].histFullHar[j].mHistPhiWgtAll->Divide(histFull[k].histFullHar[j].mHistPhiAll);
+   mPhiWgtHistList->AddLast(histFull[k].histFullHar[j].mHistPhiWgtAll);
+
+   histFull[k].histFullHar[j].mHistPhiWgt->Divide(histFull[k].histFullHar[j].mHistPhi);
+   mPhiWgtHistList->AddLast(histFull[k].histFullHar[j].mHistPhiWgt);
+  }
+ }
+ if(Debug2) { mPhiWgtHistList->ls() ; }
+
+ // Write PhiWgt histograms
+ TString wgtName ;
+ if(mRedoWgt) { wgtName = "new." ; }
+ else        { wgtName = "" ; }
+ wgtName += GetPhiWgtFileName() ;
+ TFile* phiWgtFile = new TFile(wgtName.Data(), "RECREATE");
+ phiWgtFile->cd() ; mPhiWgtHistList->Write();
+ delete mPhiWgtHistList ; delete wgtName ;
+ // Write Bayesian Weights for P.Id.
+ phiWgtFile->cd() ; 
+ for(int k=0;k<Flow::nSels;k++) { histFull[k].mHistBayPidMult->Write() ; }
+ phiWgtFile->Close();
+
+ if(Debug1) { cout << FlowAnalysis << "Done . " << endl ; cout << endl ; }
+
+ return ;
+}
+//----------------------------------------------------------------------
+void AliFlowAnalysisMaker::GetRunBayesian(Double_t bayes[Flow::nPid],int sel)  
+{
+ // Returns the normalized particle abundance of all the events.
+ // This is called at the end of the analysis.
+
+ if(sel>Flow::nSels) 
+ { 
+  if(Debug1) { cout << "Wrong Selection! " << endl ; } 
+  return ; 
+ }
+ Double_t totCount = histFull[sel].mHistBayPidMult->GetSumOfWeights() ;
+ for(int i=0;i<Flow::nPid;i++)
+ {
+  if(totCount) { bayes[i] = histFull[sel].mHistBayPidMult->GetBinContent(i+1) / totCount ; }
+  else         { bayes[i] = 1. ; }
+ }
+ return ;
+}
+//----------------------------------------------------------------------
+void AliFlowAnalysisMaker::PrintRunBayesian(int sel)  
+{
+ // Prints the normalized particle abundance of all the events (at this step).
+
+ if(sel>Flow::nSels) 
+ { 
+  if(Debug1) { cout << "Wrong Selection! " << endl ; } 
+  return ; 
+ }
+ Double_t totCount = histFull[sel].mHistBayPidMult->GetSumOfWeights() ;
+ Char_t* names[Flow::nPid] = {"e","mu","pi","k","p","d"} ;
+ Double_t bayes = 0. ;
+ cout << "  " ;
+ for(int i=0;i<Flow::nPid;i++)
+ {
+  if(totCount) { bayes = histFull[sel].mHistBayPidMult->GetBinContent(i+1) / totCount ; }
+  else         { bayes = 1. ; }
+  cout << bayes << "_" << names[i] << " ; " ;
+ }
+ cout << endl ;
+ return ;
+}
+//-----------------------------------------------------------------------
+// ###
+//-----------------------------------------------------------------------
+Bool_t AliFlowAnalysisMaker::Open(const Char_t* filename)              
+{
+ // Checks/Opens the FlowEvents file for analysis. Sets the n. of events 
+ // (for the loop) and sets the internal counter evtN to 0.
+
+ if(Debug1) { cout << spaces << "...opening file . " << endl ; }
+ //if(pFlowEventsFile) { if(Debug1) { cout << spaces << "...file already open (I'll go on) . " << endl ; } return kTRUE ; } 
+ if(Debug0)  { cout << FlowAnalysis << "Opening input-File :  " << filename << "  . " << endl ; }
+ pFlowEventsFile = new TFile(filename ,"READ") ; 
+ if(!pFlowEventsFile || pFlowEventsFile->IsZombie())
+ {
+  if(Debug0) { cout << FlowAnalysis << "flow events file NOT FOUND ( " << filename << " ) . " << endl ; }
+  return kFALSE ;
+ }
+ else
+ {
+  nEvents = pFlowEventsFile->GetNkeys() ; 
+  pFlowEventsList = (TList*)pFlowEventsFile->GetListOfKeys() ; 
+  evtN = 0 ;  
+  if(Debug0) { cout << spaces << "file: " << GetInputFileName().Data() << " , found " << nEvents << " Flow Events . " << endl ; }
+  if(Debug2) { pFlowEventsFile->ls() ; } //if(Debug2) { cout << " Lista : " << endl ; pFlowEventsList->Dump() ; }
+ }
+ if(Debug0) { cout << endl ; }
+
+ return kTRUE ;
+}
+//-----------------------------------------------------------------------
+AliFlowEvent* AliFlowAnalysisMaker::GetEvt(Int_t evt)         
+{
+ // Gets the FlowEvent n.evt from file, loads Tracks and V0s arrays into memory
+ // if evt is not specified, gets the next event basing on the internal counter evtN (0...N)
+ if(Debug1) { cout << spaces << "Getting Event " << evt << " . " << endl ; } 
+ if(!pFlowEventsFile) { return 0 ; }    // if no file open -> quit!
+ else
+ {
+  if(evt>=0) { evtN = evt ; }   // specified event "evt" is selected, the iterator "evtN" changes accordingly
+  //evt_name = "ev" ; evt_name += evtN ;
+  if(evtN<nEvents) //&& (pFlowEventsFile->GetKey(evt_name)))
+  {
+   // gets the name of the key
+   evt_name = pFlowEventsList->At(evtN)->GetName() ;
+   if(Debug1) { cout << "####" << endl ; cout << evt_name << endl ; cout << "####" << endl ; }
+
+   // gets the event from file
+   pFlowEventsFile->GetObject(evt_name.Data(),pFlowEvent) ;                    // new way
+   //pFlowEvent = (AliFlowEvent*)pFlowEventsFile->Get(evt_name.Data()) ;       // old way
+
+   if(Debug2) { cout << "     dumping: " << endl ; pFlowEvent->Dump() ; cout << endl ; }
+    
+   // loading tracks and v0s collections
+   pFlowTracks = pFlowEvent->TrackCollection() ; 
+   nTracks = pFlowTracks->GetEntries() ;
+   if(Debug1) { cout << FlowAnalysis << "event: " << evt_name.Data() << " , found " << nTracks << " Flow Tracks . " << endl ; }
+   pFlowV0s = pFlowEvent->V0Collection() ; 
+   nV0s = pFlowV0s->GetEntries() ;
+   if(Debug1) { cout << FlowAnalysis << "event: " << evt_name.Data() << " , found " << nV0s << " Flow V0s . " << endl ; }
+  }
+  else 
+  { 
+   cout << FlowAnalysis << "! no event !" << endl ; 
+   return 0 ;
+  }
+ }
+ return pFlowEvent ;
+}
+//-----------------------------------------------------------------------
+Bool_t AliFlowAnalysisMaker::Analyze(AliFlowEvent* pFlowEvent)         
+{
+ // Runs the analysis on a single AliFlowEvent (pointer given). 
+ // In principle this method can be used externally by the 
+ // AliSelectorFlow for on-fly analysis.
+//
+cout << "* 1 . " << endl ;
+//
+ if(pFlowSelect->Select(pFlowEvent))              // event selected - here below the ANALYSIS FLAGS are setted -
+ {
+//
+cout << "* 2 . " << endl ;
+//
+  if(mReadPhiWgt)                                       // if weights file is there (previously checked by WgtChk()
+  { 
+   if(mPhiWgt)    { FillEvtPhiWgt() ;  }                // pFlowEvent->SetPhiWgt(...)
+   if(mOnePhiWgt) { pFlowEvent->SetOnePhiWgt() ; }      // one phi-wgt histogram
+   else          { pFlowEvent->SetFirstLastPhiWgt() ; } // three phi-wgt histogram
+  }
+  if(mBayWgt)    { FillBayesianWgt() ; }                // pFlowEvent->SetBayesian(...)
+  if(mRePid)     { pFlowEvent->SetPids() ; }            // re-calculate all p.id. hypotesis with the (new) bayesian array
+
+  if(mPtWgt)     { pFlowEvent->SetPtWgt(); ; }          // pT as a weight
+  if(mEtaWgt)    { pFlowEvent->SetEtaWgt() ; }          // eta as a weight
+
+  pFlowEvent->SetSelections(pFlowSelect) ;              // does the selection of tracks for r.p. calculation (sets flags in AliFlowTrack)
+  if(mShuffle)    { pFlowEvent->RandomShuffle() ; }     // tracks re-shuffling
+  pFlowEvent->SetEtaSubs(mEtaSub) ;                     // setting for the subevents (eta or random)
+  pFlowEvent->MakeSubEvents() ;                         // makes the subevent, eta or random basing on the previous flag
+
+  if(mMakeAll)
+  {
+   if(Debug1) { cout << FlowAnalysis << "All calculation in one shoot for ev." << evtN << " . " << endl ; }
+   pFlowEvent->MakeAll() ; 
+  }
+  else 
+  {
+   if(Debug1) { cout << FlowAnalysis << "Single calls for each Q,Psi,... for ev." << evtN << " . " << endl ; }
+  }
+  if(FillFromFlowEvent())                         // calculates event quantities
+  {
+//  
+cout << "* 3 . " << endl ;
+//
+   FillEventHistograms();                         // fill histograms from AliFlowEvents
+   FillParticleHistograms();                      // fill histograms from AliFlowTracks
+   if(mV0)       { FillV0Histograms() ; }         // fill histograms from AliFlowV0s 
+   if(mLabelling) { FillLabels() ; }              // fill the histogram of MC labels (from the simulation)
+  }
+  else 
+  {
+   cout << FlowAnalysis << "Event psi = 0 . " << endl ; 
+   cout << FlowAnalysis << "                           Skipping! " << endl ; 
+   return kFALSE ;
+  }
+  
+ }
+ else 
+ {
+  if(Debug1) { cout << FlowAnalysis << "Event  ev" << evtN << " discarded . " << endl ; }
+  delete pFlowEvent  ; pFlowEvent = 0 ; 
+  return kFALSE ;
+ }
+ return kTRUE ;
+}
+//-----------------------------------------------------------------------
+Bool_t AliFlowAnalysisMaker::FillFromFlowEvent()
+{
+ // gets event quantities ;
+
+ if(Debug1) { cout << spaces << "Getting Event quantities . " << endl ; } 
+ Int_t selCheck = 0 ;
+ for(int k = 0; k < Flow::nSels; k++) 
+ {
+  pFlowSelect->SetSelection(k) ;
+  for(int j = 0; j < Flow::nHars; j++) 
+  {
+   pFlowSelect->SetHarmonic(j) ;
+   for(int n = 0; n < Flow::nSubs; n++) 
+   {
+    pFlowSelect->SetSubevent(n) ;
+    mPsiSub[n][k][j] = pFlowEvent->Psi(pFlowSelect) ;          // sub-event quantities
+    mMultSub[n][k][j] = pFlowEvent->Mult(pFlowSelect) ;
+   }
+   pFlowSelect->SetSubevent(-1);
+   mQ[k][j]    = pFlowEvent->Q(pFlowSelect) ;          // full event quantities
+   mPsi[k][j]  = pFlowEvent->Psi(pFlowSelect) ;
+   m_q[k][j]   = pFlowEvent->NormQ(pFlowSelect).Mod() ; // was: pFlowEvent->q(pFlowSelect) ; // but the normalization was bad (no pT,eta weight)
+   mMult[k][j] = pFlowEvent->Mult(pFlowSelect) ;
+   selCheck += mMult[k][j] ; 
+  }
+ }
+ if(!selCheck) { return kFALSE ; }                     // if there are no particles in the selection -> skip the event
+ if(Debug1)                                            // prints event by event calculated quantities
+ {
+  cout << FlowAnalysis << "Read from FlowEvent : " << endl ;
+  cout << endl ; cout << spaces << "mQ[k][j] = " ; 
+  for(int k=0;k<Flow::nSels;k++) 
+  {
+   for(int j=0;j<Flow::nHars;j++) 
+   { 
+    cout << (Float_t)mQ[k][j].X() << "," << (Float_t)mQ[k][j].Y() << " ; " ; 
+   }
+   cout << endl ;
+   cout << spaces << "            " ; 
+  }
+  cout << endl ; cout << spaces << "mPsi[k][j] = " ; 
+  for(int k=0;k<Flow::nSels;k++) 
+  {
+   for(int j=0;j<Flow::nHars;j++) { Float_t aaa = (Float_t)mPsi[k][j] ; cout << aaa << " , " ; }
+   cout << endl ;
+   cout << spaces << "              " ; 
+  }
+  cout << endl ; cout << spaces << "m_q[k][j] = " ; 
+  for(int k=0;k<Flow::nSels;k++) 
+  {
+   for(int j=0;j<Flow::nHars;j++) { Float_t aaa = (Float_t)m_q[k][j] ; cout << aaa << " , " ; }
+   cout << endl ;
+   cout << spaces << "             " ; 
+  }
+  cout << endl ; cout << spaces << "mMult[k][j] = " ; 
+  for(int k=0;k<Flow::nSels;k++) 
+  {
+   for(int j=0;j<Flow::nHars;j++) { Float_t aaa = (Float_t)mMult[k][j] ; cout << aaa << " , " ; } 
+   cout << endl ;
+   cout << spaces << "               " ; 
+  }
+  if(Debug1)
+  {
+   cout << endl ; cout << spaces << "mMultSub[n][k][j] = " ; 
+   for(int n=0;n<Flow::nSubs;n++) 
+   {
+    for(int k=0;k<Flow::nSels;k++) 
+    {
+     for(int j=0;j<Flow::nHars;j++) { Float_t aaa = mMultSub[n][k][j] ; cout << aaa << " , " ; } 
+     cout << endl ;
+     cout << spaces << "                 " ; 
+    }
+   }
+   cout << endl ; cout << spaces << "mPsiSub[n][k][j] = " ; 
+   for(int n=0;n<Flow::nSubs;n++) 
+   {
+    for(int k=0;k<Flow::nSels;k++) 
+    {
+     for(int j=0;j<Flow::nHars;j++) { Float_t aaa = mPsiSub[n][k][j] ; cout << aaa << " , " ; } 
+     cout << endl ;
+     cout << spaces << "                 " ; 
+    }
+   }
+   cout << endl ; cout << spaces << "Delta_PsiSub[k][j] = " ; 
+   for(int k=0;k<Flow::nSels;k++) 
+   {
+    for(int j=0;j<Flow::nHars;j++) { Float_t aaa = mPsiSub[0][k][j]-mPsiSub[1][k][j] ; cout << aaa << " , " ; } 
+    cout << endl ;
+    cout << spaces << "                  " ; 
+   }
+  }
+  cout << endl ;
+ }
+ return kTRUE ;
+}
+//-------------------------------------------------------------
+void AliFlowAnalysisMaker::FillEventHistograms()    
+{
+ // event histograms
+
+ if(Debug1) { cout << spaces << "Event Histograms . " << endl ; } 
+
+ Float_t trigger = (Float_t)pFlowEvent->L0TriggerWord() ;
+ mHistTrigger->Fill(trigger);
+
+ // no selections: OrigMult, Centrality, Mult, MultOverOrig, VertexZ, VertexXY
+ int origMult = pFlowEvent->OrigMult();
+ mHistOrigMult->Fill((float)origMult);
+ mHistMultEta->Fill((float)pFlowEvent->MultEta());
+
+ int cent = pFlowEvent->Centrality();
+ mHistCent->Fill((float)cent);
+
+ mHistMult->Fill((float)nTracks) ;
+ mHistV0Mult->Fill((float)nV0s) ;
+ if(origMult) { mHistMultOverOrig->Fill((float)nTracks/(float)origMult) ; }
+
+ pFlowEvent->VertexPos(vertex) ;
+ mHistVertexZ->Fill(vertex[2]) ;
+ mHistVertexXY2D->Fill(vertex[0],vertex[1]) ;
+
+ // ZDC info
+ mHistPartZDC->Fill(pFlowEvent->ZDCpart()) ;
+ for(int ii=0;ii<3;ii++) { mHistEnergyZDC->Fill(ii,pFlowEvent->ZDCenergy(ii)) ; }
+
+ // sub-event Psi_Subs
+ for(int k = 0; k < Flow::nSels; k++) 
+ {
+  for(int j = 0; j < Flow::nHars; j++) 
+  {
+   for(int n = 0; n < Flow::nSubs; n++) 
+   {
+    int iii = Flow::nSubs * k + n ;    //cout << "  " << k << j << n << " , " << iii << endl ;
+    histSub[iii].histSubHar[j].mHistPsiSubs->Fill(mPsiSub[n][k][j]) ;
+   }
+  }
+ }
+
+ // full event Psi, PsiSubCorr, PsiSubCorrDiff, cos, mult, q
+ for(int k = 0; k < Flow::nSels; k++) 
+ {
+  for(int j = 0; j < Flow::nHars; j++) 
+  {
+   float order = (float)(j+1);
+   histFull[k].histFullHar[j].mHistPsi->Fill(mPsi[k][j]);
+   if(k<2 && j<2)
+   {
+    if(k==0) 
+    { 
+     float psi1 = mPsi[0][j] ; 
+     float psi2 = mPsi[1][j] ;
+     float diff = psi1 - psi2 ;
+     if(diff < -TMath::Pi()/(j+1))      { diff += 2*TMath::Pi()/(j+1) ; } 
+     else if(diff > +TMath::Pi()/(j+1)) { diff -= 2*TMath::Pi()/(j+1) ; }
+     histFull[k].histFullHar[j].mHistPsi_Diff->Fill(diff) ; // k=0
+    } 
+    else if(k==1) 
+    {
+     float psi1 ; float psi2 ;
+     if (j==0)     { psi1 = mPsi[0][0] ; psi2 = mPsi[1][1] ; }  
+     else if(j==1) { psi1 = mPsi[0][0] ; psi2 = mPsi[0][1] ; }
+     float diff = psi1 - psi2 ;
+     diff = (TMath::Abs(diff) > TMath::Pi()) ? ((diff > 0.) ? -(2*TMath::Pi()-diff) : -(diff+2*TMath::Pi())) : diff ;
+     histFull[k].histFullHar[j].mHistPsi_Diff->Fill(diff) ; // k=1
+    }     
+   }
+
+   if(mPsiSub[0][k][j] != 0. && mPsiSub[1][k][j] != 0.)
+   {
+    float psiSubCorr;                          // this is:  delta_Psi
+    if(mV1Ep1Ep2 == kFALSE || order != 1) 
+    {
+     psiSubCorr = mPsiSub[0][k][j] - mPsiSub[1][k][j];
+    }
+    else // i.e. (mV1Ep1Ep2 == kTRUE && order == 1)
+    { 
+     psiSubCorr = mPsiSub[0][k][0] + mPsiSub[1][k][0] - 2*mPsi[k][1];
+    }
+    histFull[k].mHistCos->Fill(order, (float)cos(order * psiSubCorr)) ;
+    if(psiSubCorr < 0.)                 { psiSubCorr += 2*TMath::Pi()/order ; }
+    if(psiSubCorr > 2*TMath::Pi()/order) { psiSubCorr -= 2*TMath::Pi()/order ; } // for v1Ep1Ep2 which gives -2*TMath::Pi() < psiSubCorr < 2*2*TMath::Pi()
+    histFull[k].histFullHar[j].mHistPsiSubCorr->Fill(psiSubCorr);
+   }
+
+   if(j < Flow::nHars - 1) // subevents of different harmonics
+   {
+    int j1, j2;
+    float psiSubCorrDiff;
+    if(j==0)     { j1 = 1, j2 = 2 ; } 
+    else if(j==1) { j1 = 1, j2 = 3 ; } 
+    else if(j==2) { j1 = 2, j2 = 4 ; }
+    psiSubCorrDiff = fmod((double)mPsiSub[0][k][j1-1],2*TMath::Pi()/(double)j2)-fmod((double)mPsiSub[1][k][j2-1],2*TMath::Pi()/(double)j2) ;
+    if(psiSubCorrDiff < 0.) { psiSubCorrDiff += 2*TMath::Pi()/(float)j2 ; }
+    histFull[k].histFullHar[j].mHistPsiSubCorrDiff->Fill(psiSubCorrDiff) ;
+    psiSubCorrDiff = fmod((double)mPsiSub[0][k][j2-1],2*TMath::Pi()/(double)j2)-fmod((double)mPsiSub[1][k][j1-1],2*TMath::Pi()/(double)j2) ;
+    if(psiSubCorrDiff < 0.) { psiSubCorrDiff += 2*TMath::Pi()/(float)j2 ; }
+    histFull[k].histFullHar[j].mHistPsiSubCorrDiff->Fill(psiSubCorrDiff) ;
+   }
+   
+   histFull[k].histFullHar[j].mHistMult->Fill((float)mMult[k][j]) ;
+   histFull[k].histFullHar[j].mHist_q->Fill(m_q[k][j]) ;
+  }
+ }
+ if(Debug1) { cout << FlowAnalysis << "Event  " << (pFlowEvent->GetName()) << endl ; }
+}
+//-----------------------------------------------------------------------
+void AliFlowAnalysisMaker::FillParticleHistograms() 
+{
+ // tracks histograms
+
+ if(Debug0) { cout << spaces << "Tracks Loop . " << endl ; } 
+
+ float corrMultUnit   = 0. ;
+ float corrMultN      = 0. ;
+ float etaSymPosTpcN  = 0. ;
+ float etaSymNegTpcN  = 0. ;
+ float etaSymPosTpcNpart = 0. ;
+ float etaSymNegTpcNpart = 0. ;
+ float hPlusN        = 0. ;
+ float hMinusN        = 0. ;
+ float piPlusN        = 0. ;
+ float piMinusN       = 0. ;
+ float protonN        = 0. ;
+ float pbarN         = 0. ;
+ float kMinusN        = 0. ;
+ float kPlusN        = 0. ;
+ float deuteronN      = 0. ;
+ float dbarN         = 0. ;
+ float electronN      = 0. ;
+ float positronN      = 0. ;
+ float muonMinusN     = 0. ;
+ float muonPlusN      = 0. ;
+ int numPid = -1 ;
+
+ mOnlyConstrainable = pFlowSelect->JustLoopConstrainable() ;
+ if(Debug1) { cout << spaces << "Looping over " << nTracks << "  flow tracks  " ; if(mOnlyConstrainable) { cout << " (just constrainable) " ; } cout << ". " << endl ; } 
+ int itr ;
+ for(itr=0;itr<nTracks;itr++) 
+ {
+  pFlowTrack = (AliFlowTrack*)pFlowTracks->At(itr) ;   if(Debug2) { cout << "Track n. " << itr << endl ; pFlowTrack->Dump() ; }
+  
+  bool constrainable = pFlowTrack->IsConstrainable() ;  if(Debug2) {  
+                                                        if(constrainable) { cout << "Constrainable" << endl ; }
+                                                        else              { cout << "UnConstrainable" << endl ; }
+                                                       }
+  if(mOnlyConstrainable && !constrainable) { continue ; } 
+  
+  int label = pFlowTrack->Label() ;                    if(Debug2) { cout << itr << " label: " << label << endl ; }
+  if(label>maxLabel) { maxLabel = label ; }             // this has just the purpose to fill a labels histogram
+  // -
+  float dcaGlobal = TMath::Abs(pFlowTrack->Dca()) ;    if(Debug2) { cout << "dcaGlob "  << dcaGlobal << endl ; }               
+  float dcaSigned = pFlowTrack->TransDcaSigned() ;     if(Debug2) { cout << "dcaSigned " << dcaSigned  << endl ; }             
+  float dcaTrans = TMath::Abs(dcaSigned) ;             if(Debug2) { cout << "dcaTrans "  << dcaTrans << endl ; }
+  float eta = pFlowTrack->Eta() ;                      if(Debug2) { cout << "eta "  << eta << endl ; }
+                                                       if(Debug2) { cout << "rapidity " << pFlowTrack->Y() << endl ; }
+  float phi = pFlowTrack->Phi() ;                      if(Debug2) { cout << "Phi "  << phi<< endl ; } 
+  float pt = pFlowTrack->Pt() ;                        if(Debug2) { cout << "Pt  "   << pt << endl ; }
+  float totalp = pFlowTrack->P() ;                     if(Debug2) { cout << "P "    << totalp << endl ; }
+  // float logp = TMath::Log10(totalp) ;
+  float etaGlob = pFlowTrack->EtaGlobal() ;            if(Debug2) { cout << "etaGlobal "  << eta << endl ; }
+                                                       if(Debug2) { cout << "rapidityGlobal " << pFlowTrack->YGlobal() << endl ; }
+  float phiGlob = pFlowTrack->PhiGlobal() ;            if(Debug2) { cout << "PhiGlobal "  << phi<< endl ; } 
+  float ptGlob = pFlowTrack->PtGlobal() ;              if(Debug2) { cout << "PtGlobal  "   << pt << endl ; }
+  float zFirstPoint = pFlowTrack->ZFirstPoint() ;      if(Debug2) { cout << "Zfirst " << zFirstPoint << endl ; }
+  float zLastPoint = pFlowTrack->ZLastPoint() ;        if(Debug2) { cout << "Zlast " << zLastPoint << endl ; }
+  float lenght = pFlowTrack->TrackLength() ;           if(Debug2) { cout << "lenght " << lenght << endl ; }
+  int  charge = pFlowTrack->Charge() ;                 if(Debug2) { cout << "charge " << charge << endl ; }
+  float chi2 = pFlowTrack->Chi2() ;                    if(Debug2) { cout << "chi2 " << chi2 << endl ; } 
+  int  fitPtsTPC = (int)((float)pFlowTrack->FitPtsTPC()) ;     if(Debug2) { cout << "fitPtsTPC " << fitPtsTPC << endl ; }
+  int  maxPtsTPC = pFlowTrack->MaxPtsTPC() ;           if(Debug2) { cout << "maxPtsTPC " << maxPtsTPC << endl ; }          
+  float chi2TPC = pFlowTrack->Chi2TPC() ;              if(Debug2) { cout << "chi2TPC " << chi2TPC << endl ; }
+  int  fitPtsITS = pFlowTrack->FitPtsITS() ;           if(Debug2) { cout << "fitPtsITS " << fitPtsITS << endl ; }      
+  int  maxPtsITS = pFlowTrack->MaxPtsITS() ;           if(Debug2) { cout << "maxPtsITS " << maxPtsITS << endl ; }  
+  float chi2ITS = pFlowTrack->Chi2ITS() ;              if(Debug2) { cout << "chi2ITS " << chi2ITS << endl ; }
+  int  fitPtsTRD = pFlowTrack->NhitsTRD() ;            if(Debug2) { cout << "fitPtsTRD " << fitPtsTRD << endl ; }
+  int  maxPtsTRD = pFlowTrack->MaxPtsTRD() ;           if(Debug2) { cout << "maxPtsTRD " << maxPtsTRD << endl ; }          
+  float chi2TRD = pFlowTrack->Chi2TRD() ;              if(Debug2) { cout << "chi2TRD " << chi2TRD << endl ; }
+  int  fitPtsTOF = pFlowTrack->NhitsTOF() ;            if(Debug2) { cout << "fitPtsTOF " << fitPtsTOF << endl ; }
+  int  maxPtsTOF = pFlowTrack->MaxPtsTOF() ;           if(Debug2) { cout << "maxPtsTOF " << maxPtsTOF << endl ; }          
+  float chi2TOF = pFlowTrack->Chi2TOF() ;              if(Debug2) { cout << "chi2TOF " << chi2TOF << endl ; }
+  float dEdx = pFlowTrack->DedxTPC() ;                         if(Debug2) { cout << "dEdxTPC " << dEdx << endl ; }
+  float its = pFlowTrack->DedxITS() ;                  if(Debug2) { cout << "dEdxITS " << its << endl ; }
+  float trd = pFlowTrack->SigTRD() ;                   if(Debug2) { cout << "SigTRD " << trd << endl ; }
+  float tof = pFlowTrack->TofTOF() ;                   if(Debug2) { cout << "TofTOF " << tof << endl ; }
+
+  float lpTPC = 0 ; if(pFlowTrack->PatTPC()>0) { lpTPC = TMath::Log10(pFlowTrack->PatTPC()) ; }
+                                                       if(Debug2) { cout << "log(pTPC) " << lpTPC << endl ; }                                                  
+  float lpITS = 0 ; if(pFlowTrack->PatITS()>0) { lpITS = TMath::Log10(pFlowTrack->PatITS()) ; }
+                                                       if(Debug2) { cout << "log(pTPC) " << lpITS << endl ; }
+  float lpTRD = 0 ; if(pFlowTrack->PatTRD()>0) { lpTRD = TMath::Log10(pFlowTrack->PatTRD()) ; }
+                                                       if(Debug2) { cout << "log(pTPC) " << lpTRD << endl ; }
+  float lpTOF = 0 ; if(pFlowTrack->PatTOF()>0) { lpTOF = TMath::Log10(pFlowTrack->PatTOF()) ; }
+                                                       if(Debug2) { cout << "log(pTPC) " << lpTOF << endl ; }  
+  
+  float invMass = pFlowTrack->InvMass() ;              if(Debug2) { cout << "InvMass " << invMass << endl ; }
+  Char_t pid[10]="0" ; strcpy(pid,pFlowTrack->Pid()) ;         if(Debug2) { cout << "pid "  << pid << endl ; }   
+
+  // no selections: Charge, Dca, Chi2, FitPts, MaxPts, FitOverMax, PID
+  mHistCharge->Fill((float)charge);
+  mHistDcaGlobal->Fill(dcaGlobal);
+  mHistDca->Fill(dcaTrans) ;
+  mHistTransDca->Fill(dcaSigned);
+  mHistChi2->Fill(chi2);
+  
+  // - here ITS   (chi2 & nHits)
+  mHistChi2ITS->Fill(chi2ITS);
+  mHistChi2normITS->Fill(chi2ITS/((float)fitPtsITS-5.));  // 5 is the # of parameters in the track fit
+  mHistFitPtsITS->Fill((float)fitPtsITS);
+  mHistMaxPtsITS->Fill((float)maxPtsITS);
+
+  // - here TPC   (chi2 & nHits)
+  mHistChi2TPC->Fill(chi2TPC);
+  mHistChi2normTPC->Fill(chi2TPC/((float)fitPtsTPC-5.));
+  mHistFitPtsTPC->Fill((float)fitPtsTPC);
+  mHistMaxPtsTPC->Fill((float)maxPtsTPC);
+  if(maxPtsTPC) { mHistFitOverMaxTPC->Fill((float)(fitPtsTPC)/(float)maxPtsTPC) ; }
+
+  // - here TRD  (chi2 & nHits)
+  mHistChi2TRD->Fill(chi2TRD);
+  mHistChi2normTRD->Fill(chi2TRD/((float)fitPtsTRD-5.));
+  mHistFitPtsTRD->Fill((float)fitPtsTRD);
+  mHistMaxPtsTRD->Fill((float)maxPtsTRD);
+
+  // - here TOF   (chi2 & nHits)
+  mHistChi2TOF->Fill(chi2TOF);
+  mHistChi2normTOF->Fill(chi2TOF/((float)fitPtsTOF-5.));
+  mHistFitPtsTOF->Fill((float)fitPtsTOF);
+  mHistMaxPtsTOF->Fill((float)maxPtsTOF);
+  
+  // fit over max (all)
+  int maxPts = maxPtsITS + maxPtsTPC + maxPtsTRD + maxPtsTOF ;
+  int fitPts = fitPtsITS + fitPtsTPC + fitPtsTRD + fitPtsTOF ;
+  if(maxPts) { mHistFitOverMax->Fill((float)(fitPts)/(float)maxPts) ; }
+  
+  // lenght
+  mHistLenght->Fill(lenght) ;
+  mHistInvMass->Fill(invMass) ;
+
+  // PID histograms & multiplicity count (for bayesian histogram)
+  if(charge == 1) 
+  {
+   hPlusN++ ;
+   mHistMeanDedxPos2D->Fill(lpTPC, dEdx) ;
+   mHistMeanDedxPos2DITS->Fill(lpITS, its) ;
+   mHistMeanDedxPos2DTRD->Fill(lpTRD, trd) ;
+   mHistMeanDedxPos2DTOF->Fill(lpTOF, tof) ;
+   //
+   float positron  = pFlowTrack->ElectronPositronProb() ;
+   mHistPidPositron->Fill(positron) ;
+   if(strcmp(pid, "e+") == 0) 
+   {
+    numPid = 0 ; positronN++ ; mHistPidPt->Fill(1.5,pt) ;
+    mHistMeanTPCPositron->Fill(lpTPC, dEdx) ;
+    mHistMeanITSPositron->Fill(lpITS, its);
+    mHistMeanTRDPositron->Fill(lpTRD, trd);
+    mHistMeanTOFPositron->Fill(invMass, tof);
+    mHistPidPositronPart->Fill(positron) ;
+   }
+   float muonPlus  = pFlowTrack->MuonPlusMinusProb() ;
+   mHistPidMuonPlus->Fill(muonPlus) ;
+   if(strcmp(pid, "mu+") == 0) 
+   {
+    numPid = 1 ; muonPlusN++ ; mHistPidPt->Fill(3.5,pt) ; 
+    mHistMeanTPCMuonPlus->Fill(lpTPC, dEdx) ;
+    mHistMeanITSMuonPlus->Fill(lpITS, its);
+    mHistMeanTRDMuonPlus->Fill(lpTRD, trd);
+    mHistMeanTOFMuonPlus->Fill(invMass, tof);
+    mHistPidMuonPlusPart->Fill(muonPlus) ;
+   }
+   float piPlus = pFlowTrack->PionPlusMinusProb() ;
+   mHistPidPiPlus->Fill(piPlus) ;
+   if(strcmp(pid, "pi+") == 0) 
+   { 
+    numPid = 2 ; piPlusN++ ; mHistPidPt->Fill(5.5,pt) ;
+    mHistMeanTPCPiPlus->Fill(lpTPC, dEdx) ;
+    mHistMeanITSPiPlus->Fill(lpITS, its);
+    mHistMeanTRDPiPlus->Fill(lpTRD, trd);
+    mHistMeanTOFPiPlus->Fill(invMass, tof);
+    mHistPidPiPlusPart->Fill(piPlus) ;
+   }
+   float kplus  = pFlowTrack->KaonPlusMinusProb() ;
+   mHistPidKplus->Fill(kplus) ;
+   if(strcmp(pid, "k+") == 0) 
+   {
+    numPid = 3 ; kPlusN++ ; mHistPidPt->Fill(7.5,pt) ; 
+    mHistMeanTPCKplus->Fill(lpTPC, dEdx) ;
+    mHistMeanITSKplus->Fill(lpITS, its);
+    mHistMeanTRDKplus->Fill(lpTRD, trd);
+    mHistMeanTOFKplus->Fill(invMass, tof);
+    mHistPidKplusPart->Fill(kplus) ;
+   }
+   float proton  = pFlowTrack->ProtonPbarProb() ;
+   mHistPidProton->Fill(proton) ;
+   if(strcmp(pid, "pr+") == 0) 
+   {
+    numPid = 4 ; protonN++ ; mHistPidPt->Fill(9.5,pt) ;  
+    mHistMeanTPCProton->Fill(lpTPC, dEdx) ;
+    mHistMeanITSProton->Fill(lpITS, its);
+    mHistMeanTRDProton->Fill(lpTRD, trd);
+    mHistMeanTOFProton->Fill(invMass, tof);
+    mHistPidProtonPart->Fill(proton) ;
+   }
+   float deuteron  = pFlowTrack->DeuteriumAntiDeuteriumProb() ;
+   mHistPidDeuteron->Fill(deuteron) ;
+   if(strcmp(pid, "d+") == 0) 
+   {
+    numPid = 6 ; deuteronN++ ; mHistPidPt->Fill(11.5,pt) ; 
+    mHistMeanTPCDeuteron->Fill(lpTPC, dEdx) ;
+    mHistMeanITSDeuteron->Fill(lpITS, its);
+    mHistMeanTRDDeuteron->Fill(lpTRD, trd);
+    mHistMeanTOFDeuteron->Fill(invMass, tof);
+    mHistPidDeuteronPart->Fill(deuteron) ;
+   }
+  } 
+  else if(charge == -1) 
+  {
+   hMinusN++ ;
+   mHistMeanDedxNeg2D->Fill(lpTPC, dEdx) ;
+   mHistMeanDedxNeg2DITS->Fill(lpITS, its) ;
+   mHistMeanDedxNeg2DTRD->Fill(lpTRD, trd) ;
+   mHistMeanDedxNeg2DTOF->Fill(lpTOF, tof) ;
+   //
+   float electron  = pFlowTrack->ElectronPositronProb() ;
+   mHistPidElectron->Fill(electron);
+   if(strcmp(pid, "e-") == 0) 
+   {
+    numPid = 0 ; electronN++ ; mHistPidPt->Fill(0.5,pt) ; 
+    mHistMeanTPCElectron->Fill(lpTPC, dEdx);
+    mHistMeanITSElectron->Fill(lpITS, its);
+    mHistMeanTRDElectron->Fill(lpTRD, trd);
+    mHistMeanTOFElectron->Fill(invMass, tof);
+    mHistPidElectronPart->Fill(electron);
+   }
+   float muonMinus  = pFlowTrack->MuonPlusMinusProb() ;
+   mHistPidMuonMinus->Fill(muonMinus) ;
+   if(strcmp(pid, "mu-") == 0) 
+   {
+    numPid = 1 ; muonMinusN++ ; mHistPidPt->Fill(2.5,pt) ;
+    mHistMeanTPCMuonMinus->Fill(lpTPC, dEdx) ;
+    mHistMeanITSMuonMinus->Fill(lpITS, its);
+    mHistMeanTRDMuonMinus->Fill(lpTRD, trd);
+    mHistMeanTOFMuonMinus->Fill(invMass, tof);
+    mHistPidMuonMinusPart->Fill(muonMinus) ;
+   }
+   float piMinus = pFlowTrack->PionPlusMinusProb() ;
+   mHistPidPiMinus->Fill(piMinus) ;
+   if(strcmp(pid, "pi-") == 0) 
+   {
+    numPid = 2 ; piMinusN++ ; mHistPidPt->Fill(4.5,pt) ;
+    mHistMeanTPCPiMinus->Fill(lpTPC, dEdx);
+    mHistMeanITSPiMinus->Fill(lpITS, its);
+    mHistMeanTRDPiMinus->Fill(lpTRD, trd);
+    mHistMeanTOFPiMinus->Fill(invMass, tof);
+    mHistPidPiMinusPart->Fill(piMinus);
+   }
+   float kminus  = pFlowTrack->KaonPlusMinusProb() ;
+   mHistPidKminus->Fill(kminus);
+   if(strcmp(pid, "k-") == 0) 
+   {
+    numPid = 3 ; kMinusN++ ; mHistPidPt->Fill(6.5,pt) ;
+    mHistMeanTPCKminus->Fill(lpTPC, dEdx);
+    mHistMeanITSKminus->Fill(lpITS, its);
+    mHistMeanTRDKminus->Fill(lpTRD, trd);
+    mHistMeanTOFKminus->Fill(invMass, tof);
+    mHistPidKminusPart->Fill(kminus);
+   }
+   float antiproton  = pFlowTrack->ProtonPbarProb() ;
+   mHistPidAntiProton->Fill(antiproton);
+   if(strcmp(pid, "pr-") == 0) 
+   {
+    numPid = 4 ; pbarN++ ; mHistPidPt->Fill(8.5,pt) ;
+    mHistMeanTPCPbar->Fill(lpTPC, dEdx);
+    mHistMeanITSPbar->Fill(lpITS, its);
+    mHistMeanTRDPbar->Fill(lpTRD, trd);
+    mHistMeanTOFPbar->Fill(invMass, tof);
+    mHistPidAntiProtonPart->Fill(antiproton);
+   }
+   float antideuteron  = pFlowTrack->DeuteriumAntiDeuteriumProb() ;
+   mHistPidAntiDeuteron->Fill(antideuteron);
+   if(strcmp(pid, "d-") == 0) 
+   {
+    numPid = 6 ; dbarN++ ; mHistPidPt->Fill(10.5,pt) ;
+    mHistMeanTPCAntiDeuteron->Fill(lpTPC, dEdx);
+    mHistMeanITSAntiDeuteron->Fill(lpITS, its);
+    mHistMeanTRDAntiDeuteron->Fill(lpTRD, trd);
+    mHistMeanTOFAntiDeuteron->Fill(invMass, tof);
+    mHistPidAntiDeuteronPart->Fill(antideuteron);
+   }
+  }
+  
+  // Yield3D, Yield2D, Eta, Pt, Phi, bayP.Id.
+  mHistPtot->Fill(totalp) ;
+  mHistPt->Fill(pt) ;
+  mHistPhi->Fill(phi);  
+  mHistAllEtaPtPhi3D->Fill(eta, pt, phi) ;
+  mHistYieldAll2D->Fill(eta, pt) ;
+  mHistBayPidMult->Fill(numPid) ;
+  if(constrainable) 
+  { 
+   mHistPhiCons->Fill(phi);  
+   mHistPhiPtCon->Fill(phi, pt);  
+   mHistYieldCon2D->Fill(eta, pt) ;
+   mHistConsEtaPtPhi3D->Fill(eta, pt, phi) ;
+   mHistGlobEtaPtPhi3D->Fill(etaGlob, ptGlob, phiGlob) ;
+  }
+  else 
+  { 
+   mHistYieldUnc2D->Fill(etaGlob, ptGlob) ;
+   mHistUncEtaPtPhi3D->Fill(etaGlob, ptGlob, phiGlob) ;
+   mHistPhiPtUnc->Fill(phiGlob, ptGlob) ; 
+  }
+  if(pFlowTrack->Charge()>0)       { mHistPtPhiPos->Fill(phi, pt); }
+  else if(pFlowTrack->Charge()<0)  { mHistPtPhiNeg->Fill(phi, pt); }
+
+  // fills selected part histograms
+  if(pFlowSelect->SelectPart(pFlowTrack)) 
+  {
+   if(strlen(pFlowSelect->PidPart()) != 0) 
+   {
+    float rapidity = pFlowTrack->Y();
+    mHistBinEta->Fill(rapidity, rapidity);
+    mHistYieldPart2D->Fill(rapidity, pt);
+   }
+   else 
+   {
+    mHistBinEta->Fill(eta, eta) ;
+    mHistYieldPart2D->Fill(eta, pt) ;
+   }
+   mHistBayPidMultPart->Fill(numPid) ;
+   mHistBinPt->Fill(pt, pt) ;
+   mHistEtaPtPhi3DPart->Fill(eta,pt,phi) ;
+   mHistDcaGlobalPart->Fill(dcaGlobal) ;
+   mHistInvMassPart->Fill(invMass) ;
+   if(charge == 1) 
+   {
+    mHistMeanDedxPos3DPart->Fill(lpITS, dEdx, numPid) ;
+    mHistMeanDedxPos3DPartITS->Fill(lpITS, its, numPid) ;
+   }
+   else if(charge == -1) 
+   {
+    mHistMeanDedxNeg3DPart->Fill(lpITS, dEdx, numPid) ;
+    mHistMeanDedxNeg3DPartITS->Fill(lpITS, its, numPid) ;
+   }
+   if(eta > 0.) { etaSymPosTpcNpart++ ; }  // for mHistEtaSymPart 
+   else         { etaSymNegTpcNpart++ ; }
+  }
+  else         
+  {
+   mHistEtaPtPhi3DOut->Fill(eta,pt,phi) ;
+   mHistYieldOut2D->Fill(eta, pt) ;
+   mHistDcaGlobalOut->Fill(dcaGlobal) ;
+   mHistInvMassOut->Fill(invMass) ;
+  }
+
+  // cos(n*phiLab)
+  for(int j = 0; j < Flow::nHars; j++) 
+  {
+   bool oddHar = (j+1) % 2 ;
+   float order = (float)(j+1) ;
+   float vIn   = 100 * cos((double)order * phi) ;
+   if(eta < 0 && oddHar) { vIn *= -1 ; }
+   mHistCosPhi->Fill(order, vIn);
+  }
+
+  //For Eta symmetry TPC
+  if(pFlowTrack->FitPtsTPC())
+  {
+   if(eta > 0.) { etaSymPosTpcN++ ; } // for mHistEtaSym 
+   else         { etaSymNegTpcN++ ; }
+  }
+  
+  // not to call it twice ...
+  int nEtaS = HarmonicsLoop(eta,phi,pt,numPid) ;
+
+  //For Correlated Multiplicity 
+  corrMultN += (float)nEtaS ;
+
+  //For Correlated Multiplicity in 1 unit rapidity
+  if(TMath::Abs(eta) <= 0.5) { corrMultUnit += (float)nEtaS ; }
+
+  //delete pointer
+  pFlowTrack = 0 ;
+ }                                                                                              // end of tracks loop
+                                                    
+ // EtaSym
+ float etaSymTpc = 0 ; 
+ if(etaSymPosTpcN || etaSymNegTpcN)        { etaSymTpc  = (etaSymPosTpcN  - etaSymNegTpcN)  / (etaSymPosTpcN  + etaSymNegTpcN); }
+ float etaSymTpcPart = 0 ; 
+ if(etaSymPosTpcNpart || etaSymNegTpcNpart) { etaSymTpcPart  = (etaSymPosTpcNpart  - etaSymNegTpcNpart)  / (etaSymPosTpcNpart  + etaSymNegTpcNpart) ; }
+ Float_t vertexZ = vertex[2] ;
+ // all
+ mHistEtaSym->Fill(etaSymTpc);
+ mHistEtaSymVerZ2D->Fill(vertexZ , etaSymTpc);
+ // selected
+ mHistEtaSymPart->Fill(etaSymTpc);
+ mHistEtaSymVerZ2DPart->Fill(vertexZ , etaSymTpcPart);
+
+ // PID multiplicities
+ float totalMult = (float)pFlowTracks->GetEntries() ;
+ mHistPidMult->Fill(1., totalMult);
+ mHistPidMult->Fill(2., hPlusN);
+ mHistPidMult->Fill(3., hMinusN);
+ mHistPidMult->Fill(4., piPlusN);
+ mHistPidMult->Fill(5., piMinusN);
+ mHistPidMult->Fill(6., protonN);
+ mHistPidMult->Fill(7., pbarN);
+ mHistPidMult->Fill(8., kPlusN);
+ mHistPidMult->Fill(9., kMinusN);
+ mHistPidMult->Fill(10., deuteronN);
+ mHistPidMult->Fill(11., dbarN);
+ mHistPidMult->Fill(12., electronN);
+ mHistPidMult->Fill(13., positronN);
+ mHistPidMult->Fill(14., muonMinusN);
+ mHistPidMult->Fill(15., muonPlusN);
+
+ // Multiplicity of particles correlated with the event planes
+ corrMultN /= (float)(Flow::nHars * Flow::nSels) ; 
+ mHistMultPart->Fill(corrMultN) ;
+ // ...in one unit rapidity
+ corrMultUnit /= (float)(Flow::nHars * Flow::nSels) ; 
+ mHistMultPartUnit->Fill(corrMultUnit) ;
+
+ if(Debug1) { cout << FlowAnalysis << "Tracks Loop...    " << totalMult << " tracks done . (" << corrMultN << ") . " << endl ; }
+}
+//-----------------------------------------------------------------------
+int AliFlowAnalysisMaker::HarmonicsLoop(float eta, float phi, float pt, int numPid)
+{
+ // HarmonicsLoop ...
+
+ if(Debug2) { cout << FlowAnalysis << "Harmonic Loop . " << endl ; }
+
+ int corrMultN = 0 ;
+ float zFirstPoint = pFlowTrack->ZFirstPoint() ; 
+ // float zLastPoint = pFlowTrack->ZLastPoint() ;
+
+ // Looping over Selections and Harmonics
+ for (int k = 0; k < Flow::nSels; k++) 
+ {
+  pFlowSelect->SetSelection(k) ;
+  for (int j = 0; j < Flow::nHars; j++) 
+  {
+   bool oddHar = (j+1) % 2;
+   pFlowSelect->SetHarmonic(j);
+   double order  = (double)(j+1);
+   float psi_i, psi_2;
+   if(pFlowEvent->EtaSubs())          // particles with the opposite subevent
+   {
+    if(eta > 0) { psi_i = mPsiSub[1][k][j] ; }     //check
+    else       { psi_i = mPsiSub[0][k][j] ; }
+   } 
+   else if(order > 3. && !oddHar) 
+   {
+    psi_i = mPsi[k][1];  // 2nd harmomic event plane
+    if(psi_i > 2*TMath::Pi()/order) { psi_i -= 2*TMath::Pi()/order ; } 
+    if(psi_i > 2*TMath::Pi()/order) { psi_i -= 2*TMath::Pi()/order ; }
+   } 
+   else  // random subevents
+   {
+    psi_i = mPsi[k][j] ;
+   }
+
+   if(pFlowSelect->Select(pFlowTrack)) // Get detID
+   {
+    Bool_t kTpcPlus  = kFALSE ;
+    Bool_t kTpcMinus = kFALSE ;
+    Bool_t kTpcAll   = kFALSE ;
+
+    histFull[k].histFullHar[j].mHistYieldPt->Fill(pt);
+    histFull[k].histFullHar[j].mHistEtaPtPhi3D->Fill(eta, pt, phi);
+    histFull[k].histFullHar[j].mHistYield2D->Fill(eta, pt);
+    histFull[k].histFullHar[j].mHistDcaGlob->Fill(TMath::Abs(pFlowTrack->Dca()));
+
+    // Set Tpc (+ and -)
+    if(pFlowTrack->FitPtsTPC())    //OR*: AliESDtrack:: "TBits& GetTPCClusterMap()" or "Int_t GetTPCclusters(Int_t* idx)" ...
+    {
+     if(zFirstPoint >= 0. && eta > 0.)     { kTpcPlus  = kTRUE ; } 
+     else if(zFirstPoint <= 0. && eta < 0.) { kTpcMinus = kTRUE ; }
+     else                                  { kTpcAll   = kTRUE ; }       
+    }
+    else 
+    {
+     if(Debug2) { cout << FlowAnalysis << "!!! no TPC hits ( track ??? ) ." << endl ; }
+    }
+
+    // PID Multiplicities (particle for R.P.) - done just one time for each selection
+    if(j==0) { histFull[k].mHistBayPidMult->Fill(numPid) ; }
+
+    // Calculate weights for filling histograms   
+    float wt = 1. ; // TMath::Abs(pFlowEvent->Weight(k, j, pFlowTrack)) ; 
+
+    // Fill histograms with selections
+    if(kTpcPlus)       { histFull[k].histFullHar[j].mHistPhiPlus->Fill(phi,wt) ;  } 
+    else if(kTpcMinus) { histFull[k].histFullHar[j].mHistPhiMinus->Fill(phi,wt) ; } 
+    else if(kTpcAll)   { histFull[k].histFullHar[j].mHistPhiAll->Fill(phi,wt) ;   } 
+    histFull[k].histFullHar[j].mHistPhi->Fill(phi,wt) ;
+
+    // Get phiWgt from file
+    double phiWgt;
+    if(order > 3. && !oddHar) { phiWgt = pFlowEvent->PhiWeight(k, 1, pFlowTrack) ; } 
+    else                     { phiWgt = pFlowEvent->PhiWeight(k, j, pFlowTrack) ; }
+    if(oddHar && eta<0.)      { phiWgt /= -1. ; } // only for flat hists
+    // chk
+    if(Debug2) { cout << " Weight [" << k << "][" << j << "] (" << pFlowTrack->GetName() << ") = " << phiWgt << " or " << wt << " for phi = " << phi << endl ; }
+
+    // Fill Flat histograms
+    if(kTpcPlus)       { histFull[k].histFullHar[j].mHistPhiFlatPlus->Fill(phi, phiWgt) ; } 
+    else if(kTpcMinus) { histFull[k].histFullHar[j].mHistPhiFlatMinus->Fill(phi, phiWgt) ; } 
+    else if(kTpcAll)   { histFull[k].histFullHar[j].mHistPhiFlatAll->Fill(phi, phiWgt) ; } 
+    histFull[k].histFullHar[j].mHistPhiFlat->Fill(phi,phiWgt) ;
+    
+    if(oddHar && eta<0.)  { phiWgt *= -1. ; } // restore value
+
+    // Remove autocorrelations
+    TVector2 Q_i;
+    if(!pFlowEvent->EtaSubs())   // random subevents
+    {
+     if(order > 3. && !oddHar) // 2nd harmonic event plane
+     { 
+      Q_i.Set(phiWgt * cos(phi * 2), phiWgt * sin(phi * 2));
+      TVector2 mQ_i = mQ[k][1] - Q_i;
+      psi_i = mQ_i.Phi() / 2;
+      if(psi_i < 0.) { psi_i += TMath::Pi() ; } 
+     } 
+     else 
+     {
+      Q_i.Set(phiWgt * cos(phi * order), phiWgt * sin(phi * order));
+      TVector2 mQ_i = mQ[k][j] - Q_i;
+      psi_i = mQ_i.Phi() / order;
+      if(psi_i < 0.) { psi_i += 2*TMath::Pi()/order ; }
+     }
+    }
+          
+    // Remove autocorrelations of the second order 'particles' which are used for v1{EP1,EP2}.
+    if (mV1Ep1Ep2 == kTRUE && order == 1) 
+    {
+     AliFlowSelection usedForPsi2 = *pFlowSelect ;
+     usedForPsi2.SetHarmonic(1);
+     if(usedForPsi2.Select(pFlowTrack))  // particle was used for Psi2
+     {
+      Q_i.Set(phiWgt * cos(phi * 2), phiWgt * sin(phi * 2));
+      TVector2 mQ_i = mQ[k][1] - Q_i;
+      psi_2 = mQ_i.Phi() / 2;
+      if(psi_2 < 0.) { psi_2 += TMath::Pi() ; }
+     }
+     else                               // particle was not used for Psi2
+     { 
+      psi_2 = mPsi[k][1];
+     }
+    }
+   }
+   else
+   {
+    histFull[k].histFullHar[j].mHistYieldPtout->Fill(pt);
+    histFull[k].histFullHar[j].mHistEtaPtPhi3Dout->Fill(eta, pt, phi);
+    histFull[k].histFullHar[j].mHistYield2Dout->Fill(eta, pt);
+    histFull[k].histFullHar[j].mHistDcaGlobout->Fill(TMath::Abs(pFlowTrack->Dca()));
+   }
+
+   // Caculate v for all particles selected for correlation analysis
+   if(pFlowSelect->SelectPart(pFlowTrack)) 
+   {
+    corrMultN++;
+    
+    float v;
+    if (mV1Ep1Ep2 == kFALSE || order != 1) 
+    {
+     v = 100 * cos(order * (phi - psi_i)) ;
+    }
+    else // i.e. (mV1Ep1Ep2 == kTRUE && order == 1)
+    {
+     v = 100 * cos(phi + psi_i - 2*psi_2) ;
+    }
+    
+    float vFlip = v;
+    if(eta < 0 && oddHar) { vFlip *= -1 ; }
+    if(strlen(pFlowSelect->PidPart()) != 0) // pid, fill rapidity 
+    {
+     float rapidity = pFlowTrack->Y();
+     histFull[k].histFullHar[j].mHist_vObs2D->Fill(rapidity, pt, v);
+   
+     if(mPtRange_for_vEta[1] > mPtRange_for_vEta[0])  // cut is used
+     {
+      if(pt < mPtRange_for_vEta[1] && pt >= mPtRange_for_vEta[0]) // check cut range, fill if in range
+      {
+       histFull[k].histFullHar[j].mHist_vObsEta->Fill(rapidity, v);
+      }
+     }
+     else // cut is not used, fill in any case
+     { 
+      histFull[k].histFullHar[j].mHist_vObsEta->Fill(rapidity, v);
+     }
+    } 
+    else  // no pid, fill eta
+    {
+     histFull[k].histFullHar[j].mHist_vObs2D->Fill(eta, pt, v);
+
+     if(mPtRange_for_vEta[1] > mPtRange_for_vEta[0]) // cut is used
+     {
+      if(pt < mPtRange_for_vEta[1] && pt >= mPtRange_for_vEta[0]) // check cut range, fill if in range
+      {
+       histFull[k].histFullHar[j].mHist_vObsEta->Fill(eta, v);
+      }
+     }
+     else // cut is not used, fill in any case
+     { 
+      histFull[k].histFullHar[j].mHist_vObsEta->Fill(eta, v);
+     }
+    }
+
+    if(mEtaRange_for_vPt[1] > mEtaRange_for_vPt[0]) // cut is used
+    { 
+     if(TMath::Abs(eta) < mEtaRange_for_vPt[1] && TMath::Abs(eta) >= mEtaRange_for_vPt[0]) // check cut range, fill if in range
+     {
+      histFull[k].histFullHar[j].mHist_vObsPt->Fill(pt, vFlip);  // for odd harmonis /-/
+     }
+    }
+    else  // cut is not used, fill in any case
+    {
+     histFull[k].histFullHar[j].mHist_vObsPt->Fill(pt, vFlip);
+    }
+
+    // v_
+    Bool_t etaPtNoCut = kTRUE;
+    if(mPtRange_for_vEta[1] > mPtRange_for_vEta[0] && (pt < mPtRange_for_vEta[0] || pt >= mPtRange_for_vEta[1])) 
+    {
+     etaPtNoCut = kFALSE;
+    }
+    if(mEtaRange_for_vPt[1] > mEtaRange_for_vPt[0] && (TMath::Abs(eta) < mEtaRange_for_vPt[0] || TMath::Abs(eta) >= mEtaRange_for_vPt[1]))
+    {
+     etaPtNoCut = kFALSE;
+    }
+    if(etaPtNoCut) { histFull[k].mHist_vObs->Fill(order, vFlip) ; }
+    // Correlation of Phi of selected particles with Psi
+    float phi_i = phi;
+    if(eta < 0 && oddHar) 
+    {
+     phi_i += TMath::Pi() ; // backward particle and odd harmonic
+     if(phi_i > 2*TMath::Pi()) { phi_i -= 2*TMath::Pi() ; }
+    }
+    float dPhi = phi_i - psi_i;
+    if(dPhi < 0.)             { dPhi += 2*TMath::Pi() ; }
+    histFull[k].histFullHar[j].mHistPhiCorr->Fill(fmod((double)dPhi, 2*TMath::Pi() / order));
+   }
+  }
+ }
+ return corrMultN ;
+}
+//-----------------------------------------------------------------------
+void AliFlowAnalysisMaker::FillV0Histograms()
+{
+ // v0s histograms
+
+ if(Debug0) { cout << spaces << "V0s Loop . " << endl ; } 
+
+ int corrMultV0 = 0 ;
+
+ if(Debug1) { cout << spaces << "Looping over " << nV0s << "  flow V0s  . " << endl ; } 
+ for(Int_t vloop=0;vloop<nV0s;vloop++) 
+ {
+  pFlowV0 = (AliFlowV0*)pFlowV0s->At(vloop) ;      if(Debug3) { cout << "v0 n. " << vloop << endl ; pFlowV0->Dump() ; }
+
+  // // LABELS FOR V0s ARE NOT DEFINED !!!
+  // int label = pFlowV0->Label() ;                if(Debug3) { cout << vloop << " label: " << label << endl ; }
+
+  float mass = pFlowV0->Mass() ;                   if(Debug3) { cout << "mass " << mass << endl ; } 
+  float eta = pFlowV0->Eta() ;                     if(Debug3) { cout << "eta "  << eta << endl ; } 
+  float rapidity = pFlowV0->Y() ;                  if(Debug3) { cout << "Y   "  << rapidity << endl ; } 
+  float phi = pFlowV0->Phi() ;                     if(Debug3) { cout << "Phi "  << phi<< endl ; } 
+  float pt = pFlowV0->Pt() ;                       if(Debug3) { cout << "Pt "  << pt << endl ; }  
+  float totalp = pFlowV0->P() ;                    if(Debug3) { cout << "P "   << totalp << endl ; }   
+  int  charge = pFlowV0->Charge() ;                if(Debug3) { cout << "charge " << charge << endl ; }
+  float dca = pFlowV0->Dca() ;                     if(Debug3) { cout << "dca "  << dca << endl ; }  
+  float lenght = pFlowV0->V0Lenght() ;             if(Debug3) { cout << "lenght " << lenght << endl ; }
+  float sigma = pFlowV0->Sigma() ;                 if(Debug3) { cout << "sigma " << sigma << endl ; }  
+  float chi2 = pFlowV0->Chi2() ;                   if(Debug3) { cout << "chi2 " << chi2 << endl ; }  
+  Char_t pid[10] ; strcpy(pid, pFlowV0->Pid()) ;    if(Debug3) { cout << "pid "  << pid << endl ; }   
+  AliFlowTrack* daughterPlus = pFlowV0->DaughterP() ;   if(Debug3) { cout << "daughter + :  " << daughterPlus << endl ; }
+  AliFlowTrack* daughterMinus = pFlowV0->DaughterN() ;  if(Debug3) { cout << "daughter - :  " << daughterMinus << endl ; }
+  // -
+  mHistV0Mass->Fill(mass) ;
+  mHistV0EtaPtPhi3D->Fill(eta, pt, phi) ;
+  mHistV0YieldAll2D->Fill(eta, pt) ;
+  mHistV0Dca->Fill(dca);
+  mHistV0Chi2->Fill(chi2);
+  mHistV0Lenght->Fill(lenght);
+  mHistV0Sigma->Fill(sigma);
+  mHistV0MassPtSlices->Fill(mass,pt);
+  if(Debug3) { cout << spaces <<  "global histograms filled . " << endl ; }
+
+  if(pFlowSelect->SelectPart(pFlowV0))
+  {
+   bool inWin = pFlowSelect->SelectV0Part(pFlowV0) ;
+   bool sx = pFlowSelect->SelectV0sxSide(pFlowV0) ;
+   bool dx = pFlowSelect->SelectV0dxSide(pFlowV0) ;
+   corrMultV0++ ;
+
+   mHistV0YieldPart2D->Fill(eta, pt) ;
+   if(inWin) 
+   { 
+    mHistV0EtaPtPhi3DPart->Fill(eta, pt, phi) ;
+    mHistV0LenghtPart->Fill(lenght);
+    mHistV0DcaPart->Fill(dca);
+    mHistV0MassWin->Fill(mass) ; 
+    mHistV0BinEta->Fill(eta, eta);
+    mHistV0BinPt->Fill(pt, pt);   
+   }
+   else      
+   { 
+    mHistV0sbEtaPtPhi3DPart->Fill(eta, pt, phi) ;
+    mHistV0sbLenghtPart->Fill(lenght);
+    mHistV0sbDcaPart->Fill(dca);
+    mHistV0sbMassSide->Fill(mass) ; 
+    mHistV0sbBinEta->Fill(eta, eta);
+    mHistV0sbBinPt->Fill(pt, pt);
+   }
+
+   for(int k = 0; k < Flow::nSels; k++)  // sort of HarmonicsLoop - selection number used
+   {
+    pFlowSelect->SetSelection(k) ;
+    for(Int_t j=0;j<Flow::nHars;j++) 
+    {
+     Bool_t oddHar = (j+1) % 2 ;
+     Float_t order = (Float_t)(j+1) ;
+     pFlowSelect->SetHarmonic(j);                        if(Debug3) { cout << spaces <<  "start correlation computation .   " << j << endl ; }
+
+     // Remove autocorrelations
+     Float_t psi_i, psi_2 ;
+     TVector2 Q_1, Q_2 ;
+     Float_t phiDaughter1 = 0. ; Float_t phiDaughter2 = 0. ;
+     Double_t phiWgt1 = 0. ; Double_t phiWgt2 = 0. ;
+     // -
+     if(daughterPlus)
+     { // 1
+      pFlowTrack = daughterPlus ;
+      phiDaughter1 = pFlowTrack->Phi() ;                 if(Debug3) { cout << spaces <<  "track 1 . " << daughterPlus << " . phi1 = " << phiDaughter1 << " . " << endl ; } 
+      if(pFlowSelect->Select(pFlowTrack)) // Get phiWgt from file
+      {
+       if(order > 3. && !oddHar) { phiWgt1 = pFlowEvent->PhiWeight(k, 1, pFlowTrack) ; } 
+       else                     { phiWgt1 = pFlowEvent->PhiWeight(k, j, pFlowTrack) ; }
+      }
+      if(Debug3) { cout << spaces <<  "track 1 . " << daughterPlus << " . wgt1 = " << phiWgt1 << " . " << endl ; } 
+     }
+     if(daughterMinus)
+     { // 2
+      pFlowTrack = daughterMinus ;
+      phiDaughter2 = pFlowTrack->Phi() ;                 if(Debug3) { cout << spaces <<  "track 2 . " << daughterMinus << " . phi2 = " << phiDaughter2 << " . " << endl ; }
+      if(pFlowSelect->Select(pFlowTrack)) // Get phiWgt from file
+      {
+       if(order > 3. && !oddHar) { phiWgt2 = pFlowEvent->PhiWeight(k, 1, pFlowTrack) ; } 
+       else                     { phiWgt2 = pFlowEvent->PhiWeight(k, j, pFlowTrack) ; }
+      }
+      if(Debug3) { cout << spaces <<  "track 2 . " << daughterMinus << " . wgt2 = " << phiWgt2 << " . " << endl ; } 
+     }
+
+     // psi_2
+     Q_1.Set(phiWgt1 * cos(phiDaughter1 * 2), phiWgt1 * sin(phiDaughter1 * 2));
+     Q_2.Set(phiWgt2 * cos(phiDaughter2 * 2), phiWgt2 * sin(phiDaughter2 * 2));
+     TVector2 mQ_i = mQ[k][1] ; mQ_i -= Q_1 ; mQ_i -= Q_2 ; 
+     psi_2 = mQ_i.Phi() / 2 ;    
+     if(psi_2 < 0.)         { psi_2 += TMath::Pi() ; }
+     if(psi_2 > TMath::Pi()) { psi_2 -= TMath::Pi() ; } 
+     if(Debug3) { cout << spaces <<  "psi2 = " << psi_2 << " . " << endl ; }
+
+     // psi_i
+     if(order > 3. && !oddHar) { psi_i = psi_2 ; } 
+     else 
+     {
+      Q_1.Set(phiWgt1 * cos(phiDaughter1 * order), phiWgt1 * sin(phiDaughter1 * order));
+      Q_2.Set(phiWgt2 * cos(phiDaughter2 * order), phiWgt2 * sin(phiDaughter2 * order));
+      TVector2 mQ_i = mQ[k][j] ; mQ_i -= Q_1 ; mQ_i -= Q_2 ;
+      psi_i = mQ_i.Phi()/order ; 
+      if(psi_i < 0.)                 { psi_i += 2*TMath::Pi()/order ; }        
+      if(psi_i > 2*TMath::Pi()/order) { psi_i -= 2*TMath::Pi()/order ; } 
+     }
+     if(Debug3) { cout << spaces <<  "psi_i = " << psi_i << " . " << endl ; }
+
+    // Caculate v for all V0s selected for correlation analysis
+     float v ;
+     if(mV1Ep1Ep2 == kFALSE || order != 1) { v = 100 * cos(order * (phi - psi_i)) ; }
+     else { v = 100 * cos(phi + psi_i - 2*psi_2) ; }
+     float vFlip = v ; if(eta < 0 && oddHar) { vFlip *= -1 ; }
+
+     // invariant mass windows & sidebands
+     if(inWin) { histFull[k].histFullHar[j].mHistV0_vObs2D->Fill(eta, pt, v) ; }
+     else      { histFull[k].histFullHar[j].mHistV0sb_vObs2D->Fill(eta, pt, v) ; }
+
+     if(mPtRange_for_vEta[1] > mPtRange_for_vEta[0]) // cut is used
+     {
+      if(pt < mPtRange_for_vEta[1] && pt >= mPtRange_for_vEta[0]) // check cut range, fill if in range
+      {
+       if(inWin) { histFull[k].histFullHar[j].mHistV0_vObsEta->Fill(eta, v) ; }
+       else      
+       { 
+        histFull[k].histFullHar[j].mHistV0sb_vObsEta->Fill(eta, v) ; 
+       if(sx)      { histFull[k].histFullHar[j].mHistV0sb_vObsEta_sx->Fill(eta, v) ; } 
+       else if(dx) { histFull[k].histFullHar[j].mHistV0sb_vObsEta_dx->Fill(eta, v) ; } 
+       }
+      }
+     }
+     else // cut is not used, fill in any case
+     { 
+      if(inWin) { histFull[k].histFullHar[j].mHistV0_vObsEta->Fill(eta, v) ; }
+      else     
+      { 
+       histFull[k].histFullHar[j].mHistV0sb_vObsEta->Fill(eta, v) ; 
+       if(sx)     { histFull[k].histFullHar[j].mHistV0sb_vObsEta_sx->Fill(eta, v) ; } 
+       else if(dx) { histFull[k].histFullHar[j].mHistV0sb_vObsEta_dx->Fill(eta, v) ; } 
+      }
+     } 
+     if(mEtaRange_for_vPt[1] > mEtaRange_for_vPt[0]) // cut is used
+     {
+      if(TMath::Abs(eta) < mEtaRange_for_vPt[1] && TMath::Abs(eta) >= mEtaRange_for_vPt[0]) // check cut range, fill if in range
+      {          
+       if(inWin) { histFull[k].histFullHar[j].mHistV0_vObsPt->Fill(pt, vFlip) ; }      // for odd harmonis /-/
+       else      
+       { 
+        histFull[k].histFullHar[j].mHistV0sb_vObsPt->Fill(pt, vFlip) ; 
+        if(sx)     { histFull[k].histFullHar[j].mHistV0sb_vObsPt_sx->Fill(eta, v) ; } 
+        else if(dx) { histFull[k].histFullHar[j].mHistV0sb_vObsPt_dx->Fill(eta, v) ; }         
+       }
+      }
+     }
+     else  // cut is not used, fill in any case
+     {
+      if(inWin) { histFull[k].histFullHar[j].mHistV0_vObsPt->Fill(pt, vFlip) ; } 
+      else     
+      { 
+       histFull[k].histFullHar[j].mHistV0sb_vObsPt->Fill(pt, vFlip) ; 
+       if(sx)     { histFull[k].histFullHar[j].mHistV0sb_vObsPt_sx->Fill(eta, v) ; } 
+       else if(dx) { histFull[k].histFullHar[j].mHistV0sb_vObsPt_dx->Fill(eta, v) ; }  
+      }
+     }
+     // v_
+     Bool_t etaPtNoCut = kTRUE;
+     if(mPtRange_for_vEta[1] > mPtRange_for_vEta[0] && (pt < mPtRange_for_vEta[0] || pt >= mPtRange_for_vEta[1])) 
+     {
+      etaPtNoCut = kFALSE;
+     }
+     if(mEtaRange_for_vPt[1] > mEtaRange_for_vPt[0] && (TMath::Abs(eta) < mEtaRange_for_vPt[0] || TMath::Abs(eta) >= mEtaRange_for_vPt[1]))
+     {
+      etaPtNoCut = kFALSE;
+     }
+     if(etaPtNoCut) 
+     { 
+      if(inWin) { histFull[k].mHistV0_vObs->Fill(order, vFlip) ; }
+      else     
+      { 
+       if(sx)     { histFull[k].mHistV0sb_vObs_sx->Fill(order, vFlip) ; } 
+       else if(dx) { histFull[k].mHistV0sb_vObs_dx->Fill(order, vFlip) ; }  
+      }
+     }
+   
+     // Correlation of Phi of selected v0s with Psi
+     float phi_i = phi;
+     if(eta < 0 && oddHar)
+     {
+      phi_i += TMath::Pi() ; // backward particle and odd harmonic
+      if(phi_i > 2*TMath::Pi()) { phi_i -= 2*TMath::Pi() ; }
+     }
+     float dPhi = phi_i - psi_i;
+     if(dPhi < 0.)  { dPhi += 2*TMath::Pi() ; }
+
+     if(inWin) { histFull[k].histFullHar[j].mHistV0PhiCorr->Fill(fmod((double)dPhi, 2*TMath::Pi() / order)) ; } 
+     else      { histFull[k].histFullHar[j].mHistV0sbPhiCorr->Fill(fmod((double)dPhi, 2*TMath::Pi() / order)) ; }
+    }
+   }
+  }
+  //delete pFlowV0 ; pFlowV0 = 0 ;
+  //delete pFlowTrack ; pFlowTrack = 0 ;
+ }
+ mHistV0MultPart->Fill(corrMultV0) ;
+
+ if(Debug1) { cout << FlowAnalysis << "V0s Loop...    " << nV0s << " v0s done . (" << corrMultV0 << ") . " << endl ; }
+}
+//-----------------------------------------------------------------------
+void AliFlowAnalysisMaker::FillLabels()  
+{
+ // Reads the tracks label (i.e. the link from ESD tracking to KineTree)
+ // and puts them in a TH2F (nEvt x nLabels) for later use. The histogram 
+ // is then  saved in the standar output.
+ if(Debug1) { cout << FlowAnalysis << "Filling Labels . " << endl ; } 
+
+// *temp*  --  !uncomment!
+//  if(mLabellingFirst)        
+//  {
+//   if(Debug1) { cout << spaces << " Creating Labels hist ( max label = " << maxLabel << " ) . " << endl ; }
+//   mLabellingFirst = kFALSE ; 
+//   TString* labTitle = new TString("TracksLabel_full") ; 
+//   int maxMaxLabel = maxLabel + (int)((float)maxLabel / 10.) ;
+//   mLabHist = new TH2F(labTitle->Data(),labTitle->Data(),Flow::nSels+4,0.,Flow::nSels+4.,maxMaxLabel+1,0.,maxMaxLabel+1.) ;
+//   if(Flow::nSels==2) { mLabHist->SetXTitle("tracks , sel0 , sel1 , selPart , v0s , selV0s ") ; }
+//   else  { mLabHist->SetXTitle("tracks , sel... , selPart , v0s , selV0s ") ; }
+//   mLabHist->SetYTitle("MC label") ;
+//   delete labTitle ;
+//   if(Debug1) { cout << spaces << " Labels histogram created ( max bin = " << maxMaxLabel << " ) . " << endl ; }
+//  }
+// *temp*  --  !uncomment! 
+
+ // Labels histogram
+ float lBin = 0. ; float label = 0. ; 
+ for(int tk=0;tk<nTracks;tk++) 
+ {
+  pFlowTrack = (AliFlowTrack*)pFlowTracks->At(tk) ;
+  label = (float)pFlowTrack->Label() ;                                 if(Debug4) { cout << " trak. " << tk  << " label. " << label  << endl ; }
+  lBin = 0.1 ; 
+  mLabHist->Fill(lBin,label) ;                                 if(Debug4) { cout << "    allTr -       bin " << lBin << endl ; } 
+  for(int ss=0;ss<Flow::nSels;ss++) 
+  {
+   lBin = (float)ss + 1.1 ;
+   if(pFlowTrack->Select(0,ss,-1))       
+   { 
+    mLabHist->Fill(lBin,label) ;                                       if(Debug4) { cout << "    sel " << ss << "      -       bin " << lBin << endl ; } 
+   }
+  }
+  lBin = (float)Flow::nSels + 1.1 ;
+  if(pFlowSelect->SelectPart(pFlowTrack)) 
+  { 
+   mLabHist->Fill(lBin,label) ;                                if(Debug4) { cout << "    part  -       bin " << lBin << endl ; }  
+  }
+ }
+ // LABELS FOR V0s ARE NOT DEFINED (...but for each daughter)
+ if(mV0)
+ {
+  float label1 = 0. ; float label2 = 0. ; 
+  for(int vk=0;vk<nV0s;vk++) 
+  {
+   pFlowV0 = (AliFlowV0*)pFlowV0s->At(vk) ;                          if(Debug4) { cout << " v0  . " << vk  << " label from daughters .... " << endl ; }
+   //label = (float)pFlowV0->Label() ;                       if(Debug4) { cout << " v0  . " << vk  << " label. " << label  << endl ; }
+   pFlowTrack = (AliFlowTrack*)pFlowV0->DaughterP() ; label1 = (float)pFlowTrack->Label() ;
+   pFlowTrack = (AliFlowTrack*)pFlowV0->DaughterN() ; label2 = (float)pFlowTrack->Label() ;
+                                                             if(Debug4) { cout << " daughter1 = " << label1  << " , daughter2 = " << label2  << endl ; }
+   lBin = (float)Flow::nSels + 2.1 ; 
+   mLabHist->Fill(lBin,label1) ;                             if(Debug4) { cout << "    allV0 -       bin " << lBin << endl ; } 
+   mLabHist->Fill(lBin,label2) ;                             if(Debug4) { cout << "    allV0 -       bin " << lBin << endl ; } 
+   lBin = (float)Flow::nSels + 3.1 ;   
+   if(pFlowSelect->SelectPart(pFlowV0)) 
+   {
+    mLabHist->Fill(lBin,label1) ;                            if(Debug4) { cout << "    V0 part        -       bin " << lBin << endl ; }  
+    mLabHist->Fill(lBin,label2) ;                            if(Debug4) { cout << "    V0 part        -       bin " << lBin << endl ; }  
+   }
+  }
+ }
+}
+//----------------------------------------------------------------------
+// ###
+//----------------------------------------------------------------------
+void AliFlowAnalysisMaker::Resolution()
+{
+ // Calculates the resolution, corrects the flow values, and stores all 
+ // of them in few new histograms (see mVnResHistList). Histogram are 
+ // then saved in the same otput file.
+ if(Debug0) { cout << FlowAnalysis << "Calculating Resolution . " << endl ; cout << endl ; } 
+ // VnRes histogram collection
+ mVnResHistList = new TOrdCollection(Flow::nSels*Flow::nHars);
+ // Calculate resolution from sqrt(mHistCos)
+ double cosPair[Flow::nSels][Flow::nHars];
+ double cosPairErr[Flow::nSels][Flow::nHars];
+ double content, contentV0;
+ double error, errorV0;
+ double totalError;
+ TString* histTitle;
+
+ for(int k = 0; k < Flow::nSels; k++)
+ {
+  // v for tracks (corrected for resolution)
+  histTitle = new TString("Flow_v_Sel");
+  *histTitle += k+1;
+  histFull[k].mHist_v = histFull[k].mHist_vObs->ProjectionX(histTitle->Data());
+  histFull[k].mHist_v->SetTitle(histTitle->Data());
+  histFull[k].mHist_v->SetXTitle("Harmonic");
+  histFull[k].mHist_v->SetYTitle("v (%)");
+  delete histTitle;
+  mVnResHistList->AddLast(histFull[k].mHist_v);
+   
+  // v for v0s (corrected for resolution)
+  histTitle = new TString("FlowV0_v_Sel");
+  *histTitle += k+1;
+  histFull[k].mHistV0_v = histFull[k].mHistV0_vObs->ProjectionX(histTitle->Data());
+  histFull[k].mHistV0_v->SetTitle(histTitle->Data());
+  histFull[k].mHistV0_v->SetXTitle("Harmonic");
+  histFull[k].mHistV0_v->SetYTitle("v (%)");
+  delete histTitle;
+  mVnResHistList->AddLast(histFull[k].mHistV0_v);
+   
+  for(int j = 0; j < Flow::nHars; j++) 
+  {
+   double order = (double)(j+1);
+   cosPair[k][j]    = histFull[k].mHistCos->GetBinContent(j+1);
+   cosPairErr[k][j] = histFull[k].mHistCos->GetBinError(j+1);
+   if(cosPair[k][j] > 0.) 
+   {
+    double resSub = 0. ;
+    double resSubErr = 0. ;
+    if(mV1Ep1Ep2 == kTRUE && order == 1) // calculate resolution of second order event plane first
+    {
+     double res2 = 0. ;
+     double res2error = 0. ;
+     if(histFull[k].mHistCos->GetBinContent(2) > 0.) 
+     {
+      if(mEtaSub)  // sub res only
+      {
+       res2 = TMath::Sqrt(histFull[k].mHistCos->GetBinContent(2));
+       res2error = histFull[k].mHistCos->GetBinError(2) / (2. * res2);
+      }
+      else 
+      {
+       if (histFull[k].mHistCos->GetBinContent(2) > 0.92)  // resolution saturates
+       {
+        res2 = 0.99;
+        res2error = 0.007;
+       } 
+       else 
+       {
+        double deltaRes2Sub = 0.005;  // differential for the error propagation
+        double res2Sub = TMath::Sqrt(histFull[k].mHistCos->GetBinContent(2));
+        double res2SubErr = histFull[k].mHistCos->GetBinError(2) / (2. * res2Sub);
+        double chiSub2 = chi(res2Sub);
+        double chiSub2Delta = chi(res2Sub + deltaRes2Sub);
+        res2 = resEventPlane(TMath::Sqrt(2.) * chiSub2); // full event plane res.
+        double mRes2Delta = resEventPlane(TMath::Sqrt(2.) * chiSub2Delta);
+        res2error = res2SubErr * fabs((double)res2 - mRes2Delta) / deltaRes2Sub;
+       }
+      }
+     }
+     else 
+     {
+      res2 = 0.;
+      res2error = 0.;
+     }
+     // now put everything together with first order event plane
+     mRes[k][j]    = TMath::Sqrt(cosPair[k][0]*res2);
+     mResErr[k][j] = 1./(2.*mRes[k][j]) * TMath::Sqrt(cosPairErr[k][0]*cosPairErr[k][0] + res2error*res2error); // Gaussian error propagation
+    }
+    else if(mEtaSub)  // sub res only
+    {
+     resSub = TMath::Sqrt(cosPair[k][j]);                
+     resSubErr = cosPairErr[k][j] / (2. * resSub);
+     mRes[k][j]    = resSub;
+     mResErr[k][j] = resSubErr;
+    } 
+    else if(order==4. || order==6.|| order==8.)  // 2nd harmonic event plane
+    {
+     double deltaResSub = 0.005;  // differential for the error propagation
+     double resSub = TMath::Sqrt(cosPair[k][1]);
+     double resSubErr = cosPairErr[k][1] / (2. * resSub);
+     double chiSub = chi(resSub);
+     double chiSubDelta = chi(resSub + deltaResSub);
+     double mResDelta;
+     if (order==4.) 
+     {
+      mRes[k][j] = resEventPlaneK2(TMath::Sqrt(2.) * chiSub); // full event plane res.
+      mResDelta = resEventPlaneK2(TMath::Sqrt(2.) * chiSubDelta);
+     } 
+     else if(order==6.) 
+     {
+      mRes[k][j] = resEventPlaneK3(TMath::Sqrt(2.) * chiSub); // full event plane res.
+      mResDelta = resEventPlaneK3(TMath::Sqrt(2.) * chiSubDelta);
+     } 
+     else 
+     {
+      mRes[k][j] = resEventPlaneK4(TMath::Sqrt(2.) * chiSub); // full event plane res.
+      mResDelta = resEventPlaneK4(TMath::Sqrt(2.) * chiSubDelta);
+     }
+     mResErr[k][j] = resSubErr * fabs((double)mRes[k][j] - mResDelta) / deltaResSub;
+    }
+    else 
+    {
+     if(cosPair[k][j] > 0.92) // resolution saturates
+     {
+      mRes[k][j]    = 0.99;
+      mResErr[k][j] = 0.007;
+     } 
+     else 
+     {
+      double deltaResSub = 0.005;  // differential for the error propagation
+      double resSub = TMath::Sqrt(cosPair[k][j]);
+      double resSubErr = cosPairErr[k][j] / (2. * resSub);
+      double chiSub = chi(resSub);
+      double chiSubDelta = chi(resSub + deltaResSub);
+      mRes[k][j] = resEventPlane(TMath::Sqrt(2.) * chiSub); // full event plane res.
+      double mResDelta = resEventPlane(TMath::Sqrt(2.) * chiSubDelta);
+      mResErr[k][j] = resSubErr * TMath::Abs((double)mRes[k][j] - mResDelta) / deltaResSub;
+     }
+    }
+   }
+   else  // subevent correlation must be positive
+   {
+    mRes[k][j]    = 0.;
+    mResErr[k][j] = 0.;
+   }
+   histFull[k].mHistRes->SetBinContent(j+1, mRes[k][j]);
+   histFull[k].mHistRes->SetBinError(j+1, mResErr[k][j]);
+
+   // Create the v 2D histogram (Flow corrected for res.) - v,Pt,Eta
+   histTitle = new TString("Flow_v2D_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHist_v2D = histFull[k].histFullHar[j].mHist_vObs2D->ProjectionXY(histTitle->Data());
+   histFull[k].histFullHar[j].mHist_v2D->SetTitle(histTitle->Data());
+   histFull[k].histFullHar[j].mHist_v2D->SetXTitle((char*)xLabel.Data());
+   histFull[k].histFullHar[j].mHist_v2D->SetYTitle("Pt (GeV/c)");
+   histFull[k].histFullHar[j].mHist_v2D->SetZTitle("v (%)");
+   delete histTitle;
+   mVnResHistList->AddLast(histFull[k].histFullHar[j].mHist_v2D);
+
+   // Create the 1D v histograms - v,Eta
+   histTitle = new TString("Flow_vEta_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHist_vEta = histFull[k].histFullHar[j].mHist_vObsEta->ProjectionX(histTitle->Data());
+   histFull[k].histFullHar[j].mHist_vEta->SetTitle(histTitle->Data());
+   histFull[k].histFullHar[j].mHist_vEta->SetXTitle((char*)xLabel.Data());
+   histFull[k].histFullHar[j].mHist_vEta->SetYTitle("v (%)");
+   delete histTitle;
+   mVnResHistList->AddLast(histFull[k].histFullHar[j].mHist_vEta);
+   
+   // v,Pt
+   histTitle = new TString("Flow_vPt_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHist_vPt = histFull[k].histFullHar[j].mHist_vObsPt->ProjectionX(histTitle->Data());
+   histFull[k].histFullHar[j].mHist_vPt->SetTitle(histTitle->Data());
+   histFull[k].histFullHar[j].mHist_vPt->SetXTitle("Pt (GeV/c)");
+   histFull[k].histFullHar[j].mHist_vPt->SetYTitle("v (%)");
+   delete histTitle;
+   mVnResHistList->AddLast(histFull[k].histFullHar[j].mHist_vPt);
+
+   // Create the v 2D histogram (V0s Flow corrected for res.) - v,Pt,Eta
+   histTitle = new TString("FlowV0_v2D_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0_v2D = histFull[k].histFullHar[j].mHistV0_vObs2D->ProjectionXY(histTitle->Data());
+   histFull[k].histFullHar[j].mHistV0_v2D->SetTitle(histTitle->Data());
+   histFull[k].histFullHar[j].mHistV0_v2D->SetXTitle((char*)xLabel.Data());
+   histFull[k].histFullHar[j].mHistV0_v2D->SetYTitle("Pt (GeV/c)");
+   histFull[k].histFullHar[j].mHistV0_v2D->SetZTitle("v (%)");
+   delete histTitle;
+   mVnResHistList->AddLast(histFull[k].histFullHar[j].mHistV0_v2D);
+
+   // Create the 1D v histograms (V0s) - v,Eta
+   histTitle = new TString("FlowV0_vEta_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0_vEta = histFull[k].histFullHar[j].mHistV0_vObsEta->ProjectionX(histTitle->Data());
+   histFull[k].histFullHar[j].mHistV0_vEta->SetTitle(histTitle->Data());
+   histFull[k].histFullHar[j].mHistV0_vEta->SetXTitle((char*)xLabel.Data());
+   histFull[k].histFullHar[j].mHistV0_vEta->SetYTitle("v (%)");
+   delete histTitle;
+   mVnResHistList->AddLast(histFull[k].histFullHar[j].mHistV0_vEta);
+   
+   // (V0s) v,Pt
+   histTitle = new TString("FlowV0_vPt_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0_vPt = histFull[k].histFullHar[j].mHistV0_vObsPt->ProjectionX(histTitle->Data());
+   histFull[k].histFullHar[j].mHistV0_vPt->SetTitle(histTitle->Data());
+   histFull[k].histFullHar[j].mHistV0_vPt->SetXTitle("Pt (GeV/c)");
+   histFull[k].histFullHar[j].mHistV0_vPt->SetYTitle("v (%)");
+   delete histTitle;
+   mVnResHistList->AddLast(histFull[k].histFullHar[j].mHistV0_vPt);
+
+   // Create the v 2D histogram (V0s sidebands Flow corrected for res.) - v,Pt,Eta
+   histTitle = new TString("FlowV0sb_v2D_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0sb_v2D = histFull[k].histFullHar[j].mHistV0sb_vObs2D->ProjectionXY(histTitle->Data());
+   histFull[k].histFullHar[j].mHistV0sb_v2D->SetTitle(histTitle->Data());
+   histFull[k].histFullHar[j].mHistV0sb_v2D->SetXTitle((char*)xLabel.Data());
+   histFull[k].histFullHar[j].mHistV0sb_v2D->SetYTitle("Pt (GeV/c)");
+   histFull[k].histFullHar[j].mHistV0sb_v2D->SetZTitle("v (%)");
+   delete histTitle;
+   mVnResHistList->AddLast(histFull[k].histFullHar[j].mHistV0sb_v2D);
+
+   // Create the 1D v histograms (V0s sidebands) - v,Eta
+   histTitle = new TString("FlowV0sb_vEta_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0sb_vEta = histFull[k].histFullHar[j].mHistV0sb_vObsEta->ProjectionX(histTitle->Data());
+   histFull[k].histFullHar[j].mHistV0sb_vEta->SetTitle(histTitle->Data());
+   histFull[k].histFullHar[j].mHistV0sb_vEta->SetXTitle((char*)xLabel.Data());
+   histFull[k].histFullHar[j].mHistV0sb_vEta->SetYTitle("v (%)");
+   delete histTitle;
+   mVnResHistList->AddLast(histFull[k].histFullHar[j].mHistV0sb_vEta);
+   
+   // (V0s sidebands) v,Pt
+   histTitle = new TString("FlowV0sb_vPt_Sel");
+   *histTitle += k+1;
+   histTitle->Append("_Har");
+   *histTitle += j+1;
+   histFull[k].histFullHar[j].mHistV0sb_vPt = histFull[k].histFullHar[j].mHistV0sb_vObsPt->ProjectionX(histTitle->Data());
+   histFull[k].histFullHar[j].mHistV0sb_vPt->SetTitle(histTitle->Data());
+   histFull[k].histFullHar[j].mHistV0sb_vPt->SetXTitle("Pt (GeV/c)");
+   histFull[k].histFullHar[j].mHistV0sb_vPt->SetYTitle("v (%)");
+   delete histTitle;
+   mVnResHistList->AddLast(histFull[k].histFullHar[j].mHistV0sb_vPt);
+
+  // Calulate v = vObs / Resolution
+   if(mRes[k][j]) 
+   {
+    cout << FlowAnalysis << "Resolution of the " << j+1 << "th harmonic = " << mRes[k][j] << " +/- " << mResErr[k][j] << endl;
+    // selected tracks
+    histFull[k].histFullHar[j].mHist_v2D->Scale(1. / mRes[k][j]);
+    histFull[k].histFullHar[j].mHist_vEta->Scale(1. / mRes[k][j]);
+    histFull[k].histFullHar[j].mHist_vPt->Scale(1. / mRes[k][j]);
+    content = histFull[k].mHist_v->GetBinContent(j+1);        
+    content /=  mRes[k][j]; 
+    histFull[k].mHist_v->SetBinContent(j+1, content);            
+    // selected V0s    
+    histFull[k].histFullHar[j].mHistV0_v2D->Scale(1. / mRes[k][j]);
+    histFull[k].histFullHar[j].mHistV0_vEta->Scale(1. / mRes[k][j]);
+    histFull[k].histFullHar[j].mHistV0_vPt->Scale(1. / mRes[k][j]);
+    contentV0 = histFull[k].mHistV0_v->GetBinContent(j+1);        
+    contentV0 /=  mRes[k][j];
+    histFull[k].mHistV0_v->SetBinContent(j+1, contentV0);            
+    // V0s sidebands    
+    histFull[k].histFullHar[j].mHistV0sb_v2D->Scale(1. / mRes[k][j]);
+    histFull[k].histFullHar[j].mHistV0sb_vEta->Scale(1. / mRes[k][j]);
+    histFull[k].histFullHar[j].mHistV0sb_vPt->Scale(1. / mRes[k][j]);
+    // The systematic error of the resolution is folded in.
+    // tracks
+    error = histFull[k].mHist_v->GetBinError(j+1) ; 
+    error /= mRes[k][j];                                         
+    totalError = fabs(content) * TMath::Sqrt((error/content)*(error/content) + (mResErr[k][j]/mRes[k][j])*(mResErr[k][j]/mRes[k][j]));
+    histFull[k].mHist_v->SetBinError(j+1, totalError);
+    cout << FlowAnalysis << "v" << j+1 << "= (" << content << " +/- " << error << " +/- " << totalError << "(with syst.)) %" << endl;
+    // V0s
+    errorV0 = histFull[k].mHistV0_v->GetBinError(j+1) ; 
+    errorV0 /= mRes[k][j];                                         
+    totalError = fabs(contentV0) * TMath::Sqrt((errorV0/contentV0)*(errorV0/contentV0) + (mResErr[k][j]/mRes[k][j])*(mResErr[k][j]/mRes[k][j]));
+    histFull[k].mHistV0_v->SetBinError(j+1, totalError);
+   } 
+   else 
+   {
+    cout << "##### Resolution of the " << j+1 << "th harmonic was zero." << endl;
+    // tracks hist
+    histFull[k].histFullHar[j].mHist_v2D->Reset();
+    histFull[k].histFullHar[j].mHist_vEta->Reset();
+    histFull[k].histFullHar[j].mHist_vPt->Reset();
+    histFull[k].mHist_v->SetBinContent(j+1, 0.);
+    histFull[k].mHist_v->SetBinError(j+1, 0.);
+    // v0s hist
+    histFull[k].histFullHar[j].mHistV0_v2D->Reset();
+    histFull[k].histFullHar[j].mHistV0_vEta->Reset();
+    histFull[k].histFullHar[j].mHistV0_vPt->Reset();
+    histFull[k].histFullHar[j].mHistV0sb_v2D->Reset();
+    histFull[k].histFullHar[j].mHistV0sb_vEta->Reset();
+    histFull[k].histFullHar[j].mHistV0sb_vPt->Reset();
+    histFull[k].mHistV0_v->SetBinContent(j+1, 0.);
+    histFull[k].mHistV0_v->SetBinError(j+1, 0.);
+   }
+  }
+ }
+ if(Debug1) { cout << FlowAnalysis << "Done . " << endl ; cout << endl ; }
+
+ return ;
+}
+//-----------------------------------------------------------------------
+Double_t AliFlowAnalysisMaker::chi(double res)          // chi from the event plane resolution
+{
+ double chi   = 2.0;
+ double delta = 1.0;
+ for(int i = 0; i < 15; i++) 
+ {
+  if(resEventPlane(chi) < res) { chi = chi + delta ; }
+  else                         { chi = chi - delta ; }
+  delta = delta / 2.;
+ }
+
+ return chi;
+}
+//-----------------------------------------------------------------------
+Double_t AliFlowAnalysisMaker::resEventPlane(double chi)    // plane resolution as function of chi
+{
+ double con = TMath::Sqrt(TMath::Pi()/2)/2 ;   // ~ 0.626657
+ double arg = chi * chi / 4.;
+ Double_t res = con * chi * exp(-arg) * (TMath::BesselI0(arg) + TMath::BesselI1(arg)); 
+
+ return res ;
+}
+//-----------------------------------------------------------------------
+Double_t AliFlowAnalysisMaker::resEventPlaneK2(double chi)  // ... for the case k=2.
+{
+ double con = TMath::Sqrt(TMath::Pi()/2)/2 ;   // ~ 0.626657
+ double arg = chi * chi / 4.;
+
+ double besselOneHalf = TMath::Sqrt(arg/(TMath::Pi()/2)) * sinh(arg)/arg;
+ double besselThreeHalfs = TMath::Sqrt(arg/(TMath::Pi()/2)) * (cosh(arg)/arg - sinh(arg)/(arg*arg));
+ Double_t res = con * chi * exp(-arg) * (besselOneHalf + besselThreeHalfs); 
+
+ return res;
+}
+//-----------------------------------------------------------------------
+Double_t AliFlowAnalysisMaker::resEventPlaneK3(double chi) // ...for the case k=3.
+{
+ double con = TMath::Sqrt(TMath::Pi()/2)/2 ;   // ~ 0.626657
+ double arg = chi * chi / 4.;
+ Double_t res = con * chi * exp(-arg) * (TMath::BesselI1(arg) + TMath::BesselI(2, arg)); 
+
+ return res;
+}
+//-----------------------------------------------------------------------
+Double_t AliFlowAnalysisMaker::resEventPlaneK4(double chi) // ...for the case k=4.
+{
+ double con = TMath::Sqrt(TMath::Pi()/2)/2 ;   // ~ 0.626657
+ double arg = chi * chi / 4.;
+
+ double besselOneHalf = TMath::Sqrt(arg/(TMath::Pi()/2)) * sinh(arg)/arg;
+ double besselThreeHalfs = TMath::Sqrt(arg/(TMath::Pi()/2)) * (cosh(arg)/arg - sinh(arg)/(arg*arg));
+ double besselFiveHalfs = besselOneHalf - 3*besselThreeHalfs/arg;
+ Double_t res = con * chi * exp(-arg) * (besselThreeHalfs + besselFiveHalfs); 
+
+ return res;
+}
+//-----------------------------------------------------------------------
+Float_t AliFlowAnalysisMaker::Res(Int_t eventN, Int_t harN)    const   { return mRes[eventN][harN]; }
+Float_t AliFlowAnalysisMaker::ResErr(Int_t eventN, Int_t harN)         const   { return mResErr[eventN][harN]; }
+//-----------------------------------------------------------------------
+// ###
+//-----------------------------------------------------------------------
+TString AliFlowAnalysisMaker::GetHistFileName()                const   { return mHistFileName ; }
+TString AliFlowAnalysisMaker::GetPhiWgtFileName()              const   { return mPhiWgtFileName ; }
+TString AliFlowAnalysisMaker::GetInputFileName()               const   { return mFlowEvtFileName ; }
+//-----------------------------------------------------------------------
+void AliFlowAnalysisMaker::SetV1Ep1Ep2(Bool_t v1Ep1Ep2)                { mV1Ep1Ep2 = v1Ep1Ep2 ; }
+void AliFlowAnalysisMaker::SetFlowForV0(Bool_t fV0)                    { mV0 = fV0 ; }
+void AliFlowAnalysisMaker::SetEtaSub()                                         { mEtaSub = kTRUE ; }
+void AliFlowAnalysisMaker::SetHistFileName(TString name)               { mHistFileName = name ; }
+void AliFlowAnalysisMaker::SetPhiWgtFileName(TString name)             { mPhiWgtFileName = name ; }
+void AliFlowAnalysisMaker::SetInputFileName(TString name)              { mFlowEvtFileName = name ; }
+void AliFlowAnalysisMaker::SetShuffle(Bool_t sh)                       { mShuffle = sh ; }
+void AliFlowAnalysisMaker::SetRedoWgt(Bool_t rd)                       { mRedoWgt = rd ; }
+
+void AliFlowAnalysisMaker::SetUsePhiWgt(Bool_t pw)                     { mPhiWgt = pw ; }
+void AliFlowAnalysisMaker::SetUseBayWgt(Bool_t bw)                     { mBayWgt = bw ; }
+void AliFlowAnalysisMaker::SetUsePtWgt(Bool_t ptw)                     { mPtWgt = ptw ; }
+void AliFlowAnalysisMaker::SetUseEtaWgt(Bool_t etw)                    { mEtaWgt = etw ; }
+void AliFlowAnalysisMaker::SetUseOnePhiWgt()                           { mOnePhiWgt = kTRUE ; }
+void AliFlowAnalysisMaker::SetUseFirstLastPhiWgt()                     { mOnePhiWgt = kFALSE ; }
+
+void AliFlowAnalysisMaker::SetFillLabels(Bool_t lb)                    { mLabelling = lb ; }
+void AliFlowAnalysisMaker::SetMaxLabel(Int_t bin)                      { maxLabel = bin ; }
+void AliFlowAnalysisMaker::SetOneInputFile(Bool_t in)                  { fOneInputFile = in ; }
+void AliFlowAnalysisMaker::SetMakeAll(Bool_t mka)                      { mMakeAll = mka ; }
+//-----------------------------------------------------------------------
+void AliFlowAnalysisMaker::SetInputFileNames(TString name)             
+{ 
+ TObjString* objName = new TObjString(name.Data()) ; 
+ fFileNames.Add(objName) ;
+}
+//-----------------------------------------------------------------------
+void AliFlowAnalysisMaker::SetHistoRanges(float etaMin, float etaMax, int EtaBins)    
+{
+ // sets eta limits for histogram 
+
+ mEtaMin = etaMin ;
+ mEtaMax = etaMax ;
+ mNEtaBins = EtaBins ;
+}
+//------------------------------------------------------------------------
+void AliFlowAnalysisMaker::SetPtRange_for_vEta(Float_t lo, Float_t hi)  
+{
+ // pt range for the v(eta) histograms
+
+ mPtRange_for_vEta[0] = lo ;
+ mPtRange_for_vEta[1] = hi ;
+}
+//------------------------------------------------------------------------
+void AliFlowAnalysisMaker::SetEtaRange_for_vPt(Float_t lo, Float_t hi)
+{
+ // |eta| range for the v(pt) histograms 
+ mEtaRange_for_vPt[0] = lo ;
+ mEtaRange_for_vPt[1] = hi ;
+}
+//------------------------------------------------------------------------
+void AliFlowAnalysisMaker::SetDebugg(Int_t db)  
+{
+ // debug options (0..3) 
+ mDebug = db ; 
+ Debug0 = kTRUE ; Debug1 = kFALSE ; Debug2 = kFALSE ; Debug3 = kFALSE ; 
+ if(mDebug == 1) { Debug1 = kTRUE ; }
+ if(mDebug == 2) { Debug1 = kTRUE ; Debug2 = kTRUE ; } 
+ if(mDebug == 3) { Debug1 = kTRUE ; Debug3 = kTRUE ; } 
+ if(mDebug == 4) { Debug1 = kTRUE ; Debug4 = kTRUE ; } 
+ if(mDebug > 4)  { Debug1 = kTRUE ; Debug2 = kTRUE ; Debug3 = kTRUE ; Debug4 = kTRUE ; } 
+}
+//-----------------------------------------------------------------------
+
diff --git a/PWG2/FLOW/AliFlowAnalysisMaker.h b/PWG2/FLOW/AliFlowAnalysisMaker.h
new file mode 100644 (file)
index 0000000..4444ed9
--- /dev/null
@@ -0,0 +1,570 @@
+//////////////////////////////////////////////////////////////////////
+//
+// $Id$
+//
+// Author: Emanuele Simili
+//
+//////////////////////////////////////////////////////////////////////
+//
+// Description: routines to study Flow from AliFlowEvent, adapted from STAR
+// Original Authors:                 Raimond Snellings & Art Poskanzer
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef AliFlowAnalysisMaker_H
+#define AliFlowAnalysisMaker_H
+
+#include <stdlib.h>
+#include <iostream>
+
+#include "AliFlowTrack.h"
+#include "AliFlowV0.h"
+#include "AliFlowEvent.h"
+#include "AliFlowSelection.h"
+#include "AliFlowConstants.h"
+
+#include "TTree.h"
+#include "TFile.h"
+#include "TString.h"
+#include "TH1.h"
+#include "TH2.h"
+#include "TH3.h"
+#include "TProfile.h"
+#include "TProfile2D.h"
+#include "TOrdCollection.h"
+#include "TMath.h"
+#include "TText.h"
+#include "TVector2.h"
+#include "TString.h"
+#include "TList.h" 
+#include "TObjArray.h"
+#include "TObjString.h"
+
+class AliFlowTrack;
+class AliFlowV0;
+class AliFlowEvent;
+class AliFlowSelection;
+class Flow;
+class TH1F;
+class TH1D;
+class TH2F;
+class TH2D;
+class TH3F;
+class TProfile;
+class TProfile2D;
+
+class AliFlowAnalysisMaker {
+
+  /*!
+    \class AliFlowAnalysisMaker
+    Makes histograms for the flow analysis. It reads event and particle quantities
+    from AliFlowEvent. It removes autocorrelations of each particle with respect
+    to the event plane. For each harmonic and each selection makes a 2D histogram
+    of the anisotropic flow, v, vs. y and p_t.
+  */
+  
+public:
+  
+  AliFlowAnalysisMaker(const Char_t* name="FlowAnalysis");                        // Default constructor
+  AliFlowAnalysisMaker(const Char_t* name, const AliFlowSelection& pFlowSelect);   // Constructor with selection object
+  AliFlowAnalysisMaker(const AliFlowAnalysisMaker &from) {};
+  virtual  ~AliFlowAnalysisMaker();
+
+ // Steps of the flow analysis
+  void     InitDefault() ;                                     // Default sets
+  Int_t    Init() ;                                            // Books histograms for flow analysis
+  Int_t    Make() ;                                            // Open FlowEvents, Gets quantities, Fills histograms
+  Int_t    Finish() ;                                          // Saves histograms, Closes stuff
+
+ // Analysis of 1 event (can be called from outside)
+  Bool_t   Analyze(AliFlowEvent* pFlowEvent = 0) ;             // Fills the defaults histograms (init them first!) and performs the calculation for the given event         
+
+ // Analysis options
+  void    SetEtaSub() ;                                        // Set eta subevents
+  void     SetV1Ep1Ep2(Bool_t v1Ep1Ep2 = kTRUE);               // Switches the v_1{EP1,EP2} calculation on/off
+  void    SetShuffle(Bool_t sh = kTRUE) ;                      // Set to re-shuffle evt tracks
+  void     SetUsePhiWgt(Bool_t pw = kTRUE) ;                   // Set to use phi weights (true by default...if there)
+  void            SetUseBayWgt(Bool_t bw = kTRUE) ;                    // Set to use bayesian weights for p.id. (false by default)
+
+  void     SetUsePtWgt(Bool_t ptw = kTRUE);                    // uses pT as a weight for RP determination
+  void     SetUseEtaWgt(Bool_t etw = kTRUE);                   // uses eta as a weight for RP determination
+  void     SetUseOnePhiWgt();                                  // just one wgt histogram
+  void     SetUseFirstLastPhiWgt();                            // uses 3 wgt histograms
+
+ // Other options
+  void    SetMakeAll(Bool_t mka=kTRUE) ;                       // Set to calculate all events variables in one shoot
+  void    SetFlowForV0(Bool_t fV0 = kTRUE) ;                   // Enables Flow study for v0
+  void    SetRedoWgt(Bool_t rd = kTRUE) ;                      // Set recalculation of weights
+
+ // Histograms
+  void     SetHistoRanges(float etaMin = -1.,float etaMax = 1.,int EtaBins = 40) ; // Sets the histograms' limits
+  void     SetPtRange_for_vEta(Float_t lo, Float_t hi);                // Sets the pt range for the v(eta) histograms.
+  void     SetEtaRange_for_vPt(Float_t lo, Float_t hi);                // Sets the |eta| range for the v(pt) histograms.
+
+ // Input/Output 
+  void    SetHistFileName(TString name) ;                      // Sets output file name
+  void    SetPhiWgtFileName(TString name) ;                    // Sets Wgt file name
+  void    SetInputFileName(TString name) ;                     // Sets Input File name (the FlowEvents file) 
+  void    SetInputFileNames(TString name) ;                    // Sets Input Files (more than 1)
+  void    SetOneInputFile(Bool_t in=kTRUE) ;                   // Sets just one Input file 
+  TString  GetHistFileName() const ;                           // Output File Name
+  TString  GetPhiWgtFileName() const ;                         // Wgt File Name
+  TString  GetInputFileName() const ;                          // Input (Flow Events) file Name
+
+ // MC simulation & debug
+  void     SetDebugg(Int_t db = 1) ;                           // set the cout's for debug (default is 1)
+  void     SetFillLabels(Bool_t lb=kTRUE) ;                    // fills labels histogram (execution is heavier)
+  void            SetMaxLabel(Int_t bin) ;                             // set the last bin in the MC-label histogram
+
+ // Some Results
+  Float_t  Res(Int_t eventN, Int_t harN) const ;               // Returns the calculated resolution for the RP
+  Float_t  ResErr(Int_t eventN, Int_t harN) const ;            // Returns the estimated error on the resolution 
+  void     GetRunBayesian(Double_t bayes[Flow::nPid],int sel=0) ;  // Normalized Particle abundance (all events up to here)
+  void     PrintRunBayesian(int sel=0) ;                       // Prints the normalized Particle abundance (up to here)
+
+
+private:
+
+ // Weightening
+  void     WgtChk() ;                                          // Check for Read/Write weights, sets labels accordingly
+  void     FillEvtPhiWgt() ;                                   // Plugs the PhiWeights into the AliFlowEvent
+  void     FillWgtArrays(TFile* wgtFile) ;                     // Loads phi & bayesian weights from file (flowPhiWgt.hist.root) and fills the specific arrays
+  void     FillBayesianWgt(int sel=0) ;                        // Plugs the Bayesian Weights into the AliFlowEvent (selection 0)
+  void     Weightening() ;                                     // Calculates weights and fills PhiWgt histograms
+
+ // Open a new Imput File / Load a new Event
+  AliFlowEvent* GetEvt(Int_t evt = -1) ;                       // Gets flow event & V0s
+  Bool_t   Open(const Char_t* filename="") ;                   // Open FlowEvents file
+  Bool_t   FillFromFlowEvent() ;                               // Fills internal variables and array from Flow Events
+
+ // Internal methods to fill the histogram
+  void     FillEventHistograms() ;                             // Fills Events' histograms (from AliFlowEvent)
+  void     FillParticleHistograms() ;                          // Fills Tracks' histograms (from AliFlowTrack)
+  void     FillV0Histograms() ;                                 // Fills V0s' histograms
+  int      HarmonicsLoop(float eta,float phi,float pt,int numPid=-1) ;         // Harmonics & Selections relates histograms (from AliFlowTracks)
+  void     FillLabels() ;                                      // fills an histogram of Labels (the ones from ESD) 
+
+ // Resolution Calculation
+  void     Resolution() ;                                      // Calculates resolution and mean flow values
+  Double_t chi(double res) ;                                   // Calculates chi from the event plane resolution
+  Double_t resEventPlane(double chi) ;                         // Calculates the event plane resolution as a function of chi
+  Double_t resEventPlaneK2(double chi) ;                       // Calculates the event plane resolution as a function of chi for the case k=2.
+  Double_t resEventPlaneK3(double chi) ;                       // Calculates the event plane resolution as a function of chi for the case k=3.
+  Double_t resEventPlaneK4(double chi) ;                       // Calculates the event plane resolution as a function of chi for the case k=4.
+
+ // Flags
+  Bool_t   mV0 ;                                               //! correlation analysis is done also for neutral secundary vertex
+  Bool_t   mShuffle ;                                          //! to randomly reshuffle tracks
+  Bool_t   mV1Ep1Ep2;                                          //! Flag for v_1{EP1,EP2} calculation on/off
+  Bool_t   mEtaSub;                                             //! eta subevents
+  Bool_t   mReadPhiWgt ;                                       //! Flag for reading Wgt histograms from file (automatic if flowPhi.hist.root is there)
+  Bool_t   mWritePhiWgt ;                                      //! Flag for writing Wgt histograms to file (automatic if flowPhi.hist.root is NOT there)
+  Bool_t   mRedoWgt ;                                          //! Flag for recalculating Wgt histograms (even if flowPhi.hist.root exist)
+  Bool_t   mPhiWgt ;                                           //! Phi Weights are applied to Phi distrib. (default is true)
+  Bool_t   mBayWgt ;                                           //! Bayesian Weights are applied to P.Id. (default is false) 
+  Bool_t   mRePid ;                                            //! Re-Calculates the P.Id. basing on the bayesian wgts (if plugged in)
+  Bool_t   mOnlyConstrainable ;                                        //! to loop just over constrainable tracks
+  Bool_t   mMakeAll ;                                          //! claculates all events vars in one shoot (should run faster)
+  Bool_t   mLabellingFirst ;                                   //! creates label file (internal)
+  Bool_t   mLabelling ;                                                //! takes note of Labels from ESD
+
+  Bool_t   mPtWgt ;                                            //! flag to use pT as a weight for RP determination
+  Bool_t   mEtaWgt ;                                           //! flag to use eta as a weight for RP determination
+  Bool_t   mOnePhiWgt ;                                        //! if kTRUE: just one phi-wgt histogram, if kFALSE: three phi-wgt histogram (TPC+,TPC-,cross)
+
+ // ...for debugging
+  Int_t    mDebug ;                                            //! Debug level (0,1,2,3)
+  Bool_t   Debug0 ;                                            //! Flag for Debug couts
+  Bool_t   Debug1 ;                                            //! Flag for Debug couts lev.1
+  Bool_t   Debug2 ;                                            //! Flag for Debug couts lev.2
+  Bool_t   Debug3 ;                                            //! Flag for Debug couts lev.3
+  Bool_t   Debug4 ;                                            //! Flag for Debug couts lev.3
+
+ // File names
+  TString          mHistFileName ;                             //! Output File Name (histograms from flow analysis)
+  TString          mPhiWgtFileName ;                           //! Wgt File Name (histograms for weight)
+  TString          mFlowEvtFileName ;                          //! Input file name (Flow Events)
+  Bool_t           fOneInputFile ;                             //! one/more imput file
+  TObjArray         fFileNames ;
+
+ // Couts
+  TString          mName ;                                     //! Name from the constructor
+  TString          FlowAnalysis ;                              //! Default mark for cout's
+  TString          spaces ;                                    //! Default spaces for cout's
+
+ // variables
+  Int_t             nEvents ;                                  //! number of FlowEvents in file
+  Int_t             nTracks ;                                  //! number of FlowTracks in FlowEvent
+  Int_t             nV0s ;                                     //! number of FlowV0s in FlowEvent
+  Int_t             evtN ;                                     //! current Event number (after selected ++)
+  TString           evt_name ;                                         //! current Event name (number) 
+  Float_t           vertex[3] ;                                        //! Event's Vertex position 
+
+ // For weights
+  Flow::PhiWgt_t nPhiWgt ;                                     //! PhiWgt Array (all TPC)
+  Flow::PhiWgt_t nPhiWgtPlus ;                                 //! PhiWgt Array (TPC+)
+  Flow::PhiWgt_t nPhiWgtMinus ;                                //! PhiWgt Array (TPC-)
+  Flow::PhiWgt_t nPhiWgtCross ;                                //! PhiWgt Array (TPC/)     
+ // For bayesian weights
+  Double_t nBayWgt[Flow::nSels][Flow::nPid] ;                  //! Bayesian weights (expected particle abundance)
+
+#ifndef __CINT__
+  TVector2 mQ[Flow::nSels][Flow::nHars];                       //! flow vector
+  Float_t  mPsi[Flow::nSels][Flow::nHars];                     //! event plane angle
+  UInt_t   mMult[Flow::nSels][Flow::nHars];                    //! multiplicity
+  Float_t  m_q[Flow::nSels][Flow::nHars];                      //! Q/::sqrt(Mult)
+  TVector2 mQSub[Flow::nSubs][Flow::nSels][Flow::nHars];       //! flow vector subs
+  Float_t  mPsiSub[Flow::nSubs][Flow::nSels][Flow::nHars];     //! plane angle of subevents
+  UInt_t   mMultSub[Flow::nSubs][Flow::nSels][Flow::nHars];    //! multiplicity subs
+  Float_t  mRes[Flow::nSels][Flow::nHars];                     //! event plane resolution
+  Float_t  mResErr[Flow::nSels][Flow::nHars];                  //! event plane resolution error
+#endif /*__CINT__*/
+
+ // Internal pointers
+  AliFlowEvent*     pFlowEvent ;                               //! pointer to AliFlowEvent
+  AliFlowTrack*     pFlowTrack ;                               //! pointer to AliFlowTrack
+  AliFlowV0*        pFlowV0 ;                                  //! pointer to AliFlowV0
+  AliFlowSelection* pFlowSelect ;                              //! selection object
+  TFile*            pFlowEventsFile ;                          //! pointer to FlowEvents file (input)
+  TList*            pFlowEventsList ;                          //! FlowEvents in the file (input)
+  TObjArray*        pFlowTracks ;                              //! pointer to the TrackCollection
+  TObjArray*        pFlowV0s ;                                 //! pointer to the V0Collection
+  TFile*            histFile ;                                         //! histograms file (output)
+  //TTree*            pFlowTree;                               //! flow events TTree (NEW input - not there)
+
+ // for Histograms
+  TString           xLabel ;                                   //! label axis with rapidity or pseudorapidity
+  Float_t          mEtaMin ;                                   //! histo range (eta)
+  Float_t          mEtaMax ;                                   //! histo range (eta)
+  Int_t            mNEtaBins ;                                 //! histo bins  (eta)
+  Float_t          mPtRange_for_vEta[2] ;                      //! pt range for the v(eta) histograms.
+  Float_t          mEtaRange_for_vPt[2] ;                      //! |eta| range for the v(pt) histograms.
+  Int_t            maxLabel ;                                  //! for the MC labels histogram (max bin)
+
+  TOrdCollection*   mPhiWgtHistList ;                          //! Weights:  histogram list
+  TOrdCollection*   mVnResHistList ;                           //! Resolution and Vn:  histogram list
+// for Single histograms
+
+ // *****************
+ // EVENTs HISTOGRAMS
+ // *****************
+  TH1F*     mHistTrigger;                                 //!
+  TH1F*     mHistMult;                                    //!
+  TH1F*     mHistV0Mult;                                  //!
+  TH1F*     mHistOrigMult;                                //!
+  TH1F*     mHistMultOverOrig;                            //!
+  TH1F*     mHistMultEta;                                 //!
+  TH1F*     mHistCent;                                    //!
+  TH1F*     mHistVertexZ;                                 //!
+  TH2F*     mHistVertexXY2D;                              //!
+  TH2F*     mHistEnergyZDC;                               //!
+  TH1F*     mHistPartZDC;                                         //!
+  TProfile* mHistPidMult;                                 //!
+  TH1F*     mHistBayPidMult;                              //!
+  TH1F*     mHistEtaSym;                                  //!          // ...part also
+  TH1F*     mHistEtaSymPart;                              //!
+  TH2F*     mHistEtaSymVerZ2D;                            //!          // ...part also
+  TH2F*     mHistEtaSymVerZ2DPart;                        //!
+ // selected (TR & V0)
+  TH1F*     mHistMultPart;                                //!
+  TH1F*     mHistV0MultPart;                              //!
+  TH1F*     mHistBayPidMultPart;                          //!
+  TH1F*     mHistMultPartUnit;                                    //!
+  
+ // *****************
+ // TRACKs HISTOGRAMS (all tracks)
+ // *****************
+  TH1F*     mHistPtot ;                                   //!
+  TH1F*     mHistPt ;                                     //!
+  TH1F*     mHistCharge;                                  //!
+  TH1F*     mHistDcaGlobal;                               //!
+  TH1F*     mHistDca;                                     //!
+  TH1F*     mHistTransDca;                                        //!
+  TH1F*     mHistChi2;                                    //!
+  TH1F*     mHistLenght;                                  //!
+  TH1F*     mHistInvMass ;                                //!
+  TH1F*     mHistFitOverMax;                                      //!
+  TH2D*     mHistPhiPtCon ;                               //!
+  TH2D*     mHistPhiPtUnc ;                               //!
+  TH2D*     mHistPtPhiPos ;                               //!
+  TH2D*     mHistPtPhiNeg ;                               //!
+  TH3F*     mHistAllEtaPtPhi3D;                           //!
+  TProfile* mHistCosPhi;                                  //!
+  TH2F*     mHistPidPt;                                   //!
+  TH1F*     mHistPhi ;                                            //!
+  TH1F*     mHistPhiCons ;                                //!
+  TH2D*     mHistYieldAll2D;                              //!
+  TH2D*     mHistYieldCon2D;                              //!
+  TH2D*     mHistYieldUnc2D;                              //!
+  TH3F*     mHistConsEtaPtPhi3D;                          //!
+  TH3F*     mHistGlobEtaPtPhi3D;                          //! 
+  TH3F*     mHistUncEtaPtPhi3D ;                          //!
+  // fit & dE/dX for each detector (all tracks) 
+  TH1F*     mHistChi2ITS;                                 //!
+  TH1F*     mHistChi2normITS;                             //!
+  TH1F*     mHistFitPtsITS;                               //!
+  TH1F*     mHistMaxPtsITS;                               //!
+  TH2F*     mHistMeanDedxPos2DITS;                        //!
+  TH2F*     mHistMeanDedxNeg2DITS;                        //!
+  // -
+  TH1F*     mHistChi2TPC;                                 //!
+  TH1F*     mHistChi2normTPC;                             //!
+  TH1F*     mHistFitPtsTPC;                               //!
+  TH1F*     mHistMaxPtsTPC;                               //!
+  TH1F*     mHistFitOverMaxTPC;                           //!
+  TH2F*     mHistMeanDedxPos2D;                           //!
+  TH2F*     mHistMeanDedxNeg2D;                           //!
+  // -
+  TH1F*     mHistChi2TRD;                                 //!
+  TH1F*     mHistChi2normTRD;                             //!
+  TH1F*     mHistFitPtsTRD;                               //!
+  TH1F*     mHistMaxPtsTRD;                               //!
+  TH2F*     mHistMeanDedxPos2DTRD;                        //!
+  TH2F*     mHistMeanDedxNeg2DTRD;                        //!
+  // -
+  TH1F*     mHistChi2TOF;                                 //!
+  TH1F*     mHistChi2normTOF;                             //!
+  TH1F*     mHistFitPtsTOF;                               //!
+  TH1F*     mHistMaxPtsTOF;                               //!
+  TH2F*     mHistMeanDedxPos2DTOF;                        //!
+  TH2F*     mHistMeanDedxNeg2DTOF;                        //!
+  // detector response for particle type (all tracks, based on Pid)
+  TH2F*     mHistMeanTPCPiPlus ;                          //!
+  TH2F*     mHistMeanTPCPiMinus ;                         //!
+  TH2F*     mHistMeanTPCProton ;                          //!
+  TH2F*     mHistMeanTPCPbar ;                            //!
+  TH2F*     mHistMeanTPCKplus ;                           //!
+  TH2F*     mHistMeanTPCKminus ;                          //!
+  TH2F*     mHistMeanTPCDeuteron ;                        //!
+  TH2F*     mHistMeanTPCAntiDeuteron ;                    //!
+  TH2F*     mHistMeanTPCPositron ;                        //!
+  TH2F*     mHistMeanTPCElectron ;                        //!
+  TH2F*     mHistMeanTPCMuonPlus ;                        //!
+  TH2F*     mHistMeanTPCMuonMinus ;                       //!
+  // -
+  TH2F*     mHistMeanITSPiPlus ;                          //!
+  TH2F*     mHistMeanITSPiMinus ;                         //!
+  TH2F*     mHistMeanITSProton ;                          //!
+  TH2F*     mHistMeanITSPbar ;                            //!
+  TH2F*     mHistMeanITSKplus ;                           //!
+  TH2F*     mHistMeanITSKminus ;                          //!
+  TH2F*     mHistMeanITSDeuteron ;                        //!
+  TH2F*     mHistMeanITSAntiDeuteron ;                    //!
+  TH2F*     mHistMeanITSPositron ;                        //!
+  TH2F*     mHistMeanITSElectron ;                        //!
+  TH2F*     mHistMeanITSMuonPlus ;                        //!
+  TH2F*     mHistMeanITSMuonMinus ;                       //!
+  // -
+  TH2F*     mHistMeanTOFPiPlus ;                          //!
+  TH2F*     mHistMeanTOFPiMinus ;                         //!
+  TH2F*     mHistMeanTOFProton ;                          //!
+  TH2F*     mHistMeanTOFPbar ;                            //!
+  TH2F*     mHistMeanTOFKplus ;                           //!
+  TH2F*     mHistMeanTOFKminus ;                          //!
+  TH2F*     mHistMeanTOFDeuteron ;                        //!
+  TH2F*     mHistMeanTOFAntiDeuteron ;                    //!
+  TH2F*     mHistMeanTOFPositron ;                        //!
+  TH2F*     mHistMeanTOFElectron ;                        //!
+  TH2F*     mHistMeanTOFMuonPlus ;                        //!
+  TH2F*     mHistMeanTOFMuonMinus ;                       //!
+  // -
+  TH2F*     mHistMeanTRDPiPlus ;                          //!
+  TH2F*     mHistMeanTRDPiMinus ;                         //!
+  TH2F*     mHistMeanTRDProton ;                          //!
+  TH2F*     mHistMeanTRDPbar ;                            //!
+  TH2F*     mHistMeanTRDKplus ;                           //!
+  TH2F*     mHistMeanTRDKminus ;                          //!
+  TH2F*     mHistMeanTRDDeuteron ;                        //!
+  TH2F*     mHistMeanTRDAntiDeuteron ;                    //!
+  TH2F*     mHistMeanTRDPositron ;                        //!
+  TH2F*     mHistMeanTRDElectron ;                        //!
+  TH2F*     mHistMeanTRDMuonPlus ;                        //!
+  TH2F*     mHistMeanTRDMuonMinus ;                       //!
+  // pid probability for all particle (all tracks)
+  TH1F*     mHistPidPiPlus;                               //!
+  TH1F*     mHistPidPiMinus;                              //!
+  TH1F*     mHistPidProton;                               //!
+  TH1F*     mHistPidAntiProton;                           //!
+  TH1F*     mHistPidKplus;                                //!
+  TH1F*     mHistPidKminus;                               //!
+  TH1F*     mHistPidDeuteron;                             //!
+  TH1F*     mHistPidAntiDeuteron;                         //!
+  TH1F*     mHistPidElectron;                             //!
+  TH1F*     mHistPidPositron;                             //!
+  TH1F*     mHistPidMuonMinus;                            //!
+  TH1F*     mHistPidMuonPlus;                             //!
+  // pid probability for particle type (all tracks, based on Pid)
+  TH1F*     mHistPidPiPlusPart;                           //!
+  TH1F*     mHistPidPiMinusPart;                          //!
+  TH1F*     mHistPidProtonPart;                           //!
+  TH1F*     mHistPidAntiProtonPart;                       //!
+  TH1F*     mHistPidKplusPart;                            //!
+  TH1F*     mHistPidKminusPart;                           //!
+  TH1F*     mHistPidDeuteronPart;                         //!
+  TH1F*     mHistPidAntiDeuteronPart;                     //!
+  TH1F*     mHistPidElectronPart;                         //!
+  TH1F*     mHistPidPositronPart;                         //!
+  TH1F*     mHistPidMuonMinusPart;                        //!
+  TH1F*     mHistPidMuonPlusPart;                         //!
+  // MC labels from the simulation (all tracks)
+  TH2F*     mLabHist;                                     //! 
+ // *****************
+ // selected TRACKS
+ // *****************
+  TProfile* mHistBinEta;                                  //!
+  TProfile* mHistBinPt;                                   //!
+  //
+  TH3F*     mHistEtaPtPhi3DPart ;                         //!
+  TH2D*     mHistYieldPart2D;                             //!
+  TH1F*     mHistDcaGlobalPart ;                          //!
+  TH1F*     mHistInvMassPart ;                            //!
+  TH3F*     mHistEtaPtPhi3DOut ;                          //!
+  TH2D*     mHistYieldOut2D;                              //!
+  TH1F*     mHistDcaGlobalOut ;                                   //!
+  TH1F*     mHistInvMassOut ;                             //!
+  TH3F*     mHistMeanDedxPos3DPart ;                      //!
+  TH3F*     mHistMeanDedxNeg3DPart ;                      //!
+  TH3F*     mHistMeanDedxPos3DPartITS ;                           //!
+  TH3F*     mHistMeanDedxNeg3DPartITS ;                           //!
+//
+
+ // *****************
+ // V0s HISTOGRAMS (all v0s)
+ // *****************
+  TH1F*     mHistV0Mass;                                  //!
+  TH3F*     mHistV0EtaPtPhi3D;                            //!
+  TH2D*     mHistV0YieldAll2D;                            //!
+  TH1F*     mHistV0Dca;                                           //!
+  TH1F*     mHistV0Chi2;                                  //!
+  TH1F*     mHistV0Lenght;                                //!
+  TH1F*     mHistV0Sigma;                                 //!
+  TProfile* mHistV0CosPhi;                                //! 
+  TH2D*     mHistV0MassPtSlices;                          //!
+ // *****************
+ // selected V0s
+ // *****************
+  TProfile* mHistV0BinEta;                                //! 
+  TProfile* mHistV0BinPt;                                 //! 
+  TProfile* mHistV0sbBinEta;                              //! 
+  TProfile* mHistV0sbBinPt;                               //!
+  //
+  TH1F*     mHistV0MassWin ;                              //!
+  TH3F*     mHistV0EtaPtPhi3DPart ;                       //!
+  TH2D*     mHistV0YieldPart2D;                           //!
+  TH1F*     mHistV0DcaPart ;                              //!
+  TH1F*     mHistV0LenghtPart ;                                   //!
+  TH1F*     mHistV0sbMassSide ;                           //!
+  TH3F*     mHistV0sbEtaPtPhi3DPart ;                     //!
+  TH2D*     mHistV0sbYieldPart2D;                         //!
+  TH1F*     mHistV0sbDcaPart ;                            //!
+  TH1F*     mHistV0sbLenghtPart ;                         //!
+
+// for each harmonic, each selection, and each sub-event
+
+ // *****************
+ // SUB-EVENTs HISTOGRAMS
+ // *****************
+  struct histSubHars {
+   TH1F*     mHistPsiSubs;
+  };
+  struct histSubs;     
+  friend struct histSubs;
+  struct histSubs {
+   struct histSubHars histSubHar[Flow::nHars];
+  };
+  struct histSubs histSub[Flow::nSels*Flow::nSubs];        //!
+
+// for each harmonic and each selection
+
+  struct histFullHars 
+  {
+   // weights
+    TH1D*       mHistPhiPlus;
+    TH1D*       mHistPhiMinus;
+    TH1D*       mHistPhiAll;
+    TH1D*       mHistPhiWgtPlus;
+    TH1D*       mHistPhiWgtMinus;
+    TH1D*       mHistPhiWgtAll;
+    TH1D*       mHistPhiFlatPlus;
+    TH1D*       mHistPhiFlatMinus;
+    TH1D*       mHistPhiFlatAll;
+    TH1D*       mHistPhi;
+    TH1D*       mHistPhiWgt;
+    TH1D*       mHistPhiFlat;
+   // flow (events)
+    TH1F*       mHistPsi;
+    TH1F*       mHistPsiSubCorr;
+    TH1F*       mHistPsiSubCorrDiff;
+    TH1F*       mHistPsi_Diff;
+    TH1F*       mHistMult;
+    TH1F*       mHist_q;
+   // flow (tracks)
+    TH1F*       mHistPhiCorr;
+    TProfile2D* mHist_vObs2D;
+    TProfile*   mHist_vObsEta;
+    TProfile*   mHist_vObsPt;
+    TH2D*       mHist_v2D;
+    TH1D*       mHist_vEta;
+    TH1D*       mHist_vPt;
+   // flow (v0s)
+    TH1F*       mHistV0PhiCorr;   
+    TProfile2D* mHistV0_vObs2D;   
+    TProfile*   mHistV0_vObsEta;  
+    TProfile*   mHistV0_vObsPt;   
+    TH2D*      mHistV0_v2D;      
+    TH1D*      mHistV0_vEta;     
+    TH1D*      mHistV0_vPt;      
+   // flow (v0s sidebands)
+    TProfile*   mHistV0sb_vObsEta_sx ;  
+    TProfile*   mHistV0sb_vObsPt_sx ;   
+    TProfile*   mHistV0sb_vObsEta_dx ;  
+    TProfile*   mHistV0sb_vObsPt_dx ;   
+    TH1F*       mHistV0sbPhiCorr ;   
+    TProfile2D* mHistV0sb_vObs2D ;   
+    TProfile*   mHistV0sb_vObsEta ;  
+    TProfile*   mHistV0sb_vObsPt ;   
+    TH2D*      mHistV0sb_v2D ;      
+    TH1D*      mHistV0sb_vEta ;     
+    TH1D*      mHistV0sb_vPt ;      
+   // check (tracks used for R.P.)
+    TH1F*       mHistYieldPt ;
+    TH3F*       mHistEtaPtPhi3D ;
+    TH2D*       mHistYield2D ;
+    TH1F*       mHistDcaGlob ;
+   // check (tracks excluded)
+    TH1F*      mHistYieldPtout;
+    TH3F*      mHistEtaPtPhi3Dout ;
+    TH2D*      mHistYield2Dout ;
+    TH1F*      mHistDcaGlobout ;
+  };
+
+// for each selection
+
+  struct histFulls;    
+  friend struct histFulls;
+  struct histFulls 
+  {
+   TH1F*     mHistBayPidMult;
+  // flow (events)
+   TProfile* mHistCos;
+   TH1F*     mHistRes;
+   TProfile* mHist_vObs;
+   TH1D*     mHist_v;
+   TProfile* mHistV0_vObs;
+   TProfile* mHistV0sb_vObs_sx;
+   TProfile* mHistV0sb_vObs_dx;
+   TH1D*     mHistV0_v;
+  // wgt, evts, trks, v0s (as defined above)
+   struct histFullHars histFullHar[Flow::nHars];
+  };
+  struct histFulls histFull[Flow::nSels];                     //!
+
+  ClassDef(AliFlowAnalysisMaker,2)              // macro for rootcint
+};
+
+#endif
+
+
+
+// lame = not productive; poorly designed; uncool ...
diff --git a/PWG2/FLOW/AliFlowConstants.cxx b/PWG2/FLOW/AliFlowConstants.cxx
new file mode 100644 (file)
index 0000000..726ded9
--- /dev/null
@@ -0,0 +1,50 @@
+//////////////////////////////////////////////////////////////////////
+//
+// $Id$
+//
+// Author: Emanuele Simili
+//
+//////////////////////////////////////////////////////////////////////
+//_____________________________________________________________
+//
+// Description: constants for the flow makers and the flow analysis
+//
+// Original Authors:                 Art Poskanzer & Raimond Snellings
+//
+
+#include "AliFlowConstants.h"
+
+ClassImp(Flow)
+  
+  Float_t  Flow::fEtaMin    = -2.5 ;
+  Float_t  Flow::fEtaMax    =  2.5 ;
+  Float_t  Flow::fPtMin     =  0. ;
+  Float_t  Flow::fPtMax     = 10. ;
+  Float_t  Flow::fPtMaxPart =  5. ;
+  Float_t  Flow::fPtWgtSaturation =  5. ;
+  Float_t  Flow::fEtaMinTpcOnly = -0.9 ;
+  Float_t  Flow::fEtaMaxTpcOnly =  0.9 ;
+
+  Float_t  Flow::fEtaMid = 0.5 ;
+  Float_t  Flow::fEtaGood = 0.9 ;
+  Float_t  Flow::fMaxMult = 2900. ; // Maximum expected multiplicity (now hijing)
+  Float_t  Flow::fCentNorm[nCents] = {0.0205,0.044,0.08,0.133,0.203,0.301,0.462,0.596,0.707} ;
+  Int_t    Flow::fCent0[nCents]  = {50,100,200,500,1000,2000,5000,8000,10000} ;
+  Double_t Flow::fBayesian[nPid] = {1.,1.,1.,1.,1.,1.} ;
+  Double_t Flow::fMagneticField = 0.4 ;
+  Double_t Flow::fCenterOfMassEnergy = 5500. ;
+  Short_t  Flow::fBeamMassNumberEast = 208 ;
+  Short_t  Flow::fBeamMassNumberWest = 208 ;
+
+  Float_t  Flow::fITSx = 15. ;         // SDD (?) where dE/dx is measured
+  Float_t  Flow::fTPCx = 84.5 ;                // TPC (?) inner wall
+  Float_t  Flow::fTRDx = 294.5 ;       // TRD first plate
+  Float_t  Flow::fTOFx = 370. ;                // TOF (?)
+
+  Int_t    Flow::fMClabel = 10000 ;              // mcLabel < 0 --> not used
+  Bool_t   Flow::fDebug = kFALSE ;
+  
+  Float_t  Flow::fMaxInt = 1000. ;
+
+//////////////////////////////////////////////////////////////////////
diff --git a/PWG2/FLOW/AliFlowConstants.h b/PWG2/FLOW/AliFlowConstants.h
new file mode 100644 (file)
index 0000000..e0f85f9
--- /dev/null
@@ -0,0 +1,84 @@
+//////////////////////////////////////////////////////////////////////
+//
+// $Id$
+//
+// Author: Emanuele Simili
+//
+//////////////////////////////////////////////////////////////////////
+//
+// Description: constants for the flow makers
+//
+// Original Authors:                 Art Poskanzer & Raimond Snellings
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef AliFlowConstants_h
+#define AliFlowConstants_h
+
+#include <TROOT.h>
+
+class Flow {
+
+ public:
+
+  enum {
+    nHars        =   2,                                        // number of harmonics (>= 2)
+    nSels        =   2,                                        // number of selections (for each harmonics) 
+    nSubs        =   2,                                        // number of sub-events
+    nPhiBins     = 360,                                        // number of phi bins in weighting histograms
+    nEtaBins     = 100,                                                // number of eta bins in FlowAnalysis histograms
+    nPtBins      = 100,                                                // number of pT bins in FlowAnalysis histograms
+    nPtBinsPart  = 100,                                                // number of pT bins in flow histograms
+    nCumulIntegOrders =   3,                                   // order of the cumulant analysis
+    nCumulInteg_qMax  =   8,                                   // ..
+    nCumulDiffOrders  =   2,                                   // ..
+    nCumulDiff_qMax   =   8,                                   // ..
+    nCents       = 9,                                          // total number of centrality classes
+    nPid         = 6                                           // total number of p.id. hypotesis
+  };
+
+  typedef Double_t PhiWgt_t[nSels][nHars][nPhiBins];           // intermediate type to import weights from histograms' file 
+
+  static Int_t   fMClabel ;                                    // checking the simulation: pTrack->Label()<fMClabel = primary track 
+  static Bool_t  fDebug ;                                      // for more cout statements (debugging purpose)
+
+ // Histograms limits
+  static Float_t fEtaMin ;                                     // eta lower limit for FlowAnalysis histograms
+  static Float_t fEtaMax ;                                     // eta upper limit for FlowAnalysis histograms
+  static Float_t fPtMin ;                                      // pT lower limit for FlowAnalysis histograms
+  static Float_t fPtMax ;                                      // pT upper limit for yield histograms
+  static Float_t fPtMaxPart ;                                  // pT upper limit for flow histograms
+  static Float_t fPtWgtSaturation ;                            // flow(pT) saturation value
+  static Float_t fEtaMinTpcOnly ;                              // eta lower limit of the full TPC acceptance (unused)
+  static Float_t fEtaMaxTpcOnly ;                              // eta upper limit of the full TPC acceptance (unused)
+
+ // Centrality Measurement
+  static Float_t  fEtaMid ;                                    // Mid-Rapidity interval, used for Centrality measurement
+  static Float_t  fEtaGood ;                                   // Good Rapidity interval (TPC acceptance)
+  static Int_t    fCent0[Flow::nCents] ;                       // Expected Multiplicity for each Centrality class
+  static Double_t fBayesian[Flow::nPid] ;                      // Expected particles' abundance
+  static Float_t  fCentNorm[Flow::nCents] ;                    // Normalized Multiplicity for each Centrality class
+  static Float_t  fMaxMult ;                                   // Maximum expected multiplicity
+
+ // Experimental Conditions
+  static Double_t fMagneticField;                              // magnetic field value (0.4 Tesla)
+  static Double_t fCenterOfMassEnergy;                         // center of mass energy (5.5 TeV)
+  static Short_t  fBeamMassNumberEast;                         // beam mass (Pb = 208)
+  static Short_t  fBeamMassNumberWest;                         // beam mass (Pb = 208)
+
+ // ALICE detector measures ...
+  static Float_t fITSx ;                                       // inner ITS radial distance from the interaction point
+  static Float_t fTPCx ;                                       // inner TPC radial distance from the interaction point 
+  static Float_t fTRDx ;                                       // inner TRD radial distance from the interaction point 
+  static Float_t fTOFx ;                                       // inner TOF radial distance from the interaction point 
+
+  static Float_t  fMaxInt ;                                    // big number (to avoid infinity)
+
+  ClassDef(Flow,1)                                             // macro for rootcint
+};
+
+typedef Flow AliFlowConstants; //PK: Make rootcint happy, class name=file name
+
+#endif
+
+//////////////////////////////////////////////////////////////////////
diff --git a/PWG2/FLOW/AliFlowEvent.cxx b/PWG2/FLOW/AliFlowEvent.cxx
new file mode 100644 (file)
index 0000000..0549886
--- /dev/null
@@ -0,0 +1,1054 @@
+//////////////////////////////////////////////////////////////////////
+//
+// $Id$
+//
+// Author: Emanuele Simili
+//
+//////////////////////////////////////////////////////////////////////
+//
+//_____________________________________________________________
+//
+// Description: 
+//         AliFlowEvent is the basic class to perform flow study in ALICE. 
+// The AliFlowEvent object contains data mebers wich summarize the ESD 
+// informations that are most useful for flow study, together with a 
+// collection of tracks (AliFlowTrackCollection) and reconstructed v0s. 
+// The class also implements member functions to calculate Multiplicity, 
+// Mean P and Pt, Q (the event plane vector), Psi (the event plane angle), 
+// normalized q (Q/sqrt(Mult) and Q/sqrt(sum of weights^2)), moreover, 
+// functions to separate random or eta sub-events, to fill the bayesian vector 
+// of particle abundance (for bayesian p.id calculation), to plug-in weights
+// (to make the tracks' distribution isotropic and to enhance the resolution), 
+// and to select the tracks that are used in the event plane calculation (for 
+// each harmonic, selection, and subevent. 
+// AliFlowEvent supports the standard analysis as well as the Cumulant 
+// Analysis: method to extract the generating functions for the old and new 
+// cumulant methods is also there.
+// The Flow Event structure (AliFlowEvent, AliFlowTrack, AliFlowV0 and 
+// AliFlowSelection) is independent from AliRoot, i.e. once the FlowEvents 
+// are filled from the AliESD or the MC KineTree (see AliFlowInterface: here 
+// AliRoot is needed), the flow analysis itself can be performed just under 
+// ROOT (see AliFlowAnalysisMaker).
+//
+// AliFlowEvent is adapted from the original class StFlowEvent, succesfully 
+// employed to study flow in the STAR experiment at RICH.
+// Original Authors:                 Raimond Snellings & Art Poskanzer
+//
+
+#include "AliFlowEvent.h"
+#include "AliFlowConstants.h"
+#include "TVector.h"
+#include "TVector2.h"
+#include "TVector3.h"
+#include <iostream>
+using namespace std; //required for resolving the 'cout' symbol
+
+// - Flags & Sets
+Bool_t  AliFlowEvent::fPtWgt          = kFALSE ;  // gives pT-based weights
+Bool_t  AliFlowEvent::fEtaWgt         = kFALSE ;  // gives eta-based weights
+Bool_t  AliFlowEvent::fOnePhiWgt       = kTRUE  ;  // kTRUE --> ENABLEs SINGLE WEIGHT ISTOGRAM , kFALSE --> ENABLEs 3 WEIGHT ISTOGRAMS
+Bool_t  AliFlowEvent::fNoWgt          = kFALSE ;  // No Weight is used
+// - Eta Sub-Events (later used to calculate the resolution)
+Bool_t  AliFlowEvent::fEtaSubs                = kFALSE ;  // makes eta subevents
+
+ClassImp(AliFlowEvent) ;
+//-----------------------------------------------------------
+AliFlowEvent::AliFlowEvent(Int_t lenght)  
+{
+ // Default constructor: initializes the ObjArray of FlowTracks and FlowV0s, 
+ // cleans the internal variables, sets all the weights to 1, sets default flags.
+ fEventID = 0 ; 
+ fRunID = 0 ;                 
+ fOrigMult = 0 ;
+ fL0TriggerWord = 0 ;                         
+ fCentrality = -1 ;
+ fZDCpart = 0 ;
+ for(int zz=0;zz<3;zz++) { fZDCenergy[zz] = 0. ; }
+ // Make a new track collection
+ fTrackCollection =  new TObjArray(lenght) ;
+ fV0Collection =  new TObjArray(0) ;
+ // Set Weights Arrays to 1 (default)
+ for(int nS=0;nS<Flow::nSels;nS++)
+ {
+  for(int nH=0;nH<Flow::nHars;nH++) 
+  {
+   for(int nP=0;nP<Flow::nPhiBins;nP++) 
+   { 
+    // enable this with: SetOnePhiWgt()  
+    fPhiWgt[nS][nH][nP] = 1.     ; // cout << nS << nH << nP << "  val  " << fPhiWgt[nS][nH][nP] << endl ; 
+    // enable these with: SetFirstLastPhiWgt()  
+    fPhiWgtPlus[nS][nH][nP]  = 1. ; // cout << nS << nH << nP << "  val  " << fPhiWgtPlus[nS][nH][nP] << endl ; 
+    fPhiWgtMinus[nS][nH][nP] = 1. ; // cout << nS << nH << nP << "  val  " << fPhiWgtMinus[nS][nH][nP] << endl ; 
+    fPhiWgtCross[nS][nH][nP] = 1. ; // cout << nS << nH << nP << "  val  " << fPhiWgtCross[nS][nH][nP] << endl ; 
+   }
+  }
+ }
+ //for(int nH=0;nH<Flow::nHars;nH++) { fExtPsi[nH] = 0. ; fExtRes[nH] = 0. ; }
+ // The Expected particles abundance is taken directly from Flow::fBayesian[] (see Bayesian P.Id.)
+ fDone = kFALSE ;
+}
+//-----------------------------------------------------------
+AliFlowEvent::~AliFlowEvent() 
+{
+ // Default distructor: deletes the ObjArrays. 
+ fTrackCollection->Delete() ; delete fTrackCollection ;
+ fV0Collection->Delete()    ; delete fV0Collection ;
+}
+//-------------------------------------------------------------
+
+//-------------------------------------------------------------
+Double_t AliFlowEvent::PhiWeightRaw(Int_t selN, Int_t harN, AliFlowTrack* pFlowTrack) const  
+{
+ // Weight for making the event plane isotropic in the lab.
+
+ float phi = pFlowTrack->Phi() ; if(phi < 0.) { phi += 2*TMath::Pi() ; }
+ Double_t  eta = (Double_t)pFlowTrack->Eta() ;
+ int n = (int)((phi/(2*TMath::Pi()))*Flow::nPhiBins);
+
+ Double_t phiWgt = 1. ;
+ if(OnePhiWgt()) 
+ {
+  phiWgt = (Double_t)fPhiWgt[selN][harN][n]; //cout << "Selection " << selN << " ; Harmonic " << harN << " ; PhiBin " << n << "  -  Wgt = " << phiWgt << endl ; 
+ } 
+ else if(FirstLastPhiWgt())
+ {
+  float zFirstPoint = pFlowTrack->ZFirstPoint(); // float zLastPoint = pFlowTrack->ZLastPoint();
+  
+  if (zFirstPoint > 0. && eta > 0.)     { phiWgt = (Double_t)fPhiWgtPlus[selN][harN][n] ; } 
+  else if(zFirstPoint < 0. && eta < 0.) { phiWgt = (Double_t)fPhiWgtMinus[selN][harN][n] ; } 
+  else                                 { phiWgt = (Double_t)fPhiWgtCross[selN][harN][n] ; }
+ } 
+
+ // ... weight can be implemented as well for ITS , TRD , PHOS , etc.
+ // 
+ // if(...) 
+ // {
+ //  n = (int)((phi/2*TMath::Pi())*Flow::nPhiBins...) ;
+ //  ...
+ // }
+
+ return phiWgt ;
+}
+//-------------------------------------------------------------
+Double_t AliFlowEvent::Weight(Int_t selN, Int_t harN, AliFlowTrack* pFlowTrack) const  
+{ 
+ // Weight for enhancing the resolution (eta gives sign +/- for Odd Harmonics)
+
+ bool oddHar = (harN+1) % 2 ;
+ Double_t phiWgt = 1. ;
+ if(PtWgt()) 
+ {
+  Double_t pt = (Double_t)pFlowTrack->Pt();
+  if(pt < Flow::fPtWgtSaturation) { phiWgt *= pt ; } 
+  else                                   { phiWgt *= Flow::fPtWgtSaturation ; } // pt weighting going constant
+ }
+ Double_t eta = (Double_t)pFlowTrack->Eta();
+ Double_t etaAbs = TMath::Abs(eta);
+ if(EtaWgt() && oddHar)     { phiWgt *= etaAbs ; }
+ if(oddHar && eta < 0.)     { phiWgt *= -1. ; }
+
+ return phiWgt ;
+}
+//-------------------------------------------------------------
+Double_t AliFlowEvent::PhiWeight(Int_t selN, Int_t harN, AliFlowTrack* pFlowTrack) const
+{
+ // Weight for making the event plane isotropic in the lab and enhancing the resolution
+ // (it simply rerurns PhiWeightRaw() * Weight()). If fNoWgt = kTRUE, returns +/-1 ,
+ // basing on Sign(eta), for odd harmonics .
+ if(NoWgt()) // no weights (but +/- according to eta)
+ { 
+  bool oddHar = (harN+1) % 2 ;
+  if(oddHar) { return TMath::Sign((Double_t)1.,(Double_t)pFlowTrack->Eta()) ; }
+  else       { return (Double_t)1. ; }
+ } 
+ Double_t phiWgtRaw = PhiWeightRaw(selN, harN, pFlowTrack);
+ Double_t weight = Weight(selN, harN, pFlowTrack);
+ if(Flow::fDebug) { cout << "[PhiWeight]: phiWgtRaw = " << phiWgtRaw << " , weight = " << weight << " , eta = " << pFlowTrack->Eta() << endl ; }
+
+ return phiWgtRaw * weight;
+}
+//-------------------------------------------------------------
+Int_t AliFlowEvent::Mult(AliFlowSelection* pFlowSelect)        
+{
+ // Multiplicity of tracks in the specified Selection 
+ if(fDone) 
+ {
+  int sub = pFlowSelect->Sub() ;
+  if(sub<0) { return fMult[pFlowSelect->Sel()][pFlowSelect->Har()] ; }
+  else      { return fMultSub[sub][pFlowSelect->Sel()][pFlowSelect->Har()] ; }
+ }
+ // -
+ Int_t mult = 0;
+ Int_t itr ;
+ for(itr=0;itr<TrackCollection()->GetEntries();itr++) 
+ {
+  AliFlowTrack* pFlowTrack ;
+  pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+  if(pFlowSelect->Select(pFlowTrack)) { mult++ ; }
+ }
+ return mult;
+}
+//-------------------------------------------------------------
+Float_t AliFlowEvent::MeanPt(AliFlowSelection* pFlowSelect)
+{
+ // Mean pt of tracks in the specified Selection 
+
+ Double_t meanPt = 0. ;
+ Float_t sumPt = 0. ;
+ UInt_t mult = 0 ;
+ Int_t itr ;
+ for(itr=0;itr<TrackCollection()->GetEntries();itr++) 
+ {
+  AliFlowTrack* pFlowTrack ;
+  pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+  if (pFlowSelect->Select(pFlowTrack)) 
+  {
+   sumPt += pFlowTrack->Pt();
+   mult++;
+  }
+ }
+ if(mult) { meanPt = sumPt/(float)mult ; }
+ return meanPt ;
+}
+//-------------------------------------------------------------
+TVector2 AliFlowEvent::Q(AliFlowSelection* pFlowSelect)
+{
+ // Event plane vector for the specified Selection 
+
+ if(fDone) 
+ { 
+  int sub = pFlowSelect->Sub() ;
+  if(sub<0) { return fQ[pFlowSelect->Sel()][pFlowSelect->Har()] ; }
+  else      { return fQSub[sub][pFlowSelect->Sel()][pFlowSelect->Har()] ; }
+ } 
+ // -
+ TVector2 mQ ;
+ Double_t mQx=0. , mQy=0. ;
+ int    selN  = pFlowSelect->Sel() ;
+ int    harN  = pFlowSelect->Har() ;
+ double order = (double)(harN + 1) ;
+
+ Int_t itr ;
+ for(itr=0;itr<TrackCollection()->GetEntries();itr++)
+ {
+  AliFlowTrack* pFlowTrack ;
+  pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+  if(pFlowSelect->Select(pFlowTrack)) 
+  {
+   double phiWgt = PhiWeight(selN, harN, pFlowTrack);  
+   float phi = pFlowTrack->Phi();                      
+   mQx += phiWgt * cos(phi * order) ;
+   mQy += phiWgt * sin(phi * order) ;
+   if(Flow::fDebug) { cout << itr << " phi = " << phi << " ,  wgt = " << phiWgt << endl ; }
+  }
+ }
+ mQ.Set(mQx, mQy);
+
+ return mQ;
+}
+//-------------------------------------------------------------
+Float_t AliFlowEvent::Psi(AliFlowSelection* pFlowSelect)
+{
+ // Event plane angle for the specified Selection 
+
+ int   harN = pFlowSelect->Har() ;
+ float order = (float)(harN + 1) ;
+ Float_t psi = 0. ;
+
+ TVector2 mQ = Q(pFlowSelect);
+ if(mQ.Mod())  // if vector is not 0
+ {
+  psi= mQ.Phi() / order ;
+  if (psi < 0.) { psi += 2*TMath::Pi() / order ; }
+ }
+ return psi;
+}
+//-------------------------------------------------------------
+TVector2 AliFlowEvent::NormQ(AliFlowSelection* pFlowSelect)    
+{
+ // Normalized Q = Q/sqrt(sum of weights^2) for the specified Selection 
+
+ if(fDone) 
+ {
+  TVector2 mQ = fQ[pFlowSelect->Sel()][pFlowSelect->Har()] ;   
+  double SumOfWeightSqr = fSumOfWeightSqr[pFlowSelect->Sel()][pFlowSelect->Har()] ;
+  if(SumOfWeightSqr) { mQ /= TMath::Sqrt(SumOfWeightSqr) ; }
+  else { mQ.Set(0.,0.) ; }
+  return mQ ;
+ }
+ // -
+ TVector2 mQ ;
+ Double_t mQx=0. , mQy=0. ;
+ double SumOfWeightSqr = 0 ;
+ int selN     = pFlowSelect->Sel() ;
+ int harN     = pFlowSelect->Har() ;
+ double order = (double)(harN + 1) ;
+ Int_t itr ;
+ for(itr=0;itr<TrackCollection()->GetEntries();itr++) 
+ {
+  AliFlowTrack* pFlowTrack ;
+  pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+  if (pFlowSelect->Select(pFlowTrack)) 
+  {
+   double phiWgt = PhiWeight(selN, harN, pFlowTrack);
+   SumOfWeightSqr += phiWgt*phiWgt;
+
+   float phi = pFlowTrack->Phi();
+   mQx += phiWgt * cos(phi * order);
+   mQy += phiWgt * sin(phi * order);
+  }
+ }
+ if(SumOfWeightSqr) { mQ.Set(mQx/TMath::Sqrt(SumOfWeightSqr), mQy/TMath::Sqrt(SumOfWeightSqr)); }
+ else { mQ.Set(0.,0.); }
+  
+ return mQ;
+}
+//-------------------------------------------------------------
+Float_t AliFlowEvent::q(AliFlowSelection* pFlowSelect) 
+{ 
+ // Magnitude of normalized Q vector (without pt or eta weighting) for the specified Selection 
+
+ TVector2 mQ ;
+ Double_t mQx = 0. , mQy = 0. ;
+ int selN     = pFlowSelect->Sel() ;
+ int harN     = pFlowSelect->Har() ;
+ double order = (double)(harN + 1) ;
+ double SumOfWeightSqr = 0 ;
+
+ Int_t itr ;
+ for(itr=0;itr<TrackCollection()->GetEntries();itr++) 
+ {
+  AliFlowTrack* pFlowTrack ;
+  pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+  if(pFlowSelect->Select(pFlowTrack)) 
+  {
+   double phiWgt = PhiWeightRaw(selN, harN, pFlowTrack); // Raw
+   SumOfWeightSqr += phiWgt*phiWgt;
+   float phi = pFlowTrack->Phi();
+   mQx += phiWgt * cos(phi * order);
+   mQy += phiWgt * sin(phi * order);
+  }
+ }
+ if(SumOfWeightSqr) { mQ.Set(mQx/TMath::Sqrt(SumOfWeightSqr), mQy/TMath::Sqrt(SumOfWeightSqr)); }
+ else { mQ.Set(0.,0.); }
+  
+ return mQ.Mod();
+}
+//-----------------------------------------------------------------------
+Double_t AliFlowEvent::G_New(AliFlowSelection* pFlowSelect, Double_t Zx, Double_t Zy)
+{ 
+ // Generating function for the new cumulant method. Eq. 3 in the Practical Guide 
+
+ int selN     = pFlowSelect->Sel();
+ int harN     = pFlowSelect->Har();
+ double order = (double)(harN + 1);
+
+ double mult = (double)Mult(pFlowSelect);
+ Double_t theG = 1.;
+
+ Int_t itr ;
+ for(itr=0;itr<TrackCollection()->GetEntries();itr++) 
+ {
+  AliFlowTrack* pFlowTrack ;
+  pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+  if (pFlowSelect->Select(pFlowTrack)) 
+  {
+   double phiWgt = PhiWeight(selN, harN, pFlowTrack);     
+   float phi = pFlowTrack->Phi();
+   theG *= (1. + (phiWgt/mult) * (2.* Zx * cos(phi * order) + 2.* Zy * sin(phi * order) ) );           
+  }
+ }
+ return theG;
+}
+//-----------------------------------------------------------------------
+Double_t AliFlowEvent::G_Old(AliFlowSelection* pFlowSelect, Double_t Zx, Double_t Zy) 
+{ 
+ // Generating function for the old cumulant method (if expanded in Taylor
+ // series, one recovers G_New() in new new cumulant method)
+
+ TVector2 normQ = NormQ(pFlowSelect);
+
+ return exp(2*Zx*normQ.X() + 2*Zy*normQ.Y());
+}
+//-----------------------------------------------------------------------
+Double_t AliFlowEvent::SumWeightSquare(AliFlowSelection* pFlowSelect)
+{
+ // Return sum of weights^2 for the specified Selection (used for normalization)
+
+ if(fDone) 
+ { 
+  return fSumOfWeightSqr[pFlowSelect->Sel()][pFlowSelect->Har()] ; 
+ }
+ // -
+ int selN = pFlowSelect->Sel();
+ int harN = pFlowSelect->Har();
+ Double_t SumOfWeightSqr = 0;
+
+ Int_t itr ;
+ for(itr=0;itr<TrackCollection()->GetEntries();itr++) 
+ {
+  AliFlowTrack* pFlowTrack ;
+  pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+  if (pFlowSelect->Select(pFlowTrack)) 
+  {
+   double phiWgt = PhiWeight(selN, harN, pFlowTrack);
+   SumOfWeightSqr += phiWgt*phiWgt;
+  }
+ }
+ if(SumOfWeightSqr < 0.) { return Mult(pFlowSelect) ; }
+
+ return SumOfWeightSqr;
+}
+//-------------------------------------------------------------
+Double_t AliFlowEvent::WgtMult_q4(AliFlowSelection* pFlowSelect)
+{ 
+ // Used only for the old cumulant method, for getting q4 when weight is on.
+ // Replace multiplicity in Eq.(74b) by this quantity when weight is on.
+ // This is derived based on (A4) in the old cumulant paper.
+
+ int selN = pFlowSelect->Sel();
+ int harN = pFlowSelect->Har();
+ double theMult        = 0.;
+ double theMeanWj4     = 0.;
+ double theMeanWj2     = 0.;
+ double theSumOfWgtSqr = 0;
+ double phiWgtSq;
+
+ Int_t itr ;
+ for(itr=0;itr<TrackCollection()->GetEntries();itr++) 
+ {
+  AliFlowTrack* pFlowTrack ;
+  pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+  if (pFlowSelect->Select(pFlowTrack)) 
+  {
+   double phiWgt   = PhiWeight(selN, harN, pFlowTrack);
+   phiWgtSq       = phiWgt*phiWgt;
+   theSumOfWgtSqr += phiWgtSq;
+   theMeanWj4    += phiWgtSq*phiWgtSq;
+   theMult       += 1.;      
+  }
+ }
+ if (theMult <= 0.) return theMult;
+
+ theMeanWj4 /= theMult;
+ theMeanWj2  = theSumOfWgtSqr / theMult;
+
+ return (theSumOfWgtSqr*theSumOfWgtSqr)/(theMult*(-theMeanWj4+2*theMeanWj2*theMeanWj2));
+}
+//-------------------------------------------------------------
+Double_t AliFlowEvent::WgtMult_q6(AliFlowSelection* pFlowSelect)
+{ 
+ // Used only for the old cumulant method. For getting q6 when weight is on.
+ // Replace multiplicity in Eq.(74c) by this quantity when weight is on.
+ // This is derived based on (A4) in the old cumulant paper.
+
+ int selN = pFlowSelect->Sel();
+ int harN = pFlowSelect->Har();
+ double theMult        = 0.;
+ double theMeanWj6     = 0.;
+ double theMeanWj4     = 0.;
+ double theMeanWj2     = 0.;
+ double theSumOfWgtSqr = 0;
+ double phiWgtSq;
+
+ Int_t itr ;
+ for(itr=0;itr<TrackCollection()->GetEntries();itr++) 
+ {
+  AliFlowTrack* pFlowTrack ;
+  pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+  if (pFlowSelect->Select(pFlowTrack)) 
+  {
+   double phiWgt   = PhiWeight(selN, harN, pFlowTrack);
+   phiWgtSq       = phiWgt*phiWgt;
+   theSumOfWgtSqr += phiWgtSq;
+   theMeanWj4    += phiWgtSq*phiWgtSq;
+   theMeanWj6    += phiWgtSq*phiWgtSq*phiWgtSq;
+   theMult       += 1.;
+  }
+ } 
+ if (theMult <= 0.) return theMult*theMult;
+
+ theMeanWj6 /= theMult;
+ theMeanWj4 /= theMult;
+ theMeanWj2  = theSumOfWgtSqr / theMult;
+
+ return 4.*(theSumOfWgtSqr*theSumOfWgtSqr*theSumOfWgtSqr)/(theMult*(theMeanWj6-9.*theMeanWj2*theMeanWj4+12.*theMeanWj2*theMeanWj2*theMeanWj2));
+}
+//-------------------------------------------------------------
+void AliFlowEvent::SetSelections(AliFlowSelection* pFlowSelect)         
+{
+ // Sets the selection of tracks used in the Reaction Plane calculation 
+ // for the specific Harmonic and Selection - this does not cut trow away 
+ // tracks from the event, neither exclude them from flow study. See also 
+ // the AliFlowSelection class.
+ // Strategy of Selection: 
+ //                     For the specific Harmonic and Selection, IF cuts 
+ // are defined (such that low<high) and IF the track satisfies them, THEN 
+ // the respective track's flag (bool AliFlowTrack::mSelection[har][sel]) 
+ // is set kTRUE so that the track, from now on, will be included in the 
+ // R.P. determination for that selection.
+ // If NO cuts are defined -> ALL Flags are setted kTRUE (all particle 
+ // used for all the Reaction Planes -> no difference in Psi[har][sel]).
+ // -------------------------------------------------------------------
+ // The first selection (all harmonics) is set kTRUE : no conditions.
+
+ Int_t itr ;
+ for(itr=0;itr<TrackCollection()->GetEntries();itr++) 
+ {
+  AliFlowTrack* pFlowTrack ;
+  pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+  pFlowTrack->ResetSelection() ;               // this re-sets all the mSelection flags to 0
+
+ // * this sets all the selection n.[0] flag kTRUE (all harmonics) *
+  for(int harN=0;harN<Flow::nHars;harN++) { pFlowTrack->SetSelect(harN,0) ; } 
+
+ // Track need to be Constrainable
+  if(pFlowSelect->ConstrainCut() && !pFlowTrack->IsConstrainable()) continue ;
+
+ // PID - gets rid of the track with AliFlowTrack::Pid() != AliFlowSelection::Pid() (if there)
+  if(pFlowSelect->Pid()[0] != '\0') 
+  {
+   if(strstr(pFlowSelect->Pid(), "h")!=0) 
+   {
+    int charge = pFlowTrack->Charge() ;
+    if(strcmp("h+",pFlowSelect->Pid())==0 && charge != 1)  continue;
+    if(strcmp("h-",pFlowSelect->Pid())==0 && charge != -1) continue;
+   } 
+   else 
+   {
+    Char_t pid[10];
+    strcpy(pid, pFlowTrack->Pid());
+    if(strstr(pid, pFlowSelect->Pid())==0) continue;
+   }
+  }
+  double eta = (double)(pFlowTrack->Eta());      
+  float  Pt  = pFlowTrack->Pt();                
+  float  gDca = pFlowTrack->Dca() ;                    
+
+ // Global DCA - gets rid of the track with DCA outside the range
+  if((pFlowSelect->DcaGlobalCutHi()>pFlowSelect->DcaGlobalCutLo()) && (gDca<pFlowSelect->DcaGlobalCutLo() || gDca>pFlowSelect->DcaGlobalCutHi())) continue ;
+
+ // Pt & Eta - this is done differently for different Harmonic & Selection
+  for(int selN = 1; selN < Flow::nSels; selN++)               // not even consider the 0th selection (no cut applied there)
+  {
+  // min. TPC hits required
+   if(pFlowSelect->NhitsCut(selN) && (pFlowTrack->FitPtsTPC()<pFlowSelect->NhitsCut(selN))) continue ;
+
+   for(int harN = 0; harN < Flow::nHars; harN++) 
+   {
+   // Eta - gets rid of the track with Eta outside the range
+    if((pFlowSelect->EtaCutHi(harN%2,selN)>pFlowSelect->EtaCutLo(harN%2,selN)) && (TMath::Abs(eta)<pFlowSelect->EtaCutLo(harN%2,selN) || TMath::Abs(eta)>pFlowSelect->EtaCutHi(harN%2,selN))) continue ; 
+   // Pt - gets rid of the track with Pt outside the range
+    if((pFlowSelect->PtCutHi(harN%2,selN)>pFlowSelect->PtCutLo(harN%2,selN)) && (Pt<pFlowSelect->PtCutLo(harN%2,selN) || Pt>pFlowSelect->PtCutHi(harN%2,selN))) continue ; 
+  
+    pFlowTrack->SetSelect(harN, selN) ;  // if cuts defined (low<high) && track is in the range -> Set [har][sel] Flag ON
+
+    if(Flow::fDebug) 
+    {
+     cout << " harN " << harN%2 << " ,  selN " << selN << " - si" << endl ;
+     if(pFlowSelect->Pid()[0] != '\0') { cout << " track:  pid  " << pFlowTrack->Pid() << " = "<< pFlowSelect->Pid() << endl ; } 
+     cout << " track:  dca  " << pFlowSelect->DcaGlobalCutLo() << " < " << gDca << " < " << pFlowSelect->DcaGlobalCutHi() << endl ;
+     cout << " track:  eta  " << pFlowSelect->EtaCutLo(harN,selN) << " < |" << eta << "| < " << pFlowSelect->EtaCutHi(harN,selN) << endl ;
+     cout << " track:  pT   " << pFlowSelect->PtCutLo(harN,selN) << " < " << Pt << " < " << pFlowSelect->PtCutHi(harN,selN) << endl ;
+     pFlowTrack->PrintSelection() ;
+    }
+   }
+  }
+ }
+}
+//-------------------------------------------------------------
+void AliFlowEvent::SetPids()
+{
+ // Re-sets the tracks P.id. (using the current Flow::fBayesian[] array)
+ const Int_t code[] = {11,13,211,321,2212,10010020} ;
+ for(Int_t itr=0;itr<TrackCollection()->GetEntries();itr++) 
+ {
+  AliFlowTrack* pFlowTrack ;
+  pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+  TVector bayPid = pFlowTrack->PidProbs() ;
+  Int_t maxN = 2 ;                // if No id. -> then is a Pi
+  Float_t pid_max = bayPid[2] ;    // (if all equal, Pi probability get's the advantage to be the first)
+  for(Int_t nP=0;nP<Flow::nPid;nP++)
+  {
+   if(bayPid[nP]>pid_max) { maxN = nP ; pid_max = bayPid[nP] ; }
+  }
+  Int_t pdg_code = TMath::Sign(code[maxN],pFlowTrack->Charge()) ;     
+  pFlowTrack->SetMostLikelihoodPID(pdg_code);                  
+ }
+}
+//-------------------------------------------------------------
+void AliFlowEvent::MakeSubEvents() 
+{
+ // Make random or eta sub-events
+ if(EtaSubs())  { MakeEtaSubEvents() ; }
+ else          { MakeRndSubEvents() ; }
+} 
+//-------------------------------------------------------------
+void AliFlowEvent::MakeRndSubEvents() 
+{
+ // Make random subevents
+ int eventMult[Flow::nHars][Flow::nSels] = {{0}};
+ int harN, selN, subN = 0;
+ // loop to count the total number of tracks for each selection
+ for(Int_t itr=0;itr<TrackCollection()->GetEntries();itr++) 
+ {
+  AliFlowTrack* pFlowTrack ;
+  pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+  for (selN = 0; selN < Flow::nSels; selN++) 
+  {
+   for (harN = 0; harN < Flow::nHars; harN++) 
+   {
+    if(pFlowTrack->Select(harN, selN)) { eventMult[harN][selN]++ ; }
+   }
+  }
+ }
+ // loop to set the SubEvent member
+ for (selN = 0; selN < Flow::nSels; selN++) 
+ {
+  for (harN = 0; harN < Flow::nHars; harN++) 
+  {
+   int subEventMult = eventMult[harN][selN] / Flow::nSubs;
+   if (subEventMult) 
+   {
+    subN = 0;
+    int countN = 0;
+    for(Int_t itr=0;itr<TrackCollection()->GetEntries();itr++) 
+    {
+     AliFlowTrack* pFlowTrack ;
+     pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+     if(pFlowTrack->Select(harN, selN)) 
+     {
+      pFlowTrack->SetSubevent(harN, selN, subN);
+      countN++;
+      if (countN % subEventMult == 0.) { subN++ ; }
+     }
+    }
+   }
+  }
+ }
+ return ; 
+}
+//-------------------------------------------------------------
+void AliFlowEvent::MakeEtaSubEvents() 
+{
+ // Make subevents for positive and negative eta 
+ // (when done, fEtaSubs flag setted to kTRUE).
+ int harN, selN = 0;
+ // loop to set the SubEvent member
+ for (selN = 0; selN < Flow::nSels; selN++) 
+ {
+  for (harN = 0; harN < Flow::nHars; harN++) 
+  {
+   for(Int_t itr=0;itr<TrackCollection()->GetEntries();itr++) 
+   {
+    AliFlowTrack* pFlowTrack ;
+    pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+    if(pFlowTrack->Select(harN, selN)) 
+    {
+     float eta = pFlowTrack->Eta();
+     if (eta > 0.) { pFlowTrack->SetSubevent(harN, selN, 0) ; } 
+     else          { pFlowTrack->SetSubevent(harN, selN, 1) ; }
+    }
+   }
+  }
+ }
+}
+//-------------------------------------------------------------
+void AliFlowEvent::RandomShuffle() 
+{
+ // Randomly re-shuffles the tracks in the array; if a track is not
+ // primary, the reference carried by the reconstructed mother (in 
+ // the v0 array) is changed accordingly.
+
+ Int_t tot = 0 ;
+ UInt_t imax = TrackCollection()->GetEntries() ;
+ TRandom* rnd = new TRandom(0) ; // SetSeed(0) ;
+ TObjArray* newTrackCollection = new TObjArray(imax) ;
+
+ // re-arranges the ObjArray (TrackCollection())
+ for(UInt_t itr=0;itr<imax;itr++)
+ {
+  AliFlowTrack* pFlowTrack ;
+  pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+  
+  UInt_t rndNumber = rnd->Integer(imax) ;
+  Bool_t put = kFALSE ;
+  while(!put)
+  { 
+   if(!newTrackCollection->At(rndNumber)) 
+   { 
+    newTrackCollection->AddAt(pFlowTrack, rndNumber) ; 
+    put = kTRUE ; tot++ ;              if(Flow::fDebug) { cout << "  " << itr << " --> " << rndNumber << endl ; } 
+   }
+   else 
+   {
+    rndNumber++ ; if(rndNumber>=imax) { rndNumber -= imax ; }
+   }
+  }
+ }
+ if(Flow::fDebug) { cout << "* RandomShuffle() :  " << tot << "/" << imax << " flow tracks have been shuffled " << endl ; }  
+ fTrackCollection = newTrackCollection ;
+}
+//-----------------------------------------------------------------------
+UInt_t AliFlowEvent::Centrality() 
+{
+ // Returns the Centrality Class as stored
+
+ if(fCentrality < 0)  { SetCentrality() ; } 
+ return fCentrality ;
+}
+//-----------------------------------------------------------------------
+void AliFlowEvent::SetCentrality(Int_t cent) 
+{
+ // Set the Centrality Classes to "cent" .
+
+ fCentrality = cent ; 
+}
+//-----------------------------------------------------------------------
+void AliFlowEvent::SetCentrality() 
+{
+ // Sets the Centrality Classes basing on Multiplicity at mid rapidity, 
+ // ... (ZDC information can be added) .
+ Float_t* cent ;
+ Int_t  tracks = MultEta() ;
+
+ if(RunID() == -1)
+ { 
+  cent = Flow::fCentNorm ;
+  //if centrality classes are not defined, does it now (with CentNorm & MaxMult)
+  if(cent[Flow::nCents-1] <= 1) 
+  {
+   for(Int_t ic=0;ic<Flow::nCents;ic++)
+   {
+    cent[ic] *= Flow::fMaxMult ; 
+    if(Flow::fDebug) { cout << "Centrality[" << ic << "] = " << cent[ic] << " . " << endl ; }
+   }
+  }
+ }
+ else if((RunID() != -1) && (CenterOfMassEnergy() == 5500.))
+ {
+  cent = (Float_t*)Flow::fCent0 ;
+ } 
+ else // other definition of centrality are possible...
+ {
+  cent = (Float_t*)Flow::fCent0 ;
+ } 
+ if      (tracks < cent[0])  { fCentrality = 0; }
+ else if (tracks < cent[1])  { fCentrality = 1; }
+ else if (tracks < cent[2])  { fCentrality = 2; }
+ else if (tracks < cent[3])  { fCentrality = 3; }
+ else if (tracks < cent[4])  { fCentrality = 4; }
+ else if (tracks < cent[5])  { fCentrality = 5; }
+ else if (tracks < cent[6])  { fCentrality = 6; }
+ else if (tracks < cent[7])  { fCentrality = 7; }
+ else if (tracks < cent[8])  { fCentrality = 8; }
+ else                        { fCentrality = 9; }
+
+ if(Flow::fDebug) { cout << " * Centrality Class :  " << fCentrality << " . " << endl ; }
+}
+//-----------------------------------------------------------------------
+void AliFlowEvent::Bayesian(Double_t bayes[Flow::nPid]) 
+{
+ // Returns bayesian array of particles' abundances (from Flow::)
+ for(Int_t i=0;i<Flow::nPid;i++) { bayes[i] = Flow::fBayesian[i] ; }
+}
+//-----------------------------------------------------------------------
+TVector AliFlowEvent::Bayesian() 
+{ 
+ TVector bayes(Flow::nPid) ; 
+ for(Int_t i=0;i<Flow::nPid;i++) { bayes[i] = Flow::fBayesian[i] ; }
+ return bayes ;
+}
+//-----------------------------------------------------------------------
+void AliFlowEvent::PrintFlagList() const 
+{
+ // Prints the list of selection cuts ( called in AliFlowInterface::Finish() )
+ cout << "#######################################################" << endl;
+ cout << "# Weighting and Striping:" << endl;
+ if(PtWgt()) 
+ {
+  cout << "#   PtWgt =  kTRUE " << endl ;      // (also for output of PhiWgt file?)
+  cout << "#   PtWgt Saturation =  " << Flow::fPtWgtSaturation << endl;
+ } 
+ else 
+ {
+  cout << "#   PtWgt = kFALSE" << endl;
+ }
+ if(EtaWgt()) 
+ {
+  cout << "#   EtaWgt = kTRUE " << endl ;      // (also for output of PhiWgt file for odd harmonics?)
+ } 
+ else 
+ {
+  cout << "#   EtaWgt = kFALSE" << endl;
+ }
+ cout << "#######################################################" << endl;  
+}
+//-----------------------------------------------------------------------
+void AliFlowEvent::SetEventID(const Int_t& id)                   
+{ 
+ // Sets Event ID and the Event name (name = evtNumber_runId)
+ fEventID = id ; 
+ TString name = "" ;
+ name += fEventID ;
+ if(fRunID) { name += "_" ; name += fRunID ; }
+ SetName(name) ;  // from TNamed::SetName
+}
+//-----------------------------------------------------------------------
+Int_t AliFlowEvent::MultEta()
+{
+ // Returns the multiplicity in the interval |eta|<(Flow::fEetaMid), used 
+ // for centrality measurement (see centrality classes in fCentrality) .
+ Int_t goodtracks = 0 ;
+ for(Int_t itr=0;itr<TrackCollection()->GetEntries();itr++) 
+ {
+  AliFlowTrack* pFlowTrack ;
+  pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+  if((pFlowTrack->Charge()) && (TMath::Abs(pFlowTrack->Eta())<Flow::fEtaMid)) { goodtracks++ ; }
+ }
+ return goodtracks ; 
+}
+//-----------------------------------------------------------------------
+Int_t AliFlowEvent::UncorrNegMult(Float_t eta)  const
+{ 
+ // Negative multiplicity in the interval (-eta..eta)
+ // (default is  Flow::fEetaGood = 0.9)
+ Int_t negMult = 0 ;
+ for(Int_t itr=0;itr<TrackCollection()->GetEntries();itr++) 
+ {
+  AliFlowTrack* pFlowTrack ;
+  pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+  if((pFlowTrack->Charge()<0) && (TMath::Abs(pFlowTrack->Eta())<TMath::Abs(eta))) { negMult++ ; }
+  delete pFlowTrack ;
+ }
+ return negMult; 
+}
+//-----------------------------------------------------------------------
+Int_t AliFlowEvent::UncorrPosMult(Float_t eta)  const
+{ 
+ // Positive multiplicity in the interval (-eta..eta)
+ // (default is  Flow::fEetaGood = 0.9)
+ Int_t posMult ;
+ for(Int_t itr=0;itr<TrackCollection()->GetEntries();itr++) 
+ {
+  AliFlowTrack* pFlowTrack ;
+  pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+  if((pFlowTrack->Charge()>0) && (TMath::Abs(pFlowTrack->Eta())<TMath::Abs(eta))) { posMult++ ; }
+  delete pFlowTrack ;
+ }
+ return posMult; 
+}
+//-----------------------------------------------------------------------
+void AliFlowEvent::VertexPos(Float_t vtx[3])  const            
+{ 
+ for(Int_t ii=0;ii<3;ii++) { vtx[ii] = fVertexPos[ii] ; }
+}
+//-----------------------------------------------------------------------
+TVector3 AliFlowEvent::VertexPos() const
+{
+ Float_t vertex[3] ;
+ VertexPos(vertex) ;
+ return TVector3(vertex) ;
+}
+//-----------------------------------------------------------------------
+void AliFlowEvent::SetVertexPos(Float_t v1,Float_t v2,Float_t v3)
+{ 
+ fVertexPos[0] = v1 ; fVertexPos[1] = v2 ; fVertexPos[2] = v3 ; 
+}
+//-----------------------------------------------------------------------
+void AliFlowEvent::MakeAll()
+{ 
+ // calculates all quantities in 1 shoot ...
+ //  ...
+
+ Double_t mQx[Flow::nSels][Flow::nHars] ;
+ Double_t mQy[Flow::nSels][Flow::nHars] ;
+ Double_t mQxSub[Flow::nSubs][Flow::nSels][Flow::nHars] ;
+ Double_t mQySub[Flow::nSubs][Flow::nSels][Flow::nHars] ;
+ // -
+ int selN, harN, subN ;
+ for(selN=0;selN<Flow::nSels;selN++) 
+ {
+  for(harN=0;harN<Flow::nHars;harN++) 
+  {
+   mQx[selN][harN]    = 0. ;   
+   mQy[selN][harN]    = 0. ;   
+   fMult[selN][harN]  = 0 ;    
+   fSumOfWeightSqr[selN][harN] = 0. ;
+   for(subN=0;subN<Flow::nSubs;subN++)
+   {
+    mQxSub[subN][selN][harN]   = 0. ;
+    mQySub[subN][selN][harN]   = 0. ;
+    fMultSub[subN][selN][harN] = 0 ;
+   }
+  }
+ }
+ double order = 0.  ;
+ double phiWgt = 0. ;  
+ float  phi = 0.    ;               
+ // -
+ int itr ;
+ for(itr=0;itr<TrackCollection()->GetEntries();itr++) 
+ {
+  AliFlowTrack* pFlowTrack ;
+  pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ;
+  phi = pFlowTrack->Phi();
+  for(selN=0;selN<Flow::nSels;selN++) 
+  {
+   for(harN=0;harN<Flow::nHars;harN++) 
+   {
+    order = (double)(harN+1) ;
+    if(pFlowTrack->Select(harN,selN)) 
+    {
+     phiWgt = PhiWeight(selN,harN,pFlowTrack) ;  
+     fSumOfWeightSqr[selN][harN] += phiWgt*phiWgt ;
+     mQx[selN][harN] += phiWgt * cos(phi * order) ;
+     mQy[selN][harN] += phiWgt * sin(phi * order) ;
+     fMult[selN][harN]++ ;     
+     for(subN=0;subN<Flow::nSubs;subN++)
+     {
+      if(pFlowTrack->Select(harN,selN,subN))
+      {
+       mQxSub[subN][selN][harN] += phiWgt * cos(phi * order) ;
+       mQySub[subN][selN][harN] += phiWgt * sin(phi * order) ;
+       fMultSub[subN][selN][harN]++  ;
+      }
+     }  // sub
+    }  // if
+   }  // har
+  }  // sel
+ }  //itr
+
+ for(selN=0;selN<Flow::nSels;selN++)  
+ {
+  for(harN=0;harN<Flow::nHars;harN++)
+  {
+   fQ[selN][harN].Set(mQx[selN][harN],mQy[selN][harN]) ;  
+   for(subN=0;subN<Flow::nSubs;subN++) { fQSub[subN][selN][harN].Set(mQxSub[subN][selN][harN],mQySub[subN][selN][harN]) ; }
+  }
+ }
+
+ fDone = kTRUE ;
+}
+// //-----------------------------------------------------------------------
+// Float_t  AliFlowEvent::ExtPsi(Int_t harN) const     
+// { 
+//  // external R.P. angle (check input source...)
+// 
+//  if(harN<Flow::nHars) { return fExtPsi[harN] ; }
+//  else 
+//  { 
+//   cout << "AliFlowEvent::ExtPsi(" << harN << ") : harmonic " << harN+1 << " is not there !" << endl ; 
+//   return 0. ; 
+//  }
+// }
+// //-----------------------------------------------------------------------
+// Float_t  AliFlowEvent::ExtRes(Int_t harN) const
+// { 
+//  // external R.P. resolution (check input source...)
+// 
+//  if(harN<Flow::nHars) { return fExtRes[harN] ; }
+//  else 
+//  { 
+//   cout << "AliFlowEvent::ExtRes(" << harN << ") : harmonic " << harN+1 << " is not there !" << endl ; 
+//   return 0. ; 
+//  }
+// }
+// //-----------------------------------------------------------------------
+// void AliFlowEvent::SetExtPsi(Int_t harN,Float_t psi)         
+// { 
+//  if(harN<Flow::nHars) { fExtPsi[harN] = psi ; }
+// }
+// //-----------------------------------------------------------------------
+// void AliFlowEvent::SetExtRes(Int_t harN,Float_t res)         
+// { 
+//  if(harN<Flow::nHars) { fExtRes[harN] = res ; }
+// }
+// //-----------------------------------------------------------------------
+
+
+
+//-----------------------------------------------------------------------
+// - those will go into the .h as inline functions ..................... 
+//-----------------------------------------------------------------------
+TObjArray* AliFlowEvent::TrackCollection() const       { return fTrackCollection; }
+TObjArray* AliFlowEvent::V0Collection() const          { return fV0Collection; }
+//-----------------------------------------------------------------------
+Int_t   AliFlowEvent::EventID() const                  { return fEventID; }
+Int_t   AliFlowEvent::RunID() const                    { return fRunID; }
+Double_t AliFlowEvent::CenterOfMassEnergy() const      { return Flow::fCenterOfMassEnergy ; }
+Double_t AliFlowEvent::MagneticField() const           { return Flow::fMagneticField ; }
+Short_t  AliFlowEvent::BeamMassNumberEast() const      { return Flow::fBeamMassNumberEast ; }
+Short_t  AliFlowEvent::BeamMassNumberWest() const      { return Flow::fBeamMassNumberWest ; }
+UInt_t   AliFlowEvent::OrigMult() const                { return fOrigMult; }
+Long_t   AliFlowEvent::L0TriggerWord() const           { return fL0TriggerWord; }
+Int_t    AliFlowEvent::V0Mult() const                  { return V0Collection()->GetEntries() ; }
+Int_t    AliFlowEvent::FlowEventMult() const           { return TrackCollection()->GetEntries() ; }
+Int_t    AliFlowEvent::ZDCpart() const                 { return fZDCpart; }
+Float_t  AliFlowEvent::ZDCenergy(Int_t npem) const     { return fZDCenergy[npem]; }
+Float_t  AliFlowEvent::PtWgtSaturation() const         { return Flow::fPtWgtSaturation; }
+Bool_t   AliFlowEvent::PtWgt() const                   { return fPtWgt; }
+Bool_t   AliFlowEvent::EtaWgt() const                  { return fEtaWgt; }
+Bool_t   AliFlowEvent::FirstLastPhiWgt() const         { return !fOnePhiWgt ; }
+Bool_t   AliFlowEvent::OnePhiWgt() const               { return fOnePhiWgt ; }
+Bool_t   AliFlowEvent::NoWgt() const                   { return fNoWgt; }
+Bool_t   AliFlowEvent::EtaSubs() const                 { return fEtaSubs ; }
+//-----------------------------------------------------------------------
+void            AliFlowEvent::SetEtaSubs(Bool_t etasub)                      { fEtaSubs = etasub ; }
+void    AliFlowEvent::SetRunID(const Int_t& id)                      { fRunID = id; }
+void    AliFlowEvent::SetMagneticField(const Double_t& mf)           { Flow::fMagneticField = mf; }
+void    AliFlowEvent::SetCenterOfMassEnergy(const Double_t& cms)     { Flow::fCenterOfMassEnergy = cms; }
+void    AliFlowEvent::SetBeamMassNumberEast(const Short_t& bme)      { Flow::fBeamMassNumberEast = bme; }
+void    AliFlowEvent::SetBeamMassNumberWest(const Short_t& bmw)      { Flow::fBeamMassNumberWest = bmw; }
+void    AliFlowEvent::SetOrigMult(const UInt_t& tracks)              { fOrigMult = tracks; }
+void    AliFlowEvent::SetL0TriggerWord(const Long_t& trigger)        { fL0TriggerWord = trigger; }
+void    AliFlowEvent::SetZDCpart(Int_t zdcp)                         { fZDCpart = zdcp ; }
+void    AliFlowEvent::SetZDCenergy(Float_t n, Float_t p, Float_t em) { fZDCenergy[0] = n ; fZDCenergy[1] = p ; fZDCenergy[2] = em ; }
+//-----------------------------------------------------------------------
+void AliFlowEvent::SetBayesian(Double_t bayes[Flow::nPid])       
+{ 
+ for(Int_t i=0;i<Flow::nPid;i++) { Flow::fBayesian[i] = bayes[i] ; } 
+}
+//-----------------------------------------------------------------------
+void AliFlowEvent::SetNoWgt(Bool_t nowgt) 
+{ 
+ // Sets no phi weightening, but Wgt = 1*sign(Eta) for odd harmonics .
+ fNoWgt = nowgt ; // cout << " Wgt = +1 (positive Eta) or -1 (negative Eta) . " << endl ;
+}
+//-----------------------------------------------------------------------
+void AliFlowEvent::SetOnePhiWgt()                                { fOnePhiWgt = kTRUE ; }
+void AliFlowEvent::SetFirstLastPhiWgt()                          { fOnePhiWgt = kFALSE ; }
+void AliFlowEvent::SetPtWgt(Bool_t PtWgt)                        { fPtWgt = PtWgt; }
+void AliFlowEvent::SetEtaWgt(Bool_t EtaWgt)                      { fEtaWgt = EtaWgt; }
+//-----------------------------------------------------------------------
+#ifndef __CINT__
+void AliFlowEvent::SetPhiWeight(const Flow::PhiWgt_t& pPhiWgt)          { memcpy (fPhiWgt, pPhiWgt, sizeof(Flow::PhiWgt_t)); }
+void AliFlowEvent::SetPhiWeightPlus(const Flow::PhiWgt_t& pPhiWgtPlus)   { memcpy (fPhiWgtPlus,  pPhiWgtPlus,  sizeof(Flow::PhiWgt_t)); }
+void AliFlowEvent::SetPhiWeightMinus(const Flow::PhiWgt_t& pPhiWgtMinus) { memcpy (fPhiWgtMinus, pPhiWgtMinus, sizeof(Flow::PhiWgt_t)); }
+void AliFlowEvent::SetPhiWeightCross(const Flow::PhiWgt_t& pPhiWgtCross) { memcpy (fPhiWgtCross, pPhiWgtCross, sizeof(Flow::PhiWgt_t)); }
+#endif
+//-----------------------------------------------------------------------
+//////////////////////////////////////////////////////////////////////
diff --git a/PWG2/FLOW/AliFlowEvent.h b/PWG2/FLOW/AliFlowEvent.h
new file mode 100644 (file)
index 0000000..3324d07
--- /dev/null
@@ -0,0 +1,193 @@
+//////////////////////////////////////////////////////////////////////
+//
+// $Id$
+//
+// Author: Emanuele Simili
+//
+//////////////////////////////////////////////////////////////////////
+//
+// Description: event format fitted to flow study, adapted from STAR 
+// Original Authors:               Raimond Snellings & Art Poskanzer
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef AliFlowEvent_h
+#define AliFlowEvent_h
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include "TVector.h"
+#include "TVector2.h"
+#include "TVector3.h"
+#include "TObject.h"
+#include "TRandom.h"
+#include "TObjArray.h"
+#include <TROOT.h>
+
+#include "AliFlowTrack.h"
+#include "AliFlowV0.h"
+#include "AliFlowSelection.h"
+#include "AliFlowConstants.h"
+
+class AliFlowTrack ;
+class AliFlowV0 ;
+class AliFlowSelection ;
+class Flow ;
+
+class AliFlowEvent : public TNamed {
+
+public:                                                                           
+                                                                                  
+  AliFlowEvent(Int_t length = 1000) ;                                             
+  virtual        ~AliFlowEvent();                                                 
+                                                                                  
+ // Gets
+  Int_t          EventID()             const;                                  // Returns ID of the event
+  Int_t          RunID()               const;                                  // Returns ID of the run
+  Long_t         L0TriggerWord()       const;                                  // Returns L0 trigger word
+  Int_t          ZDCpart()             const;                                  // Returns estimated number of participants by the ZDC
+  Float_t        ZDCenergy(Int_t npem) const;                                  // Returns reconstructed energy in the neutron(1), proton(2), em(3) ZDC
+  void           VertexPos(Float_t vtx[3]) const;                              // Returns primary vertex position
+  TVector3       VertexPos()           const;                                  // Returns primary vertex position as a TVector3
+  UInt_t         Centrality() ;                                                        // Returns centrality bin (based on MultEta() )
+  UInt_t         OrigMult()            const;                                  // Returns the original number of tracks (maybe some were trown away)
+  Int_t         V0Mult()               const;                                  // Returns the number of V0s 
+  Int_t          FlowEventMult()       const;                                  // Returns number of tracks stored in the event
+  Int_t          UncorrNegMult(Float_t eta = Flow::fEtaGood) const ;           // Returns number of - tracks in eta (-eta;eta)
+  Int_t          UncorrPosMult(Float_t eta = Flow::fEtaGood) const ;           // Returns number of + tracks in eta (-eta;eta)
+  Int_t          MultEta() ;                                                   // Returns multiplicity in |eta|<Flow::fEetaMid
+  Double_t       CenterOfMassEnergy()  const;                                  // Returns center of mass energy (5.5 TeV)
+  Double_t       MagneticField()       const;                                  // Returns magnetic field value
+  Short_t        BeamMassNumberEast()  const;                                  // Returns beam mass (Pb = 208)
+  Short_t        BeamMassNumberWest()  const;                                  // Returns beam mass (Pb = 208)
+
+                                                                         
+ // Sets
+  void          SetEventID(const Int_t&);
+  void          SetRunID(const Int_t&);
+  void          SetCenterOfMassEnergy(const Double_t&);
+  void          SetMagneticField(const Double_t&);
+  void           SetCentrality() ; 
+  void           SetCentrality(Int_t cent) ; 
+  void          SetBeamMassNumberEast(const Short_t&);
+  void          SetBeamMassNumberWest(const Short_t&);
+  void          SetOrigMult(const UInt_t&);
+  void          SetL0TriggerWord(const Long_t&);
+  void          SetVertexPos(Float_t v1=0.,Float_t v2=0.,Float_t v3=0.);
+  void          SetZDCpart(Int_t zdcp);
+  void          SetZDCenergy(Float_t n, Float_t p, Float_t em);
+
+//  // new
+//   void               SetExtPsi(Int_t harN, Float_t psi=0.) ;
+//   void               SetExtRes(Int_t harN, Float_t res=0.) ;
+//   Float_t    ExtPsi(Int_t harN)     const ;                                 // external RP angle
+//   Float_t    ExtRes(Int_t harN)     const ;                                 // external RP resolution
+
+ // Arrays
+  TObjArray*     TrackCollection()     const;                                  // Returns a pointer to the TObjArray of AliFlowTrack
+  TObjArray*     V0Collection()        const;                                  // Returns a pointer to the TObjArray of AliFlowV0
+
+ // Calculations
+  Int_t          Mult(AliFlowSelection*);                                      // Returns Multiplicity of tracks selected for the event plane
+  TVector2       Q(AliFlowSelection*);                                         // Returns Event plane vector
+  Float_t        q(AliFlowSelection*);                                         // Returns Magnitude of normalized Q vector without pt or eta weighting
+  Float_t        MeanPt(AliFlowSelection*);                                    // Returns Mean pt of tracks selected for the event plane
+  Float_t        Psi(AliFlowSelection*);                                       // Returns Event plane angle
+  Double_t       G_New(AliFlowSelection* pFlowSelect,Double_t Zx,Double_t Zy); // Generating function for the new cumulant method (eq.3 in the Practical Guide)
+  Double_t       G_Old(AliFlowSelection* pFlowSelect,Double_t Zx,Double_t Zy); // Generating function for the old cumulant method (if expanded in Taylor series, one recovers G_New() in new new cumulant method)
+  Double_t       SumWeightSquare(AliFlowSelection* pFlowSelect);               // Returns Sum of weights^2
+  Double_t       WgtMult_q4(AliFlowSelection* pFlowSelect);                    // old comulants
+  Double_t       WgtMult_q6(AliFlowSelection* pFlowSelect);                    // old comulants
+  TVector2       NormQ(AliFlowSelection* pFlowSelect);                         // Returns normalized Q = Q/sqrt(weights^2++)
+ // -
+  void          SetSelections(AliFlowSelection* pFlowSelect) ;                 // Sets the tracks selection for R.P. calculations (see static cuts in AliFlowSelection class)
+  void          RandomShuffle() ;                                              // Randomly re-shuffles the ObjArray of tracks
+  void          MakeSubEvents() ;                                              // Makes sub-events, eta based (if EtaSubs()) or Random (otherwise)
+  void          MakeRndSubEvents() ;                                           // Makes random sub-events
+  void          MakeEtaSubEvents() ;                                           // Makes eta sub-events
+  void                  SetPids() ;                                                    // Re-sets the tracks P.id. (using the current fBayesianCs[] array)
+ // -
+  void          MakeAll() ;                                                    // In just one loop, makes all the calculaton (Q, psi, mult) basing on the selection. 
+
+ // Weights & settings
+  Float_t        PtWgtSaturation()     const;                                  // Returns saturation value for pt weighting
+  Bool_t         PtWgt()               const;                                  // Returns flag for pt weighting
+  Bool_t         EtaWgt()              const;                                  // Returns flag for eta weighting for odd harmonics
+  Bool_t         FirstLastPhiWgt()     const;                                  // Returns flag for using z of first and last points for phi weights (TPC +/-)
+  Bool_t         OnePhiWgt()           const;                                  // Returns flag for using just one phi weight
+  Bool_t         NoWgt()               const;                                  // returns kTRUE if weight are NOT used
+  Double_t       PhiWeight(Int_t selN,Int_t harN,AliFlowTrack* pFlowTrack) const ;     // Returns PhiWeightRaw()*Weight()  
+  Double_t       PhiWeightRaw(Int_t selN,Int_t harN,AliFlowTrack* pFlowTrack) const ;  // Returns weights for making the R.P. isotropic in the lab
+  Double_t       Weight(Int_t selN,Int_t harN,AliFlowTrack* pFlowTrack) const ;        // Returns weights for enhancing the resolution (+/-Sign(eta) for odd harmonics)
+  void          Bayesian(Double_t bayes[Flow::nPid]) ;                         // Returns the stored particles' abundances
+  TVector       Bayesian() ;                                                   // Returns the stored particles' abundances as a TVector
+ // -
+  static void   SetPtWgt(Bool_t PtWgt = kTRUE);
+  static void   SetEtaWgt(Bool_t EtaWgt = kTRUE);
+  static void   SetOnePhiWgt();
+  static void   SetFirstLastPhiWgt();
+  static void   SetNoWgt(Bool_t nowgt = kTRUE) ;
+ // -
+  void          SetBayesian(Double_t bayes[Flow::nPid]) ;                      // Set the Bayesian vector of particles' abundances
+#ifndef __CINT__               
+  void          SetPhiWeight(const Flow::PhiWgt_t &pPhiWgt);                   // Fills Weights from Arrays (from file: flowPhiWgt.hist.root)
+  void          SetPhiWeightPlus(const Flow::PhiWgt_t &pPhiWgtPlus);
+  void          SetPhiWeightMinus(const Flow::PhiWgt_t &pPhiWgtMinus);
+  void          SetPhiWeightCross(const Flow::PhiWgt_t &pPhiWgtCross);
+#endif
+
+ // Analysis flags
+  Bool_t         EtaSubs() const;                                              // Returns flag for eta sub-events
+  static void   SetEtaSubs(Bool_t etasub = kTRUE) ;                            // Sets the flag for eta sub-events
+  void          PrintFlagList() const ;                                        // Prints a summary of the event's flag
+
+
+private:
+
+ // Data Members
+  Int_t               fEventID;                                  // ID of the event
+  Int_t               fRunID;                                    // ID of the run
+  UInt_t              fOrigMult;                                 // Original number of tracks
+  Long_t              fL0TriggerWord;                            // L0 trigger word
+  Int_t               fZDCpart;                                  // ZDC estimated number of participants 
+  Float_t             fZDCenergy[3];                             // ZDC reconstructed energy [neutron,proton,em]
+  Float_t            fVertexPos[3];                             // primary vertex position
+  Int_t               fCentrality;                               //! Centrality Class (calculated from mult.)
+
+ // extension
+  //Float_t          fExtPsi[Flow::nHars] ;                     // external RP angle (should be an input)
+  //Float_t          fExtRes[Flow::nHars] ;                     // external RP resolution (should be an input as well)
+
+ // Tracks & V0s
+  TObjArray*         fTrackCollection ;                         // collection of Flow Tracks
+  TObjArray*         fV0Collection ;                            // collection of Flow V0s
+
+ // Weights
+  Flow::PhiWgt_t      fPhiWgt;                                   //! flattening weights (single hist)
+  Flow::PhiWgt_t      fPhiWgtPlus;                               //! flattening weights (3 hist) - plus Z
+  Flow::PhiWgt_t      fPhiWgtMinus;                              //! flattening weights (3 hist) - minus Z
+  Flow::PhiWgt_t      fPhiWgtCross;                              //! flattening weights (3 hist) - cross Z
+  //Double_t           fBayesianCs[Flow::nPid] ;                //! expected particles abundance (see Bayesian P.Id.)
+
+ // Weighting & Settings
+  static Bool_t       fPtWgt;                                    //! flag for pt weighting
+  static Bool_t       fEtaWgt;                                   //! flag for eta weighting for odd harmonics
+  static Bool_t       fOnePhiWgt;                                //! flag for phi weights (just one hist)
+  static Bool_t       fNoWgt;                                           //! No Weights (Wgt == 1)
+  static Bool_t       fEtaSubs;                                  //! Flag for making Eta Subevents
+
+#ifndef __CINT__
+ // shortcuts (to speed up the execution)
+  Bool_t   fDone ;                                             //! flag setted kTRUE when the loop is done
+  TVector2 fQ[Flow::nSels][Flow::nHars];                       //! flow vector
+  UInt_t   fMult[Flow::nSels][Flow::nHars];                    //! multiplicity
+  Float_t  fSumOfWeightSqr[Flow::nSels][Flow::nHars];           //! Sqrt(Sum(wgt)) ~ Sqrt(Mult)
+  TVector2 fQSub[Flow::nSubs][Flow::nSels][Flow::nHars];       //! flow vector subs
+  UInt_t   fMultSub[Flow::nSubs][Flow::nSels][Flow::nHars];    //! multiplicity subs
+#endif /*__CINT__*/
+
+  ClassDef(AliFlowEvent,2) ;                    // macro for rootcint
+};
+
+#endif
diff --git a/PWG2/FLOW/AliFlowSelection.cxx b/PWG2/FLOW/AliFlowSelection.cxx
new file mode 100644 (file)
index 0000000..747b17c
--- /dev/null
@@ -0,0 +1,549 @@
+//////////////////////////////////////////////////////////////////////
+//
+// $Id$
+//
+// Author: Emanuele Simili
+//
+//////////////////////////////////////////////////////////////////////
+//_____________________________________________________________
+//
+// Description:  
+//       the AliFlowSelection Class selects tracks from the AliFlowEvent. 
+// There are two kind of selection :
+// - Selection of tracks for the R.P. determination is performed via the
+//  method Select(AliFlowTrack*): it simply checks the labels array of 
+//  the track. Those arrays must be previously filled by calling 
+//  AliFlowEvent::SetSelection(), wich uses the static cuts defined here.
+//  Set the flag to Select via SetHarmonic() and SetSelection().   
+// - Selection of tracks for Correlation Analysis is performed via the 
+//  method SelectPart(AliFlowEvent*): cuts are applied to tracks 
+//  (such as p.id, pT, total P, rapidity, eta, number of fit points, 
+//  ratio of fit points to max points, chi2, and global dca). 
+//  Set the cuts to apply via the appropriate Set...() methods.
+// 
+// The AliFlowSelection Class is adapted from the original StFlowSelection,
+// succesfully used to study flow in the STAR experiment at RICH.
+// Original Authors:                 Raimond Snellings & Art Poskanzer
+//
+
+#include "AliFlowSelection.h"
+#include "AliFlowConstants.h"
+#include <iostream>
+using namespace std; //required for resolving the 'cout' symbol
+
+// - 1st selection (both harmonic) is Disabled ! - the 2 following are the same (basic cuts, no P.id)
+Float_t  AliFlowSelection::fEtaTpcCuts[2][Flow::nHars][Flow::nSels] = {{{1.0,0.0},{1.0,0.0}},{{0.0,2.1},{0.0,2.1}}} ;
+Float_t  AliFlowSelection::fPtTpcCuts[2][Flow::nHars][Flow::nSels]  = {{{1.0,0.1},{1.0,0.1}},{{0.0,9.0},{0.0,9.0}}} ;
+Float_t  AliFlowSelection::fDcaGlobalCuts[2]    = { 0. , 1. } ;
+Char_t   AliFlowSelection::fPid[10]              = { '\0' } ;
+Bool_t   AliFlowSelection::fConstrainable        = kTRUE ;
+Int_t    AliFlowSelection::fTPChits[Flow::nSels] = { 0 , 1 } ;
+
+ClassImp(AliFlowSelection)
+//-----------------------------------------------------------------------
+AliFlowSelection::AliFlowSelection()
+{
+ // Default constructor: when initialized all selection cuts are disabled (lo>hi).
+
+ fJustLoopConstrainable = kFALSE ;     // = kTRUE
+ // -
+ fCent                = -1 ; 
+ fRun                 = -1 ; 
+ // -
+ fPidPart[0] = '\0' ;
+ fConstrainablePart    = kFALSE ;      // = kTRUE
+ fPidProbPart[0]       = 1 ;           // = 0.  
+ fPidProbPart[1]       = 0 ;           // = 1.  
+ fPtPart[0]           = 1 ;            // = 0.  
+ fPtPart[1]           = 0 ;            // = 10. 
+ fPPart[0]            = 1 ;            // = 0.  
+ fPPart[1]            = 0 ;            // = 10. 
+ fEtaPart[0]          = 1 ;            // = -0.9
+ fEtaPart[1]          = 0 ;            // = 0.9 
+ fEtaAbsPart[0]               = 1 ;            // = 0.
+ fEtaAbsPart[1]               = 0 ;            // = 0.9 
+ fFitPtsPart[0]        = 1 ;           // = 0   
+ fFitPtsPart[1]        = 0 ;           // = 0   
+ fDedxPtsPart[0]       = 1 ;           // = 0   
+ fDedxPtsPart[1]       = 0 ;           // = 0   
+ fFitOverMaxPtsPart[0] = 1 ;           // = 0.  
+ fFitOverMaxPtsPart[1] = 0 ;           // = 0.  
+ fChiSqPart[0]         = 1 ;           // = 0.  
+ fChiSqPart[1]         = 0 ;           // = 100.
+ fDcaGlobalPart[0]     = 1 ;           // = 0.  
+ fDcaGlobalPart[1]     = 0 ;           // = 1.  
+ fYPart[0]            = 1 ;            // = 0.  
+ fYPart[1]            = 0 ;            // = 0.  
+ // -
+ fV0Pid[10] = '\0' ;
+ fV0SideBand          = 0. ;
+ fV0Pt[0]             = 1 ;  
+ fV0Pt[1]             = 0 ;  
+ fV0P[0]              = 1 ;  
+ fV0P[1]              = 0 ;  
+ fV0Eta[0]            = 1 ;  
+ fV0Eta[1]            = 0 ;  
+ fV0EtaAbs[0]          = 1 ;  
+ fV0EtaAbs[1]          = 0 ;  
+ fV0Y[0]              = 1 ;  
+ fV0Y[1]              = 0 ;  
+ fV0ChiSq[0]          = 1 ;  
+ fV0ChiSq[1]          = 0 ;  
+ fV0Lenght[0]          = 1 ;  
+ fV0Lenght[1]          = 0 ;  
+ fV0LenghtOverSigma[0] = 1 ;  
+ fV0LenghtOverSigma[1] = 0 ;  
+ fV0DcaCross[0]        = 1 ;  
+ fV0DcaCross[1]        = 0 ;  
+ // -
+ fPtBinsPart          = Flow::nPtBinsPart ;  
+ // -                  
+ fHarmonic  = -1 ;   // harmonic
+ fSelection = -1 ;   // selection
+ fSubevent  = -1 ;   // sub-event
+}
+//-----------------------------------------------------------------------
+AliFlowSelection::~AliFlowSelection() 
+{
+ // default destructor (dummy)
+}
+//-----------------------------------------------------------------------
+Bool_t AliFlowSelection::Select(AliFlowEvent* pFlowEvent) 
+{
+ // Returns kTRUE if the event is selected. 
+
+ if((fCent>=0) && ((Int_t)pFlowEvent->Centrality() != fCent)) { return kFALSE ; }
+ //if(pFlowEvent->RunID() != fRun) { return kFALSE ; }
+ //if(pFlowEvent->... != ...) { return kFALSE ; }
+ return kTRUE ;
+}
+//-----------------------------------------------------------------------
+Bool_t AliFlowSelection::Select(AliFlowTrack* pFlowTrack)
+{
+ // Selects particles for event plane determination.
+ // Returns kTRUE if the track is selected.
+ if(!pFlowTrack->Select(fHarmonic, fSelection, fSubevent)) { return kFALSE ; }
+ return kTRUE ;
+}
+//-----------------------------------------------------------------------
+Bool_t AliFlowSelection::Select(AliFlowV0* pFlowV0) 
+{
+ // Returns kTRUE if the v0 is selected. (dummy) 
+
+ return kTRUE ;
+}
+//-----------------------------------------------------------------------
+Bool_t AliFlowSelection::SelectPart(AliFlowTrack* pFlowTrack) 
+{
+ // Make track selection for Correlation Analysis & Vn (charged particles 
+ // to correlate with the event plane).  
+ // Returns kTRUE if the track is selected.
+
+ // PID
+ if(fPidPart[0] != '\0') 
+ {
+  if(strstr(fPidPart, "h")!=0)                                 // if fPidPart contains the char "h" 
+  {
+   int charge = pFlowTrack->Charge();
+   if(strcmp("h+", fPidPart)==0 && charge != 1)  return kFALSE;        // if fPidPart == "h+"
+   if(strcmp("h-", fPidPart)==0 && charge != -1) return kFALSE;
+  } 
+  else 
+  {
+   const Char_t* pid = pFlowTrack->Pid() ;
+   if(strstr(pid, fPidPart)==0) return kFALSE;                 // if pFlowTrack->Pid() does not contain fPidPart (RP. selected parts.)
+  }
+ } 
+ // PID probability
+ float pidProb = pFlowTrack->MostLikelihoodProb() ;
+ if (fPidProbPart[1] > fPidProbPart[0] &&  (pidProb < fPidProbPart[0] || pidProb > fPidProbPart[1])) return kFALSE;
+ // Constrainable
+ bool constrainable = pFlowTrack->IsConstrainable() ;
+ if (fConstrainablePart && !constrainable)  return kFALSE;
+ // Pt
+ float pt = pFlowTrack->Pt();
+ if (fPtPart[1] > fPtPart[0] &&  (pt < fPtPart[0] || pt > fPtPart[1])) return kFALSE;
+ // P
+ float totalp = pFlowTrack->P();
+ if (fPPart[1] > fPPart[0] && (totalp < fPPart[0] || totalp > fPPart[1])) return kFALSE;
+ // Eta
+ float eta = pFlowTrack->Eta();
+ if (fEtaPart[1] > fEtaPart[0] && (eta < fEtaPart[0] || eta > fEtaPart[1])) return kFALSE;
+ // |Eta|
+ float absEta = TMath::Abs(pFlowTrack->Eta());
+ if (fEtaAbsPart[1] > fEtaAbsPart[0] && (absEta < fEtaAbsPart[0] || absEta > fEtaAbsPart[1])) return kFALSE;
+ // Fit Points (TPC)
+ int fitPts = pFlowTrack->FitPtsTPC();
+ if (fFitPtsPart[1] > fFitPtsPart[0] && (fitPts < fFitPtsPart[0] || fitPts > fFitPtsPart[1])) return kFALSE;
+ // Fit Points over Max Points (TPC)
+ int maxPts = pFlowTrack->MaxPtsTPC();
+ if(maxPts) 
+ { 
+  float fitOverMaxPts = (float)(fitPts)/(float)maxPts ;
+  if (fFitOverMaxPtsPart[1] > fFitOverMaxPtsPart[0] && (fitOverMaxPts < fFitOverMaxPtsPart[0] || fitOverMaxPts > fFitOverMaxPtsPart[1])) return kFALSE;
+ }
+ // Chi Squared (main Vertex)
+ float chiSq = pFlowTrack->Chi2();
+ if (fChiSqPart[1] > fChiSqPart[0] && (chiSq < fChiSqPart[0] || chiSq > fChiSqPart[1])) return kFALSE;
+ // DCA Global
+ float globdca = pFlowTrack->Dca();
+ if (fDcaGlobalPart[1] > fDcaGlobalPart[0] && (globdca < fDcaGlobalPart[0] || globdca > fDcaGlobalPart[1])) return kFALSE;
+
+ // Rapidity
+ float Y = pFlowTrack->Y();
+ if (fYPart[1] > fYPart[0] && (Y < fYPart[0] || Y > fYPart[1])) return kFALSE;
+
+ return kTRUE;
+}
+//-----------------------------------------------------------------------
+Bool_t AliFlowSelection::SelectPart(AliFlowV0* pFlowV0) 
+{
+ // Make v0 selection for Correlation Analysis & Vn (neutral particles 
+ // to correlate with the event plane).  
+ // Returns kTRUE if the v0 is selected.
+
+ // PID
+ if(fV0Pid[0] != '\0') 
+ {
+  if(strstr(fV0Pid, '\0')!=0)
+  {
+   int charge = pFlowV0->Charge();
+   if(strcmp("0", fV0Pid)==0 && charge != 0) return kFALSE;
+  } 
+  else 
+  {
+   const Char_t* pid = pFlowV0->Pid() ;
+   if(strstr(pid, fV0Pid)==0) return kFALSE;
+  }
+ }
+
+ // InvMass
+ float mass = pFlowV0->Mass() ;
+ if(fV0Mass[1]>fV0Mass[0])
+ {
+  float massMin = fV0Mass[0]-fV0SideBand ;
+  float massMax = fV0Mass[1]+fV0SideBand ;
+  if((mass < massMin) || (mass > massMax)) return kFALSE ;
+ }
+
+ // Pt
+ float pt = pFlowV0->Pt();
+ if (fV0Pt[1] > fV0Pt[0] &&  (pt < fV0Pt[0] || pt > fV0Pt[1])) return kFALSE;
+
+ // P
+ float totalp = pFlowV0->P();
+ if (fV0P[1] > fV0P[0] && (totalp < fV0P[0] || totalp > fV0P[1])) return kFALSE;
+
+ // Eta
+ float eta = pFlowV0->Eta();
+ if (fV0Eta[1] > fV0Eta[0] && (eta < fV0Eta[0] || eta > fV0Eta[1])) return kFALSE;
+ // |Eta|
+ float absEta = TMath::Abs(pFlowV0->Eta());
+ if (fV0EtaAbs[1] > fV0EtaAbs[0] && (absEta < fV0EtaAbs[0] || absEta > fV0EtaAbs[1])) return kFALSE;
+ // Chi Squared (main Vertex)
+ float chiSq = pFlowV0->Chi2();
+ if (fV0ChiSq[1] > fV0ChiSq[0] && (chiSq < fV0ChiSq[0] || chiSq > fV0ChiSq[1])) return kFALSE;
+
+ // DCA Cross
+ float cdca = pFlowV0->CrossDca() ;
+ if (fV0DcaCross[1] > fV0DcaCross[0] && (cdca < fV0DcaCross[0] || cdca > fV0DcaCross[1])) return kFALSE;
+
+ // V0 lenght
+ float lenght = pFlowV0->V0Lenght() ;
+ if (fV0Lenght[1] > fV0Lenght[0] && (lenght < fV0Lenght[0] || lenght > fV0Lenght[1])) return kFALSE;
+
+ // V0 lenght
+ float sigma  = pFlowV0->Sigma() ;
+ if(sigma) 
+ {
+  float lenghtOverSigma = lenght/sigma ;
+  if (fV0LenghtOverSigma[1] > fV0LenghtOverSigma[0] && (lenghtOverSigma < fV0LenghtOverSigma[0] || lenghtOverSigma > fV0LenghtOverSigma[1])) return kFALSE;
+ }
+
+ // Rapidity
+ float Y = pFlowV0->Y();
+ if (fV0Y[1] > fV0Y[0] && (Y < fV0Y[0] || Y > fV0Y[1])) return kFALSE;
+
+ return kTRUE;
+}
+//-----------------------------------------------------------------------
+Bool_t  AliFlowSelection::SelectV0Part(AliFlowV0* pFlowV0)
+{ 
+ // selects v0s in the invariant Mass window
+ float mass = pFlowV0->Mass() ;
+ if(fV0Mass[1]>fV0Mass[0])
+ {
+  if(mass < fV0Mass[0] || mass > fV0Mass[1]) return kFALSE ; 
+ } 
+ return kTRUE;
+}
+//-----------------------------------------------------------------------
+Bool_t  AliFlowSelection::SelectV0Side(AliFlowV0* pFlowV0)
+{ 
+ // selects v0s in the sidebands of the Mass window
+ float mass = pFlowV0->Mass() ;
+ if(fV0Mass[1]>fV0Mass[0])
+ { 
+  float massMin = fV0Mass[0]-fV0SideBand ;
+  float massMax = fV0Mass[1]+fV0SideBand ;
+  if((mass < massMin) || (mass >= fV0Mass[0] && mass <= fV0Mass[1]) || (mass > massMax)) return kFALSE ;
+ }
+ return kTRUE;
+}
+//-----------------------------------------------------------------------
+Bool_t  AliFlowSelection::SelectV0sxSide(AliFlowV0* pFlowV0)
+{ 
+ // selects v0s in the left hand sideband
+ float mass = pFlowV0->Mass() ;
+ float massMin = fV0Mass[0]-fV0SideBand ;
+ if((mass >= massMin) && (mass < fV0Mass[0]))  { return kTRUE ; }
+ else                                          { return kFALSE ; }
+}
+//-----------------------------------------------------------------------
+Bool_t  AliFlowSelection::SelectV0dxSide(AliFlowV0* pFlowV0)
+{ 
+ // selects v0s in the right hand sideband
+ float mass = pFlowV0->Mass() ;
+ float massMax = fV0Mass[1]+fV0SideBand ;
+ if((mass > fV0Mass[1]) && (mass <= massMax))  { return kTRUE ; }
+ else                                          { return kFALSE ; }
+}
+//-----------------------------------------------------------------------
+void AliFlowSelection::PrintList() const 
+{
+ // Prints the selection criteria for correlation analysis
+
+ cout << "#################################################################" << endl;
+ cout << "# Selection List (particles correlated to the event plane):" << endl;
+ cout << "# " << endl;
+ if(fPidPart[0]!='\0') 
+ { cout << "# P.id for particles correlated to the event plane: " << fPidPart << "  " <<endl ; }
+ if(fPtPart[1]>fPtPart[0]) 
+ { cout << "# Pt for particles correlated to the event plane: " << fPtPart[0] << " to " << fPtPart[1] << " GeV/c" <<endl ; }
+ if(fPPart[1]>fPPart[0]) 
+ { cout << "# P for particles correlated to the event plane: " << fPPart[0] << " to " << fPPart[1] << " GeV/c" <<endl ; }
+ if(fEtaPart[1]>fEtaPart[0]) 
+ { cout << "# Eta for particles correlated to the event plane: " << fEtaPart[0] << " to " << fEtaPart[1] <<endl ; }
+ if(fEtaAbsPart[1]>fEtaAbsPart[0]) 
+ { cout << "# |Eta| for V0s correlated to the event plane: " << fEtaAbsPart[0] << " to " << fEtaAbsPart[1] <<endl ; }
+ if(fYPart[1]>fYPart[0]) 
+ { cout << "# Y for particles correlated to the event plane: " << fYPart[0] << " to " << fYPart[1] <<endl ; }
+ if(fFitPtsPart[1]>fFitPtsPart[0]) 
+ { cout << "# Fit Points for particles correlated to the event plane: " << fFitPtsPart[0] << " to " << fFitPtsPart[1] <<endl ; }
+ if(fDedxPtsPart[1]>fDedxPtsPart[0]) 
+ { cout << "# Dedx Points for particles correlated to the event plane: " << fDedxPtsPart[0] << " to " << fDedxPtsPart[1] << endl ; }
+ if(fFitOverMaxPtsPart[1]>fFitOverMaxPtsPart[0]) 
+ { cout << "# Fit/Max Points for particles correlated to the event plane: " << fFitOverMaxPtsPart[0] << " to " << fFitOverMaxPtsPart[1] <<endl ; }
+ if(fChiSqPart[1]>fChiSqPart[0]) 
+ { cout << "# Chi2 for particles correlated to the event plane: " << fChiSqPart[0] << " to " << fChiSqPart[1] <<endl ; }
+ if(fDcaGlobalPart[1]>fDcaGlobalPart[0]) 
+ { cout << "# Global Dca for particles correlated with the event plane: " << fDcaGlobalPart[0] << " to " << fDcaGlobalPart[1] <<endl ; }
+ if(fConstrainablePart)         { cout << "# Constrainability cut:   Constrained  Tracks " << endl ; }
+ cout << "#################################################################" << endl;
+}
+//-----------------------------------------------------------------------
+void AliFlowSelection::PrintV0List() const 
+{
+ // Prints the selection criteria for V0s
+
+ cout << "#################################################################" << endl;
+ cout << "# Selection List (V0s correlated with the event plane):" << endl;
+ cout << "# " << endl;
+ if(fV0Pid[0]!='\0') 
+ { cout << "# P.id for V0s correlated to the event plane: " << fV0Pid << "  " <<endl ; }
+ if(fV0Mass[1]>fV0Mass[0]) 
+ {
+  if(!fV0SideBand)
+  { cout << "# Invariant Mass for V0s correlated to the event plane: " << fV0Mass[0] << " to " << fV0Mass[1] << endl ; }
+  else
+  { cout << "# Invariant Mass for V0-SideBands correlated to the event plane: " << fV0Mass[0]-fV0SideBand << " to " << fV0Mass[0]  << " & " << fV0Mass[1] << " to " << fV0Mass[1]+fV0SideBand << endl ; }
+ }
+ if(fV0Pt[1]>fV0Pt[0]) 
+ { cout << "# Pt for V0s correlated to the event plane: " << fV0Pt[0] << " to " << fV0Pt[1] << " GeV/c" <<endl ; }
+ if(fV0P[1]>fV0P[0]) 
+ { cout << "# P for V0s correlated to the event plane: " << fV0P[0] << " to " << fV0P[1] << " GeV/c" <<endl ; }
+ if(fV0Eta[1]>fV0Eta[0]) 
+ { cout << "# Eta for V0s correlated to the event plane: " << fV0Eta[0] << " to " << fV0Eta[1] <<endl ; }
+ if(fV0EtaAbs[1]>fV0EtaAbs[0]) 
+ { cout << "# |Eta| for V0s correlated to the event plane: " << fV0EtaAbs[0] << " to " << fV0EtaAbs[1] <<endl ; }
+ if(fV0Y[1]>fV0Y[0]) 
+ { cout << "# Y for V0s correlated to the event plane: " << fV0Y[0] << " to " << fV0Y[1] <<endl ; }
+ if(fV0ChiSq[1]>fV0ChiSq[0]) 
+ { cout << "# Chi2 for V0s correlated to the event plane: " << fV0ChiSq[0] << " to " << fV0ChiSq[1] <<endl ; }
+ if(fV0DcaCross[1]>fV0DcaCross[0]) 
+ { cout << "# Closest approach between the daughter tracks for V0s correlated to the event plane: " << fV0DcaCross[0] << " to " << fV0DcaCross[1] <<endl ; }
+ if(fV0Lenght[1]>fV0Lenght[0]) 
+ { cout << "# ... for V0s correlated to the event plane: " << fV0Lenght[0] << " to " << fV0Lenght[1] <<endl ; }
+ if(fV0LenghtOverSigma[1]>fV0LenghtOverSigma[0]) 
+ { cout << "# ... for V0s correlated to the event plane: " << fV0LenghtOverSigma[0] << " to " << fV0LenghtOverSigma[1] <<endl ; }
+ cout << "#################################################################" << endl;
+}
+//-----------------------------------------------------------------------
+void AliFlowSelection::PrintSelectionList() const
+{
+ // Prints the list of selection cuts for RP determination
+ if(fCent>=0)      
+ { 
+  cout << "#######################################################" << endl;
+  cout << "# Event centrality: " << endl ; 
+  float lowC, hiC ;
+  if(fCent==0)      { lowC=0 ; hiC=Flow::fCentNorm[0] * Flow::fMaxMult ; }
+  else if(fCent>8)  { lowC=Flow::fCentNorm[8] * Flow::fMaxMult ; hiC=99999 ; }
+  else              { lowC=Flow::fCentNorm[fCent-1] * Flow::fMaxMult ; hiC=Flow::fCentNorm[fCent] * Flow::fMaxMult ; }
+  cout << "#  - Centrality Class = " << fCent << " ( " << (int)lowC << " < mult < " << (int)hiC << " ) . " << endl ; 
+ }
+ else      
+ { 
+  cout << "#######################################################" << endl;
+  cout << "# All centralities " << endl ; 
+ }
+
+ cout << "#######################################################" << endl;
+ cout << "# Tracks used for the event plane: " << endl ; 
+ cout << "#  - Selection[0]    (for all " << Flow::nHars << " Harmonics) :  " << endl ; 
+ cout << "#   NO CUTS " << endl ; 
+ cout << "#  - Selection[1+]   (for all " << Flow::nHars << " Harmonics) : " << endl ; 
+ if(Pid()[0] != '\0')                  { cout << "#   Particle ID =  " << Pid() << endl ; } 
+ if(ConstrainCut())                    { cout << "#   Constrainable Tracks " << endl ; }
+ if(DcaGlobalCutHi()>DcaGlobalCutLo())         { cout << "#   Global Dca Tpc cuts =  " << DcaGlobalCutLo() << " , " << DcaGlobalCutHi() << endl ; }
+ for (int k = 1; k < Flow::nSels; k++) 
+ {
+  for (int j = 0; j < Flow::nHars ; j++) 
+  {
+   cout << "#  - Selection[" << k << "] , Harmonic[" << j+1 << "] :" << endl ;
+   if(NhitsCut(k))                     { cout << "#   Minimum TPC hits =  " << NhitsCut(k) << endl ; }
+   if(EtaCutHi(j,k)>EtaCutLo(j,k))     { cout << "#   TMath::Abs(Eta) cuts =  " << EtaCutLo(j,k) << " , "  << EtaCutHi(j,k) << endl ; }
+   if(PtCutHi(j,k)>PtCutLo(j,k))       { cout << "#   Pt cuts = " << PtCutLo(j,k) << " , "  << PtCutHi(j,k) << endl ; }
+  }
+ }
+ cout << "#######################################################" << endl;  
+}
+//-----------------------------------------------------------------------
+void AliFlowSelection::SetHarmonic(const Int_t& harN) 
+{
+ if (harN < 0 || harN >= Flow::nHars) 
+ {
+  cout << "### Harmonic " << harN << " not valid" << endl;
+  fHarmonic = 0;
+ } 
+ else { fHarmonic = harN; } 
+}
+//-----------------------------------------------------------------------
+void AliFlowSelection::SetSelection(const Int_t& selN) 
+{
+ if (selN < 0 || selN >= Flow::nSels) 
+ {
+  cout << "### Selection " << selN << " not valid" << endl;
+  fSelection = 0;
+ } 
+ else { fSelection = selN; } 
+}
+//-----------------------------------------------------------------------
+void AliFlowSelection::SetSubevent(const Int_t& subN) 
+{
+ if (subN < -1 || subN > Flow::nSubs) 
+ {
+  cout << "### Subevent " << subN << " not valid" << endl;
+  fSubevent = -1;
+ } 
+ else { fSubevent = subN; } 
+}
+//-----------------------------------------------------------------------
+Float_t AliFlowSelection::PtMaxPart() const                           
+{ 
+ if(fPtPart[1]>fPtPart[0]) { return fPtPart[1] ; } 
+ else { return 0. ; } 
+}
+//-----------------------------------------------------------------------
+void AliFlowSelection::SetEtaCut(Float_t lo, Float_t hi, Int_t harN, Int_t selN) 
+{ 
+ fEtaTpcCuts[0][harN][selN] = lo ; 
+ fEtaTpcCuts[1][harN][selN] = hi ; 
+}
+//-----------------------------------------------------------------------
+void AliFlowSelection::SetPtCut(Float_t lo, Float_t hi, Int_t harN, Int_t selN)  
+{ 
+ fPtTpcCuts[0][harN][selN] = lo  ; 
+ fPtTpcCuts[1][harN][selN] = hi ; 
+}
+//-----------------------------------------------------------------------
+void AliFlowSelection::SetV0SideBands() 
+{  
+ Float_t massInterval = fV0Mass[1] - fV0Mass[0] ;
+ SetV0SideBands(TMath::Abs(massInterval/2)) ; 
+}                      
+//-----------------------------------------------------------------------
+void AliFlowSelection::SetV0SideBands(Float_t sb)                     
+{ 
+ fV0SideBand = sb ; 
+}                      
+//-----------------------------------------------------------------------
+void    AliFlowSelection::SetCentralityCut(Int_t cent)                        { fCent = cent ; }
+void    AliFlowSelection::SetRunIdCut(Int_t run)                      { fRun = run ; }
+void   AliFlowSelection::SetDcaGlobalCut(Float_t lo, Float_t hi)      { fDcaGlobalCuts[0] = lo ; fDcaGlobalCuts[1] = hi ; }
+void   AliFlowSelection::SetPidCut(const Char_t* pid)                 { strncpy(fPid, pid, 9) ; fPid[9] = '\0' ; }
+void   AliFlowSelection::SetConstrainCut(Bool_t tf)                   { fConstrainable = tf ; }
+void   AliFlowSelection::SetNhitsCut(Int_t hits,Int_t selN)           { fTPChits[selN] = hits; }
+void   AliFlowSelection::SetPidPart(const Char_t* pid)                { strncpy(fPidPart, pid, 9); fPidPart[9] = '\0'; }
+void   AliFlowSelection::SetPidProbPart(Float_t lo, Float_t hi)       { fPidProbPart[0] = lo ; fPidProbPart[1] = hi; }
+void   AliFlowSelection::SetPtPart(Float_t lo, Float_t hi)            { fPtPart[0] = lo; fPtPart[1] = hi; }
+void   AliFlowSelection::SetPtBinsPart(Int_t bins)                    { fPtBinsPart = bins; }
+void   AliFlowSelection::SetPPart(Float_t lo, Float_t hi)             { fPPart[0] = lo; fPPart[1] = hi; }
+void   AliFlowSelection::SetEtaPart(Float_t lo, Float_t hi)           { fEtaPart[0] = lo; fEtaPart[1] = hi; }
+void    AliFlowSelection::SetEtaAbsPart(Float_t lo, Float_t hi)        { fEtaAbsPart[0] = TMath::Abs(lo); fEtaAbsPart[1] = TMath::Abs(hi); }
+void   AliFlowSelection::SetYPart(Float_t lo, Float_t hi)             { fYPart[0] = lo; fYPart[1] = hi; }
+void   AliFlowSelection::SetFitPtsPart(Int_t lo, Int_t hi)            { fFitPtsPart[0] = lo; fFitPtsPart[1] = hi; }
+void   AliFlowSelection::SetDedxPtsPart(Int_t lo, Int_t hi)           { fDedxPtsPart[0] = lo; fDedxPtsPart[1] = hi; }
+void   AliFlowSelection::SetFitOverMaxPtsPart(Float_t lo, Float_t hi) { fFitOverMaxPtsPart[0] = lo; fFitOverMaxPtsPart[1] = hi; }
+void   AliFlowSelection::SetChiSqPart(Float_t lo, Float_t hi)         { fChiSqPart[0] = lo; fChiSqPart[1] = hi; }
+void   AliFlowSelection::SetDcaGlobalPart(Float_t lo, Float_t hi)     { fDcaGlobalPart[0] = lo; fDcaGlobalPart[1] = hi; }
+void    AliFlowSelection::SetConstrainablePart(Bool_t constr)          { fConstrainablePart = constr ; }
+void   AliFlowSelection::SetV0Pid(const Char_t* pid)                  { strncpy(fV0Pid, pid, 9) ; fV0Pid[9] = '\0' ; }                 
+void    AliFlowSelection::SetV0Mass(Float_t lo, Float_t hi)            { fV0Mass[0] = lo ; fV0Mass[1] = hi; }
+void   AliFlowSelection::SetV0Pt(Float_t lo, Float_t hi)              { fV0Pt[0] = lo ; fV0Pt[1] = hi; }
+void   AliFlowSelection::SetV0P(Float_t lo, Float_t hi)               { fV0P[0] = lo ; fV0P[1] = hi; }
+void   AliFlowSelection::SetV0Eta(Float_t lo, Float_t hi)             { fV0Eta[0] = lo ; fV0Eta[1] = hi; }
+void   AliFlowSelection::SetV0EtaAbs(Float_t lo, Float_t hi)          { fV0EtaAbs[0] = lo ; fV0EtaAbs[1] = hi; }
+void   AliFlowSelection::SetV0Y(Float_t lo, Float_t hi)               { fV0Y[0] = lo ; fV0Y[1] = hi; }
+void   AliFlowSelection::SetV0ChiSqPart(Float_t lo, Float_t hi)       { fV0ChiSq[0] = lo ; fV0ChiSq[1] = hi; }
+void   AliFlowSelection::SetV0Lenght(Float_t lo, Float_t hi)          { fV0Lenght[0] = lo ; fV0Lenght[1] = hi; }
+void   AliFlowSelection::SetV0DcaCross(Float_t lo, Float_t hi)        { fV0DcaCross[0] = lo ; fV0DcaCross[1] = hi; }
+void   AliFlowSelection::SetV0LenghtOverSigma(Float_t lo, Float_t hi) { fV0LenghtOverSigma[0] = lo ; fV0LenghtOverSigma[1] = hi; }
+//-----------------------------------------------------------------------
+Char_t* AliFlowSelection::PidPart()                                   { return fPidPart; }
+Int_t  AliFlowSelection::PtBinsPart() const                           { return fPtBinsPart; }
+Int_t  AliFlowSelection::Sel() const                                  { return fSelection; }
+Int_t  AliFlowSelection::Har() const                                  { return fHarmonic; }
+Int_t  AliFlowSelection::Sub() const                                  { return fSubevent; }
+Float_t AliFlowSelection::EtaCutLo(Int_t harN, Int_t selN) const       { return fEtaTpcCuts[0][harN][selN] ; }
+Float_t AliFlowSelection::EtaCutHi(Int_t harN, Int_t selN) const       { return fEtaTpcCuts[1][harN][selN] ; }
+Float_t AliFlowSelection::PtCutLo(Int_t harN, Int_t selN) const        { return fPtTpcCuts[0][harN][selN] ; }
+Float_t AliFlowSelection::PtCutHi(Int_t harN, Int_t selN) const        { return fPtTpcCuts[1][harN][selN] ; }
+Char_t* AliFlowSelection::Pid() const                                 { return fPid; }
+Float_t AliFlowSelection::DcaGlobalCutLo() const                      { return fDcaGlobalCuts[0] ; }
+Float_t AliFlowSelection::DcaGlobalCutHi() const                      { return fDcaGlobalCuts[1] ; }
+Bool_t  AliFlowSelection::ConstrainCut() const                        { return fConstrainable ; }
+Int_t   AliFlowSelection::NhitsCut(Int_t selN) const                  { return fTPChits[selN] ; }
+//-----------------------------------------------------------------------
+Int_t   AliFlowSelection::CentralityCut() const                       { return fCent ; }
+Int_t   AliFlowSelection::RunIdCut() const                            { return fRun ; }
+//-----------------------------------------------------------------------
+void    AliFlowSelection::SetJustLoopConstrainable()                  { fJustLoopConstrainable = kTRUE ; }
+Bool_t  AliFlowSelection::JustLoopConstrainable() const                       { return fJustLoopConstrainable ; }
+//-----------------------------------------------------------------------
diff --git a/PWG2/FLOW/AliFlowSelection.h b/PWG2/FLOW/AliFlowSelection.h
new file mode 100644 (file)
index 0000000..d9f683c
--- /dev/null
@@ -0,0 +1,190 @@
+//////////////////////////////////////////////////////////////////////
+//
+// $Id$
+//
+// Author: Emanuele Simili
+//
+//////////////////////////////////////////////////////////////////////
+//
+// Description: class for selections in flow study, adapted from STAR 
+// Original Authors:                Raimond Snellings & Art Poskanzer
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef AliFlowSelection_h
+#define AliFlowSelection_h
+
+#include <iostream>
+#include <stdlib.h>
+#include <string.h>
+
+#include "TObject.h"
+#include "TVector.h"
+#include "TMath.h"
+#include <TROOT.h>
+
+#include "AliFlowSelection.h"
+#include "AliFlowEvent.h"
+#include "AliFlowTrack.h"
+#include "AliFlowV0.h"
+#include "AliFlowConstants.h"
+
+class AliFlowTrack ;
+class AliFlowEvent ;
+class Flow ;
+
+class AliFlowSelection : public TObject {
+
+ public:
+
+          AliFlowSelection();
+  virtual ~AliFlowSelection();
+
+ // Selection Methods for ... 
+  Bool_t  Select(AliFlowEvent*);                               // (dummy)
+  Bool_t  Select(AliFlowTrack*);                               // selection for R.P.[nSel][nHar]
+  Bool_t  Select(AliFlowV0*);                                  // (dummy) 
+  Bool_t  SelectPart(AliFlowTrack*);                           // track selection for Correlation Analysis
+  Bool_t  SelectPart(AliFlowV0*);                              // v0 selection for Correlation Analysis (mass window + sidebands)
+  Bool_t  SelectV0Part(AliFlowV0*);                                    // v0 mass window for Correlation Analysis 
+  Bool_t  SelectV0Side(AliFlowV0*);                                    // v0 sidebands for Correlation Analysis 
+  Bool_t  SelectV0sxSide(AliFlowV0*);                          // selects v0s in the left hand sideband
+  Bool_t  SelectV0dxSide(AliFlowV0*);                          // selects v0s in the right hand sideband
+
+ // Gets (Harmonic, Selection, Sub-event)
+  Int_t   Sel() const;                                         // Returns the Harmonic                       
+  Int_t   Har() const;                                         // Returns the Selection
+  Int_t   Sub() const;                                         // Returns the Sub-Event
+
+ // Gets (Event cuts)
+  Int_t   CentralityCut() const ;                              // Returns Event Centrality class
+  Int_t   RunIdCut() const ;                                   // Returns Run number 
+
+ // Gets (R.P. cuts) and CutList
+  Float_t EtaCutLo(Int_t harN, Int_t selN) const;              // Returns lower eta cut for R.P.[harN][selN] calculation (absolute values)
+  Float_t EtaCutHi(Int_t harN, Int_t selN) const;              // Returns upper eta cut for R.P.[harN][selN] calculation (absolute values)                             
+  Float_t PtCutLo(Int_t harN, Int_t selN)  const;              // Returns lower pT cut for R.P.[harN][selN] calculation 
+  Float_t PtCutHi(Int_t harN, Int_t selN) const ;              // Returns upper pT cut for R.P.[harN][selN] calculation
+  Float_t DcaGlobalCutLo() const;                              // Returns lower DCA cut for R.P. calculation
+  Float_t DcaGlobalCutHi() const;                              // Returns upper DCA cut for R.P. calculation
+  Char_t* Pid() const;                                         // Returns particle specie used in R.P. calculation
+  Bool_t  ConstrainCut() const;                                        // Returns kTRUE/kFalse if the cut over un-constrainable tracks is enabled
+  Int_t   NhitsCut(Int_t selN) const;                                  // Returns the minimum number of TPC hits for R.P.[selN] calculation
+
+ // Gets (correlation cuts)
+  Char_t* PidPart() ;                                          // Returns selected particle species wrt Reaction Plane
+  Float_t PtMaxPart() const ;                                  // Returns the max pT for evt.plane calc.
+  Int_t   PtBinsPart() const ;                                 // Returns N. of pT binning
+  void    SetPtBinsPart(const Int_t);                          // Sets N. of bins from fPtPart[0] to fPtPart[1]
+  void    PrintList() const ;                                  // Prints the tracks cut-list (for correlation analysis)
+  void    PrintSelectionList() const ;                         // Prints a summary of the selection criteria (for RP determination)
+  void    PrintV0List() const ;                                        // Prints the v0s cut-list (for correlation analysis)
+
+ // Harmonic & Selection set (R.P.)
+  void    SetHarmonic(const Int_t&);                           // Sets the Harmonic
+  void    SetSelection(const Int_t&);                          // Sets the Selection
+  void    SetSubevent(const Int_t&);                           // Sets the Sub-Event
+  
+ // Cuts set (Events)
+  void    SetCentralityCut(Int_t cent) ;                       // Sets Event Centrality class
+  void    SetRunIdCut(Int_t run) ;                             // Sets Run number 
+  
+ // Cuts set (Reaction Plane)
+  static void  SetPidCut(const Char_t* pid);                              // Sets the particle specie used in R.P. calculation
+  static void  SetEtaCut(Float_t lo, Float_t hi, Int_t harN, Int_t selN);  // Sets |eta| cut for R.P.[harN][selN] calculation
+  static void  SetPtCut(Float_t lo, Float_t hi, Int_t harN, Int_t selN);   // Sets pT cut for R.P.[harN][selN] calculation
+  static void  SetDcaGlobalCut(Float_t lo, Float_t hi);                   // Sets DCA cut for R.P. calculation
+  static void  SetConstrainCut(Bool_t tf = kTRUE) ;                       // Sets the cut over un-constrainable tracks
+  static void  SetNhitsCut(Int_t hits, Int_t selN) ;                      // Sets the minimum number of TPC hits for R.P.[selN] calculation
+
+ // Cuts set (Correlation Analysis)
+  void    SetPidPart(const Char_t*);                           // Sets PID for particles wrt Reaction plane 
+  void   SetPidProbPart(const Float_t, const Float_t);         // Sets PID probability for particles wrt Reaction plane
+  void    SetPtPart(const Float_t, const Float_t);             // Sets pT for particles wrt Reaction plane 
+  void    SetPPart(const Float_t, const Float_t);              // Sets Momentum for particles wrt Reaction plane 
+  void    SetEtaPart(const Float_t, const Float_t);            // Sets Eta for particles wrt Reaction plane    
+  void    SetEtaAbsPart(const Float_t, const Float_t);         // Sets |Eta| for particles wrt Reaction plane          
+  void    SetYPart(const Float_t, const Float_t);              // Sets Rapidity for particles (with sign.) wrt Reaction plane 
+  void    SetFitPtsPart(const Int_t, const Int_t);             // Sets FitPoints for particles wrt Reaction plane  
+  void    SetDedxPtsPart(const Int_t, const Int_t);            // Sets dE/dx for particles wrt Reaction plane          
+  void    SetFitOverMaxPtsPart(const Float_t, const Float_t);  // Sets FitPoints/MaxPoints for particles wrt Reaction plane 
+  void    SetChiSqPart(const Float_t, const Float_t);          // Sets Chi^2 for particles wrt Reaction plane          
+  void    SetDcaGlobalPart(const Float_t, const Float_t);      // Sets d.c.a. for particles wrt Reaction plane         
+  void    SetConstrainablePart(Bool_t constr = kTRUE);         // Sets constrainability for particles wrt Reaction plane       
+
+ // Cuts set (V0 Analysis)
+  void    SetV0Pid(const Char_t*) ;                            // Sets PID for v0 wrt plane (...)
+  void    SetV0Mass(const Float_t, const Float_t) ;            // Sets invariant mass cut for v0 wrt plane 
+  void    SetV0Pt(const Float_t, const Float_t) ;              // Sets pT for v0 wrt plane 
+  void    SetV0P(const Float_t, const Float_t) ;               // Sets Momentum for v0 wrt plane 
+  void    SetV0Eta(const Float_t, const Float_t) ;             // Sets Eta cut for v0 wrt plane 
+  void    SetV0EtaAbs(const Float_t, const Float_t) ;          // Sets |Eta| cut (absolute value) for v0 wrt plane 
+  void    SetV0Y(const Float_t, const Float_t) ;               // Sets Rapidity for v0 wrt plane 
+  void    SetV0ChiSqPart(const Float_t, const Float_t) ;       // Sets Chi^2 for v0 wrt plane 
+  void    SetV0DcaCross(const Float_t, const Float_t) ;        // Sets distance to the main vertex for v0 wrt plane
+  void    SetV0Lenght(const Float_t, const Float_t) ;          // Sets distance to the main vertex in sigma units for v0 wrt plane
+  void    SetV0LenghtOverSigma(const Float_t, const Float_t) ; // Sets closest approach (between the 2 daughter tracks) for v0 wrt plane  
+  void   SetV0SideBands() ;                                    // Includes the v0 sideband analysis wrt plane          
+  void   SetV0SideBands(const Float_t) ;                       // Includes the v0 sideband analysis and a width                
+
+ // For just constrainable track analysis (main loop, R.P. excluded)
+  void    SetJustLoopConstrainable() ;                         // Sets for the analysis loop just over constrainable track
+  Bool_t  JustLoopConstrainable() const ;                      // kFALSE (default) or kTRUE (set it above) 
+
+ private:
+
+ // These are just 3 integers - simple way to look at the [nHar][nSel] and [nSub] array
+  Int_t   fHarmonic;                                           // harmonic
+  Int_t   fSelection;                                          // selection
+  Int_t   fSubevent;                                           // sub-event
+
+  Int_t   fPtBinsPart;                                         // N. of bins in pT histograms (pT binning)
+
+ // Event Cuts  (new)
+  Int_t  fCent ;                                               // Event Centrality class
+  Int_t  fRun ;                                                // Run number 
+
+ // Cuts for V0 correlated to the Raction Plane (new)
+  Char_t  fV0Pid[10];                                          // PID for v0 wrt plane (...)
+  Float_t fV0SideBand ;                                                // width of the sidebands (using the sidebands' candidates)
+  Float_t fV0Mass[2] ;                                         // mass cut for v0 wrt plane
+  Float_t fV0Pt[2];                                            // pT for v0 wrt plane 
+  Float_t fV0P[2];                                             // Momentum for v0 wrt plane 
+  Float_t fV0Eta[2];                                           // Eta cut for v0 wrt plane 
+  Float_t fV0EtaAbs[2];                                        // |Eta| cut (absolute value) for v0 wrt plane 
+  Float_t fV0Y[2];                                             // Rapidity for v0 wrt plane 
+  Float_t fV0ChiSq[2];                                         // Chi^2 for v0 wrt plane 
+  Float_t fV0Lenght[2];                                        // distance to the main vertex for v0 wrt plane
+  Float_t fV0LenghtOverSigma[2];                               // distance to the main vertex in sigma units for v0 wrt plane
+  Float_t fV0DcaCross[2];                                      // closest approach (between the 2 daughter tracks) for v0 wrt plane
+
+ // Cuts for Tracks that will be related to the Raction Plane (original strategy from STAR)
+  Char_t  fPidPart[10];                                        // PID for parts. wrt plane (h+, h-, pi-, pi+, pi, k+, k-, k, pr+, pr-, pr, d+, d-, d, e+, e-, e)
+  Float_t fPidProbPart[2] ;                                    // probability of the most likelihood p.id. (you should specify also PidPart())
+  Float_t fPtPart[2];                                          // pT for parts. wrt plane
+  Float_t fPPart[2];                                           // Momentum for parts. wrt plane
+  Float_t fEtaPart[2];                                         // Eta cut for parts. wrt plane
+  Float_t fEtaAbsPart[2];                                      // |Eta| cut (absolute value) for parts. wrt plane
+  Float_t fYPart[2];                                           // Rapidity for parts. wrt plane 
+  Int_t   fFitPtsPart[2];                                      // FitPoints for parts. wrt plane
+  Int_t   fDedxPtsPart[2];                                     // dE/dx for parts. wrt plane
+  Float_t fFitOverMaxPtsPart[2];                               // FitPoints/MaxPoints for parts. wrt plane
+  Float_t fChiSqPart[2];                                       // Chi^2 for parts. wrt plane
+  Float_t fDcaGlobalPart[2];                                   // closest approach (to the main vertex) for parts. wrt plane
+  Bool_t  fConstrainablePart;                                  // constrainability for parts. wrt plane 
+
+ // Cuts for Tracks used in determining the Raction Plane (in STAR this selection was done inside the AliFlowEvent class)
+  static Float_t  fEtaTpcCuts[2][Flow::nHars][Flow::nSels];    //! eta range (absolute values)
+  static Float_t  fPtTpcCuts[2][Flow::nHars][Flow::nSels];     //! pT range
+  static Float_t  fDcaGlobalCuts[2];                           //! DCA cuts
+  static Char_t   fPid[10];                                    //! h+, h-, pi-, pi+, pi, k+, k-, k, pr+, pr-, pr, e+, e-, e, d+, d-, d
+  static Int_t    fTPChits[Flow::nSels];                       //! minimum number of TPC hits
+  static Bool_t   fConstrainable;                              //! cut un-constrainable tracks 
+
+ // Cuts for all tracks entering the main loop (R.P. loop is excluded)
+  Bool_t  fJustLoopConstrainable ;                             // constrainability for tracks entering the main loop 
+
+  ClassDef(AliFlowSelection,1)                                 // macro for rootcint
+}; 
+
+#endif
diff --git a/PWG2/FLOW/AliFlowTrack.cxx b/PWG2/FLOW/AliFlowTrack.cxx
new file mode 100644 (file)
index 0000000..835e654
--- /dev/null
@@ -0,0 +1,511 @@
+//////////////////////////////////////////////////////////////////////
+//
+// $Id$
+//
+// Author: Emanuele Simili
+//
+//////////////////////////////////////////////////////////////////////
+//
+//_____________________________________________________________
+//
+// Description: 
+//         an array of AliFlowTrack is the core of the AliFlowEvent. 
+// The object AliFlowTrack contains data members wich summarize the track 
+// information most useful for flow study (such as Pt, eta, phi angle, 
+// p.id hypothesis, some detector informations like fitpoints, chi2, 
+// energy loss, t.o.f., ecc.). 
+// This class is optimized for reaction plane calculation and sub-event 
+// selection, through the appropriate methods in AliFlowEvent.  
+// Two arrays of flags in the AliFlowTrack object (fSelection[][] and 
+// fSubevent[][]) specify whether a track is included or not in a certain 
+// Selection or Subevent. Those flags are switched on/off by the method 
+// AliFlowEvent::SetSelection(), according to Eta, Pt, dca, constrainability  
+// of the track, number of TPC hits, and p.id hypotesis (static member of the
+// AliFlowEvent class (fEtaTpcCuts[][][], fPtTpcCuts[][][], fDcaGlobalCuts[], 
+// fPid[], ecc.). 
+//
+// The AliFlowTrack Class is adapted from the original StFlowTrack,
+// succesfully employed to study flow in the STAR experiment at RICH.
+// Original Authors:                 Raimond Snellings & Art Poskanzer
+//
+
+#include "AliFlowTrack.h"
+#include "AliFlowConstants.h"
+#include <iostream>
+using namespace std; //required for resolving the 'cout' symbol
+
+ClassImp(AliFlowTrack) ;
+//////////////////////////////////////////////////////////////////////////////
+AliFlowTrack::AliFlowTrack()
+{
+ // Default constructor
+ fPhi = 0. ;
+ fEta = 0. ;
+ fPt  = 0. ;
+ fPhiGlobal = 0. ;
+ fEtaGlobal = 0. ;
+ fPtGlobal  = 0. ;
+ fChi2 = 0. ;
+ fZFirstPoint = 0. ;                 
+ fZLastPoint = 0. ;                          
+ fTrackLength = 0. ;
+ fMostLikelihoodPID = 0 ;                    
+ for(Int_t ii=0;ii<2;ii++)         { fDcaSigned[ii] = 0 ; }                          
+ for(Int_t ii=0;ii<Flow::nPid;ii++) { fPidProb[ii] = 0. ; }
+ for(Int_t ii=0;ii<4;ii++)
+ {
+  fFitPts[4]  = 0  ; fMaxPts[4]  = 0  ; 
+  fFitChi2[4] = 0. ; fDedx[4]    = 0. ;
+  fMom[4] = 0. ;
+ }
+ ResetSelection() ;                          
+}
+//////////////////////////////////////////////////////////////////////////////
+AliFlowTrack::AliFlowTrack(const Char_t* name) 
+{
+ // TNamed constructor
+  
+ SetName(name) ;
+ AliFlowTrack() ;
+}
+//////////////////////////////////////////////////////////////////////////////
+AliFlowTrack::~AliFlowTrack() 
+{
+ // default destructor (dummy)
+}
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+Float_t  AliFlowTrack::P() const 
+{ 
+ // Returns the total momentum of the constrained track (calculated from Pt & Eta),
+ // if the track is not constrainable returns 0 (used as flag for contrainable tracks).
+ if(!IsConstrainable()) { return 0 ; }               
+ Float_t momentum = Pt()/TMath::Sqrt(1-(TMath::TanH(Eta())*TMath::TanH(Eta()))); 
+ return momentum; 
+}
+//////////////////////////////////////////////////////////////////////////////
+Float_t  AliFlowTrack::PGlobal()                   const 
+{ 
+ // Returns the total momentum of the unconstrained track (always>0). 
+
+ Float_t momentum = PtGlobal()/TMath::Sqrt(1-(TMath::TanH(EtaGlobal())*TMath::TanH(EtaGlobal()))); 
+ return momentum; 
+}
+//////////////////////////////////////////////////////////////////////////////
+Float_t  AliFlowTrack::Mass() const 
+{ 
+ // Returns the mass of the track, basing on its P.Id. hypotesis
+
+ Float_t M = 0.13957 ;  // pion mass 
+
+ if(MostLikelihoodPID() == 0)                        { M = -1.    ; }
+ else if(TMath::Abs(MostLikelihoodPID()) == 11)              { M = 0.00051; }
+ else if(TMath::Abs(MostLikelihoodPID()) == 13)              { M = 0.10566; }
+ else if(TMath::Abs(MostLikelihoodPID()) == 211)      { M = 0.49368; }
+ else if(TMath::Abs(MostLikelihoodPID()) == 321)      { M = 0.13957; }
+ else if(TMath::Abs(MostLikelihoodPID()) == 2212)     { M = 0.93827; }
+ else if(TMath::Abs(MostLikelihoodPID()) == 10010020) { M = 1.87505; }
+
+ return M ;
+}
+//////////////////////////////////////////////////////////////////////////////
+Float_t  AliFlowTrack::InvMass() const 
+{ 
+ // Returns the invariant mass of the track, calculated from T.O.F. and P_tot
+
+ Float_t M = -1 ;                  // if no calculation possible, it returns -1
+ Float_t c = TMath::Ccgs()/1e+12 ;  // = 0.02998 ;  --> speed of light in cm/psec
+ Float_t tof = TofTOF() ;          // in pico-seconds
+ Float_t lenght = TrackLength() ;   // in cm
+ Float_t Ptot = 0 ;                // constrained parameters are used if there, otherwise unconstrained
+ if(IsConstrainable()) { Ptot = P() ; }
+ else                  { Ptot = PGlobal() ; }
+ if(tof>0 && lenght>0)
+ { 
+  Float_t beta = lenght / (tof * c) ;
+  if(beta<1) 
+  {
+   Float_t gamma = 1/TMath::Sqrt(1-(beta*beta)) ;
+   M = TMath::Abs(Ptot/(beta*gamma)) ;  
+  } // cout << ii << ": Mass = " << cmass << " , t/l = " << (tof/lenght) << " , beta = " << beta << " , gamma = " << gamma << endl ; }
+ }  // else { cout << ii << ": TOF = " << tof << "     , Lenght = " << lenght << endl ; }
+
+ return M ;
+}
+//////////////////////////////////////////////////////////////////////////////
+Float_t  AliFlowTrack::Y() const 
+{
+ // Rapidity of the constrained track.
+ // If track is not constrainable, the unconstrained rapidity is returned.
+ if(!IsConstrainable()) { return YGlobal() ; }
+ if(TMath::Abs((Float_t)P()) == TMath::Abs((Float_t)Pt()))     { return 0. ; }
+ else if(TMath::Abs((Float_t)P()) < TMath::Abs((Float_t)Pt())) { cout << "track: " << GetName() << "has  Pt() > P() !!!" << endl ; }
+ // -
+ float M = Mass() ; 
+ double Pz = TMath::Sqrt(P()*P() - Pt()*Pt()); 
+ if(Eta()<0) { Pz = -Pz ; }
+ double E = TMath::Sqrt(P()*P() + M*M) ;
+ float rapidity = 0.5*TMath::Log((E + Pz)/(E - Pz)) ;
+ return rapidity ;
+}
+//////////////////////////////////////////////////////////////////////////////
+Float_t  AliFlowTrack::YGlobal() const 
+{
+ // Rapidity of the unconstrained track
+
+ if(TMath::Abs((Float_t)PGlobal()) == TMath::Abs((Float_t)PtGlobal()))            { return 0. ; }
+ else if(TMath::Abs((Float_t)PGlobal()) < TMath::Abs((Float_t)PtGlobal())) { cout << "track: " << GetName() << "has  Pt() > P() !!!" << endl ; }
+ // -
+ float M = Mass() ; 
+ double Pz = TMath::Sqrt(PGlobal()*PGlobal() - PtGlobal()*PtGlobal()); 
+ if(EtaGlobal()<0) { Pz = -Pz ; }
+ double E = TMath::Sqrt(PGlobal()*PGlobal() + M*M) ;
+ float rapidity = 0.5*TMath::Log((E + Pz)/(E - Pz)) ;
+ return rapidity ;
+}
+//////////////////////////////////////////////////////////////////////////////
+Bool_t AliFlowTrack::Select(Int_t harmonic,Int_t selection,Int_t subevent) const 
+{
+ // Returns the selection flag for [harmonic] [selection] [sub-event]
+
+ if((subevent == -1) || (subevent == fSubevent[harmonic][selection])) 
+ {
+  if(fSelection[harmonic][selection]) { return kTRUE ; }
+ } 
+ return kFALSE ;       
+}
+//////////////////////////////////////////////////////////////////////////////
+void AliFlowTrack::SetSelect(Int_t harmonic,Int_t selection) 
+{ 
+ fSelection[harmonic][selection] = kTRUE ;
+}
+//////////////////////////////////////////////////////////////////////////////
+void AliFlowTrack::SetSubevent(Int_t harmonic,Int_t selection,Int_t subevent) 
+{ 
+ fSubevent[harmonic][selection] = subevent ; 
+}
+//////////////////////////////////////////////////////////////////////////////
+void AliFlowTrack::PrintSelection() 
+{
+ // Prints a short string of 0 & 1 to visualize the selections' flags
+ // [har1][sel0],[har1][sel1],[har1][sel2],...,[har2][sel0],...
+ for(int i=0;i<Flow::nHars;i++)
+ {
+  for(int j=0;j<Flow::nSels;j++)
+  {
+   if(Select(i,j)) { cout << 1 ; }
+   else           { cout << 0 ; }
+  }
+ }
+ cout << endl ;
+}
+//////////////////////////////////////////////////////////////////////////////
+void AliFlowTrack::ResetSelection() 
+{
+ // Re-sets all the selection/sub-event flags to 0 
+ // (track won't be used in any R.P. calculation)
+
+ for(Int_t ii=0;ii<Flow::nHars;ii++)
+ {
+  for(Int_t jj=0;jj<Flow::nSels;jj++)
+  {
+   fSelection[ii][jj] = kFALSE ; 
+   fSubevent[ii][jj] = -1 ; 
+  }
+ }
+}
+//////////////////////////////////////////////////////////////////////////////
+const char* AliFlowTrack::Pid() const
+{
+ // Returns the P.Id. in characters (e,mu,pi,k,p,d) basing on the stored pdg code 
+ // and its sign (both stored in MostLikelihoodPID() ) .
+ const char *name[] = {"e","mu","pi","k","pr","d"} ;
+ int pdg_code = TMath::Abs(MostLikelihoodPID()) ;
+ int charge = Charge() ;
+
+ TString p_id = "" ;
+ if(pdg_code == 11)            { p_id = name[0] ; }
+ else if(pdg_code == 13)       { p_id = name[1] ; }
+ else if(pdg_code == 211)      { p_id = name[2] ; }
+ else if(pdg_code == 321)      { p_id = name[3] ; }
+ else if(pdg_code == 2212)     { p_id = name[4] ; }
+ else if(pdg_code == 10010020) { p_id = name[5] ; }
+ else                         { p_id = "0" ; }
+
+ if(charge>0)          { p_id += "+" ; } 
+ else if(charge<0)     { p_id += "-" ; }
+ else                  { p_id += "" ; }
+ return p_id.Data() ; 
+}
+//////////////////////////////////////////////////////////////////////////////
+void AliFlowTrack::PidProbs(Float_t pidN[Flow::nPid]) const 
+{ 
+ // Returns the normalized probability for the given track to be [e,mu,pi,k,p,d] 
+ // The detector response is weighted by the bayesian vector of particles 
+ // abundances, stored in Flow::fBayesian[] .
+
+ Double_t sum = 0 ; 
+ for(Int_t n=0;n<Flow::nPid;n++)  { sum += fPidProb[n] * Flow::fBayesian[n] ; }
+ if(sum)
+ {
+  for(Int_t n=0;n<Flow::nPid;n++) { pidN[n] = fPidProb[n] * Flow::fBayesian[n] / sum ; }
+ }
+ else { cout << " ERROR - Empty Bayesian Vector !!! " << endl ; }
+} 
+//////////////////////////////////////////////////////////////////////////////
+Float_t  AliFlowTrack::PidProb(Int_t nn)       const
+{
+ // Returns the normalized probability of the track to be [nn] (e,mu,pi,k,pi,d).
+
+ Float_t pidN[Flow::nPid] ; 
+ PidProbs(pidN) ;
+ return pidN[nn] ;
+}
+//////////////////////////////////////////////////////////////////////////////
+TVector AliFlowTrack::PidProbs()               const
+{
+ // Returns the normalized probability for the given track to be [e,mu,pi,k,p,d] 
+ // as a TVector.
+
+ TVector pidNvec(Flow::nPid) ;
+ Float_t pidN[Flow::nPid] ; 
+ PidProbs(pidN) ;
+ for(Int_t n=0;n<Flow::nPid;n++)  { pidNvec[n] = pidN[n] ; }
+
+ return pidNvec ;
+}
+//////////////////////////////////////////////////////////////////////////////
+void AliFlowTrack::RawPidProbs(Float_t pidV[Flow::nPid]) const 
+{ 
+ // Returns the array of probabilities for the track to be [e,mu,pi,k,pi,d].
+
+ for(Int_t ii=0;ii<Flow::nPid;ii++) { pidV[ii] = fPidProb[ii] ; }
+} 
+//////////////////////////////////////////////////////////////////////////////
+Float_t AliFlowTrack::MostLikelihoodProb()         const 
+{ 
+ // Returns the probability of the most probable P.id.
+ // (Warning: THIS IS NOT WEIGHTED IN THE BAYESIAN WAY...) 
+
+ int pdg_code = TMath::Abs(MostLikelihoodPID()) ;
+ if(pdg_code == 11)            { return fPidProb[0] ; }
+ else if(pdg_code == 13)       { return fPidProb[1] ; }
+ else if(pdg_code == 211)      { return fPidProb[2] ; }
+ else if(pdg_code == 321)      { return fPidProb[3] ; }
+ else if(pdg_code == 2212)     { return fPidProb[4] ; }
+ else if(pdg_code == 10010020) { return fPidProb[5] ; }
+ else { return 0. ; }
+} 
+//////////////////////////////////////////////////////////////////////////////
+void AliFlowTrack::SetPid(const Char_t* pid)           
+{ 
+ // Sets the P.Id. hypotesis of the track from a String imput (that should be 
+ // ("e","mu","pi","k","pr","d"). Sign is allowed as well. The string itself 
+ // is not stored, what is stored is the signed PDG code.
+ if(strstr(pid,"e"))      { fMostLikelihoodPID = 11    ; }
+ else if(strstr(pid,"mu")) { fMostLikelihoodPID = 13   ; }
+ else if(strstr(pid,"pi")) { fMostLikelihoodPID = 211  ; }
+ else if(strstr(pid,"k"))  { fMostLikelihoodPID = 321  ; }
+ else if(strstr(pid,"pr")) { fMostLikelihoodPID = 2212  ; }
+ else if(strstr(pid,"d"))  { fMostLikelihoodPID = 10010020 ; }
+ else { fMostLikelihoodPID = 0 ; cout << "AliFlowTrack - !BAD IMPUT!" << endl ; }
+ if(strchr(pid,'+'))      { fMostLikelihoodPID = TMath::Abs(fMostLikelihoodPID) * 1 ; }
+ else if(strchr(pid,'-'))  { fMostLikelihoodPID = TMath::Abs(fMostLikelihoodPID) * -1 ; } 
+}
+//////////////////////////////////////////////////////////////////////////////
+Int_t AliFlowTrack::Charge() const 
+{ 
+ // Tracks charge (stored as sign of fMostLikelihoodPID). +/-2 if deuterium.
+ if(MostLikelihoodPID() == 10010020) { return TMath::Sign(2,MostLikelihoodPID()) ; }
+ else                               { return TMath::Sign(1,MostLikelihoodPID()) ; }
+}            
+//////////////////////////////////////////////////////////////////////////////
+void AliFlowTrack::SetCharge(Int_t charge)
+{ 
+ // Sets the charge of the track (+/- sign of MostLikelihoodPID()).
+ fMostLikelihoodPID = TMath::Sign(TMath::Abs(fMostLikelihoodPID),charge) ;
+}
+//////////////////////////////////////////////////////////////////////////////
+Bool_t AliFlowTrack::IsConstrainable()             const 
+{ 
+ // Returns kTRUE if the track is constrainable. 
+ // If the track is constrainable -> the constrained parameters are stored (and the
+ // unconstrained ones as well in ...Global). 
+ // Otherwise (if track is not constrainable) -> just the unconstrained parameters 
+ // are stored, and returned instead of the constrained ones .
+ if(fPt==0 && fEta==0) { return kFALSE ; }
+ else                 { return kTRUE ; }
+} 
+//////////////////////////////////////////////////////////////////////////////
+Float_t AliFlowTrack::Dca()                        const 
+{
+ Double_t mag = 0 ;
+ for(Int_t ii=0;ii<2;ii++) { mag += (fDcaSigned[ii]*fDcaSigned[ii]) ; } 
+ return TMath::Sqrt(mag) ; 
+}     
+//////////////////////////////////////////////////////////////////////////////
+Float_t AliFlowTrack::Dca2(Float_t dca[2])         const 
+{ 
+ Double_t mag = 0 ;
+ for(Int_t ii=0;ii<2;ii++) 
+ { 
+  dca[ii] = fDcaSigned[ii] ; 
+  mag += (fDcaSigned[ii]*fDcaSigned[ii]) ; 
+ } 
+ return TMath::Sqrt(mag) ; 
+}
+//////////////////////////////////////////////////////////////////////////////
+Float_t AliFlowTrack::Dca3(Float_t dca[3])         const 
+{
+ dca[0] = TMath::Abs(fDcaSigned[0])* TMath::Cos(Phi()) ;
+ dca[1] = TMath::Abs(fDcaSigned[0])* TMath::Sin(Phi()) ;
+ dca[2] = TMath::Abs(fDcaSigned[1]) ;          
+ return Dca() ; 
+}     
+//////////////////////////////////////////////////////////////////////////////
+Float_t  AliFlowTrack::Phi()                       const 
+{ 
+ if(IsConstrainable()) { return fPhi ; }
+ else          { return PhiGlobal() ; }
+}                  
+//////////////////////////////////////////////////////////////////////////////
+Float_t  AliFlowTrack::Pt()                        const 
+{  
+ if(IsConstrainable())  { return fPt ; }
+ else           { return PtGlobal() ; }
+}
+//////////////////////////////////////////////////////////////////////////////
+Float_t  AliFlowTrack::Eta()                       const 
+{  
+ if(IsConstrainable())  { return fEta ; }
+ else           { return EtaGlobal() ; }
+}                    
+//////////////////////////////////////////////////////////////////////////////
+Float_t  AliFlowTrack::PhiGlobal()                 const { return fPhiGlobal ; }                   
+Float_t  AliFlowTrack::PtGlobal()                  const { return fPtGlobal ; }                    
+Float_t  AliFlowTrack::EtaGlobal()                 const { return fEtaGlobal ; }                     
+//////////////////////////////////////////////////////////////////////////////
+Float_t AliFlowTrack::TransDcaSigned()                     const { return fDcaSigned[0] ; }            
+Float_t AliFlowTrack::TransDca()                   const { return TMath::Abs(TransDcaSigned()) ; }     
+Float_t  AliFlowTrack::Chi2()                      const { return fChi2 ; }                
+Float_t  AliFlowTrack::TrackLength()               const { return fTrackLength ; }         
+Float_t  AliFlowTrack::ZFirstPoint()               const { return fZFirstPoint ; }         
+Float_t  AliFlowTrack::ZLastPoint()                const { return fZLastPoint ; }          
+
+Int_t   AliFlowTrack::MostLikelihoodPID()          const { return fMostLikelihoodPID; } 
+Float_t  AliFlowTrack::ElectronPositronProb()      const { return PidProb(0) ; }
+Float_t  AliFlowTrack::MuonPlusMinusProb()         const { return PidProb(1) ; }
+Float_t  AliFlowTrack::PionPlusMinusProb()         const { return PidProb(2) ; }
+Float_t  AliFlowTrack::KaonPlusMinusProb()         const { return PidProb(3) ; }
+Float_t  AliFlowTrack::ProtonPbarProb()            const { return PidProb(4) ; }
+Float_t  AliFlowTrack::DeuteriumAntiDeuteriumProb() const { return PidProb(5) ; }
+
+Int_t   AliFlowTrack::FitPtsTPC()                  const { return fFitPts[0]  ; }  
+Int_t   AliFlowTrack::MaxPtsTPC()                  const { return fMaxPts[0]  ; }  
+Float_t  AliFlowTrack::Chi2TPC()                   const { return fFitChi2[0] ; }          
+Float_t  AliFlowTrack::DedxTPC()                   const { return fDedx[0]    ; }  
+Int_t   AliFlowTrack::FitPtsITS()                  const { return fFitPts[1]  ; }       
+Int_t   AliFlowTrack::MaxPtsITS()                  const { return fMaxPts[1]  ; }
+Float_t  AliFlowTrack::Chi2ITS()                   const { return fFitChi2[1] ; }               
+Float_t  AliFlowTrack::DedxITS()                   const { return fDedx[1]    ; }  
+Int_t   AliFlowTrack::NhitsTRD()                   const { return fFitPts[2]  ; }       
+Int_t   AliFlowTrack::MaxPtsTRD()                  const { return fMaxPts[2]  ; }  
+Float_t  AliFlowTrack::Chi2TRD()                   const { return fFitChi2[2] ; }               
+Float_t  AliFlowTrack::SigTRD()                            const { return fDedx[2]    ; }  
+Int_t   AliFlowTrack::NhitsTOF()                   const { return fFitPts[3]  ; }       
+Int_t   AliFlowTrack::MaxPtsTOF()                  const { return fMaxPts[3]  ; }  
+Float_t  AliFlowTrack::Chi2TOF()                   const { return fFitChi2[3] ; }               
+Float_t  AliFlowTrack::TofTOF()                            const { return fDedx[3]    ; }  
+
+Float_t  AliFlowTrack::PatTPC()                    const { return fMom[0] ; }
+Float_t  AliFlowTrack::PatITS()                    const { return fMom[1] ; }
+Float_t  AliFlowTrack::PatTRD()                    const { return fMom[2] ; }
+Float_t  AliFlowTrack::PatTOF()                    const { return fMom[3] ; }
+
+Int_t    AliFlowTrack::Label()                     const { return fLabel ; }         
+//////////////////////////////////////////////////////////////////////////////
+void AliFlowTrack::SetConstrainable()                        
+{ 
+ // fills the constrained parameters with the unconstrained ones, making it
+ // a constrainable track.                            !!! TRICKY METHOD !!!
+
+ if(!IsConstrainable()) 
+ { 
+  fPhi = fPhiGlobal ; 
+  fEta = fEtaGlobal ; 
+  fPt  = fPtGlobal ; 
+ } 
+}
+//////////////////////////////////////////////////////////////////////////////
+void AliFlowTrack::SetUnConstrainable()                              
+{ 
+ // deletes the constrained parameters making it  an unconstrainable track. 
+ //                                                   !!! TRICKY METHOD !!!
+
+ if(IsConstrainable()) 
+ { 
+  fPhi = 0. ; 
+  fEta = 0. ; 
+  fPt  = 0. ; 
+ } 
+}
+//////////////////////////////////////////////////////////////////////////////
+void AliFlowTrack::SetPhi(Float_t phi)                       { fPhi = phi; }
+void AliFlowTrack::SetEta(Float_t eta)                       { fEta = eta; }
+void AliFlowTrack::SetPt(Float_t pt)                         { fPt = pt; }
+void AliFlowTrack::SetPhiGlobal(Float_t phi)                 { fPhiGlobal = phi; }
+void AliFlowTrack::SetEtaGlobal(Float_t eta)                 { fEtaGlobal = eta; }
+void AliFlowTrack::SetPtGlobal(Float_t pt)                   { fPtGlobal = pt; }
+void AliFlowTrack::SetDcaSigned(Float_t xy, Float_t z)        { fDcaSigned[0] = xy ; fDcaSigned[1] = z ; }
+void AliFlowTrack::SetTransDcaSigned(Float_t xy)             { fDcaSigned[0] = xy ; }
+void AliFlowTrack::SetChi2(Float_t chi2)                     { fChi2 = chi2; }
+void AliFlowTrack::SetTrackLength(Float_t tl)                { fTrackLength = tl; }
+void AliFlowTrack::SetZFirstPoint(Float_t zFirst)            { fZFirstPoint = zFirst; }
+void AliFlowTrack::SetZLastPoint(Float_t zLast)              { fZLastPoint = zLast; }
+
+void AliFlowTrack::SetMostLikelihoodPID(Int_t val)            { fMostLikelihoodPID = val ; }   // feed here the Signed pdg_code 
+void AliFlowTrack::SetElectronPositronProb(Float_t val)       { fPidProb[0] = TMath::Abs(val) ; } 
+void AliFlowTrack::SetMuonPlusMinusProb(Float_t val)         { fPidProb[1] = TMath::Abs(val) ; } 
+void AliFlowTrack::SetPionPlusMinusProb(Float_t val)         { fPidProb[2] = TMath::Abs(val) ; } 
+void AliFlowTrack::SetKaonPlusMinusProb(Float_t val)         { fPidProb[3] = TMath::Abs(val) ; } 
+void AliFlowTrack::SetProtonPbarProb(Float_t val)            { fPidProb[4] = TMath::Abs(val) ; } 
+void AliFlowTrack::SetDeuteriumAntiDeuteriumProb(Float_t val) { fPidProb[5] = TMath::Abs(val) ; }
+
+void AliFlowTrack::SetFitPtsTPC(Int_t fitPts)                { fFitPts[0]  = fitPts ; }
+void AliFlowTrack::SetMaxPtsTPC(Int_t maxPts)                { fMaxPts[0]  = maxPts ; }
+void AliFlowTrack::SetChi2TPC(Float_t chi2)                  { fFitChi2[0] = chi2   ; }
+void AliFlowTrack::SetDedxTPC(Float_t dedx)                  { fDedx[0]    = dedx   ; }
+void AliFlowTrack::SetFitPtsITS(Int_t nhits)                 { fFitPts[1]  = nhits  ; }
+void AliFlowTrack::SetMaxPtsITS(Int_t maxPts)                { fMaxPts[1]  = maxPts ; }
+void AliFlowTrack::SetChi2ITS(Float_t chi2)                  { fFitChi2[1] = chi2   ; }
+void AliFlowTrack::SetDedxITS(Float_t dedx)                  { fDedx[1]    = dedx   ; }
+void AliFlowTrack::SetNhitsTRD(Int_t fitPts)                 { fFitPts[2]  = fitPts ; }
+void AliFlowTrack::SetMaxPtsTRD(Int_t maxPts)                { fMaxPts[2]  = maxPts ; }
+void AliFlowTrack::SetChi2TRD(Float_t chi2)                  { fFitChi2[2] = chi2   ; }
+void AliFlowTrack::SetSigTRD(Float_t dedx)                   { fDedx[2]    = dedx   ; }
+void AliFlowTrack::SetNhitsTOF(Int_t fitPts)                 { fFitPts[3]  = fitPts ; }
+void AliFlowTrack::SetMaxPtsTOF(Int_t maxPts)                { fMaxPts[3]  = maxPts ; }
+void AliFlowTrack::SetChi2TOF(Float_t chi2)                  { fFitChi2[3] = chi2   ; }
+void AliFlowTrack::SetTofTOF(Float_t dedx)                   { fDedx[3]    = dedx   ; }
+
+void AliFlowTrack::SetPatTPC(Float_t p)                      { fMom[0] = p ; }
+void AliFlowTrack::SetPatITS(Float_t p)                      { fMom[1] = p ; }
+void AliFlowTrack::SetPatTRD(Float_t p)                      { fMom[2] = p ; }
+void AliFlowTrack::SetPatTOF(Float_t p)                      { fMom[3] = p ; }
+
+void AliFlowTrack::SetLabel(Int_t label)                     { fLabel = label ; }
+//////////////////////////////////////////////////////////////////////////////
diff --git a/PWG2/FLOW/AliFlowTrack.h b/PWG2/FLOW/AliFlowTrack.h
new file mode 100644 (file)
index 0000000..974ee82
--- /dev/null
@@ -0,0 +1,193 @@
+//////////////////////////////////////////////////////////////////////
+//
+// $Id$
+//
+// Author: Emanuele Simili
+//
+//////////////////////////////////////////////////////////////////////
+//
+// Description: track optimized for flow study, part of of AliFlowEvent. 
+//                                                   Adapted from STAR 
+// Original Authors:                 Raimond Snellings & Art Poskanzer
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef AliFlowTrack_h
+#define AliFlowTrack_h
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <TROOT.h>
+#include "TMath.h"
+#include "TObject.h"
+#include "TNamed.h"
+#include "TString.h"
+#include "TVector.h"
+
+#include "AliFlowConstants.h"
+
+class Flow ;
+
+class AliFlowTrack : public TNamed {
+
+public:
+
+                AliFlowTrack();
+                AliFlowTrack(const Char_t* name);
+  virtual       ~AliFlowTrack();
+
+ // Gets - Track variables
+  const Char_t* Pid()         const;
+  Int_t         Charge()      const;
+  Float_t       Mass()        const;
+  Float_t      InvMass()     const; 
+  Float_t       Phi()         const;
+  Float_t       Eta()         const;
+  Float_t       Pt()          const;
+  Float_t       P()           const;
+  Float_t       Y()           const;
+  Float_t       PhiGlobal()   const;
+  Float_t       EtaGlobal()   const;
+  Float_t       PtGlobal()    const;
+  Float_t       PGlobal()     const;
+  Float_t       YGlobal()     const;
+  Float_t       Chi2()        const;
+  Float_t       TrackLength() const;
+  Float_t       ZFirstPoint() const;
+  Float_t       ZLastPoint()  const;
+  Bool_t        IsConstrainable()    const;
+  Float_t       TransDcaSigned()     const;
+  Float_t       TransDca()    const;       
+  Float_t       Dca()        const;
+  Float_t      Dca2(Float_t dca[2]) const;
+  Float_t       Dca3(Float_t dca[3]) const;
+  Int_t         Label()                        const;
+ // Gets - P.id.
+  Int_t         MostLikelihoodPID()            const;
+  Float_t       MostLikelihoodProb()           const;
+  Float_t       ElectronPositronProb()         const;
+  Float_t       MuonPlusMinusProb()            const;
+  Float_t       PionPlusMinusProb()            const;
+  Float_t       KaonPlusMinusProb()            const;
+  Float_t       ProtonPbarProb()               const;
+  Float_t       DeuteriumAntiDeuteriumProb()   const;
+  Float_t       PidProb(Int_t nn)              const;          // normalized detector response (using Flow::fBayesian[] )
+  TVector      PidProbs()                      const; 
+  void          PidProbs(Float_t pidN[Flow::nPid])    const; 
+  void          RawPidProbs(Float_t pidV[Flow::nPid]) const;   // raw ESD detector responses
+ // Gets - Detector response
+  Float_t       Chi2TPC()     const;
+  Int_t         FitPtsTPC()   const;
+  Int_t         MaxPtsTPC()   const;
+  Float_t       DedxTPC()     const;
+  Float_t       Chi2ITS()     const;
+  Int_t         FitPtsITS()   const;
+  Int_t         MaxPtsITS()   const;
+  Float_t       DedxITS()     const;
+  Float_t       Chi2TRD()     const;
+  Int_t         NhitsTRD()    const;
+  Int_t         MaxPtsTRD()   const;
+  Float_t       SigTRD()      const;
+  Float_t       Chi2TOF()     const;
+  Int_t         NhitsTOF()    const;
+  Int_t         MaxPtsTOF()   const;
+  Float_t       TofTOF()      const;  
+  Float_t       PatTPC()      const;           // new
+  Float_t       PatITS()      const;           // new
+  Float_t       PatTRD()      const;           // new
+  Float_t       PatTOF()      const;           // new
+
+
+ // Sets - Track variables
+  void SetPid(const Char_t* pid);
+  void SetCharge(Int_t charge);
+  void SetPhi(Float_t phi);
+  void SetEta(Float_t eta);
+  void SetPt(Float_t pt);
+  void SetPhiGlobal(Float_t phi);
+  void SetEtaGlobal(Float_t eta);
+  void SetPtGlobal(Float_t pt);
+  void SetDcaSigned(Float_t xy, Float_t z = 0.);
+  void SetTransDcaSigned(Float_t xy);
+  void SetChi2(Float_t chi2);
+  void SetTrackLength(Float_t tl);
+  void SetZFirstPoint(Float_t zFirst);
+  void SetZLastPoint(Float_t zLast);
+  void SetLabel(Int_t label);
+ // Sets - P.id.
+  void SetMostLikelihoodPID(Int_t val); 
+  void SetElectronPositronProb(Float_t val);
+  void SetMuonPlusMinusProb(Float_t val);
+  void SetPionPlusMinusProb(Float_t val);
+  void SetKaonPlusMinusProb(Float_t val);
+  void SetProtonPbarProb(Float_t val);
+  void SetDeuteriumAntiDeuteriumProb(Float_t val);
+ // Sets - Detector response
+  void SetChi2TPC(Float_t chi2);
+  void SetFitPtsTPC(Int_t fitPts);
+  void SetMaxPtsTPC(Int_t maxPts);
+  void SetDedxTPC(Float_t dedx);
+  void SetChi2ITS(Float_t chi2);
+  void SetFitPtsITS(Int_t nhits);
+  void SetMaxPtsITS(Int_t maxPts);
+  void SetDedxITS(Float_t dedx);
+  void SetChi2TRD(Float_t chi2);
+  void SetNhitsTRD(Int_t fitPts);
+  void SetMaxPtsTRD(Int_t maxPts);
+  void SetSigTRD(Float_t dedx);
+  void SetChi2TOF(Float_t chi2);
+  void SetNhitsTOF(Int_t fitPts);
+  void SetMaxPtsTOF(Int_t maxPts);
+  void SetTofTOF(Float_t dedx);
+  void SetPatTPC(Float_t p);           // new
+  void SetPatITS(Float_t p);           // new
+  void SetPatTRD(Float_t p);           // new
+  void SetPatTOF(Float_t p);           // new
+ // TRICKY
+  void SetConstrainable();
+  void SetUnConstrainable();
+
+ // Selection's methods
+  Bool_t Select(Int_t harmonic, Int_t selection, Int_t subevent= -1) const;
+  void  SetSelect(Int_t harmonic, Int_t selection);
+  void  SetSubevent(Int_t harmonic, Int_t selection, Int_t subevent);
+  void  PrintSelection() ;
+  void  ResetSelection() ;
+
+
+private:
+
+ // Data Members
+  Float_t  fPhi;                               // azimuthal angle of the constrained track
+  Float_t  fEta;                               // pseudorapidity of the constrained track
+  Float_t  fPt;                                        // transverse momentum of the constrained track 
+  Float_t  fZFirstPoint;                       // Z position at beginning of TPC
+  Float_t  fZLastPoint;                        // Z position at end of PHOS
+  Float_t  fChi2 ;                             // constrained chi2
+  Float_t  fTrackLength;                       // lenght of the track
+  Int_t    fMostLikelihoodPID;                 // PDG code of the most probable P.Id.
+  Double_t fDcaSigned[2] ;                     // positive or negative tracks -> P changes differently including vertex ...
+  //Double_t fDcaError[2] ;                    // error over the DCA (next to come)
+  Float_t  fPhiGlobal;                         // azimuthal angle of the unconstrained track
+  Float_t  fEtaGlobal;                         // pseudorapidity of the unconstrained track
+  Float_t  fPtGlobal;                          // transverse momentum of the unconstrained track 
+  Int_t    fLabel ;                            // Label of the track (link: KineTree-ESD) 
+ // -
+  Float_t  fPidProb[Flow::nPid] ;              // Array of probability to be   (e,mu,pi,k,p,d)
+  Int_t    fFitPts[4] ;                        // Array of Fit Points          (in: TPC,ITS,TRD,TOF)
+  Int_t    fMaxPts[4] ;                        // Array of Foundable Clusters  (in: TPC,ITS,TRD,TOF)
+  Float_t  fFitChi2[4] ;                       // Array of Chi2                (in: TPC,ITS,TRD,TOF)
+  Float_t  fDedx[4] ;                          // Array of dE/dx               (in: TPC,ITS,TRD,TOF)
+  Float_t  fMom[4] ;                           // Array of momentum at the entrance of TPC,ITS,TRD,TOF     
+
+ // Selection's array for R.P. & sub-event selection (not stored)  
+  Bool_t   fSelection[Flow::nHars][Flow::nSels]; //! 
+  Short_t  fSubevent[Flow::nHars][Flow::nSels];         //! 
+
+  ClassDef(AliFlowTrack,4) ;                   // macro for rootcint
+};
+
+#endif
+//////////////////////////////////////////////////////////////////////
diff --git a/PWG2/FLOW/AliFlowV0.cxx b/PWG2/FLOW/AliFlowV0.cxx
new file mode 100644 (file)
index 0000000..2141cd7
--- /dev/null
@@ -0,0 +1,172 @@
+//////////////////////////////////////////////////////////////////////
+//
+// $Id$
+//
+// Author: Emanuele Simili
+//
+//////////////////////////////////////////////////////////////////////
+//_____________________________________________________________
+//
+// Description: 
+//         an array of AliFlowV0 is part of the AliFlowEvent, 
+// The object AliFlowV0 contains data members wich summarize the V0s 
+// information most useful for flow study (Pt, eta, phi, ecc.). 
+// AliFlowV0 also contains a references to the two daughter tracks
+// in the TrackClollection() of the AliFlowEvent from wich the V0 has 
+// been reconstructed.
+//
+
+#include "AliFlowV0.h"
+#include "AliFlowConstants.h"
+#include <iostream>
+using namespace std; //required for resolving the 'cout' symbol
+
+ClassImp(AliFlowV0) ;
+//////////////////////////////////////////////////////////////////////////////
+AliFlowV0::AliFlowV0()
+{
+ // default constructor  
+ fPhi = 0. ;
+ fEta = 0. ;
+ fPt = 0. ;
+ fChi2 = 0. ;
+ fMass = 0. ;                  
+ fDca = 0. ;
+ fCrossDCA = 0. ;
+ fSigma = 1. ;
+ fLabel = 0 ;
+ for(Int_t dd=0;dd<3;dd++) { fCrossPoint[dd] = 0. ; }
+ for(Int_t dd=0;dd<2;dd++) { fDaughters[dd] = 0  ; }
+}
+//////////////////////////////////////////////////////////////////////////////
+AliFlowV0::AliFlowV0(const Char_t* name) 
+{
+ // TNamed constructor 
+ SetName(name) ;
+ AliFlowV0() ;
+}
+//////////////////////////////////////////////////////////////////////////////
+AliFlowV0::~AliFlowV0() 
+{
+ // default destructor (dummy)
+}
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+Float_t  AliFlowV0::P() const 
+{ 
+ // Returns the reconstructed momentum of the v0
+
+ float momentum = Pt()/TMath::Sqrt(1-(tanh(Eta())*tanh(Eta()))) ; 
+ return momentum; 
+}
+//////////////////////////////////////////////////////////////////////////////
+Float_t  AliFlowV0::Y() const 
+{
+ // Rapidity of the v0
+
+ if(TMath::Abs((Float_t)P()) == TMath::Abs((Float_t)Pt()))     { return 0. ; }
+ else if(TMath::Abs((Float_t)P()) < TMath::Abs((Float_t)Pt())) { cout << "v0: " << GetName() << "has  Pt() > P() !!!" << endl ; }
+ // -
+ float M = Mass() ; 
+ double Pz = TMath::Sqrt(P()*P() - Pt()*Pt()); 
+ if (Eta() < 0) { Pz = -Pz ; }
+ double E = TMath::Sqrt(P()*P() + M*M) ;
+ float rapidity = 0.5*TMath::Log((E + Pz)/(E - Pz)) ;
+ return rapidity ;
+}
+//////////////////////////////////////////////////////////////////////////////
+void AliFlowV0::SetDaughters(AliFlowTrack* pos, AliFlowTrack* neg) 
+{ 
+ // Sets positive and negative daughter tracks from the TrackCollection()
+
+ fDaughters[0] = pos ; 
+ fDaughters[1] = neg ; 
+}
+//////////////////////////////////////////////////////////////////////////////
+void  AliFlowV0::CrossPoint(Float_t Pxyz[3]) const 
+{
+ // Coordinates of the v0
+
+ for(Int_t ii=0;ii<3;ii++) { Pxyz[ii] = fCrossPoint[ii] ; }
+}
+//////////////////////////////////////////////////////////////////////////////
+// TVector3 AliFlowV0::CrossPoint() const 
+// {
+//  // Coordinates of the v0
+// 
+//  TVector3 pxyz ;
+//  pxyz.SetXYZ(fCrossPoint[0],fCrossPoint[1],fCrossPoint[2]) ;
+//  return pxyz ; 
+// }
+//////////////////////////////////////////////////////////////////////////////
+void AliFlowV0::SetCrossPoint(Float_t pox,Float_t poy,Float_t poz)
+{ 
+ // Sets the coordinates of the v0
+
+ fCrossPoint[0] = pox ; fCrossPoint[1] = poy ; fCrossPoint[2] = poz ; 
+}
+//////////////////////////////////////////////////////////////////////////////
+const char* AliFlowV0::Pid() const
+{
+ // Returns the P.Id. in characters (,...) basing on the stored pdg code 
+ // (MostLikelihoodPID()) .
+ const char *name[] = {"gamma","K0","K0s","K0l","Lambda0"} ;
+ int pdg_code = TMath::Abs(MostLikelihoodPID()) ;
+
+ TString p_id = "" ;
+ if(pdg_code == 22)       { p_id = name[0] ; }
+ else if(pdg_code == 311)  { p_id = name[1] ; }
+ else if(pdg_code == 310)  { p_id = name[2] ; }
+ else if(pdg_code == 130)  { p_id = name[3] ; }
+ else if(pdg_code == 3122) { p_id = name[4] ; }
+ // ...
+ else                     { p_id = "0" ; }
+ return p_id.Data() ; 
+}
+//////////////////////////////////////////////////////////////////////////////
+void AliFlowV0::SetPid(const Char_t* pid)              
+{ 
+ // Sets the P.Id. hypotesis of the track from a String imput ("K0","K0s",
+ // "K0l","Lambda0"). The string itself is not stored, what is stored is the
+ // PDG code.
+ if(strstr(pid,"gamma"))        { fMostLikelihoodPID = 22   ; }
+ else if(strstr(pid,"K0"))      { fMostLikelihoodPID = 311  ; }
+ else if(strstr(pid,"K0s"))     { fMostLikelihoodPID = 310  ; }
+ else if(strstr(pid,"K0l"))     { fMostLikelihoodPID = 130  ; }
+ else if(strstr(pid,"Lambda0")) { fMostLikelihoodPID = 3122 ; }
+ // ...
+ else { fMostLikelihoodPID = 0 ; cout << "AliFlowV0 - !BAD IMPUT!" << endl ; }
+}
+//////////////////////////////////////////////////////////////////////////////
+Float_t  AliFlowV0::Mass()               const { return fMass ; }
+Float_t  AliFlowV0::Phi()                const { return fPhi; }             
+Float_t  AliFlowV0::Eta()                const { return fEta; }             
+Float_t  AliFlowV0::Pt()                 const { return fPt; }              
+Short_t  AliFlowV0::Charge()             const { return 0 ; }       
+Float_t  AliFlowV0::Dca()                const { return fDca ; }                 
+Float_t  AliFlowV0::Chi2()               const { return fChi2; }                 
+Float_t  AliFlowV0::CrossDca()           const { return fCrossDCA ; }
+Float_t  AliFlowV0::V0Lenght()           const { return TMath::Sqrt(fCrossPoint[0]*fCrossPoint[0] + fCrossPoint[1]*fCrossPoint[1] + fCrossPoint[2]*fCrossPoint[2]) ; }   
+Float_t  AliFlowV0::Sigma()              const { return fSigma ; }       
+Int_t   AliFlowV0::MostLikelihoodPID()   const { return fMostLikelihoodPID; } 
+Int_t    AliFlowV0::Label()               const { return fLabel ; }          
+AliFlowTrack* AliFlowV0::DaughterP()      const { return fDaughters[0] ; }
+AliFlowTrack* AliFlowV0::DaughterN()      const { return fDaughters[1] ; }
+//////////////////////////////////////////////////////////////////////////////
+void AliFlowV0::SetMostLikelihoodPID(Int_t val) { fMostLikelihoodPID = val ; } 
+void AliFlowV0::SetVmass(Float_t mass)                 { fMass = mass ; }
+void AliFlowV0::SetPhi(Float_t phi)            { fPhi = phi; }
+void AliFlowV0::SetEta(Float_t eta)            { fEta = eta; }
+void AliFlowV0::SetPt(Float_t pt)              { fPt = pt; }
+void AliFlowV0::SetChi2(Float_t chi2)          { fChi2 = chi2; }
+void AliFlowV0::SetDca(Float_t dca)             { fDca = dca; }
+void AliFlowV0::SetCrossDca(Float_t dca)        { fCrossDCA = dca ; }
+void AliFlowV0::SetSigma(Float_t sigma)                { fSigma = sigma ; }      
+void AliFlowV0::SetLabel(Int_t label)          { fLabel = label ; }
+//////////////////////////////////////////////////////////////////////////////
diff --git a/PWG2/FLOW/AliFlowV0.h b/PWG2/FLOW/AliFlowV0.h
new file mode 100644 (file)
index 0000000..110b632
--- /dev/null
@@ -0,0 +1,93 @@
+//////////////////////////////////////////////////////////////////////
+//
+// $Id$
+//
+// Author: Emanuele Simili
+//
+//////////////////////////////////////////////////////////////////////
+//
+// Description: part of AliFlowEvent, allow flow study of v0s .
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef AliFlowV0_h
+#define AliFlowV0_h
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <TROOT.h>
+#include "TMath.h"
+#include "TObject.h"
+#include "TNamed.h"
+
+#include "AliFlowConstants.h"
+#include "AliFlowTrack.h"
+
+class Flow ;
+
+class AliFlowV0 : public TNamed {
+
+public:
+
+                AliFlowV0();
+                AliFlowV0(const Char_t* name);
+  virtual       ~AliFlowV0();
+
+ // Gets - V0's variables
+  const Char_t* Pid()         const;
+  Float_t       Phi()         const;
+  Float_t       Eta()         const;
+  Float_t       Pt()          const;
+  Float_t       P()           const;
+  Float_t       Y()           const;
+  Short_t       Charge()      const;
+  Float_t       Dca()         const;
+  Float_t       Chi2()        const;
+  Float_t       Mass()        const; 
+  AliFlowTrack* DaughterP()   const; 
+  AliFlowTrack* DaughterN()   const; 
+  Float_t       V0Lenght()    const;
+  Float_t       Sigma()       const;
+  void          CrossPoint(Float_t Pxyz[3]) const;
+  //TVector3      CrossPoint() const ;
+  Float_t       CrossDca()    const;
+  Int_t        MostLikelihoodPID() const;
+  Int_t         Label()                const;
+ // Sets - V0's variables
+  void SetPid(const Char_t* pid);
+  void SetPhi(Float_t phi);    
+  void SetEta(Float_t eta);    
+  void SetPt(Float_t pt);      
+  void SetChi2(Float_t chi2) ; 
+  void SetVmass(Float_t mass);
+  void SetCrossPoint(Float_t pox,Float_t poy,Float_t poz);
+  void SetCrossDca(Float_t dca) ;
+  void SetDca(Float_t dca) ; 
+  void SetSigma(Float_t sigma) ;         
+  void SetDaughters(AliFlowTrack* pos, AliFlowTrack* neg);
+  void SetMostLikelihoodPID(Int_t pdg_code);
+  void SetLabel(Int_t label);
+
+private:
+
+ // Data Members
+  Float_t  fPhi;                               // reconstructed azimuthal angle of the v0
+  Float_t  fPt;                                        // reconstructed transverse momentum of the v0 
+  Float_t  fEta;                               // reconstructed pseudorapidity of the v0
+  Float_t  fChi2;                              // chi2 of the reconstructed v0
+  Float_t  fMass;                              // reconstructed v0 mass 
+  Float_t  fDca;                               // distance of closest approach of the reconstructed v0 to the main vertex
+  Float_t  fCrossPoint[3] ;                    // crossing point coordinates of the two daughter tracks
+  Float_t  fCrossDCA ;                         // DCA of the 2 tracks at the crossing point 
+  Float_t  fSigma ;                            //! DCA of the 2 tracks at the crossing point 
+  Int_t    fMostLikelihoodPID;                 // most probable P.Id. hypotesis (...need to be implemented)
+  Int_t    fLabel ;                            // Label of the V0 (link: KineTree-ESD) 
+  AliFlowTrack* fDaughters[2] ;                        // daughter particles' pointers 
+  
+  ClassDef(AliFlowV0,1) ;                      // macro for rootcint
+};
+
+#endif
+//////////////////////////////////////////////////////////////////////
diff --git a/PWG2/FLOW/AliSelectorFlow.cxx b/PWG2/FLOW/AliSelectorFlow.cxx
new file mode 100644 (file)
index 0000000..0cf232e
--- /dev/null
@@ -0,0 +1,779 @@
+/* $Id$ */
+/* derived from AliSelector.cxx,v 1.17 2006/08/31 jgrosseo Exp $ */
+
+// The class definition in esdV0.h has been generated automatically
+// by the ROOT utility TTree::MakeSelector(). This class is derived
+// from the ROOT class TSelector. For more information on the TSelector
+// framework see $ROOTSYS/README/README.SELECTOR or the ROOT User Manual.
+
+// The following methods are defined in this file:
+//    Begin():        called everytime a loop on the tree starts,
+//                    a convenient place to create your histograms.
+//    SlaveBegin():   called after Begin(), when on PROOF called only on the
+//                    slave servers.
+//    Process():      called for each event, in this function you decide what
+//                    to read and fill your histograms.
+//    SlaveTerminate: called at the end of the loop on the tree, when on PROOF
+//                    called only on the slave servers.
+//    Terminate():    called at the end of the loop on the tree,
+//                    a convenient place to draw/fit your histograms.
+//
+// To use this file, try the following session on your Tree T:
+//
+// Root > T->Process("AliSelector.C")
+// Root > T->Process("AliSelector.C","some options")
+// Root > T->Process("AliSelector.C+")
+//
+
+#include "AliSelectorFlow.h"
+
+#include <TStyle.h>
+#include <TSystem.h>
+#include <TCanvas.h>
+#include <TRegexp.h>
+#include <TTime.h>
+#include <TFriendElement.h>
+#include <TTree.h>
+#include <TChain.h>
+#include <TFile.h>
+#include <TTimeStamp.h>
+#include <TMath.h>
+
+#include "/localstore/alice/alice_new/AliRoot_Head/include/AliLog.h"      //  
+#include "/localstore/alice/alice_new/AliRoot_Head/include/AliESD.h"      //  
+#include "/localstore/alice/alice_new/AliRoot_Head/include/AliESDtrack.h" //  
+#include "/localstore/alice/alice_new/AliRoot_Head/include/AliESDv0.h"    //  
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+using namespace std; //required for resolving the 'cout' symbol
+
+#include "AliFlowEvent.h"
+#include "AliFlowTrack.h"
+#include "AliFlowV0.h"
+#include "AliFlowConstants.h"
+
+ClassImp(AliSelectorFlow)
+
+//-----------------------------------------------------------------------
+
+AliSelectorFlow::AliSelectorFlow() :
+  TSelector(),
+  fTree(0),
+  fESD(0),
+  fCountFiles(0),
+  fKineFile(0)
+{
+  //
+  // Constructor. Initialization of pointers
+  //
+  
+  fFlowEventFileName = "flowEvtS.root" ;    
+
+  fEtrkLow = 0.01  ;
+  fEtrkHig = 100. ;
+  fHitsTrk = 1 ;
+}
+
+//-----------------------------------------------------------------------
+
+AliSelectorFlow::~AliSelectorFlow()
+{
+  //
+  // Destructor
+  //
+
+ if (fTree) { fTree->ResetBranchAddresses() ; }
+
+ if (fESD)
+ {
+   delete fESD;
+   fESD = 0;
+ }
+}
+
+//-----------------------------------------------------------------------
+
+void AliSelectorFlow::CheckOptions()
+{
+  // checks the option string for the debug flag
+
+  AliLog::SetClassDebugLevel(ClassName(), AliLog::kInfo);
+
+  TString option = GetOption();
+
+  if (option.Contains("moredebug"))
+  {
+    printf("Enabling verbose debug mode for %s\n", ClassName());
+    AliLog::SetClassDebugLevel(ClassName(), AliLog::kDebug+1);
+    AliInfo(Form("Called with option %s.", option.Data()));
+  }
+  else if (option.Contains("debug"))
+  {
+    printf("Enabling debug mode for %s\n", ClassName());
+    AliLog::SetClassDebugLevel(ClassName(), AliLog::kDebug);
+    AliInfo(Form("Called with option %s.", option.Data()));
+  }
+}
+
+//-----------------------------------------------------------------------
+
+void AliSelectorFlow::Begin(TTree*)
+{
+  // The Begin() function is called at the start of the query.
+  // When running with PROOF Begin() is only called on the client.
+  // The tree argument is deprecated (on PROOF 0 is passed).
+  
+  cout << " HERE I begin !!! " << endl ; cout << endl ;
+
+  CheckOptions();
+
+  AliDebug(AliLog::kDebug, "============BEGIN===========");
+
+ // Opens OutputFile
+ pFlowfile = new TFile(fFlowEventFileName.Data(),"RECREATE") ;
+ pFlowfile->cd() ; 
+ cout << " OUTput File Name : " << fFlowEventFileName.Data() << endl ; 
+  
+ // Resets counters
+ fGoodTracks = 0  ;  
+ fGoodV0s    = 0  ;    
+ fGoodTracksEta = 0  ;
+ fPosiTracks = 0  ;  
+ fNegaTracks = 0  ;  
+ for(Int_t bb=0;bb<5;bb++) { fBayesianAll[bb] = 0 ; } ;
+ fSumAll = 0 ;
+ fCutEvts = 0  ;
+ fCutTrks = 0  ;
+ fCutV0s  = 0  ; 
+ fLoopV0 = kFALSE ;     // kTRUE ;     // something is wrong with them ... too many!?
+ fDoNothing = kFALSE ;  // kFALSE ;
+ fOnFlyAnalysis = kFALSE ;  
+}
+
+//-----------------------------------------------------------------------
+
+void AliSelectorFlow::SlaveBegin(TTree* tree)
+{
+  // The SlaveBegin() function is called after the Begin() function.
+  // When running with PROOF SlaveBegin() is called on each slave server.
+  // The tree argument is deprecated (on PROOF 0 is passed).
+
+  CheckOptions();
+
+  AliDebug(AliLog::kDebug, "=======SLAVEBEGIN========");
+  AliDebug(AliLog::kDebug, Form("Hostname: %s", gSystem->HostName()));
+  AliDebug(AliLog::kDebug, Form("Time: %s", gSystem->Now().AsString()));
+
+  if (tree != 0) { Init(tree) ; }
+}
+
+//-----------------------------------------------------------------------
+
+void AliSelectorFlow::Init(TTree *tree)
+{
+  // The Init() function is called when the selector needs to initialize
+  // a new tree or chain. Typically here the branch addresses of the tree
+  // will be set. It is normaly not necessary to make changes to the
+  // generated code, but the routine can be extended by the user if needed.
+  // Init() will be called many times when running with PROOF.
+
+  AliDebug(AliLog::kDebug, "=========Init==========");
+
+  fTree = tree;
+
+  if (fTree == 0)
+  {
+   AliDebug(AliLog::kError, "ERROR: tree argument is 0.");
+   return;
+  }
+
+  // Set branch address
+  fTree->SetBranchAddress("ESD", &fESD);
+  if (fESD != 0) { AliDebug(AliLog::kInfo, "INFO: Found ESD branch in chain.") ; }
+}
+
+//-----------------------------------------------------------------------
+
+Bool_t AliSelectorFlow::Notify()
+{
+  // The Notify() function is called when a new file is opened. This
+  // can be either for a new TTree in a TChain or when when a new TTree
+  // is started when using PROOF. Typically here the branch pointers
+  // will be retrieved. It is normaly not necessary to make changes
+  // to the generated code, but the routine can be extended by the
+  // user if needed.
+
+  AliDebug(AliLog::kDebug, "=========NOTIFY==========");
+  AliDebug(AliLog::kDebug, Form("Hostname: %s", gSystem->HostName()));
+  AliDebug(AliLog::kDebug, Form("Time: %s", TTimeStamp(time(0)).AsString()));
+
+  ++fCountFiles;
+  if (fTree)
+  {
+    TFile *f = fTree->GetCurrentFile();
+    AliDebug(AliLog::kInfo, Form("Processing %d. file %s", fCountFiles, f->GetName()));
+  }
+  else
+  {
+    AliDebug(AliLog::kError, "fTree not available");
+  }
+
+  DeleteKinematicsFile();
+
+  return kTRUE;
+}
+
+//-----------------------------------------------------------------------
+
+Bool_t AliSelectorFlow::Process(Long64_t entry)
+{
+  // The Process() function is called for each entry in the tree (or possibly
+  // keyed object in the case of PROOF) to be processed. The entry argument
+  // specifies which entry in the currently loaded tree is to be processed.
+  // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
+  // to read either all or the required parts of the data. When processing
+  // keyed objects with PROOF, the object is already loaded and is available
+  // via the fObject pointer.
+  //
+  // This function should contain the "body" of the analysis. It can contain
+  // simple or elaborate selection criteria, run algorithms on the data
+  // of the event and typically fill histograms.
+
+  // WARNING when a selector is used with a TChain, you must use
+  //  the pointer to the current TTree to call GetEntry(entry).
+  //  The entry is always the local entry number in the current tree.
+  //  Assuming that fTree is the pointer to the TChain being processed,
+  //  use fTree->GetTree()->GetEntry(entry).
+
+  AliDebug(AliLog::kDebug, Form("=========PROCESS========== Entry %lld", entry));
+
+  if (!fTree)
+  {
+    AliDebug(AliLog::kError, "ERROR: fTree is 0.");
+    return kFALSE;
+  }
+
+  fEventNumber = entry ;
+  fTree->GetTree()->GetEntry(fEventNumber) ;
+
+  if(fESD) { AliDebug(AliLog::kDebug, Form("ESD: We have %d tracks.", fESD->GetNumberOfTracks())); }
+  // cout << " event !!! " << entry << endl ;
+
+  fRunID = fESD->GetRunNumber() ;
+  fEventNumber = fESD->GetEventNumber() ;
+  fNumberOfTracks = fESD->GetNumberOfTracks() ;
+  fNumberOfV0s = fESD->GetNumberOfV0s() ;
+
+  cout << " *evt n. " << fEventNumber << " (run " << fRunID << ") " << endl ;
+  cout << "  tracks: " << fNumberOfTracks << " ,   v0s " << fNumberOfV0s << endl ;
+
+ // Dummy Loop (for testing)
+  if(fDoNothing) 
+  { 
+   pFlowEvent = new AliFlowEvent() ;  
+   pFlowEvent->SetRunID(fRunID) ;              
+   pFlowEvent->SetEventID(fEventNumber) ;      
+   pFlowEvent->SetOrigMult((UInt_t)fNumberOfTracks) ;
+   return pFlowEvent ; 
+  }
+
+ // Evt cuts (dummy) :
+  // if(pFlowCuts->CheckEvent(fESD)) { fCutEvts++ ; ...  }
+
+ // Instantiate a new AliFlowEvent
+  pFlowEvent = FillFlowEvent(fESD) ;
+
+   if(!pFlowEvent) 
+   { 
+    cout << "!something bad occurred" << endl ;
+    // fCutEvts++ ; continue ; 
+    return kFALSE ;
+   }
+   else {  cout << "!event filled " << endl ; }
+
+  cout << " save event ... " << endl ;
+
+  TString strID = "" ; strID += entry ; 
+  pFlowfile->cd() ; 
+  pFlowEvent->Write(strID.Data()) ;
+
+  cout << " saved  " << strID.Data() << "                # thanks gesus ! #       " << endl ;
+  cout << endl ;  
+
+  if(fOnFlyAnalysis)  { cout << "seeeeeeeeeeeeeeeeeeeeeee :D  " << endl ;} 
+   
+  return kTRUE;
+}
+
+//-----------------------------------------------------------------------
+
+void AliSelectorFlow::SlaveTerminate()
+{
+  // The SlaveTerminate() function is called after all entries or objects
+  // have been processed. When running with PROOF SlaveTerminate() is called
+  // on each slave server.
+
+  AliDebug(AliLog::kDebug, "=======SLAVETERMINATE=======");
+
+  DeleteKinematicsFile();
+}
+
+//-----------------------------------------------------------------------
+
+void AliSelectorFlow::Terminate()
+{
+  // The Terminate() function is the last function to be called during
+  // a query. It always runs on the client, it can be used to present
+  // the results graphically or save the results to file.
+
+  AliDebug(AliLog::kDebug, "=========TERMINATE==========");
+
+ cout << " file closed . " << endl ;
+ pFlowfile->Close() ; 
+}
+
+//-----------------------------------------------------------------------
+
+TTree* AliSelectorFlow::GetKinematics()
+{
+  // Returns kinematics tree corresponding to current ESD active in fTree
+  // Loads the kinematics from the kinematics file, the file is identified by replacing "AliESDs" to
+  // "Kinematics" in the file path of the ESD file. This is a hack, to be changed!
+
+  if (!fKineFile)
+  {
+    if(!fTree->GetCurrentFile()) { return 0 ; }
+
+    TString fileName(fTree->GetCurrentFile()->GetName());
+    fileName.ReplaceAll("AliESDs", "Kinematics");
+
+    // temporary workaround for PROOF bug #18505
+    fileName.ReplaceAll("#Kinematics.root#Kinematics.root", "#Kinematics.root");
+
+    AliDebug(AliLog::kInfo, Form("Opening %s", fileName.Data()));
+
+    fKineFile = TFile::Open(fileName);
+    if(!fKineFile) { return 0 ; }
+  }
+
+  return dynamic_cast<TTree*> (fKineFile->Get(Form("Event%d/TreeK", fTree->GetTree()->GetReadEntry())));
+}
+
+//-----------------------------------------------------------------------
+
+void AliSelectorFlow::DeleteKinematicsFile()
+{
+  //
+  // Closes the kinematics file and deletes the pointer.
+  //
+
+  if (fKineFile)
+  {
+    fKineFile->Close();
+    delete fKineFile;
+    fKineFile = 0;
+  }
+}
+
+
+//----------------------------------------------------------------------
+//*** FLOW SPECIFIC METHODS (to fill the flowEvents) ***
+//----------------------------------------------------------------------
+
+AliFlowEvent* AliSelectorFlow::FillFlowEvent(AliESD* fESD)
+{
+ // Fills the AliFlowEvent . 
+ // Calls the methods to fills track & v0 arrays . 
+ // Re-Shuffles the tracks (if fShuffle) . 
+
+ fEventNumber = fESD->GetEventNumber() ; 
+ fNumberOfTracks = fESD->GetNumberOfTracks() ; 
+ fNumberOfV0s = fESD->GetNumberOfV0s() ; 
+ fRunID = fESD->GetRunNumber() ;
+
+ fTrackNumber = 0 ;
+ fV0Number = 0 ;
+
+ cout << "FillFlowEvent()   " << fEventNumber << "   (run " << fRunID << ") " << endl ; 
+   
+ // Instantiate a new AliFlowEvent
+ pFlowEvent = new AliFlowEvent() ; if(!pFlowEvent) { return 0 ; }
+
+ // Event id 
+ pFlowEvent->SetRunID(fRunID) ;                
+ pFlowEvent->SetEventID(fEventNumber) ;        
+ pFlowEvent->SetOrigMult((UInt_t)fNumberOfTracks) ;
+                                               
+ // Run information (fixed - ???)
+ fMagField = fESD->GetMagneticField() ;
+ pFlowEvent->SetMagneticField(fMagField) ;     
+ pFlowEvent->SetCenterOfMassEnergy(5500) ;     
+ pFlowEvent->SetBeamMassNumberEast(208) ;      
+ pFlowEvent->SetBeamMassNumberWest(208) ;      
+
+ // Trigger information (now is: ULon64_t - some trigger mask)
+ pFlowEvent->SetL0TriggerWord((Int_t)fESD->GetTriggerMask()); 
+ // Get primary vertex position
+ AliESDVertex* pVertex = (AliESDVertex*)fESD->GetVertex() ;
+ Double_t position[3] ; 
+ pVertex->GetXYZ(position) ;
+ pFlowEvent->SetVertexPos((Float_t)position[0],(Float_t)position[1],(Float_t)position[2]) ; 
+
+ // Zero Degree Calorimeter information
+ Int_t zdcp = fESD->GetZDCParticipants() ; 
+ Float_t zdce[3] ; 
+ zdce[0] = fESD->GetZDCN1Energy() + fESD->GetZDCN2Energy(); 
+ zdce[1] = fESD->GetZDCP1Energy() + fESD->GetZDCP2Energy() ; 
+ zdce[2] = fESD->GetZDCEMEnergy() ;
+ pFlowEvent->SetZDCpart(zdcp);                         
+ pFlowEvent->SetZDCenergy(zdce[0],zdce[1],zdce[2]);    
+  cout << "  looping tracks ... (real)  " << fNumberOfTracks << endl ;
+
+  Int_t badTrks = 0 ;
+  for(Int_t itr=0;itr<fNumberOfTracks;itr++)   // Loop over tracks
+  {
+   fTrackNumber = itr ;
+   fTrack = fESD->GetTrack(fTrackNumber) ;
+   
+  // Trk cuts (temporary) :
+   Int_t idXt[180] ;  // used for Cluster Map ( see AliESDtrack::GetTPCclusters() )
+   Int_t   nHits = fTrack->GetTPCclusters(idXt) ;
+   Float_t E    = fTrack->GetP() ; 
+   if((nHits<fHitsTrk) || ((E<fEtrkLow) || (E>fEtrkHig)))  { fCutTrks++ ; continue ; }
+   // -or-
+   // if(pFlowCuts->CheckTrack(pTrack)) { fCutTracks++ ; ...  }  // Apply track Cuts
+
+  // Instantiate a new AliFlowTrack and fills it
+   pFlowTrack = FillFlowTrack(fTrack) ;   
+   if(!pFlowTrack) { badTrks++ ; continue ; }
+
+   pFlowEvent->TrackCollection()->Add(pFlowTrack) ;   
+   fGoodTracks++ ;                                   
+  }
+  cout << " " << fCutTrks+badTrks << " tracks from event n." << fEventNumber << " have been trown away . " << endl ; 
+
+  if(fLoopV0)
+  {
+   cout << "  looping v0s ...  " << fNumberOfV0s << endl ;
+
+   Int_t badV0s = 0 ;
+   for(Int_t v0n=0;v0n<fNumberOfV0s;v0n++)   // Loop over v0 in AliESD
+   {
+    fV0Number = v0n ;
+    fV0 = fESD->GetV0(fV0Number) ;                     
+
+   // Instantiate a new AliFlowV0 and fills it
+    pFlowV0 =  FillFlowV0(fV0) ;
+    if(!pFlowV0) {  badV0s++ ; continue ; }
+    
+    pFlowEvent->V0Collection()->Add(pFlowV0) ;
+    fGoodV0s++ ;                       
+   }
+   cout << " " << fCutV0s+badV0s << " v0s from event n." << fEventNumber << " have been trown away . " << endl ; 
+  }
+ // Evt setting stuff
+ pFlowEvent->SetCentrality();  
+                               
+ return pFlowEvent ;
+}
+
+//----------------------------------------------------------------------
+
+AliFlowTrack* AliSelectorFlow::FillFlowTrack(AliESDtrack* fTrack)
+{
+
+ // cout << "FillFlowTrack() " << endl ; 
+ // fTrack->Dump() ;
+
+ TString ntra = "" ; ntra += fTrackNumber ;
+ pFlowTrack = new AliFlowTrack(ntra.Data()) ;  
+
+ // ESD particle label (link: KineTree-ESD)
+ Int_t label = TMath::Abs(fTrack->GetLabel());
+ pFlowTrack->SetLabel(label) ;                         
+
+ //cout  << "      - track " << fTrackNumber << " ... pTrack->GetLabel() = " << label << endl ;
+
+ // signed DCA from ESDtrack
+ Float_t xy = 0 ; Float_t z = 0 ; 
+ fTrack->GetImpactParameters(xy,z) ;                           // this returns (0,0) !!!
+// if(xy == 0 && z == 0)                                       // if 0 get it from the ITS method
+// {
+//   cout << " ------------- no dca !!!" << endl ; 
+//   AliITStrackV2 *itsTrack = 0 ;     
+//   UInt_t status = fTrack->GetStatus();
+//   if((status&AliESDtrack::kITSrefit)==0) 
+//   { 
+//    xy = 0 ;         
+//   }
+//   else                               
+//   {
+//    itsTrack = new AliITStrackV2(*fTrack) ;
+//    if(itsTrack) { xy = itsTrack->GetD() ; }                 // signed DCA from ITStrack
+//    delete itsTrack ;
+//   }  
+// }
+ pFlowTrack->SetDcaSigned(xy,z) ;                  
+
+ // UnConstrained (global) first
+ Double_t gD[3] ;                              
+ fTrack->GetPxPyPz(gD) ;                       
+ // -
+ Float_t phiGl = (Float_t)Phi(gD) ;  
+ if(phiGl<0) { phiGl += 2*TMath::Pi() ; }
+ pFlowTrack->SetPhiGlobal(phiGl) ;             
+ Float_t ptGl = (Float_t)Pt(gD) ; 
+ pFlowTrack->SetPtGlobal(ptGl) ;               
+ Float_t etaGl = (Float_t)Eta(gD) ; 
+ pFlowTrack->SetEtaGlobal(etaGl) ;             
+
+ // Constrained (NEW)
+ Double_t cD[3] ;
+ Double_t par1 ; Double_t par2 ;  Double_t par3[3] ;
+ if(fTrack->GetConstrainedExternalParameters(par1,par2,par3))
+ {
+  fTrack->GetConstrainedPxPyPz(cD) ;     
+ }
+ else { for(Int_t iii=0;iii<3;iii++) { cD[iii] =0 ; } }
+
+ if(Norm(cD)!=0.)   // ConstrainedPxPyPz != 0 if ConstrainedChi2 < something ...
+ {                                                     
+  Float_t phi = (Float_t)Phi(cD) ; 
+  if(phi<0) { phi += 2*TMath::Pi() ; }
+  pFlowTrack->SetPhi(phi) ;                            
+  Float_t pt = (Float_t)Pt(cD) ; 
+  pFlowTrack->SetPt(pt) ;                              
+  Float_t eta = (Float_t)Eta(cD) ; 
+  pFlowTrack->SetEta(eta) ;                            
+  // number of constrainable tracks with |eta| < Flow::fEtaGood (0.9)
+  if(TMath::Abs(eta) < Flow::fEtaGood)  { fGoodTracksEta++ ; }
+ }
+ else  // in case Constriction impossible for track, fill the UnConstrained (global)
+ {
+  fUnconstrained++ ;   
+  pFlowTrack->SetPhi(0.) ;
+  pFlowTrack->SetPt(0.) ;   
+  pFlowTrack->SetEta(0.) ; 
+ }          
+
+ // positive - negative tracks
+ Int_t trk_sign = (Int_t)fTrack->GetSign() ; 
+ pFlowTrack->SetCharge(trk_sign) ;             
+ if(trk_sign>0)        { fPosiTracks++ ; }
+ else if(trk_sign<0)   { fNegaTracks++ ; }
+ else                  { return 0 ; }
+
+ // Tracking parameters (fit , TPC , ITS , dE/dx)
+ pFlowTrack->SetChi2(fTrack->GetConstrainedChi2()) ;           
+ pFlowTrack->SetTrackLength(fTrack->GetIntegratedLength()) ;   
+ // -
+ Int_t idXt[180] ; // used for Cluster Map ( see AliESDtrack::GetTPCclusters() )    // old:    Int
+ Int_t idX[6] ;    // used for Cluster Map ( see AliESDtrack::GetITSclusters() )    // old:    UInt
+ Int_t idxr[130] ; // used for Cluster Map ( see AliESDtrack::GetTRDclusters() )    // old:    UInt
+ Int_t nClus = 0 ;     
+ Int_t fNFound = 0 ;                                                   // *!* fNFoundable (in AliTPCtrack) ... added by M.Ianov 
+ Double_t pVecAt[3] ; Bool_t boh ; Float_t pAt = (Float_t)Norm(gD) ;   // to get p at each det.
+ // -
+ boh = fTrack->GetInnerParam()->GetPxPyPzAt(Flow::fTPCx, fMagField, pVecAt) ;
+ pAt = (Float_t)Norm(pVecAt) ;
+ nClus = fTrack->GetTPCclusters(idXt) ;
+ fNFound = fTrack->GetTPCNclsF() ;  // was 160                 // *!* fNFoundable (in AliTPCtrack) ... added by M.Ianov 
+ pFlowTrack->SetMaxPtsTPC(fNFound) ;                           
+ pFlowTrack->SetFitPtsTPC(nClus) ;                             
+ pFlowTrack->SetDedxTPC(fTrack->GetTPCsignal()) ;              
+ pFlowTrack->SetChi2TPC((Float_t)(fTrack->GetTPCchi2())) ;     
+ pFlowTrack->SetPatTPC(pAt) ;                                  
+ // -
+ boh = fTrack->GetInnerParam()->GetPxPyPzAt(Flow::fITSx, fMagField, pVecAt) ;
+ pAt = (Float_t)Norm(pVecAt) ;
+ nClus = fTrack->GetITSclusters(idX) ;
+ fNFound = 6 ;
+ pFlowTrack->SetMaxPtsITS(fNFound) ;                           
+ pFlowTrack->SetFitPtsITS(nClus) ;                             
+ pFlowTrack->SetDedxITS(fTrack->GetITSsignal()) ;              
+ pFlowTrack->SetChi2ITS((Float_t)(fTrack->GetITSchi2())) ;     
+ pFlowTrack->SetPatITS(pAt) ;                                  
+ // -
+ boh = fTrack->GetInnerParam()->GetPxPyPzAt(Flow::fITSx, fMagField, pVecAt) ;
+ pAt = (Float_t)Norm(pVecAt) ;
+ fNFound = fTrack->GetTRDncls() ;  // was 130
+ nClus = fTrack->GetTRDclusters(idxr) ;
+ pFlowTrack->SetMaxPtsTRD(fNFound) ;                           
+ pFlowTrack->SetNhitsTRD(nClus) ;                              
+ pFlowTrack->SetSigTRD(fTrack->GetTRDsignal()) ;               
+ pFlowTrack->SetChi2TRD((Float_t)fTrack->GetTRDchi2()) ;       
+ pFlowTrack->SetPatTRD(pAt) ;                                  
+ // -
+ boh = fTrack->GetInnerParam()->GetPxPyPzAt(Flow::fITSx, fMagField, pVecAt) ;
+ pAt = (Float_t)Norm(pVecAt) ;
+ fNFound = 0 ; if(fTrack->GetTOFCalChannel() > 0) { fNFound = 1 ; }
+ nClus = fTrack->GetTOFcluster() ;
+ pFlowTrack->SetMaxPtsTOF(fNFound) ;                           
+ pFlowTrack->SetNhitsTOF(nClus) ;                              
+ pFlowTrack->SetTofTOF(fTrack->GetTOFsignal()) ;               
+ pFlowTrack->SetChi2TOF(fTrack->GetTOFchi2()) ;                
+ pFlowTrack->SetPatTOF(pAt) ;                                  
+ // -
+ Double_t rIn[3]  ; rIn[0] = 0.  ;  rIn[1] = 0. ;  rIn[2] = 0. ;
+ Double_t rOut[3] ; rOut[0] = 0. ; rOut[1] = 0. ; rOut[2] = 0. ;
+ // -
+ fTrack->GetInnerXYZ(rIn) ;                                    
+ pFlowTrack->SetZFirstPoint(rIn[2]) ; 
+ //fTrack->GetXYZAt(Flow::fTPCx,fMagField,rOut) ;              
+ fTrack->GetOuterXYZ(rOut) ;                                   
+ pFlowTrack->SetZLastPoint(rOut[2]) ; 
+ // ESD-P.Id. = 5-vector of Best detectors probabilities for [e , mu , pi , K , p] 
+ Double_t trkPid[5] ; fTrack->GetESDpid(trkPid) ;              
+ Double_t trkPid6[Flow::nPid] ; 
+ for(Int_t bb=0;bb<5;bb++) { trkPid6[bb] = trkPid[bb] ; } 
+ trkPid6[5] = 0. ;                                             // *!* implement P.Id. for Deuterim
+
+ // Bayesian P.Id. method (weighted probabilities for [e , mu , pi , K , p , d])
+ Double_t Bsum = 0 ; 
+ Double_t bayePid[Flow::nPid] ;    // normalized P.id
+ Double_t storedPid[Flow::nPid] ;  // stored P.id
+ for(Int_t nB=0;nB<Flow::nPid;nB++)  { Bsum += trkPid6[nB]*Flow::fBayesian[nB] ; }
+ if(Bsum)
+ {
+  for(Int_t nB=0;nB<Flow::nPid;nB++) 
+  { 
+   bayePid[nB] = trkPid6[nB]*Flow::fBayesian[nB] / Bsum ; 
+   storedPid[nB] = trkPid6[nB] ; 
+  }
+ }
+ else { cout << " ERROR - Empty Bayesian Vector !!! " << endl ; }
+ pFlowTrack->SetElectronPositronProb(storedPid[0]);               
+ pFlowTrack->SetMuonPlusMinusProb(storedPid[1]);
+ pFlowTrack->SetPionPlusMinusProb(storedPid[2]);
+ pFlowTrack->SetKaonPlusMinusProb(storedPid[3]);
+ pFlowTrack->SetProtonPbarProb(storedPid[4]);
+ pFlowTrack->SetDeuteriumAntiDeuteriumProb(storedPid[5]);      // *!* implement P.Id. for Deuterim
+
+ // P.id. label given via the weighted prob.
+ const Int_t code[]   =  {11,13,211,321,2212,10010020} ;
+ Int_t kkk = 2 ;                       // if No id. -> then is a Pi
+ Float_t pid_max = bayePid[2] ;        // (if all equal, Pi probability get's the advantage to be the first)
+ for(Int_t iii=0; iii<5; iii++) 
+ {
+  if(bayePid[iii]>pid_max) { kkk = iii ; pid_max = bayePid[iii] ; }  // !!! Bayesian as well !!!
+ }
+ fBayesianAll[kkk]++ ; fSumAll++ ;     // goes on filling the vector of observed abundance 
+ //-
+ Int_t pdg_code = trk_sign*code[kkk] ;
+ pFlowTrack->SetMostLikelihoodPID(pdg_code);
+ return pFlowTrack ; 
+}
+
+//-----------------------------------------------------------------------
+
+AliFlowV0* AliSelectorFlow::FillFlowV0(AliESDv0* fV0)
+{
+ // Fills the AliFlowV0 .
+ // Sets the index of the 2 daughter tracks in the track array . 
+  
+ // cout << "FillFlowV0()" << endl ; 
+ // fV0->Dump() ;
+
+ TString ntra = "" ; ntra += fV0Number ;
+ pFlowV0 = new AliFlowV0(ntra.Data()) ;
+
+ Double_t Pxyz[3] ;            // reconstructed momentum of the V0
+ fV0->GetPxPyPz(Pxyz[0],Pxyz[1],Pxyz[2]) ;
+
+ Float_t phi = (Float_t)Phi(Pxyz) ; if(phi<0) { phi += 2*TMath::Pi() ; }
+ pFlowV0->SetPhi(phi) ;                
+ Float_t pt = (Float_t)Pt(Pxyz) ; 
+ pFlowV0->SetPt(pt) ;          
+ Float_t eta = (Float_t)Eta(Pxyz) ; 
+ pFlowV0->SetEta(eta) ;        
+
+ Double_t xyz[3] ;             // reconstructed position of the V0 
+ fV0->GetXYZ(xyz[0],xyz[1],xyz[2]) ;           
+ pFlowV0->SetCrossPoint(xyz[0],xyz[1],xyz[2]) ;
+
+ // V0's impact parameter & error
+ pFlowV0->SetDca((Float_t)fV0->GetD()) ;       
+ //pFlowV0->SetSigma(1.) ;                     
+
+ // chi2 of the V0 
+ //pFlowV0->SetChi2((Float_t)fV0->GetChi2()) ;   // AliRoot v4-04-Release
+ //pFlowV0->SetChi2((Float_t)fV0->GetChi2V0()) ;  // AliRoot v4-04-Release (but a different one!)      
+ // ...when they'll stop annoying me with stupid name changes (see above) I may enable these lines
+ pFlowV0->SetChi2(1.) ;
+
+ // P.id. 
+ Int_t pdg_code = fV0->GetPdgCode() ;
+ pFlowV0->SetMostLikelihoodPID(pdg_code);      
+
+ // mass 
+ pFlowV0->SetVmass((Float_t)fV0->GetEffMass()) ; 
+ //Int_t pN = fV0->GetPindex() ;
+ //Int_t nN = fV0->GetNindex() ;
+ AliFlowTrack* pos = 0 ;
+ AliFlowTrack* neg = 0 ;
+ //if(fMovedTr[pN]>=0) { pos = (AliFlowTrack*)pFlowEvent->TrackCollection()->At(fMovedTr[pN]) ; }
+ //if(fMovedTr[nN]>=0) { neg = (AliFlowTrack*)pFlowEvent->TrackCollection()->At(fMovedTr[nN]) ; }
+ pFlowV0->SetDaughters(pos,neg) ;
+
+ return pFlowV0 ;
+}
+
+//----------------------------------------------------------------------
+//*** USEFULL METHODS (to use 3-array) ***
+//-----------------------------------------------------------------------
+
+Double_t AliSelectorFlow::Norm(Double_t nu[3])
+{ 
+ // returns the norm of a double[3] 
+
+ Double_t norm2 = nu[0]*nu[0] + nu[1]*nu[1] + nu[2]*nu[2] ;
+ return TMath::Sqrt(norm2) ; 
+}
+
+//-----------------------------------------------------------------------
+
+Double_t AliSelectorFlow::Phi(Double_t nu[3])
+{
+ // returns the azimuthal angle of a double[3] 
+
+ if(nu[0]==0 && nu[1]==0) { return 0. ; }
+ else                    { return TMath::ATan2(nu[1],nu[0]) ; }
+}
+
+//-----------------------------------------------------------------------
+
+Double_t AliSelectorFlow::Pt(Double_t nu[3])
+{
+ // returns the transvers momentum of a double[3] 
+
+ Double_t trans = nu[0]*nu[0] + nu[1]*nu[1] ;
+ return TMath::Sqrt(trans) ; 
+}
+
+//-----------------------------------------------------------------------
+
+Double_t AliSelectorFlow::Eta(Double_t nu[3])
+{
+ // returns the PseudoRapidity of a double[3] 
+ // if transvers momentum = 0 --> returns +/- 1.000
+
+ Double_t m = Norm(nu) ;
+ if(nu[0]!=0 || nu[1]!=0) { return 0.5*TMath::Log((m+nu[2])/(m-nu[2])) ; }
+ else                    { return TMath::Sign((Double_t)1000.,nu[2]) ; }
+}
+
+//-----------------------------------------------------------------------
+
+
+
diff --git a/PWG2/FLOW/AliSelectorFlow.h b/PWG2/FLOW/AliSelectorFlow.h
new file mode 100644 (file)
index 0000000..933f5a3
--- /dev/null
@@ -0,0 +1,143 @@
+/* $Id$ */
+/* derived from AliSelector.h,v 1.10 2006/08/15 jgrosseo Exp $ */
+
+// This selector is only dependent on the ESD library, if you need the whole of AliROOT use AliSelectorRL
+#ifndef ALISELECTORFLOW_H
+#define ALISELECTORFLOW_H
+
+// ANSI things
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <vector>
+
+// ROOT things
+#include <TROOT.h>
+#include <TSelector.h>
+#include <TVector3.h>
+#include <TVector.h>
+#include <TObject.h>
+#include <TString.h>
+#include <TObjArray.h>
+#include <TFile.h>
+#include <TTree.h>
+#include <TChain.h>
+#include <TParticlePDG.h>
+#include <TDatabasePDG.h>
+
+// // AliRoot things
+// #include "AliESD.h"
+// #include "AliESDtrack.h"
+// #include "AliKalmanTrack.h"
+// #include "AliITStrackV2.h"
+// #include "AliESDVertex.h"
+// #include "AliESDv0.h"
+
+// FLOW things
+#include "AliFlowEvent.h"
+#include "AliFlowConstants.h"
+
+class TFile;
+class TChain;
+class TTree;
+class TParticle;
+
+class AliESD;
+class AliESDtrack;
+class AliESDv0;
+
+class AliSelectorFlow : public TSelector {
+
+  public:
+    AliSelectorFlow();
+    virtual ~AliSelectorFlow();
+
+    virtual Int_t   Version() const {return 1;}
+    virtual void    Begin(TTree*);
+    virtual void    SlaveBegin(TTree* tree);
+    virtual void    Init(TTree *tree);
+    virtual Bool_t  Notify();
+    virtual Bool_t  Process(Long64_t entry);
+    virtual void    SlaveTerminate();
+    virtual void    Terminate();
+
+  // output file name
+    //void    SetFlowEventFileName(TString name) ;
+    //TString GetFlowEventFileName() ;
+
+  // FLOW SPECIFIC METHODS (to fill the flowEvents)
+    AliFlowEvent*      FillFlowEvent(AliESD* fESD) ;            // fills up evt quantities 
+    AliFlowTrack*      FillFlowTrack(AliESDtrack* fTrack) ;     // fills up track quantities (global & constrained) ; p.id. & bayesian calculation ; 
+    AliFlowV0*         FillFlowV0(AliESDv0* fV0) ;              // fills up v0 quantities ; links v0 to tracks and back ;
+
+  // USEFULL METHODS (to use 3-arrays)
+    Double_t      Norm(Double_t nu[3]) ;                        // norm of a non-vector 3 array      
+    Double_t      Phi(Double_t nu[3]) ;                         // phi of a non-vector 3 array       
+    Double_t      Pt(Double_t nu[3]) ;                          // pt of a non-vector 3 array       
+    Double_t      Eta(Double_t nu[3]) ;                         // eta of a non-vector 3 array       
+
+ protected:
+    TTree*  GetKinematics();
+    void CheckOptions();
+
+    TTree      *fTree;           //! pointer to the TTree containing the events
+    AliESD*          fESD;               //! "ESD" branch in fChain
+    AliESDtrack*     fTrack;             //! "ESD track" 
+    AliESDv0*        fV0;                //! "ESD v0" 
+    Int_t           fCountFiles ;        // number of processed file
+    TString         fFlowEventFileName ; //! output file name 
+
+ private:
+
+    TFile*        pFlowfile ;
+    AliFlowEvent* pFlowEvent ;          //! pointer to flow event
+    AliFlowTrack* pFlowTrack;           //! pointer to flow track
+    AliFlowV0*    pFlowV0;             //! pointer to flow V0
+  // enumerators                            
+    Int_t       fRunID;                 //! last run ID
+    Int_t      fEventNumber ;          //! progressive enumeration of ESD events
+    Int_t       fTrackNumber ;         //! progressive enumeration of ESD tracks
+    Int_t       fV0Number ;            //! progressive enumeration of ESD V0
+    Int_t       fNumberOfEvents ;       //! total number of ESD events in file
+    Int_t       fNumberOfTracks ;      //! total number of tracks in the current event
+    Int_t       fNumberOfV0s ;         //! total number of v0s in the current event
+  // other enumerators                              
+    Int_t      fGoodTracks ;           //! enumerator for good tracks
+    Int_t      fGoodV0s ;              //! enumerator for good v0s
+    Int_t      fGoodTracksEta ;        //! enumerator for good tracks in the good eta range (-0.9..0.9)
+    Int_t      fPosiTracks ;           //! enumerator for positive tracks
+    Int_t      fNegaTracks ;           //! enumerator for negative tracks
+    Int_t      fUnconstrained ;        //! enumerator for tracks not constrainable
+    Int_t       fBayesianAll[5] ;       //! final particles abundance -> AliFlowEvent (see Bayesian P.Id.)
+    Int_t       fSumAll ;              //! total particles abundance (all kind)
+
+    Int_t       fCutEvts ;             //! total enumerator for discarded events
+    Int_t       fCutTrks ;             //! total enumerator for discarded tracks
+    Int_t       fCutV0s ;              //! total enumerator for discarded V0s
+  // Flags
+    Bool_t      fLoopV0 ;               //! flag to loop over v0s 
+    Bool_t      fDoNothing ;            //! flag for a dummy execution 
+    Bool_t      fOnFlyAnalysis ;        //! flag for on-fly analysis 
+
+  // Cuts
+    Float_t fEtrkLow ;
+    Float_t fEtrkHig ;
+    Int_t   fHitsTrk ;
+
+  // ...
+    Float_t    fMagField ;             //! magnetic field from the ESD
+    void DeleteKinematicsFile();
+
+    TFile*        fKineFile;            //! pointer to Kinematics.root if the file was opened
+
+    AliSelectorFlow(const AliSelectorFlow&);
+    AliSelectorFlow& operator=(const AliSelectorFlow&);
+
+  ClassDef(AliSelectorFlow,0);
+};
+
+#endif