AliPhysics  db95e02 (db95e02)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AliAnalysisTaskPhiFlowDev.cxx
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  * *
4  * Author: The ALICE Off-line Project. *
5  * Contributors are mentioned in the code where appropriate. *
6  * *
7  * Permission to use, copy, modify and distribute this software and its *
8  * documentation strictly for non-commercial purposes is hereby granted *
9  * without fee, provided that the above copyright notice appears in all *
10  * copies and that both the copyright notice and this permission notice *
11  * appear in the supporting documentation. The authors make no claims *
12  * about the suitability of this software for any purpose. It is *
13  * provided "as is" without express or implied warranty. *
14  **************************************************************************/
15 
16 // AliAnalysisTaskPhiFlow:
17 // author: Redmer Alexander Bertens (rbertens@cern.ch)
18 // analyis task for phi-meson reconstruction and determination of v_n
19 // AliPhiMesonHelperTrack provides a lightweight helper track for reconstruction
20 // new in this version (use with caution): vzero event plane, event mixing
21 
22 #include "TChain.h"
23 #include "TH1.h"
24 #include "TH1F.h"
25 #include "TH2F.h"
26 #include "TMath.h"
27 #include "TObjArray.h"
28 #include "AliAnalysisTaskSE.h"
29 #include "AliAnalysisManager.h"
30 #include "AliAODEvent.h"
31 #include "AliAODInputHandler.h"
32 #include "AliCentrality.h"
33 #include "AliAnalysisTaskPhiFlow.h"
34 #include "AliFlowBayesianPID.h"
35 #include "AliPIDCombined.h"
36 #include "AliMCEvent.h"
37 #include "TProfile.h"
38 #include "AliFlowCandidateTrack.h"
39 #include "AliFlowTrackCuts.h"
40 #include "AliFlowEventCuts.h"
41 #include "AliFlowEventSimple.h"
42 #include "AliFlowTrackSimple.h"
43 #include "AliFlowCommonConstants.h"
44 #include "AliFlowEvent.h"
45 #include "TVector3.h"
46 #include "AliAODVZERO.h"
47 #include "AliPIDResponse.h"
48 #include "AliAODMCParticle.h"
49 #include "AliAnalysisTaskVnV0.h"
50 #include "AliEventPoolManager.h"
51 
52 class AliFlowTrackCuts;
53 
54 using std::cout;
55 using std::endl;
56 
59 
61  fDebug(0), fIsMC(0), fEventMixing(0), fTypeMixing(0), fQA(0), fV0(0), fMassBins(1), fMinMass(-1.), fMaxMass(0.), fCutsRP(NULL), fCutsEvent(NULL), fNullCuts(0), fPIDResponse(0), fFlowEvent(0), fBayesianResponse(0), fCandidates(0), fCandidateEtaPtCut(0), fCandidateMinEta(0), fCandidateMaxEta(0), fCandidateMinPt(0), fCandidateMaxPt(0), fNPtBins(18), fCentrality(999), fVertex(999), fAOD(0), fPoolManager(0), fOutputList(0), fEventStats(0), fCentralityPass(0), fCentralityNoPass(0), fNOPID(0), fPIDk(0),fNOPIDTOF(0), fPIDTOF(0), fPtP(0), fPtN(0), fPtKP(0), fPtKN(0), fMultCorAfterCuts(0), fMultvsCentr(0), fPOICuts(0), fPhi(0), fPt(0), fEta(0), fVZEROA(0), fVZEROC(0), fTPCM(0)/*, fDeltaDipAngle(0), fDeltaDipPt(0), fApplyDeltaDipCut(0)*/, fDCAAll(0), fDCAXYQA(0), fDCAZQA(0), fDCAPrim(0), fDCASecondaryWeak(0), fDCAMaterial(0), fSubEventDPhiv2(0), fUsePidResponse(0), fUseTrackCutsPID(kTRUE), fPIDCombined(0)
62 {
63  // Default constructor
64  for(Int_t i(0); i < 7; i++) fPIDConfig[i] = 0.;
65  for(Int_t i(0); i < 5; i++) fDCAConfig[i] = 0.;
66  for(Int_t i(0); i < 20; i++) {
67  fVertexMixingBins[i] = 0;
68  fCentralityMixingBins[i] = 0;
69  }
70  fMixingParameters[0] = 1000; fMixingParameters[1] = 50000; fMixingParameters[2] = 5;
71  for(Int_t i(0); i < 18; i++) {
72  for(Int_t j(0); j < 2; j++) fV0Data[i][j] = 0;
73  fInvMNP[i] = 0; fInvMNN[i] = 0; fInvMPP[i] = 0; fPtSpectra[i] = 0; fPtBins[i] = 0.;
74  }
75 }
76 //_____________________________________________________________________________
78  fDebug(0), fIsMC(0), fEventMixing(0), fTypeMixing(0), fQA(0), fV0(0), fMassBins(1), fMinMass(-1.), fMaxMass(0.), fCutsRP(NULL), fCutsEvent(NULL), fNullCuts(0), fPIDResponse(0), fFlowEvent(0), fBayesianResponse(0), fCandidates(0), fCandidateEtaPtCut(0), fCandidateMinEta(0), fCandidateMaxEta(0), fCandidateMinPt(0), fCandidateMaxPt(0), fNPtBins(18), fCentrality(999), fVertex(999), fAOD(0), fPoolManager(0), fOutputList(0), fEventStats(0), fCentralityPass(0), fCentralityNoPass(0), fNOPID(0), fPIDk(0), fNOPIDTOF(0), fPIDTOF(0), fPtP(0), fPtN(0), fPtKP(0), fPtKN(0), fMultCorAfterCuts(0), fMultvsCentr(0), fPOICuts(0), fPhi(0), fPt(0), fEta(0), fVZEROA(0), fVZEROC(0), fTPCM(0)/*, fDeltaDipAngle(0), fDeltaDipPt(0), fApplyDeltaDipCut(0)*/, fDCAAll(0), fDCAXYQA(0), fDCAZQA(0), fDCAPrim(0), fDCASecondaryWeak(0), fDCAMaterial(0), fSubEventDPhiv2(0), fUsePidResponse(0), fUseTrackCutsPID(kTRUE), fPIDCombined(0)
79 {
80  // Constructor
81  for(Int_t i(0); i < 7; i++) fPIDConfig[i] = 0.;
82  for(Int_t i(0); i < 5; i++) fDCAConfig[i] = 0.;
83  for(Int_t i(0); i < 20; i++) {
84  fVertexMixingBins[i] = 0;
85  fCentralityMixingBins[i] = 0;
86  }
87  fMixingParameters[0] = 1000; fMixingParameters[1] = 50000; fMixingParameters[2] = 5;
88  for(Int_t i(0); i < 18; i++) {
89  for(Int_t j(0); j < 2; j++) fV0Data[i][j] = 0;
90  fInvMNP[i] = 0; fInvMNN[i] = 0; fInvMPP[i] = 0; fPtSpectra[i] = 0; fPtBins[i] = 0.;
91  }
92  DefineInput(0, TChain::Class());
93  DefineOutput(1, TList::Class());
94  DefineOutput(2, AliFlowEventSimple::Class());
95  if(fDebug > 0) cout << " === Created instance of AliAnaysisTaskPhiFlow === " << endl;
96 }
97 //_____________________________________________________________________________
99 {
100  // Destructor
101  if (fNullCuts) delete fNullCuts;
102  if (fOutputList) delete fOutputList;
103  if (fCandidates) delete fCandidates;
104  if (fFlowEvent) delete fFlowEvent;
106  if (fEventMixing) delete fPoolManager;
107  if (fPIDCombined) delete fPIDCombined;
108  if (fDebug > 0) cout << " === Deleted instance of AliAnalysisTaskPhiFlow === " << endl;
109 }
110 //_____________________________________________________________________________
111 TH1F* AliAnalysisTaskPhiFlow::BookHistogram(const char* name)
112 {
113  // Return a pointer to a TH1 with predefined binning
114  if(fDebug > 0) cout << " *** BookHistogram() *** " << name << endl;
115  TH1F *hist = new TH1F(name, Form("M_{INV} (%s)", name), 60, .99, 1.092);
116  hist->GetXaxis()->SetTitle("M_{INV} (GeV / c^{2})");
117  hist->GetYaxis()->SetTitle("No. of pairs");
118  hist->SetMarkerStyle(kFullCircle);
119  hist->Sumw2();
120  fOutputList->Add(hist);
121  return hist;
122 }
123 //_____________________________________________________________________________
125 {
126  // Return a pointer to a TH2 with predefined binning
127  if(fDebug > 0) cout << " *** BookPIDHisotgram() *** " << endl;
128  TH2F *hist = 0x0;
129  if(TPC) {
130  hist = new TH2F(name, Form("PID (%s)", name), 100, 0, 5, 100, 0, 1000);
131  hist->GetYaxis()->SetTitle("dE/dx (a.u.)");
132  }
133  if(!TPC) {
134  hist = new TH2F(name, Form("PID (%s)", name), 100, 0, 5, 100, 0, 1.5);
135  hist->GetYaxis()->SetTitle("#beta");
136  }
137  hist->GetXaxis()->SetTitle("P (GeV / c)");
138  fOutputList->Add(hist);
139  return hist;
140 }
141 //_____________________________________________________________________________
143 {
144  // intialize p_t histograms for each p_t bin
145  if(fDebug > 0) cout << " *** InitPtSpectraHistograms() *** " << endl;
146  TH1F* hist = new TH1F(Form("%4.2f p_{t} %4.2f", nmin, nmax), Form("%f p_{t} %f", nmin, nmax), 60, nmin, nmax);
147  hist->GetXaxis()->SetTitle("p_{T} GeV / c");
148  fOutputList->Add(hist);
149  return hist;
150 }
151 //_____________________________________________________________________________
152 TH1F* AliAnalysisTaskPhiFlow::BookPtHistogram(const char* name)
153 {
154  // Return a pointer to a p_T spectrum histogram
155  if(fDebug > 0) cout << " *** BookPtHistogram() *** " << endl;
156  TH1F* ratio = new TH1F(name, name, 100, 0, 7);
157  ratio->GetXaxis()->SetTitle("p_{T} ( GeV / c^{2} )");
158  ratio->GetYaxis()->SetTitle("No. of events");
159  ratio->Sumw2();
160  fOutputList->Add(ratio);
161  return ratio;
162 }
163 //_____________________________________________________________________________
165 {
166  // Add Phi Identification Output Objects
167  if(fDebug > 0) cout << " ** AddPhiIdentificationOutputObjects() *** " << endl;
168  if(fQA) {
169  fEventStats = new TH1F("fHistStats", "Event Statistics", 18, -.25, 4.25);
170  fEventStats->GetXaxis()->SetTitle("No. of events");
171  fEventStats->GetYaxis()->SetTitle("Statistics");
172  fOutputList->Add(fEventStats);
173  }
174  fCentralityPass = new TH1F("fCentralityPass", "Centrality Pass", 101, -1, 100);
176  if(fQA) {
177  fCentralityNoPass = new TH1F("fCentralityNoPass", "Centrality No Pass", 101, -1, 100);
179  fNOPID = BookPIDHistogram("TPC signal, all particles", kTRUE);
180  fPIDk = BookPIDHistogram("TPC signal, kaons", kTRUE);
181  fNOPIDTOF = BookPIDHistogram("TOF signal, all particles", kFALSE);
182  fPIDTOF = BookPIDHistogram("TOF signal, kaons", kFALSE);
183  }
184  for(Int_t ptbin(0); ptbin < fNPtBins; ptbin++) {
185  fInvMNP[ptbin] = BookHistogram(Form("NP, %4.2f < p_{T} < %4.2f GeV", fPtBins[ptbin], fPtBins[ptbin+1]));
186  fInvMNN[ptbin] = BookHistogram(Form("NN, %4.2f < p_{T} < %4.2f GeV", fPtBins[ptbin], fPtBins[ptbin+1]));
187  fInvMPP[ptbin] = BookHistogram(Form("PP, %4.2f < p_{T} < %4.2f GeV", fPtBins[ptbin], fPtBins[ptbin+1]));
188  }
189  if(fQA) {
190  for(Int_t ptbin(0); ptbin < fNPtBins; ptbin++) fPtSpectra[ptbin] = InitPtSpectraHistograms(fPtBins[ptbin], fPtBins[ptbin+1]);
191  fPtP = BookPtHistogram("i^{+}");
192  fPtN = BookPtHistogram("i^{-}");
193  fPtKP = BookPtHistogram("K^{+}");
194  fPtKN = BookPtHistogram("K^{-}");
195  fPhi = new TH1F("fPhi", "#phi distribution", 100, -.5, 7);
196  fOutputList->Add(fPhi);
197  fPt = new TH1F("fPt", "p_{T}", 100, 0, 5.5);
198  fOutputList->Add(fPt);
199  fEta = new TH1F("fEta", "#eta distribution", 100, -1.1, 1.1);
200  fOutputList->Add(fEta);
201  fVZEROA = new TH1F("fVZEROA", "VZERO A Multiplicity", 1000, 0, 10000);
202  fOutputList->Add(fVZEROA);
203  fVZEROC = new TH1F("fVZEROC", "VZERO C Multiplicity", 1000, 0, 10000);
204  fOutputList->Add(fVZEROC);
205  fTPCM = new TH1F("fTPCM", "TPC multiplicity", 1000, 0, 10000);
206  fOutputList->Add(fTPCM);
207  fDCAXYQA = new TH1F("fDCAXYQA", "fDCAXYQA", 1000, -5, 5);
208  fOutputList->Add(fDCAXYQA);
209  fDCAZQA = new TH1F("fDCAZQA", "fDCAZQA", 1000, -5, 5);
210  fOutputList->Add(fDCAZQA);
211  }
212  if(fIsMC || fQA) {
213  fDCAAll = new TH2F("fDCAAll", "fDCAAll", 1000, 0, 10, 1000, -5, 5);
214  fOutputList->Add(fDCAAll);
215  fDCAPrim = new TH2F("fDCAprim","fDCAprim", 1000, 0, 10, 1000, -5, 5);
216  fOutputList->Add(fDCAPrim);
217  fDCASecondaryWeak = new TH2F("fDCASecondaryWeak","fDCASecondaryWeak", 1000, 0, 10, 1000, -5, 5);
219  fDCAMaterial = new TH2F("fDCAMaterial","fDCAMaterial", 1000, 0, 10, 1000, -5, 5);
221  }
222  if(fV0) {
223  fSubEventDPhiv2 = new TProfile("fSubEventDPhiv2", "fSubEventDPhiv2", 5, 0, 5);
224  fSubEventDPhiv2->GetXaxis()->SetBinLabel(1, "<#Psi_{a} - #Psi_{b}>");
225  fSubEventDPhiv2->GetXaxis()->SetBinLabel(2, "<#Psi_{a} - #Psi_{c}>");
226  fSubEventDPhiv2->GetXaxis()->SetBinLabel(3, "<#Psi_{b} - #Psi_{c}>");
227  fSubEventDPhiv2->GetXaxis()->SetBinLabel(4, "#sqrt{#frac{<#Psi_{a} - #Psi_{b}><#Psi_{a} - #Psi_{c}>}{<#Psi_{b} - #Psi_{c}>}}");
228  fSubEventDPhiv2->GetXaxis()->SetBinLabel(5, "#sqrt{#frac{<#Psi_{a} - #Psi_{c}><#Psi_{b} - #Psi_{c}>}{<#Psi_{a} - #Psi_{b}>}}");
230  const char* V0[] = {"V0A", "V0C"};
231  for(Int_t ptbin(0); ptbin < fNPtBins; ptbin++)
232  for(Int_t iV0(0); iV0 < 2; iV0++) {
233  fV0Data[ptbin][iV0] = new TProfile(Form("%s v2 %4.2f < p_{T} < %4.2f GeV", V0[iV0], fPtBins[ptbin], fPtBins[ptbin+1]), Form("%s v2 %4.2f < p_{T} < %4.2f GeV", V0[iV0], fPtBins[ptbin], fPtBins[ptbin+1]), fMassBins, fMinMass, fMaxMass);
234  fOutputList->Add(fV0Data[ptbin][iV0]);
235  }
236  }
237 }
238 //_____________________________________________________________________________
240 {
241  // Create user defined output objects
242  if(fDebug > 0) cout << " *** UserCreateOutputObjects() *** " << endl;
243  fNullCuts = new AliFlowTrackCuts("null_cuts");
245  // combined pid
246  fPIDCombined = new AliPIDCombined;
247  fPIDCombined->SetDefaultTPCPriors();
248  fPIDCombined->SetDetectorMask(AliPIDResponse::kDetTPC|AliPIDResponse::kDetTOF);
249 
250  // flag to mc
251  if(!fCutsEvent || fIsMC) fBayesianResponse->SetMC(kTRUE);
252  Double_t t(0);
253  for(Int_t i = 0; i < 7; i++) t+=TMath::Abs(fPIDConfig[i]);
254  if(t < 0.1) AliFatal("No valid PID procedure recognized -- terminating analysis !!!");
255  if(fNPtBins > 18) AliFatal("Invalid number of pt bins initialied ( > 18 ) -- terminating analysis !!!");
257  cc->SetNbinsQ(500); cc->SetNbinsPhi(180); cc->SetNbinsMult(10000);
258  cc->SetQMin(0.0); cc->SetPhiMin(0.0); cc->SetMultMin(0);
259  cc->SetQMax(3.0); cc->SetPhiMax(TMath::TwoPi()); cc->SetMultMax(10000);
260  cc->SetNbinsMass(fMassBins); cc->SetNbinsEta(200); (fMassBins == 1) ? cc->SetNbinsPt(15) : cc->SetNbinsPt(100); // high pt
261  cc->SetMassMin(fMinMass); cc->SetEtaMin(-5.0); cc->SetPtMin(0);
262  cc->SetMassMax(fMaxMass); cc->SetEtaMax(+5.0); (fMassBins == 1) ? cc->SetPtMax(15) : cc->SetPtMax(10); // high pt
264  AliAnalysisManager *man = AliAnalysisManager::GetAnalysisManager();
265  if (man) {
266  AliInputEventHandler* inputHandler = (AliInputEventHandler*)(man->GetInputEventHandler());
267  if (inputHandler) fPIDResponse = inputHandler->GetPIDResponse();
268  }
269  // Create all output objects and store them to a list
270  fOutputList = new TList();
271  fOutputList->SetOwner(kTRUE);
272  // Create and post the Phi identification output objects
274  PostData(1, fOutputList);
275  // create candidate array
276  fCandidates = new TObjArray(1000);
277  fCandidates->SetOwner(kTRUE);
278  // create and post flowevent
279  fFlowEvent = new AliFlowEvent(10000);
280  PostData(2, fFlowEvent);
282 }
283 //_____________________________________________________________________________
285 {
286  // initialize event mixing
287  if(fDebug > 0) cout << " *** InitializeEventMixing() *** " << endl;
288  Int_t _c(0), _v(0);
289  for(Int_t i(0); i < 19; i++) {
290  if (fCentralityMixingBins[i+1] < fCentralityMixingBins[i]) { _c = i; break; }
291  else _c = 19;
292  }
293  for(Int_t i(0); i < 19; i++) {
294  if (fVertexMixingBins[i+1] < fVertexMixingBins[i]) { _v = i; break; }
295  else _v = 19;
296  }
297  if(fDebug > 0 ) cout << Form(" --> found %d centrality bins for mixing, %d vertex bins for mixing", _c, _v) << endl;
298  Double_t centralityBins[_c];
299  Double_t vertexBins[_v];
300  for(Int_t i(0); i < _c + 1; i++) centralityBins[i] = fCentralityMixingBins[i];
301  for(Int_t i(0); i < _v + 1; i++) vertexBins[i] = fVertexMixingBins[i];
302  return new AliEventPoolManager(fMixingParameters[0], fMixingParameters[1], _c, (Double_t*)centralityBins, _v, (Double_t*)vertexBins);
303 }
304 //_____________________________________________________________________________
305 template <typename T> Double_t AliAnalysisTaskPhiFlow::InvariantMass(const T* track1, const T* track2) const
306 {
307  // Return the invariant mass of two tracks, assuming both tracks are kaons
308  if(fDebug > 1) cout << " *** InvariantMass() *** " << endl;
309  if ((!track2) || (!track1)) return 0.;
310  Double_t masss = TMath::Power(4.93676999999999977e-01, 2);
311  Double_t pxs = TMath::Power((track1->Px() + track2->Px()), 2);
312  Double_t pys = TMath::Power((track1->Py() + track2->Py()), 2);
313  Double_t pzs = TMath::Power((track1->Pz() + track2->Pz()), 2);
314  Double_t e1 = TMath::Sqrt(track1->P() * track1->P() + masss);
315  Double_t e2 = TMath::Sqrt(track2->P() * track2->P() + masss);
316  Double_t es = TMath::Power((e1 + e2), 2);
317  if ((es - (pxs + pys + pzs)) < 0) return 0.;
318  return TMath::Sqrt((es - (pxs + pys + pzs)));
319 }
320 //_____________________________________________________________________________
321 /*
322 template <typename T> Double_t AliAnalysisTaskPhiFlow::DeltaDipAngle(const T* track1, const T* track2) const
323 {
324  // Calculate the delta dip angle between two particles
325  if(fDebug > 1) cout << " *** DeltaDipAngle() *** " << endl;
326  if (track1->P()*track2->P() == 0) return 999;
327  return TMath::ACos(((track1->Pt() * track2->Pt()) + (track1->Pz() * track2->Pz())) / (track1->P() * track2->P()));
328 }
329 //_____________________________________________________________________________
330 template <typename T> Bool_t AliAnalysisTaskPhiFlow::CheckDeltaDipAngle(const T* track1, const T* track2) const
331 {
332  // Check if pair passes delta dip angle cut within 0 < p_t < fDeltaDipPt
333  if(fDebug > 1) cout << " *** CheckDeltaDipAngle() *** " << endl;
334  if ((TMath::Abs(DeltaDipAngle(track1, track2)) < fDeltaDipAngle) && (PhiPt(track1, track2) < fDeltaDipPt)) return kFALSE;
335  return kTRUE;
336 }
337 */
338 //_____________________________________________________________________________
339 template <typename T> Bool_t AliAnalysisTaskPhiFlow::CheckCandidateEtaPtCut(const T* track1, const T* track2) const
340 {
341  // Check if pair passes eta and pt cut
342  if(fDebug > 1) cout << " *** CheckCandidateEtaPtCut() *** " << endl;
343  if (fCandidateMinPt > PhiPt(track1, track2) || fCandidateMaxPt < PhiPt(track1, track2)) return kFALSE;
344  TVector3 a(track1->Px(), track1->Py(), track1->Pz());
345  TVector3 b(track2->Px(), track2->Py(), track2->Pz());
346  TVector3 c = a + b;
347  if (fCandidateMinEta > c.Eta() || fCandidateMaxEta < c.Eta()) return kFALSE;
348  return kTRUE;
349 }
350 //_____________________________________________________________________________
351 template <typename T> void AliAnalysisTaskPhiFlow::PlotMultiplcities(const T* event) const
352 {
353  // QA multiplicity plots
354  if(fDebug > 1) cout << " *** PlotMultiplcities() *** " << endl;
355  fVZEROA->Fill(event->GetVZEROData()->GetMTotV0A());
356  fVZEROC->Fill(event->GetVZEROData()->GetMTotV0C());
357  fTPCM->Fill(event->GetNumberOfTracks());
358 }
359 //_____________________________________________________________________________
361 {
362  // Initialize the Bayesian PID object for AOD
363  if(fDebug > 0) cout << " *** InitializeBayesianPID() *** " << endl;
365 }
366 //_____________________________________________________________________________
367 template <typename T> Bool_t AliAnalysisTaskPhiFlow::PassesTPCbayesianCut(T* track) const
368 {
369  // Check if the particle passes the TPC TOF bayesian cut.
370  if(fDebug > 1) cout << " *** PassesTPCbayesianCut() *** " << endl;
372  if (!fBayesianResponse->GetCurrentMask(0)) return kFALSE; // return false if TPC has no response
373  Float_t *probabilities = fBayesianResponse->GetProb();
374  if (probabilities[3] > fPIDConfig[6]) {
375  if(fQA) {fPhi->Fill(track->Phi()); fPt->Fill(track->Pt()); fEta->Fill(track->Eta());}
376  return kTRUE;
377  }
378  return kFALSE;
379 }
380 //_____________________________________________________________________________
381 Bool_t AliAnalysisTaskPhiFlow::PassesDCACut(AliAODTrack* track) const
382 {
383  // check if track passes dca cut according to dca routine
384  // setup the routine as follows:
385  // fDCAConfig[0] < -1 no pt dependence
386  // fDCAConfig[0] = 0 do nothing
387  // fDCAConfig[0] > 1 pt dependent dca cut
388  if(fDebug > 1) cout << " *** PassesDCACut() *** " << endl;
389  if(fIsMC) return kTRUE;
390  AliAODTrack copy(*track);
391  if( (fDCAConfig[0] < 0.1) && (fDCAConfig[0] > -0.1) ) {
392  if(fQA) {
393  Double_t b[2] = { -99., -99.};
394  Double_t bCov[3] = { -99., -99., -99.};
395  if(copy.PropagateToDCA(fAOD->GetPrimaryVertex(), fAOD->GetMagneticField(), 100., b, bCov)) {
396  fDCAXYQA->Fill(b[0]);
397  fDCAZQA->Fill(b[1]);
398  fDCAPrim->Fill(track->Pt(), b[0]);
399  }
400  }
401  return kTRUE;
402  }
403  Double_t b[2] = { -99., -99.};
404  Double_t bCov[3] = { -99., -99., -99.};
405  if(!copy.PropagateToDCA(fAOD->GetPrimaryVertex(), fAOD->GetMagneticField(), 100., b, bCov)) return kFALSE;
406  if((!fIsMC)&&fQA) fDCAMaterial->Fill(track->Pt(), b[0]);
407  if( (fDCAConfig[0] < -.9) && ( (TMath::Abs(b[0]) > fDCAConfig[1]) || (TMath::Abs(b[1]) > fDCAConfig[2])) ) return kFALSE;
408  if(fDCAConfig[0] > .9) {
409  if(fDCAConfig[4] < TMath::Abs(b[1])) return kFALSE;
410  Double_t denom = TMath::Power(track->Pt(), fDCAConfig[3]);
411  if( denom < 0.0000001 ) return kFALSE; // avoid division by zero
412  if( (fDCAConfig[1] + fDCAConfig[2] / denom) < TMath::Abs(b[0]) ) return kFALSE;
413  }
414  if(fQA) {
415  fDCAXYQA->Fill(b[0]);
416  fDCAZQA->Fill(b[1]);
417  fDCAPrim->Fill(track->Pt(), b[0]);
418  }
419  return kTRUE;
420 }
421 //_____________________________________________________________________________
422 Bool_t AliAnalysisTaskPhiFlow::IsKaon(AliAODTrack* track) const
423 {
424  // Kaon identification routine, based on multiple detectors and approaches
425  if(fDebug > 1) cout << " *** IsKaon() *** " << endl;
426  if(fUseTrackCutsPID) return fPOICuts->IsSelected(track);
427  if(!fPOICuts->IsSelected(track)) return kFALSE;
428  if(fUsePidResponse) {
429  Double_t prob[10] = {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
430  fPIDCombined->ComputeProbabilities(track, fPIDResponse, prob);
431  if(prob[3] > fPIDConfig[6]) return kTRUE;
432  }
433  if(!PassesDCACut(track)) return kFALSE;
434  if(fQA) {fNOPID->Fill(track->P(), track->GetTPCsignal());fNOPIDTOF->Fill(track->P(), track->GetTOFsignal());}
435  if(track->Pt() < fPIDConfig[1]) {
436  if(fDebug>1) cout << " ITS received track with p_t " << track->Pt() << endl;
437  // if tpc control is disabled, pure its pid
438  if(fPIDConfig[2] < 0.) {
439  if (TMath::Abs(fPIDResponse->NumberOfSigmasITS(track, AliPID::kKaon)) < fPIDConfig[0]) return kTRUE;
440  return kFALSE;
441  }
442  // else, switch to ITS pid with TPC rejection of protons and pions
443  if (TMath::Abs(fPIDResponse->NumberOfSigmasTPC(track, AliPID::kProton)) < fPIDConfig[3]) return kFALSE;
444  else if (TMath::Abs(fPIDResponse->NumberOfSigmasTPC(track, AliPID::kPion)) < fPIDConfig[3]) return kFALSE;
445  else if (TMath::Abs(fPIDResponse->NumberOfSigmasITS(track, AliPID::kKaon)) < fPIDConfig[0]) {
446  if(fQA) {fPIDk->Fill(track->P(), track->GetTPCsignal()); fPIDTOF->Fill(track->P(), track->GetTOFsignal());}
447  return kTRUE;
448  }
449  return kFALSE;
450  }
451  if((track->Pt() > fPIDConfig[1]) && (track->Pt() < fPIDConfig[4])) {
452  if(fDebug>1) cout << " TPC received track with p_t " << track->Pt() << endl;
453  // if its control is disabled, pure tpc pid
454  if(fPIDConfig[5] < 0.) {
455  if (TMath::Abs(fPIDResponse->NumberOfSigmasTPC(track, AliPID::kKaon)) < fPIDConfig[3]) return kTRUE;
456  return kFALSE;
457  }
458  // else, switch to TPC pid with ITS rejection of protons and pions
459  if (TMath::Abs(fPIDResponse->NumberOfSigmasITS(track, AliPID::kProton)) < fPIDConfig[0]) return kFALSE;
460  else if (TMath::Abs(fPIDResponse->NumberOfSigmasITS(track, AliPID::kPion)) < fPIDConfig[0]) return kFALSE;
461  else if (TMath::Abs(fPIDResponse->NumberOfSigmasTPC(track, AliPID::kKaon)) < fPIDConfig[3]) {
462  if(fQA) {fPIDk->Fill(track->P(), track->GetTPCsignal()); fPIDTOF->Fill(track->P(), track->GetTOFsignal());}
463  return kTRUE;
464  }
465  return kFALSE;
466  }
467  if(fDebug>1) cout << " Bayesian method received track with p_t " << track->Pt() << endl;
468  // switch to bayesian PID
469  if (PassesTPCbayesianCut(track)) {
470  if(fQA) {fPIDk->Fill(track->P(), track->GetTPCsignal());fPIDTOF->Fill(track->P(), track->GetTOFsignal());}
471  return kTRUE;
472  }
473  return kFALSE;
474 }
475 //_____________________________________________________________________________
476 template <typename T> Double_t AliAnalysisTaskPhiFlow::PhiPt(const T* track1, const T* track2) const
477 {
478  // return p_t of track pair
479  TVector3 a(track1->Px(), track1->Py(), track1->Pz());
480  TVector3 b(track2->Px(), track2->Py(), track2->Pz());
481  TVector3 c = a + b;
482  return c.Pt();
483 }
484 //_____________________________________________________________________________
485 template <typename T> void AliAnalysisTaskPhiFlow::PtSelector(Int_t tracktype, const T* track1, const T* track2) const
486 {
487  // plot m_inv spectra of like- and unlike-sign kaon pairs for each pt bin
488  Double_t pt = PhiPt(track1, track2);
489  if (tracktype == 0) {
490  for(Int_t ptbin(0); ptbin < fNPtBins; ptbin++) {
491  if ((fPtBins[ptbin] <= pt) && (fPtBins[ptbin+1] > pt )) {
492  fInvMNP[ptbin]->Fill(InvariantMass(track1, track2));
493  if(fQA) fPtSpectra[ptbin]->Fill(pt);
494  }
495  }
496  }
497  if (tracktype == 1) {
498  for(Int_t ptbin(0); ptbin < fNPtBins; ptbin++) {
499  if ((fPtBins[ptbin] <= pt) && (fPtBins[ptbin+1] > pt )) {
500  fInvMPP[ptbin]->Fill(InvariantMass(track1, track2));
501  }
502  }
503  }
504  if (tracktype == 2) {
505  for(Int_t ptbin(0); ptbin < fNPtBins; ptbin++) {
506  if ((fPtBins[ptbin] <= pt) && (fPtBins[ptbin+1] > pt )) {
507  fInvMNN[ptbin]->Fill(InvariantMass(track1, track2));
508  }
509  }
510  }
511 }
512 //_____________________________________________________________________________
513 template <typename T> void AliAnalysisTaskPhiFlow::SetNullCuts(T* event)
514 {
515  // Set null cuts
516  if (fDebug > 0) cout << " *** SetNullCuts() *** " << fCutsRP << endl;
517  fCutsRP->SetEvent(event, MCEvent());
519  fNullCuts->SetPtRange(+1, -1); // select nothing QUICK
520  fNullCuts->SetEtaRange(+1, -1); // select nothing VZERO
521  fNullCuts->SetEvent(event, MCEvent());
522 }
523 //_____________________________________________________________________________
525 {
526  // Prepare flow events
527  if (fDebug > 0 ) cout << " *** PrepareFlowEvent() *** " << endl;
531  fFlowEvent->DefineDeadZone(0, 0, 0, 0);
532 }
533 //_____________________________________________________________________________
535 {
536  // vzero event plane analysis using three subevents
537  if(fDebug > 0) cout << " ** VZEROSubEventAnalysis() *** " << endl;
538  if(!AliAnalysisTaskVnV0::IsPsiComputed()) { // AliAnalysisTaskVnV0 must be added to analysis que before this task !!!
539  if(fDebug > 0 ) cout << "Fatal error: unable to retrieve VZERO task output !!! Exiting ..." << endl;
540  return;
541  }
542  // retrieve data
544  for(Int_t i(0); i < 3; i++) if(abcPsi2[i] == 0) {
545  if(fDebug > 0) cout << " Warning: I've encountered 0 in one of the symmetry panes (TPC, VZERO) - skipping event !" << endl;
546  return;
547  }
548  // save info for resolution calculations
549  Float_t qaqb = TMath::Cos(2.*(abcPsi2[0]-abcPsi2[1])); // vzeroa - tpc
550  Float_t qaqc = TMath::Cos(2.*(abcPsi2[0]-abcPsi2[2])); // vzeroa - vzeroc
551  Float_t qbqc = TMath::Cos(2.*(abcPsi2[1]-abcPsi2[2])); // tpc - vzeroc
552  fSubEventDPhiv2->Fill(0.5, qaqb);
553  fSubEventDPhiv2->Fill(1.5, qaqc);
554  fSubEventDPhiv2->Fill(2.5, qbqc);
555  Float_t minv[31];
556  Float_t _dphi[30][fNPtBins][2]; //minv, pt, v0a-c
557  Int_t occurence[30][fNPtBins]; //minv, pt
558  for(Int_t mb(0); mb < 31; mb++) minv[mb] = 0.99 + mb * 0.0034;
559  for(Int_t i(0); i < 30; i++) for (Int_t j(0); j < fNPtBins; j++) for(Int_t k(0); k < 2; k ++) {
560  _dphi[i][j][k] = 0;
561  if(k==0) occurence[i][j] = 0;
562  }
563  for(Int_t iCand(0); iCand < fCandidates->GetEntriesFast(); iCand++) { // loop over unlike sign kaon pairs
564  AliFlowTrackSimple *track = dynamic_cast<AliFlowTrackSimple*>(fCandidates->At(iCand));
565  if(!track) {
566  if(fDebug > 1) cout << " --> dynamic_cast returned null-pointer, skipping candidate <-- " << endl;
567  continue;
568  }
569  for(Int_t mb(0); mb < 30; mb++) { // loop over massbands
570  if(track->Mass() <= minv[mb] || track->Mass() > minv[mb+1]) continue;
571  for(Int_t ptbin(0); ptbin < fNPtBins; ptbin++) { // loop over pt bins
572  if(track->Pt() <= fPtBins[ptbin] || track->Pt() > fPtBins[ptbin+1]) continue;
573  _dphi[mb][ptbin][0]+=TMath::Cos(2.*(track->Phi() - abcPsi2[0]));
574  _dphi[mb][ptbin][1]+=TMath::Cos(2.*(track->Phi() - abcPsi2[2]));
575  occurence[mb][ptbin]+=1;
576  }
577  }
578  for(Int_t mb(0); mb < 30; mb++) // write vn values to tprofiles
579  for(Int_t ptbin(0); ptbin < fNPtBins; ptbin++) {
580  if(occurence[mb][ptbin]==0) continue;
581  fV0Data[ptbin][0]->Fill(mb*0.0034+0.99+0.0017, _dphi[mb][ptbin][0]/(Float_t)occurence[mb][ptbin]);
582  fV0Data[ptbin][1]->Fill(mb*0.0034+0.99+0.0017, _dphi[mb][ptbin][1]/(Float_t)occurence[mb][ptbin]);
583  }
584  }
585 }
586 //_____________________________________________________________________________
588 {
589  // UserExec: called for each event. Commented where necessary
590  if(fDebug > 0 ) cout << " *** UserExec() *** " << endl;
591  TObjArray* MixingCandidates = 0x0; // init null pointer for event mixing
592  if(fEventMixing) {
593  MixingCandidates = new TObjArray();
594  MixingCandidates->SetOwner(kTRUE); // mixing candidates has ownership of objects in array
595  }
596  if (!fPIDResponse) {
597  if(fDebug > 0 ) cout << " Could not get PID response " << endl;
598  return;
599  }
600  fAOD = dynamic_cast<AliAODEvent*>(InputEvent()); // check for aod data type
601  if (fAOD) {
602  if (fCutsEvent && !fCutsEvent->PassesCuts(fAOD, 0x0)) return; // check for event cuts
603  InitializeBayesianPID(fAOD); // init event objects
604  SetNullCuts(fAOD);
605  PrepareFlowEvent(fAOD->GetNumberOfTracks());
606  fCandidates->SetLast(-1);
607  if(fIsMC) IsMC(); // launch mc stuff
608  if(fQA) fEventStats->Fill(0);
609  Int_t unTracks = fAOD->GetNumberOfTracks();
610  AliAODTrack* un[unTracks];
611  AliAODTrack* up[unTracks];
612  Int_t unp(0);
613  Int_t unn(0);
614  for (Int_t iTracks = 0; iTracks < unTracks; iTracks++) { // select analysis candidates
615  AliAODTrack* track = fAOD->GetTrack(iTracks);
616  if (fQA) {
617  if(track->Charge() > 0) {fEventStats->Fill(1); fPtP->Fill(track->Pt());}
618  if(track->Charge() < 0) {fEventStats->Fill(2); fPtN->Fill(track->Pt());}
619  }
620  if (IsKaon(track)) {
621  if(fEventMixing) MixingCandidates->Add(new AliPhiMesonHelperTrack(track->Eta(), track->Phi(), track->P(),
622  track->Px(), track->Py(), track->Pz(),
623  track->Pt(), track->Charge()));
624  if (track->Charge() > 0) {
625  up[unp] = track;
626  unp++;
627  if(fQA) {fEventStats->Fill(3);fPtKP->Fill(track->Pt());}
628  }
629  else if (track->Charge() < 0) {
630  un[unn] = track;
631  unn++;
632  if(fQA) {fEventStats->Fill(4); fPtKN->Fill(track->Pt());}
633  }
634  }
635  }
636  for (Int_t pTracks = 0; pTracks < unp ; pTracks++) { // perform analysis
637  for (Int_t nTracks = 0; nTracks < unn ; nTracks++) {
638 // if (fApplyDeltaDipCut && (!CheckDeltaDipAngle(up[pTracks], un[nTracks]))) continue;
639  if (fCandidateEtaPtCut && (!CheckCandidateEtaPtCut(up[pTracks], un[nTracks]))) continue;
640  PtSelector(0, up[pTracks], un[nTracks]);
641  Double_t pt = PhiPt(up[pTracks], un[nTracks]);
642  Double_t mass = InvariantMass(up[pTracks], un[nTracks]);
643  TVector3 a(up[pTracks]->Px(), up[pTracks]->Py(), up[pTracks]->Pz());
644  TVector3 b(un[nTracks]->Px(), un[nTracks]->Py(), up[pTracks]->Pz());
645  TVector3 c = a + b;
646  Double_t phi = c.Phi();
647  Double_t eta = c.Eta();
648  Int_t nIDs[2];
649  nIDs[0] = up[pTracks]->GetID();
650  nIDs[1] = un[nTracks]->GetID();
651  MakeTrack(mass, pt, phi, eta, 2, nIDs);
652  }
653  }
655  if (fDebug > 0) printf("I received %d candidates\n", fCandidates->GetEntriesFast()); // insert candidates into flow events
656  for (int iCand = 0; iCand != fCandidates->GetEntriesFast(); ++iCand) {
657  AliFlowCandidateTrack *cand = dynamic_cast<AliFlowCandidateTrack*>(fCandidates->At(iCand));
658  if (!cand) continue;
659  if (fDebug > 1) printf(" --> Checking at candidate %d with %d daughters: mass %f\n", iCand, cand->GetNDaughters(), cand->Mass());
660  for (int iDau = 0; iDau != cand->GetNDaughters(); ++iDau) {
661  if (fDebug>1) printf(" *** Daughter %d with fID %d ***", iDau, cand->GetIDDaughter(iDau));
662  for (int iRPs = 0; iRPs != fFlowEvent->NumberOfTracks(); ++iRPs) {
663  AliFlowTrack *iRP = dynamic_cast<AliFlowTrack*>(fFlowEvent->GetTrack(iRPs));
664  if (!iRP) continue;
665  if (!iRP->InRPSelection()) continue;
666  if (cand->GetIDDaughter(iDau) == iRP->GetID()) {
667  if (fDebug > 1) printf(" was in RP set");
668  iRP->SetForRPSelection(kFALSE);
670  }
671  }
672  if (fDebug > 1) printf("\n");
673  }
674  cand->SetForPOISelection(kTRUE);
675  fFlowEvent->InsertTrack(((AliFlowTrack*) cand));
676  }
677  if (fDebug > 0) printf("TPCevent %d\n", fFlowEvent->NumberOfTracks());
678  if(!fEventMixing) { // combinatorial background
679  for (Int_t pTracks = 0; pTracks < unp ; pTracks++) {
680  for (Int_t nTracks = pTracks + 1; nTracks < unp ; nTracks++) {
681 // if (fApplyDeltaDipCut && (!CheckDeltaDipAngle(up[pTracks], up[nTracks]))) continue;
682  if (fCandidateEtaPtCut && (!CheckCandidateEtaPtCut(up[pTracks], up[nTracks]))) continue;
683  PtSelector(1, up[pTracks], up[nTracks]);
684  }
685  }
686  for (Int_t nTracks = 0; nTracks < unn ; nTracks++) {
687  for (Int_t pTracks = nTracks + 1; pTracks < unn ; pTracks++) {
688 // if (fApplyDeltaDipCut && (!CheckDeltaDipAngle(un[nTracks], un[pTracks]))) continue;
689  if (fCandidateEtaPtCut && (!CheckCandidateEtaPtCut(un[nTracks], un[pTracks]))) continue;
690  PtSelector(2, un[nTracks], un[pTracks]);
691  }
692  }
693  }
694  if(fEventMixing) ReconstructionWithEventMixing(MixingCandidates);
695  PostData(1, fOutputList);
696  PostData(2, fFlowEvent);
697  }
698 }
699 //_____________________________________________________________________________
701 {
702  // skip the event selection for SE task (e.g. for MC productions)
704  // exec of task se will do event selection and call UserExec
705  else AliAnalysisTaskSE::Exec(c);
706 }
707 //_____________________________________________________________________________
709 {
710  // perform phi reconstruction with event mixing
711  if(fDebug > 0) cout << " *** ReconstructionWithEventMixing() *** " << endl;
712  AliEventPool* pool = fPoolManager->GetEventPool(fCentrality, fVertex);
713  if(!pool) AliFatal(Form("No pool found for centrality = %f, zVtx = %f", fCentrality, fVertex));
714  if(pool->IsReady() || pool->NTracksInPool() > fMixingParameters[1] / 10 || pool->GetCurrentNEvents() >= fMixingParameters[2]) {
715  Int_t nEvents = pool->GetCurrentNEvents();
716  if(fDebug > 0) cout << " --> " << nEvents << " events in mixing buffer ... " << endl;
717  for (Int_t iEvent(0); iEvent < nEvents; iEvent++) {
718  TObjArray* mixed_candidates = pool->GetEvent(iEvent);
719  if(!mixed_candidates) continue; // this should NEVER happen
720  Int_t bufferTracks = mixed_candidates->GetEntriesFast(); // buffered candidates
721  Int_t candidates = MixingCandidates->GetEntriesFast(); // mixing candidates
722  if(fDebug > 0) cout << Form(" - mixing %d tracks with %d buffered tracks from event %d ... ", candidates, bufferTracks, iEvent) << endl;
723  AliPhiMesonHelperTrack* buffer_un[bufferTracks]; // set values for buffered candidates
724  AliPhiMesonHelperTrack* buffer_up[bufferTracks];
725  Int_t buffer_unp(0);
726  Int_t buffer_unn(0);
727  AliPhiMesonHelperTrack* mix_un[candidates];// set values for mixing candidates
728  AliPhiMesonHelperTrack* mix_up[candidates];
729  Int_t mix_unp(0);
730  Int_t mix_unn(0);
731  for (Int_t iTracks = 0; iTracks < candidates; iTracks++) { // distinguish between k+ and k- for mixing candidates
732  AliPhiMesonHelperTrack* track = (AliPhiMesonHelperTrack*)MixingCandidates->At(iTracks);
733  if(!track) continue;
734  if (track->Charge() > 0) {
735  mix_up[mix_unp] = track;
736  mix_unp++;
737  }
738  else if (track->Charge() < 0 ) {
739  mix_un[mix_unn] = track;
740  mix_unn++;
741  }
742  }
743  for (Int_t iTracks = 0; iTracks < bufferTracks; iTracks++) { // distinguish between k+ and k- for buffered candidates
744  AliPhiMesonHelperTrack* track = (AliPhiMesonHelperTrack*)mixed_candidates->At(iTracks);
745  if(!track) continue;
746  if (track->Charge() > 0) {
747  buffer_up[buffer_unp] = track;
748  buffer_unp++;
749  }
750  else if (track->Charge() < 0 ) {
751  buffer_un[buffer_unn] = track;
752  buffer_unn++;
753  }
754  }
755  for (Int_t pMix = 0; pMix < mix_unp; pMix++) { // mix k+ (current event) k+ (buffer)
756  if(fDebug > 1 ) cout << Form("mixing current k+ track %d with", pMix);
757  if(!fTypeMixing) { // mix with like-sign kaons
758  for(Int_t pBuf = 0; pBuf < buffer_unp; pBuf++) {
759  if(fDebug > 1 ) cout << Form(" buffered k+ track %d", pBuf) << endl;
760 // if (fApplyDeltaDipCut && (!CheckDeltaDipAngle(mix_up[pMix], buffer_up[pBuf]))) continue;
761  if (fCandidateMinEta && (!CheckCandidateEtaPtCut(mix_up[pMix], buffer_up[pBuf]))) continue;
762  PtSelector(1, mix_up[pMix], buffer_up[pBuf]);
763  }
764  }
765  else if(fTypeMixing) { // mix with unlike-sign kaons
766  for(Int_t nBuf = 0; nBuf < buffer_unn; nBuf++) {
767  if(fDebug > 1 ) cout << Form(" buffered k- track %d", nBuf) << endl;
768 // if (fApplyDeltaDipCut && (!CheckDeltaDipAngle(mix_up[pMix], buffer_un[nBuf]))) continue;
769  if (fCandidateMinEta && (!CheckCandidateEtaPtCut(mix_up[pMix], buffer_un[nBuf]))) continue;
770  PtSelector(2, mix_up[pMix], buffer_un[nBuf]);
771  }
772  }
773  }
774  for (Int_t nMix = 0; nMix < mix_unn; nMix++) { // mix k- (current event) k- (buffer)
775  if(fDebug > 1 ) cout << Form("mixing current k- track %d with", nMix);
776  if(!fTypeMixing) { // mix with like-sign kaons
777  for(Int_t nBuf = 0; nBuf < buffer_unn; nBuf++) {
778  if(fDebug > 1 ) cout << Form(" buffered k- track %d", nBuf) << endl;
779 // if (fApplyDeltaDipCut && (!CheckDeltaDipAngle(mix_un[nMix], buffer_un[nBuf]))) continue;
780  if (fCandidateMinEta && (!CheckCandidateEtaPtCut(mix_un[nMix], buffer_un[nBuf]))) continue;
781  PtSelector(2, mix_un[nMix], buffer_un[nBuf]);
782  }
783  }
784  else if(fTypeMixing) { // mix with unlike-sign kaons
785  for(Int_t pBuf = 0; pBuf < buffer_unp; pBuf++) {
786  if(fDebug > 1 ) cout << Form(" buffered k+ track %d", pBuf) << endl;
787 // if (fApplyDeltaDipCut && (!CheckDeltaDipAngle(mix_un[nMix], buffer_up[pBuf]))) continue;
788  if (fCandidateMinEta && (!CheckCandidateEtaPtCut(mix_un[nMix], buffer_up[pBuf]))) continue;
789  PtSelector(1, mix_un[nMix], buffer_up[pBuf]);
790  }
791  }
792  }
793  } // end of mixed events loop
794  } // end of checking to see whether pool is filled correctly
795  pool->UpdatePool(MixingCandidates); // update pool with current mixing candidates (for next event)
796  if(fDebug > 0 ) pool->PrintInfo();
797 }
798 //_____________________________________________________________________________
800 {
801  // terminate
802  if(fDebug > 0) cout << " *** Terminate() *** " << endl;
803 }
804 //______________________________________________________________________________
806 {
807  // Construct Flow Candidate Track from two selected candidates
808  if(fDebug > 1 ) cout << " *** MakeTrack() *** " << endl;
809  Bool_t overwrite = kTRUE;
810  AliFlowCandidateTrack *sTrack = static_cast<AliFlowCandidateTrack*>(fCandidates->At(fCandidates->GetLast() + 1));
811  if (!sTrack) {
812  sTrack = new AliFlowCandidateTrack(); //deleted by fCandidates
813  overwrite = kFALSE;
814  }
815  else sTrack->ClearMe();
816  sTrack->SetMass(mass);
817  sTrack->SetPt(pt);
818  sTrack->SetPhi(phi);
819  sTrack->SetEta(eta);
820  for (Int_t iDau = 0; iDau != nDau; ++iDau) sTrack->AddDaughter(iID[iDau]);
821  sTrack->SetForPOISelection(kTRUE);
822  sTrack->SetForRPSelection(kFALSE);
823  if (overwrite) fCandidates->SetLast(fCandidates->GetLast() + 1);
824  else fCandidates->AddLast(sTrack);
825  return;
826 }
827 //_____________________________________________________________________________
829 {
830  // Fill QA histos for MC analysis
831  TClonesArray *arrayMC = 0;
832  if(fDebug > 0) cout << " -> Switching to MC mode <- " << endl;
833  // fill array with mc tracks
834  arrayMC = (TClonesArray*) fAOD->GetList()->FindObject(AliAODMCParticle::StdBranchName());
835  if (!arrayMC) AliFatal("Error: MC particles branch not found!\n");
836  for (Int_t iTracks = 0; iTracks < fAOD->GetNumberOfTracks(); iTracks++) {
837  AliAODTrack* track = fAOD->GetTrack(iTracks);
838  if(!IsKaon(track)) { // check for kaons
839  if(fDebug>1) cout << " Rejected track" << endl;
840  continue;
841  }
842  if (fDebug>1) cout << " Received MC kaon " << endl;
843  Double_t b[2] = { -99., -99.};
844  Double_t bCov[3] = { -99., -99., -99.};
845  AliAODTrack copy(*track);
846  if(!copy.PropagateToDCA(fAOD->GetPrimaryVertex(), fAOD->GetMagneticField(), 100., b, bCov)) return;
847  // find corresponding mc particle
848  AliAODMCParticle *partMC = (AliAODMCParticle*) arrayMC->At(TMath::Abs(track->GetLabel()));
849  if (!partMC) {
850  if(fDebug > 1) cout << "Cannot get MC particle" << endl;
851  continue;
852  }
853  // Check if it is primary, secondary from material or secondary from weak decay
854  Bool_t isPrimary = partMC->IsPhysicalPrimary();
855  Bool_t isSecondaryMaterial = kFALSE;
856  Bool_t isSecondaryWeak = kFALSE;
857  if (!isPrimary) {
858  Int_t mfl = -999, codemoth = -999;
859  Int_t indexMoth = partMC->GetMother();
860  if (indexMoth >= 0) { // is not fake
861  AliAODMCParticle* moth = (AliAODMCParticle*) arrayMC->At(indexMoth);
862  codemoth = TMath::Abs(moth->GetPdgCode());
863  mfl = Int_t(codemoth / TMath::Power(10, Int_t(TMath::Log10(codemoth))));
864  }
865  if (mfl == 3) isSecondaryWeak = kTRUE;
866  else isSecondaryMaterial = kTRUE;
867  }
868  if (isPrimary) {
869  fDCAPrim->Fill(track->Pt(), b[0]);
870  fDCAXYQA->Fill(b[0]);
871  fDCAZQA->Fill(b[1]);
872  }
873  if (isSecondaryWeak) fDCASecondaryWeak->Fill(track->Pt(), b[0]);
874  if (isSecondaryMaterial) fDCAMaterial->Fill(track->Pt(), b[0]);
875  }
876 }
877 //_____________________________________________________________________________
const Color_t cc[]
Definition: DrawKs.C:1
Bool_t PassesTPCbayesianCut(T *track) const
TProfile * fV0Data[18][2]
subevent resolution info for v2
double Double_t
Definition: External.C:58
void SetEta(Double_t eta)
TH2F * fDCASecondaryWeak
dca of primaries (mc) or kaons (data)
TH1F * fPtKP
QA histogram of p_t distribution of negative particles.
Definition: External.C:236
AliFlowEvent * fFlowEvent
pid response object
void ReconstructionWithEventMixing(TObjArray *MixingCandidates) const
Double_t PhiPt(const T *track_1, const T *track_2) const
Int_t GetNumberOfRPs() const
TH2F * fPIDk
QA histogram of TPC response of all charged particles.
Double_t mass
TH1F * fPtKN
QA histogram of p_t distribution of positive kaons.
TH2F * fDCAPrim
qa plot of dca z
void AddDaughter(Int_t value)
void PlotMultiplcities(const T *event) const
TH2F * fDCAMaterial
dca of weak (mc)
void ComputeProb(const AliESDtrack *t, Float_t)
TCanvas * c
Definition: TestFitELoss.C:172
TH1F * fPtSpectra[18]
like-sign kaon pairs
void SetMass(Double_t mass)
TH1F * fVZEROC
QA plot vzeroa multiplicity (all tracks in event)
Double_t InvariantMass(const T *track1, const T *track2) const
virtual Bool_t IsSelected(TObject *obj, Int_t id=-666)
void SetParamType(trackParameterType paramType)
void SetDetResponse(AliESDEvent *esd, Float_t centrality=-1.0, EStartTimeType_t flagStart=AliESDpid::kTOF_T0, Bool_t=kFALSE)
TH2F * fPIDTOF
QA histo of TOF repsonse charged particles.
void SetReferenceMultiplicity(Int_t m)
static Float_t GetPsi2TPC()
Double_t Mass() const
AliESDv0 * fV0
placeholder for the current kink
Bool_t InRPSelection() const
AliFlowBayesianPID * fBayesianResponse
AliFlowTrack * GetTrack(Int_t i)
UShort_t T(UShort_t m, UShort_t t)
Definition: RingBits.C:60
Bool_t PassesCuts(AliVEvent *event, AliMCEvent *mcevent)
void SetMC(Bool_t flag)
void SetForRPSelection(Bool_t b=kTRUE)
TH1F * fPt
QA plot of azimuthal distribution of tracks used for event plane estimation.
void SetPtRange(Float_t r1, Float_t r2)
Int_t GetNDaughters(void) const
Double_t Phi() const
virtual void Exec(Option_t *)
void SetNumberOfRPs(Int_t nr)
void Fill(AliFlowTrackCuts *rpCuts, AliFlowTrackCuts *poiCuts)
int Int_t
Definition: External.C:63
Bool_t PassesDCACut(AliAODTrack *track) const
void PrepareFlowEvent(Int_t iMulti)
float Float_t
Definition: External.C:68
Bool_t GetCurrentMask(Int_t idet) const
TH1F * fVZEROA
QA plot of eta distribution of tracks used for event plane estimation.
static AliFlowCommonConstants * GetMaster()
static Float_t GetPsi2V0C()
ClassImp(AliAnalysisTaskPhiFlow) ClassImp(AliPhiMesonHelperTrack) AliAnalysisTaskPhiFlow
TH1F * fEta
QA plot of p_t sectrum of tracks used for event plane estimation.
static Float_t GetPsi2V0A()
TH1F * fInvMNN[18]
unlike sign kaon pairs
AliEventPoolManager * InitializeEventMixing()
AliPIDResponse * fPIDResponse
void SetPhi(Double_t phi)
void DefineDeadZone(Double_t etaMin, Double_t etaMax, Double_t phiMin, Double_t phiMax)
void SetPt(Double_t pt)
TH1F * fDCAZQA
qa plot of dca xz
Int_t GetIDDaughter(Int_t value) const
Bool_t fUsePidResponse
profiles for vzero vn(minv)
TObjArray * fCandidates
PID response object.
AliFlowTrackCuts * fPOICuts
QA profile of centralty vs multiplicity.
TH1F * fInvMNP[18]
QA histo of TOF response kaons.
Bool_t CheckCandidateEtaPtCut(const T *track1, const T *track2) const
void SetEvent(AliVEvent *event, AliMCEvent *mcEvent=NULL)
void InitializeBayesianPID(AliAODEvent *event)
Float_t nEvents[nProd]
TH1F * fPtN
QA histogram of p_t distribution of positive particles.
TH1F * BookHistogram(const char *name)
AliFlowBayesianPID * fBayesianResponse
flow events (one for each inv mass band)
Double_t Pt() const
void SetNewTrackParam(Bool_t flag=kTRUE)
TH1F * InitPtSpectraHistograms(Float_t nmin, Float_t nmax)
void SetForPOISelection(Bool_t b=kTRUE)
TH1F * fDCAXYQA
qa dca of all charged particles
virtual Int_t Charge() const
TH2F * fNOPIDTOF
QA histogram of TPC response of kaons.
const char Option_t
Definition: External.C:48
Bool_t IsKaon(AliAODTrack *track) const
static Bool_t IsPsiComputed()
TH2F * fDCAAll
QA plot TPC multiplicity (tracks used for event plane estimation)
TList * fOutputList
event pool manager
bool Bool_t
Definition: External.C:53
virtual void Terminate(Option_t *)
TProfile * fSubEventDPhiv2
dca material (mc) all (data)
TH1F * BookPtHistogram(const char *name)
TH1F * fTPCM
QA plot vzeroc multiplicity (all tracks in event)
TH2F * BookPIDHistogram(const char *name, Bool_t TPC)
virtual void UserExec(Option_t *option)
void InsertTrack(AliFlowTrack *)
virtual void ClearFast()
AliEventPoolManager * fPoolManager
AOD oject.
TH1F * fInvMPP[18]
like-sign kaon pairs
void PtSelector(Int_t _track_type, const T *track_1, const T *track_2) const
TH2F * fNOPID
QA histogram of events that do not pass centrality cut.
void MakeTrack(Double_t, Double_t, Double_t, Double_t, Int_t, Int_t[], Double_t p=0., Double_t pz=0.) const
void SetEtaRange(Float_t r1, Float_t r2)
Int_t NumberOfTracks() const