Compatibility with the Root trunk
[u/mrichter/AliRoot.git] / PWGCF / EBYE / BalanceFunctions / AliAnalysisTaskTriggeredBF.cxx
1 #include <vector>\r
2 #include "TChain.h"\r
3 #include "TList.h"\r
4 #include "TCanvas.h"\r
5 #include "TLorentzVector.h"\r
6 #include "TGraphErrors.h"\r
7 #include "TH1F.h"\r
8 #include "TH2F.h"\r
9 #include "TArrayF.h"\r
10 #include "TF1.h"\r
11 #include "TRandom.h"\r
12 \r
13 #include "AliLog.h"\r
14 \r
15 #include "AliAnalysisTaskSE.h"\r
16 #include "AliAnalysisManager.h"\r
17 \r
18 #include "AliESDVertex.h"\r
19 #include "AliESDEvent.h"\r
20 #include "AliESDInputHandler.h"\r
21 #include "AliAODEvent.h"\r
22 #include "AliAODTrack.h"\r
23 #include "AliAODInputHandler.h"\r
24 #include "AliGenEventHeader.h"\r
25 #include "AliGenHijingEventHeader.h"\r
26 #include "AliMCEventHandler.h"\r
27 #include "AliMCEvent.h"\r
28 #include "AliMixInputEventHandler.h"\r
29 #include "AliStack.h"\r
30 \r
31 #include "TH2D.h"    \r
32 #include "AliTHn.h"             \r
33 \r
34 #include "AliEventPoolManager.h" \r
35 \r
36 #include "AliAnalysisTaskTriggeredBF.h"\r
37 #include "AliBalanceTriggered.h"\r
38 \r
39 \r
40 // Analysis task for the TriggeredBF code\r
41 // Authors: Panos.Christakoglou@nikhef.nl, m.weber@cern.ch\r
42 \r
43 using std::cout;\r
44 using std::endl;\r
45 using std::vector;\r
46 \r
47 ClassImp(AliAnalysisTaskTriggeredBF)\r
48 \r
49 //________________________________________________________________________\r
50 AliAnalysisTaskTriggeredBF::AliAnalysisTaskTriggeredBF(const char *name) \r
51 : AliAnalysisTaskSE(name), \r
52   fBalance(0),\r
53   fRunShuffling(kFALSE),\r
54   fShuffledBalance(0),\r
55   fRunMixing(kFALSE),\r
56   fMixingTracks(50000),\r
57   fMixedBalance(0),\r
58   fPoolMgr(0),\r
59   fList(0),\r
60   fListTriggeredBF(0),\r
61   fListTriggeredBFS(0),\r
62   fListTriggeredBFM(0),\r
63   fHistListPIDQA(0),\r
64   fHistEventStats(0),\r
65   fHistCentStats(0),\r
66   fHistTriggerStats(0),\r
67   fHistTrackStats(0),\r
68   fHistVx(0),\r
69   fHistVy(0),\r
70   fHistVz(0),\r
71   fHistClus(0),\r
72   fHistDCA(0),\r
73   fHistChi2(0),\r
74   fHistPt(0),\r
75   fHistEta(0),\r
76   fHistPhi(0),\r
77   fHistPhiBefore(0),\r
78   fHistPhiAfter(0),\r
79   fHistV0M(0),\r
80   fHistRefTracks(0),\r
81   fCentralityEstimator("V0M"),\r
82   fUseCentrality(kFALSE),\r
83   fCentralityPercentileMin(0.), \r
84   fCentralityPercentileMax(5.),\r
85   fImpactParameterMin(0.),\r
86   fImpactParameterMax(20.),\r
87   fUseMultiplicity(kFALSE),\r
88   fNumberOfAcceptedTracksMin(0),\r
89   fNumberOfAcceptedTracksMax(10000),\r
90   fHistNumberOfAcceptedTracks(0),\r
91   fUseOfflineTrigger(kFALSE),\r
92   fVxMax(0.3),\r
93   fVyMax(0.3),\r
94   fVzMax(10.),\r
95   nAODtrackCutBit(128),\r
96   fPtMin(0.3),\r
97   fPtMax(1.5),\r
98   fEtaMin(-0.8),\r
99   fEtaMax(-0.8),\r
100   fDCAxyCut(-1),\r
101   fDCAzCut(-1),\r
102   fTPCchi2Cut(-1),\r
103   fNClustersTPCCut(-1)\r
104 {\r
105   // Constructor\r
106   // Define input and output slots here\r
107   // Input slot #0 works with a TChain\r
108   DefineInput(0, TChain::Class());\r
109   // Output slot #0 writes into a TH1 container\r
110   DefineOutput(1, TList::Class());\r
111   DefineOutput(2, TList::Class());\r
112   DefineOutput(3, TList::Class());\r
113   DefineOutput(4, TList::Class());\r
114 }\r
115 \r
116 //________________________________________________________________________\r
117 AliAnalysisTaskTriggeredBF::~AliAnalysisTaskTriggeredBF() {\r
118 \r
119   // Destructor\r
120 \r
121 }\r
122 \r
123 //________________________________________________________________________\r
124 void AliAnalysisTaskTriggeredBF::UserCreateOutputObjects() {\r
125   // Create histograms\r
126   // Called once\r
127   if(!fBalance) {\r
128     fBalance = new AliBalanceTriggered();\r
129     fBalance->SetAnalysisLevel("AOD");\r
130   }\r
131   if(fRunShuffling) {\r
132     if(!fShuffledBalance) {\r
133       fShuffledBalance = new AliBalanceTriggered();\r
134       fShuffledBalance->SetAnalysisLevel("AOD");\r
135     }\r
136   }\r
137   if(fRunMixing) {\r
138     if(!fMixedBalance) {\r
139       fMixedBalance = new AliBalanceTriggered();\r
140       fMixedBalance->SetAnalysisLevel("AOD");\r
141     }\r
142   }\r
143 \r
144   //QA list\r
145   fList = new TList();\r
146   fList->SetName("listQA");\r
147   fList->SetOwner();\r
148 \r
149   //Balance Function list\r
150   fListTriggeredBF = new TList();\r
151   fListTriggeredBF->SetName("listTriggeredBF");\r
152   fListTriggeredBF->SetOwner();\r
153 \r
154   if(fRunShuffling) {\r
155     fListTriggeredBFS = new TList();\r
156     fListTriggeredBFS->SetName("listTriggeredBFShuffled");\r
157     fListTriggeredBFS->SetOwner();\r
158   }\r
159   if(fRunMixing) {\r
160     fListTriggeredBFM = new TList();\r
161     fListTriggeredBFM->SetName("listTriggeredBFMixed");\r
162     fListTriggeredBFM->SetOwner();\r
163   }\r
164   \r
165   \r
166   //Event stats.\r
167   TString gCutName[4] = {"Total","Offline trigger",\r
168                          "Vertex","Analyzed"};\r
169   fHistEventStats = new TH1F("fHistEventStats",\r
170                              "Event statistics;;N_{events}",\r
171                              4,0.5,4.5);\r
172   for(Int_t i = 1; i <= 4; i++)\r
173     fHistEventStats->GetXaxis()->SetBinLabel(i,gCutName[i-1].Data());\r
174   fList->Add(fHistEventStats);\r
175   \r
176   TString gCentName[9] = {"V0M","FMD","TRK","TKL","CL0","CL1","V0MvsFMD","TKLvsV0M","ZEMvsZDC"};\r
177   fHistCentStats = new TH2F("fHistCentStats",\r
178                             "Centrality statistics;;Cent percentile",\r
179                             9,-0.5,8.5,220,-5,105);\r
180   for(Int_t i = 1; i <= 9; i++)\r
181     fHistCentStats->GetXaxis()->SetBinLabel(i,gCentName[i-1].Data());\r
182   fList->Add(fHistCentStats);\r
183   \r
184   fHistTriggerStats = new TH1F("fHistTriggerStats","Trigger statistics;TriggerBit;N_{events}",130,0,130);\r
185   fList->Add(fHistTriggerStats);\r
186   \r
187   fHistTrackStats = new TH1F("fHistTrackStats","Event statistics;TrackFilterBit;N_{events}",130,0,130);\r
188   fList->Add(fHistTrackStats);\r
189 \r
190   fHistNumberOfAcceptedTracks = new TH1F("fHistNumberOfAcceptedTracks",";N_{acc.};Entries",4001,-0.5,4000.5);\r
191   fList->Add(fHistNumberOfAcceptedTracks);\r
192 \r
193   // Vertex distributions\r
194   fHistVx = new TH1F("fHistVx","Primary vertex distribution - x coordinate;V_{x} (cm);Entries",100,-0.5,0.5);\r
195   fList->Add(fHistVx);\r
196   fHistVy = new TH1F("fHistVy","Primary vertex distribution - y coordinate;V_{y} (cm);Entries",100,-0.5,0.5);\r
197   fList->Add(fHistVy);\r
198   fHistVz = new TH1F("fHistVz","Primary vertex distribution - z coordinate;V_{z} (cm);Entries",100,-20.,20.);\r
199   fList->Add(fHistVz);\r
200 \r
201   // QA histograms\r
202   fHistClus = new TH2F("fHistClus","# Cluster (TPC vs. ITS)",10,0,10,200,0,200);\r
203   fList->Add(fHistClus);\r
204   fHistChi2 = new TH1F("fHistChi2","Chi2/NDF distribution",200,0,10);\r
205   fList->Add(fHistChi2);\r
206   fHistDCA  = new TH2F("fHistDCA","DCA (xy vs. z)",400,-5,5,400,-5,5); \r
207   fList->Add(fHistDCA);\r
208   fHistPt   = new TH1F("fHistPt","p_{T} distribution",200,0,10);\r
209   fList->Add(fHistPt);\r
210   fHistEta  = new TH1F("fHistEta","#eta distribution",200,-2,2);\r
211   fList->Add(fHistEta);\r
212   fHistPhi  = new TH1F("fHistPhi","#phi distribution",200,-20,380);\r
213   fList->Add(fHistPhi);\r
214   fHistPhiBefore  = new TH1F("fHistPhiBefore","#phi distribution",200,0.,2*TMath::Pi());\r
215   fList->Add(fHistPhiBefore);\r
216   fHistPhiAfter  = new TH1F("fHistPhiAfter","#phi distribution",200,0.,2*TMath::Pi());\r
217   fList->Add(fHistPhiAfter);\r
218   fHistV0M  = new TH2F("fHistV0M","V0 Multiplicity C vs. A",500, 0, 20000, 500, 0, 20000);\r
219   fList->Add(fHistV0M);\r
220   TString gRefTrackName[6] = {"tracks","tracksPos","tracksNeg","tracksTPConly","clusITS0","clusITS1"};\r
221   fHistRefTracks  = new TH2F("fHistRefTracks","Nr of Ref tracks/event vs. ref track estimator;;Nr of tracks",6, 0, 6, 400, 0, 20000);\r
222   for(Int_t i = 1; i <= 6; i++)\r
223     fHistRefTracks->GetXaxis()->SetBinLabel(i,gRefTrackName[i-1].Data());\r
224   fList->Add(fHistRefTracks);\r
225 \r
226 \r
227 \r
228   // Balance function histograms\r
229   // Initialize histograms if not done yet\r
230   if(!fBalance->GetHistNp()){\r
231     AliWarning("Histograms not yet initialized! --> Will be done now");\r
232     AliWarning("--> Add 'gBalance->InitHistograms()' in your configBalanceFunction");\r
233     fBalance->InitHistograms();\r
234   }\r
235 \r
236   if(fRunShuffling) {\r
237     if(!fShuffledBalance->GetHistNp()) {\r
238       AliWarning("Histograms (shuffling) not yet initialized! --> Will be done now");\r
239       AliWarning("--> Add 'gBalance->InitHistograms()' in your configBalanceFunction");\r
240       fShuffledBalance->InitHistograms();\r
241     }\r
242   }\r
243 \r
244   if(fRunMixing) {\r
245     if(!fMixedBalance->GetHistNp()) {\r
246       AliWarning("Histograms (mixing) not yet initialized! --> Will be done now");\r
247       AliWarning("--> Add 'gBalance->InitHistograms()' in your configBalanceFunction");\r
248       fMixedBalance->InitHistograms();\r
249     }\r
250   }\r
251 \r
252   fListTriggeredBF->Add(fBalance->GetHistNp());\r
253   fListTriggeredBF->Add(fBalance->GetHistNn());\r
254   fListTriggeredBF->Add(fBalance->GetHistNpn());\r
255   fListTriggeredBF->Add(fBalance->GetHistNnn());\r
256   fListTriggeredBF->Add(fBalance->GetHistNpp());\r
257   fListTriggeredBF->Add(fBalance->GetHistNnp());\r
258   \r
259   if(fRunShuffling) {\r
260     fListTriggeredBFS->Add(fShuffledBalance->GetHistNp());\r
261     fListTriggeredBFS->Add(fShuffledBalance->GetHistNn());\r
262     fListTriggeredBFS->Add(fShuffledBalance->GetHistNpn());\r
263     fListTriggeredBFS->Add(fShuffledBalance->GetHistNnn());\r
264     fListTriggeredBFS->Add(fShuffledBalance->GetHistNpp());\r
265     fListTriggeredBFS->Add(fShuffledBalance->GetHistNnp());\r
266   }  \r
267 \r
268   if(fRunMixing) {\r
269     fListTriggeredBFM->Add(fMixedBalance->GetHistNp());\r
270     fListTriggeredBFM->Add(fMixedBalance->GetHistNn());\r
271     fListTriggeredBFM->Add(fMixedBalance->GetHistNpn());\r
272     fListTriggeredBFM->Add(fMixedBalance->GetHistNnn());\r
273     fListTriggeredBFM->Add(fMixedBalance->GetHistNpp());\r
274     fListTriggeredBFM->Add(fMixedBalance->GetHistNnp());\r
275   }  \r
276 \r
277 \r
278   // Event Mixing\r
279   Int_t trackDepth = fMixingTracks; \r
280   Int_t poolsize   = 1000;  // Maximum number of events, ignored in the present implemented of AliEventPoolManager\r
281    \r
282   Double_t centralityBins[] = {0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,15.,20.,25.,30.,35.,40.,45.,50.,55.,60.,65.,70.,75.,80.,90.,100.}; // SHOULD BE DEDUCED FROM CREATED ALITHN!!!\r
283   Double_t* centbins        = centralityBins;\r
284   Int_t nCentralityBins     = sizeof(centralityBins) / sizeof(Double_t) - 1;\r
285   \r
286   // bins for second buffer are shifted by 100 cm\r
287   Double_t vertexBins[] = {-10., -7., -5., -3., -1., 1., 3., 5., 7., 10.}; // SHOULD BE DEDUCED FROM CREATED ALITHN!!!\r
288   Double_t* vtxbins     = vertexBins;\r
289   Int_t nVertexBins     = sizeof(vertexBins) / sizeof(Double_t) - 1;\r
290   cout<<nCentralityBins<<" "<<nVertexBins<<endl;\r
291 \r
292   fPoolMgr = new AliEventPoolManager(poolsize, trackDepth, nCentralityBins, centbins, nVertexBins, vtxbins);\r
293 \r
294 \r
295   // Post output data.\r
296   PostData(1, fList);\r
297   PostData(2, fListTriggeredBF);\r
298   if(fRunShuffling) PostData(3, fListTriggeredBFS);\r
299   if(fRunMixing) PostData(4, fListTriggeredBFM);\r
300 }\r
301 \r
302 //________________________________________________________________________\r
303 void AliAnalysisTaskTriggeredBF::UserExec(Option_t *) {\r
304   // Main loop\r
305   // Called for each event\r
306 \r
307   TString gAnalysisLevel = fBalance->GetAnalysisLevel();\r
308   Float_t fCentrality = 0.;  \r
309 \r
310   // -------------------------------------------------------------                   \r
311   // AOD analysis (vertex and track cuts also here!!!!)\r
312   if(gAnalysisLevel == "AOD") {\r
313     AliVEvent* eventMain = dynamic_cast<AliVEvent*>(InputEvent()); \r
314     if(!eventMain) {\r
315       AliError("eventMain not available");\r
316       return;\r
317     }\r
318 \r
319     // check event cuts and fill event histograms\r
320     if((fCentrality = IsEventAccepted(eventMain)) < 0){\r
321       return;\r
322     }\r
323     \r
324     // get the accepted tracks in main event\r
325     TObjArray *tracksMain = GetAcceptedTracks(eventMain);\r
326 \r
327     // store charges of all accepted tracks, shuffle and reassign (two extra loops!)\r
328     TObjArray* tracksShuffled = NULL;\r
329     if(fRunShuffling){\r
330       tracksShuffled = GetShuffledTracks(tracksMain);\r
331     }\r
332     \r
333     // Event mixing --> UPDATE POOL IS MISSING!!!\r
334     if (fRunMixing)\r
335       {\r
336         // 1. First get an event pool corresponding in mult (cent) and\r
337         //    zvertex to the current event. Once initialized, the pool\r
338         //    should contain nMix (reduced) events. This routine does not\r
339         //    pre-scan the chain. The first several events of every chain\r
340         //    will be skipped until the needed pools are filled to the\r
341         //    specified depth. If the pool categories are not too rare, this\r
342         //    should not be a problem. If they are rare, you could lose`\r
343         //    statistics.\r
344         \r
345         // 2. Collect the whole pool's content of tracks into one TObjArray\r
346         //    (bgTracks), which is effectively a single background super-event.\r
347         \r
348         // 3. The reduced and bgTracks arrays must both be passed into\r
349         //    FillCorrelations(). Also nMix should be passed in, so a weight\r
350         //    of 1./nMix can be applied.\r
351         \r
352         AliEventPool* pool = fPoolMgr->GetEventPool(fCentrality, eventMain->GetPrimaryVertex()->GetZ());\r
353         \r
354         if (!pool){\r
355           AliFatal(Form("No pool found for centrality = %f, zVtx = %f", fCentrality, eventMain->GetPrimaryVertex()->GetZ()));\r
356         }\r
357         else{\r
358 \r
359         //pool->SetDebug(1);\r
360         \r
361           if (pool->IsReady() || pool->NTracksInPool() > fMixingTracks / 10 || pool->GetCurrentNEvents() >= 5){ \r
362             \r
363             \r
364             Int_t nMix = pool->GetCurrentNEvents();\r
365             //cout << "nMix = " << nMix << " tracks in pool = " << pool->NTracksInPool() << endl;\r
366             \r
367             //((TH1F*) fListOfHistos->FindObject("eventStat"))->Fill(2);\r
368             //((TH2F*) fListOfHistos->FindObject("mixedDist"))->Fill(centrality, pool->NTracksInPool());\r
369             //if (pool->IsReady())\r
370             //((TH1F*) fListOfHistos->FindObject("eventStat"))->Fill(3);\r
371             \r
372             // Fill mixed-event histos here  \r
373             for (Int_t jMix=0; jMix<nMix; jMix++) \r
374               {\r
375                 TObjArray* tracksMixed = pool->GetEvent(jMix);\r
376                 fMixedBalance->FillBalance(fCentrality,tracksMain,tracksMixed); \r
377               }\r
378           }\r
379           \r
380           // Update the Event pool\r
381           pool->UpdatePool(tracksMain);\r
382           //pool->PrintInfo();\r
383           \r
384         }//pool NULL check  \r
385       }//run mixing\r
386     \r
387     // calculate balance function\r
388     fBalance->FillBalance(fCentrality,tracksMain,NULL);\r
389     \r
390     // calculate shuffled balance function\r
391     if(fRunShuffling && tracksShuffled != NULL) {\r
392       fShuffledBalance->FillBalance(fCentrality,tracksShuffled,NULL);\r
393     }\r
394     \r
395   }//AOD analysis\r
396   else{\r
397     AliError("Triggered Balance Function analysis only for AODs!");\r
398   }\r
399 }     \r
400 \r
401 //________________________________________________________________________\r
402 Float_t AliAnalysisTaskTriggeredBF::IsEventAccepted(AliVEvent *event){\r
403   // Checks the Event cuts\r
404   // Fills Event statistics histograms\r
405   \r
406   // event selection done in AliAnalysisTaskSE::Exec() --> this is not used\r
407   fHistEventStats->Fill(1); //all events\r
408 \r
409   Bool_t isSelectedMain = kTRUE;\r
410   Float_t fCentrality = -1.;\r
411   TString gAnalysisLevel = fBalance->GetAnalysisLevel();\r
412   \r
413   if(fUseOfflineTrigger)\r
414     isSelectedMain = ((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected();\r
415   \r
416   if(isSelectedMain) {\r
417     fHistEventStats->Fill(2); //triggered events\r
418     \r
419     //Centrality stuff \r
420     if(fUseCentrality) {\r
421       if(gAnalysisLevel == "AOD") { //centrality in AOD header\r
422         AliAODHeader *header = (AliAODHeader*) event->GetHeader();\r
423         fCentrality = header->GetCentralityP()->GetCentralityPercentile(fCentralityEstimator.Data());\r
424 \r
425         // QA for centrality estimators\r
426         fHistCentStats->Fill(0.,header->GetCentralityP()->GetCentralityPercentile("V0M"));\r
427         fHistCentStats->Fill(1.,header->GetCentralityP()->GetCentralityPercentile("FMD"));\r
428         fHistCentStats->Fill(2.,header->GetCentralityP()->GetCentralityPercentile("TRK"));\r
429         fHistCentStats->Fill(3.,header->GetCentralityP()->GetCentralityPercentile("TKL"));\r
430         fHistCentStats->Fill(4.,header->GetCentralityP()->GetCentralityPercentile("CL0"));\r
431         fHistCentStats->Fill(5.,header->GetCentralityP()->GetCentralityPercentile("CL1"));\r
432         fHistCentStats->Fill(6.,header->GetCentralityP()->GetCentralityPercentile("V0MvsFMD"));\r
433         fHistCentStats->Fill(7.,header->GetCentralityP()->GetCentralityPercentile("TKLvsV0M"));\r
434         fHistCentStats->Fill(8.,header->GetCentralityP()->GetCentralityPercentile("ZEMvsZDC"));\r
435         \r
436         // centrality QA (V0M)\r
437         fHistV0M->Fill(event->GetVZEROData()->GetMTotV0A(), event->GetVZEROData()->GetMTotV0C());\r
438         \r
439         // centrality QA (reference tracks)\r
440         fHistRefTracks->Fill(0.,header->GetRefMultiplicity());\r
441         fHistRefTracks->Fill(1.,header->GetRefMultiplicityPos());\r
442         fHistRefTracks->Fill(2.,header->GetRefMultiplicityNeg());\r
443         fHistRefTracks->Fill(3.,header->GetTPConlyRefMultiplicity());\r
444         fHistRefTracks->Fill(4.,header->GetNumberOfITSClusters(0));\r
445         fHistRefTracks->Fill(5.,header->GetNumberOfITSClusters(1));\r
446         fHistRefTracks->Fill(6.,header->GetNumberOfITSClusters(2));\r
447         fHistRefTracks->Fill(7.,header->GetNumberOfITSClusters(3));\r
448         fHistRefTracks->Fill(8.,header->GetNumberOfITSClusters(4));\r
449       }\r
450     }\r
451     \r
452     \r
453     const AliVVertex *vertex = event->GetPrimaryVertex();\r
454     \r
455     if(vertex) {\r
456       Double32_t fCov[6];\r
457       vertex->GetCovarianceMatrix(fCov);\r
458       if(vertex->GetNContributors() > 0) {\r
459         if(fCov[5] != 0) {\r
460           fHistEventStats->Fill(3); //events with a proper vertex\r
461           if(TMath::Abs(vertex->GetX()) < fVxMax) {\r
462             if(TMath::Abs(vertex->GetY()) < fVyMax) {\r
463               if(TMath::Abs(vertex->GetZ()) < fVzMax) {\r
464                 fHistEventStats->Fill(4); //analyzed events\r
465                 fHistVx->Fill(vertex->GetX());\r
466                 fHistVy->Fill(vertex->GetY());\r
467                 fHistVz->Fill(vertex->GetZ());\r
468 \r
469                 // take only events inside centrality class\r
470                 if((fCentrality > fCentralityPercentileMin) && (fCentrality < fCentralityPercentileMax)){\r
471                   return fCentrality;           \r
472                 }//centrality class\r
473               }//Vz cut\r
474             }//Vy cut\r
475           }//Vx cut\r
476         }//proper vertex resolution\r
477       }//proper number of contributors\r
478     }//vertex object valid\r
479   }//triggered event \r
480   \r
481   // in all other cases return -1 (event not accepted)\r
482   return -1;\r
483 }\r
484 \r
485 //________________________________________________________________________\r
486 TObjArray* AliAnalysisTaskTriggeredBF::GetAcceptedTracks(AliVEvent *event){\r
487   // Returns TObjArray with tracks after all track cuts (only for AOD!)\r
488   // Fills QA histograms\r
489 \r
490   //output TObjArray holding all good tracks\r
491   TObjArray* tracksAccepted = new TObjArray;\r
492   tracksAccepted->SetOwner(kTRUE);\r
493 \r
494   Double_t v_charge;\r
495   Double_t v_eta;\r
496   Double_t v_phi;\r
497   Double_t v_pt;\r
498   \r
499   // Loop over tracks in event\r
500   for (Int_t iTracks = 0; iTracks < event->GetNumberOfTracks(); iTracks++) {\r
501     AliAODTrack* aodTrack = dynamic_cast<AliAODTrack *>(event->GetTrack(iTracks));\r
502     if (!aodTrack) {\r
503       AliError(Form("Could not receive track %d", iTracks));\r
504       continue;\r
505     }\r
506     \r
507     // AOD track cuts\r
508     \r
509     // For ESD Filter Information: ANALYSIS/macros/AddTaskESDfilter.C\r
510     // take only TPC only tracks \r
511     fHistTrackStats->Fill(aodTrack->GetFilterMap());\r
512     if(!aodTrack->TestFilterBit(nAODtrackCutBit)) continue;\r
513     \r
514     v_charge = aodTrack->Charge();\r
515     v_eta    = aodTrack->Eta();\r
516     v_phi    = aodTrack->Phi() * TMath::RadToDeg();\r
517     v_pt     = aodTrack->Pt();\r
518     \r
519     Float_t DCAxy = aodTrack->DCA();      // this is the DCA from global track (not exactly what is cut on)\r
520     Float_t DCAz  = aodTrack->ZAtDCA();   // this is the DCA from global track (not exactly what is cut on)\r
521     \r
522     \r
523     // Kinematics cuts from ESD track cuts\r
524     if( v_pt < fPtMin || v_pt > fPtMax)      continue;\r
525     if( v_eta < fEtaMin || v_eta > fEtaMax)  continue;\r
526     \r
527     // Extra DCA cuts (for systematic studies [!= -1])\r
528     if( fDCAxyCut != -1 && fDCAzCut != -1){\r
529       if(TMath::Sqrt((DCAxy*DCAxy)/(fDCAxyCut*fDCAxyCut)+(DCAz*DCAz)/(fDCAzCut*fDCAzCut)) > 1 ){\r
530         continue;  // 2D cut\r
531       }\r
532     }\r
533     \r
534     // Extra TPC cuts (for systematic studies [!= -1])\r
535     if( fTPCchi2Cut != -1 && aodTrack->Chi2perNDF() > fTPCchi2Cut){\r
536       continue;\r
537     }\r
538     if( fNClustersTPCCut != -1 && aodTrack->GetTPCNcls() < fNClustersTPCCut){\r
539       continue;\r
540     }\r
541     \r
542     // fill QA histograms\r
543     fHistClus->Fill(aodTrack->GetITSNcls(),aodTrack->GetTPCNcls());\r
544     fHistDCA->Fill(DCAz,DCAxy);\r
545     fHistChi2->Fill(aodTrack->Chi2perNDF());\r
546     fHistPt->Fill(v_pt);\r
547     fHistEta->Fill(v_eta);\r
548     fHistPhi->Fill(v_phi);\r
549     \r
550     // add the track to the TObjArray\r
551     tracksAccepted->Add(new AliBFBasicParticle(v_eta, v_phi, v_pt, v_charge));\r
552   }\r
553 \r
554   return tracksAccepted;\r
555 }\r
556 \r
557 //________________________________________________________________________\r
558 TObjArray* AliAnalysisTaskTriggeredBF::GetShuffledTracks(TObjArray *tracks){\r
559   // Clones TObjArray and returns it with tracks after shuffling the charges\r
560 \r
561   TObjArray* tracksShuffled = new TObjArray;\r
562   tracksShuffled->SetOwner(kTRUE);\r
563 \r
564   vector<Short_t> *chargeVector = new vector<Short_t>;   //original charge of accepted tracks \r
565 \r
566   for (Int_t i=0; i<tracks->GetEntriesFast(); i++)\r
567   {\r
568     AliVParticle* track = (AliVParticle*) tracks->At(i);\r
569     chargeVector->push_back(track->Charge());\r
570   }  \r
571  \r
572   random_shuffle(chargeVector->begin(), chargeVector->end());\r
573   \r
574   for(Int_t i = 0; i < tracks->GetEntriesFast(); i++){\r
575     AliVParticle* track = (AliVParticle*) tracks->At(i);\r
576     tracksShuffled->Add(new AliBFBasicParticle(track->Eta(), track->Phi(), track->Pt(),chargeVector->at(i)));\r
577   }\r
578 \r
579   delete chargeVector;\r
580    \r
581   return tracksShuffled;\r
582 }\r
583 \r
584 //________________________________________________________________________\r
585 void  AliAnalysisTaskTriggeredBF::FinishTaskOutput(){\r
586 \r
587   if (!fBalance) {\r
588     AliError("fBalance not available");\r
589     return;\r
590   }  \r
591   if(fRunShuffling) {\r
592     if (!fShuffledBalance) {\r
593       AliError("fShuffledBalance not available");\r
594       return;\r
595     }\r
596   }\r
597 \r
598 }\r
599 \r
600 //________________________________________________________________________\r
601 void AliAnalysisTaskTriggeredBF::Terminate(Option_t *) {\r
602   // Called once at the end of the query\r
603 \r
604   // not implemented ...\r
605 \r
606 }\r
607 \r
608 void AliAnalysisTaskTriggeredBF::UserExecMix(Option_t *)\r
609 {\r
610 \r
611   // not yet done for event mixing!\r
612   return;\r
613 \r
614 }\r
615 \r