]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGCF/Correlations/DPhi/AliAnalysisTaskPhiCorrelations.cxx
control histogram for resonance removal
[u/mrichter/AliRoot.git] / PWGCF / Correlations / DPhi / AliAnalysisTaskPhiCorrelations.cxx
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 /* $Id:$ */
17
18 #include <TROOT.h>
19 #include <TChain.h>
20 #include <TFile.h>
21 #include <TList.h>
22 #include <TMath.h>
23 #include <TTree.h>
24 #include <TH2F.h>
25 #include <TH3F.h>
26 #include <TRandom.h>
27
28 #include "AliAnalysisTaskPhiCorrelations.h"
29 #include "AliAnalyseLeadingTrackUE.h"
30 #include "AliUEHistograms.h"
31 #include "AliUEHist.h"
32
33 #include "AliAnalysisManager.h"
34 #include "AliAODHandler.h"
35 #include "AliAODInputHandler.h"
36 #include "AliAODMCParticle.h"
37 #include "AliInputEventHandler.h"
38 #include "AliLog.h"
39 #include "AliMCEventHandler.h"
40 #include "AliVParticle.h"
41 #include "AliCFContainer.h"
42
43 #include "AliESDEvent.h"
44 #include "AliESDInputHandler.h"
45 #include "AliMultiplicity.h"
46 #include "AliCentrality.h"
47 #include "AliStack.h"
48 #include "AliAODMCHeader.h"
49 #include "AliGenCocktailEventHeader.h"
50 #include "AliGenEventHeader.h"
51
52 #include "AliEventPoolManager.h"
53
54 #include "AliESDZDC.h"
55 #include "AliESDtrackCuts.h"
56
57
58 ////////////////////////////////////////////////////////////////////////
59 //
60 // Analysis class for azimuthal correlation studies
61 // Based on the UE task from Sara Vallero and Jan Fiete
62 //
63 // This class needs input AODs.
64 // The output is a list of analysis-specific containers.
65 //
66 // The AOD can be either connected to the InputEventHandler  
67 // for a chain of AOD files 
68 // or 
69 // to the OutputEventHandler
70 // for a chain of ESD files,
71 // in this case the class should be in the train after the jet-finder
72 //
73 //    Authors:
74 //    Jan Fiete Grosse-Oetringhaus
75 // 
76 ////////////////////////////////////////////////////////////////////////
77
78
79 ClassImp( AliAnalysisTaskPhiCorrelations )
80 ClassImp( AliDPhiBasicParticle )
81
82 //____________________________________________________________________
83 AliAnalysisTaskPhiCorrelations:: AliAnalysisTaskPhiCorrelations(const char* name):
84 AliAnalysisTask(name,""),
85 // general configuration
86 fDebug(0),
87 fMode(0),
88 fReduceMemoryFootprint(kFALSE),
89 fFillMixed(kTRUE),
90 fMixingTracks(50000),
91 fCompareCentralities(kFALSE),
92 fTwoTrackEfficiencyStudy(kFALSE),
93 fTwoTrackEfficiencyCut(0),
94 fUseVtxAxis(kFALSE),
95 fCourseCentralityBinning(kFALSE),
96 fSkipTrigger(kFALSE),
97 fInjectedSignals(kFALSE),
98 // pointers to UE classes
99 fAnalyseUE(0x0),
100 fHistos(0x0),
101 fHistosMixed(0),
102 fEfficiencyCorrection(0),
103 // handlers and events
104 fAOD(0x0),
105 fESD(0x0),
106 fArrayMC(0x0),
107 fInputHandler(0x0),
108 fMcEvent(0x0),
109 fMcHandler(0x0),
110 fPoolMgr(0x0),
111 // histogram settings
112 fListOfHistos(0x0), 
113 // event QA
114 fnTracksVertex(1),  // QA tracks pointing to principal vertex (= 3 default) 
115 fZVertex(7.),
116 fCentralityMethod("V0M"),
117 // track cuts
118 fTrackEtaCut(0.8),
119 fOnlyOneEtaSide(0),
120 fPtMin(0.5),
121 fFilterBit(0xFF),
122 fSelectBit(AliVEvent::kMB|AliVEvent::kUserDefined),
123 fUseChargeHadrons(kFALSE),
124 fSelectCharge(0),
125 fTriggerSelectCharge(0),
126 fTriggerRestrictEta(-1),
127 fEtaOrdering(kFALSE),
128 fCutConversions(kFALSE),
129 fCutResonances(kFALSE),
130 fFillOnlyStep0(kFALSE),
131 fSkipStep6(kFALSE),
132 fRejectCentralityOutliers(kFALSE),
133 fRemoveWeakDecays(kFALSE),
134 fFillpT(kFALSE)
135 {
136   // Default constructor
137   // Define input and output slots here
138   // Input slot #0 works with a TChain
139   DefineInput(0, TChain::Class());
140   // Output slot #0 writes into a TList container
141   DefineOutput(0, TList::Class());
142 }
143
144 AliAnalysisTaskPhiCorrelations::~AliAnalysisTaskPhiCorrelations() 
145
146   // destructor
147   
148   if (fListOfHistos  && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) 
149     delete fListOfHistos;
150 }
151
152 //____________________________________________________________________
153 void AliAnalysisTaskPhiCorrelations::ConnectInputData(Option_t* /*option*/)
154 {
155   
156   // Connect the input data  
157   if (fDebug > 1) AliInfo("ConnectInputData() ");
158   
159   // Since AODs can either be connected to the InputEventHandler
160   // or to the OutputEventHandler ( the AOD is created by a previus task in the train )
161   // we need to get the pointer to the AODEvent correctly.
162   
163   // Delta AODs are also accepted.
164   
165   TObject* handler = AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
166   
167   if( handler && handler->InheritsFrom("AliAODInputHandler") ) 
168   { // input AOD
169     fAOD = ((AliAODInputHandler*)handler)->GetEvent();
170     if (fDebug > 1) AliInfo(" ==== Tracks and Jets from AliAODInputHandler");
171   } 
172   else 
173   {  //output AOD
174     handler = AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler();
175     if (handler && handler->InheritsFrom("AliAODHandler") ) 
176     {
177       fAOD = ((AliAODHandler*)handler)->GetAOD();
178       if (fDebug > 1) AliInfo(" ==== Tracks and Jets from AliAODHandler");
179     } 
180     else 
181     {  // no AOD
182       AliWarning("I can't get any AOD Event Handler");
183     }
184   }
185   
186   if (handler && handler->InheritsFrom("AliESDInputHandler") ) 
187   { // input ESD
188     // pointer received per event in ::Exec
189     if (fDebug > 1) AliInfo(" ==== Tracks and Jets from AliESDInputHandler");
190   } 
191   
192   // Initialize common pointers
193   Initialize();
194 }
195
196 //____________________________________________________________________
197 void  AliAnalysisTaskPhiCorrelations::CreateOutputObjects()
198 {
199   // Create the output container
200   
201   if (fDebug > 1) AliInfo("CreateOutputObjects()");
202    
203   // Initialize class with main algorithms, event and track selection. 
204   fAnalyseUE = new AliAnalyseLeadingTrackUE();
205   fAnalyseUE->SetParticleSelectionCriteria(fFilterBit, fUseChargeHadrons, fTrackEtaCut, fPtMin);
206   fAnalyseUE->SetDebug(fDebug); 
207   fAnalyseUE->DefineESDCuts(fFilterBit);
208   fAnalyseUE->SetEventSelection(fSelectBit);
209
210   // Initialize output list of containers
211   if (fListOfHistos != NULL){
212         delete fListOfHistos;
213         fListOfHistos = NULL;
214         }
215   if (!fListOfHistos){
216         fListOfHistos = new TList();
217         fListOfHistos->SetOwner(kTRUE); 
218         }
219
220   // Initialize class to handle histograms 
221   TString histType = "4R";
222   if (fUseVtxAxis == 1)
223     histType = "5R";
224   else if (fUseVtxAxis == 2)
225     histType = "6R";
226   if (fCourseCentralityBinning)
227     histType += "C";
228   fHistos = new AliUEHistograms("AliUEHistogramsSame", histType);
229   fHistosMixed = new AliUEHistograms("AliUEHistogramsMixed", histType);
230   
231   fHistos->SetSelectCharge(fSelectCharge);
232   fHistosMixed->SetSelectCharge(fSelectCharge);
233   
234   fHistos->SetSelectTriggerCharge(fTriggerSelectCharge);
235   fHistosMixed->SetSelectTriggerCharge(fTriggerSelectCharge);
236
237   fHistos->SetTriggerRestrictEta(fTriggerRestrictEta);
238   fHistosMixed->SetTriggerRestrictEta(fTriggerRestrictEta);
239   
240   fHistos->SetOnlyOneEtaSide(fOnlyOneEtaSide);
241   fHistosMixed->SetOnlyOneEtaSide(fOnlyOneEtaSide);
242   
243   fHistos->SetEtaOrdering(fEtaOrdering);
244   fHistosMixed->SetEtaOrdering(fEtaOrdering);
245
246   fHistos->SetPairCuts(fCutConversions, fCutResonances);
247   fHistosMixed->SetPairCuts(fCutConversions, fCutResonances);
248   
249   fHistos->SetTrackEtaCut(fTrackEtaCut);
250   fHistosMixed->SetTrackEtaCut(fTrackEtaCut);
251   
252   if (fEfficiencyCorrection)
253   {
254     fHistos->SetEfficiencyCorrection(fEfficiencyCorrection);
255     fHistosMixed->SetEfficiencyCorrection((THnF*) fEfficiencyCorrection->Clone());
256   }
257   
258   // add histograms to list
259   fListOfHistos->Add(fHistos);
260   fListOfHistos->Add(fHistosMixed);
261   
262   fListOfHistos->Add(new TH2F("trackletsVsV0Cent", ";L1 clusters;v0 centrality", 100, -0.5, 9999.5, 101, 0, 101));
263   fListOfHistos->Add(new TH2F("processIDs", ";#Delta#phi;process id", 100, -0.5 * TMath::Pi(), 1.5 * TMath::Pi(), kPNoProcess + 1, -0.5, kPNoProcess + 0.5));
264   fListOfHistos->Add(new TH1F("eventStat", ";;events", 4, -0.5, 3.5));
265   fListOfHistos->Add(new TH2F("mixedDist", ";centrality;tracks;events", 101, 0, 101, 200, 0, fMixingTracks * 1.5));
266   fListOfHistos->Add(new TH1F("pids", ";pdg;tracks", 2001, -1000.5, 1000.5));
267   fListOfHistos->Add(new TH2F("referenceMultiplicity", ";centrality;tracks;events", 101, 0, 101, 200, 0, 200));
268   
269   PostData(0,fListOfHistos);
270   
271   // Add task configuration to output list 
272   AddSettingsTree();
273
274   // event mixing
275   Int_t trackDepth = fMixingTracks; 
276   Int_t poolsize   = 1000;  // Maximum number of events, ignored in the present implemented of AliEventPoolManager
277    
278   Int_t nCentralityBins  = fHistos->GetUEHist(2)->GetEventHist()->GetNBins(1);
279   Double_t* centralityBins = (Double_t*) fHistos->GetUEHist(2)->GetEventHist()->GetAxis(1, 0)->GetXbins()->GetArray();
280   
281   const Int_t kNZvtxBins  = 10+(1+10)*4;
282   // bins for further buffers are shifted by 100 cm
283   Double_t vertexBins[kNZvtxBins+1] = { -10,   -8,  -6,  -4,  -2,   0,   2,   4,   6,   8,  10, 
284                                        90,  92,  94,  96,  98, 100, 102, 104, 106, 108, 110, 
285                                       190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 
286                                       290, 292, 294, 296, 298, 300, 302, 304, 306, 308, 310, 
287                                       390, 392, 394, 396, 398, 400, 402, 404, 406, 408, 410 };
288
289   Int_t nZvtxBins  = kNZvtxBins;
290   Double_t* zvtxbin = vertexBins;
291
292   if (fMode == 0 && fHistos->GetUEHist(2)->GetEventHist()->GetNVar() > 2)
293   {
294     nZvtxBins = fHistos->GetUEHist(2)->GetEventHist()->GetNBins(2);
295     zvtxbin = (Double_t*) fHistos->GetUEHist(2)->GetEventHist()->GetAxis(2, 0)->GetXbins()->GetArray();
296   }
297
298   fPoolMgr = new AliEventPoolManager(poolsize, trackDepth, nCentralityBins, centralityBins, nZvtxBins, zvtxbin);
299 }
300
301 //____________________________________________________________________
302 void  AliAnalysisTaskPhiCorrelations::Exec(Option_t */*option*/)
303 {
304   // receive ESD pointer if we are not running AOD analysis
305   if (!fAOD)
306   {
307     AliVEventHandler* handler = AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
308     if (handler && handler->InheritsFrom("AliESDInputHandler"))
309       fESD = ((AliESDInputHandler*)handler)->GetEvent();
310   }
311
312   if (fMode)
313   {
314     // correction mode
315     
316     if (fMcHandler)
317       fMcEvent = fMcHandler->MCEvent();
318
319     if (fAOD)
320     {
321       // array of MC particles
322       fArrayMC = dynamic_cast<TClonesArray*>(fAOD->FindListObject(AliAODMCParticle::StdBranchName()));
323       if (!fArrayMC)
324         AliFatal("No array of MC particles found !!!");
325     }
326     
327     AnalyseCorrectionMode();
328   }
329   else AnalyseDataMode();
330 }
331
332 /******************** ANALYSIS METHODS *****************************/
333
334 //____________________________________________________________________
335 void  AliAnalysisTaskPhiCorrelations::AddSettingsTree()
336 {
337   //Write settings to output list
338   TTree *settingsTree   = new TTree("UEAnalysisSettings","Analysis Settings in UE estimation");
339   settingsTree->Branch("fnTracksVertex", &fnTracksVertex,"nTracksVertex/I");
340   settingsTree->Branch("fZVertex", &fZVertex,"ZVertex/D");
341   //settingsTree->Branch("fCentralityMethod", fCentralityMethod.Data(),"CentralityMethod/C");
342   settingsTree->Branch("fTrackEtaCut", &fTrackEtaCut, "TrackEtaCut/D");
343   settingsTree->Branch("fOnlyOneEtaSide", &fOnlyOneEtaSide,"OnlyOneEtaSide/I");
344   settingsTree->Branch("fPtMin", &fPtMin, "PtMin/D");
345   settingsTree->Branch("fFilterBit", &fFilterBit,"FilterBit/I");
346   settingsTree->Branch("fSelectBit", &fSelectBit,"EventSelectionBit/I");
347   settingsTree->Branch("fUseChargeHadrons", &fUseChargeHadrons,"UseChHadrons/O");
348   settingsTree->Branch("fSelectCharge", &fSelectCharge,"SelectCharge/I");
349   settingsTree->Branch("fTriggerSelectCharge", &fTriggerSelectCharge,"TriggerSelectCharge/I");
350   settingsTree->Branch("fTriggerRestrictEta", &fTriggerRestrictEta,"TriggerRestrictEta/D");
351   settingsTree->Branch("fEtaOrdering", &fEtaOrdering,"EtaOrdering/O");
352   settingsTree->Branch("fCutConversions", &fCutConversions,"CutConversions/O");
353   settingsTree->Branch("fCutResonances", &fCutResonances,"CutResonances/O");
354   settingsTree->Branch("fFillpT", &fFillpT,"FillpT/O");
355   settingsTree->Branch("fMixingTracks", &fMixingTracks,"MixingTracks/I");
356   settingsTree->Branch("fSkipTrigger", &fSkipTrigger,"SkipTrigger/O");
357   settingsTree->Branch("fInjectedSignals", &fInjectedSignals,"SkipTrigger/O");
358   settingsTree->Branch("fRejectCentralityOutliers", &fRejectCentralityOutliers,"RejectCentralityOutliers/O");
359   settingsTree->Branch("fRemoveWeakDecays", &fRemoveWeakDecays,"RemoveWeakDecays/O");
360   
361   settingsTree->Fill();
362   fListOfHistos->Add(settingsTree);
363 }  
364
365 //____________________________________________________________________
366 void  AliAnalysisTaskPhiCorrelations::AnalyseCorrectionMode()
367 {
368   // Run the analysis on MC to get the correction maps
369   //
370  
371   if ( fDebug > 3 ) AliInfo( " Processing event in Corrections mode ..." );
372   
373   Double_t centrality = 0;
374   
375   if (fCentralityMethod.Length() > 0)
376   {
377     AliCentrality *centralityObj = 0;
378     if (fAOD)
379       centralityObj = fAOD->GetHeader()->GetCentralityP();
380     else if (fESD)
381       centralityObj = fESD->GetCentrality();
382     
383     if (centralityObj)
384     {
385       centrality = centralityObj->GetCentralityPercentileUnchecked(fCentralityMethod);
386       AliInfo(Form("Centrality is %f", centrality));
387     }
388     else
389     {
390       Printf("WARNING: Centrality object is 0");
391       centrality = -1;
392      }
393   }
394   
395   // Support for ESD and AOD based analysis
396   AliVEvent* inputEvent = fAOD;
397   if (!inputEvent)
398     inputEvent = fESD;
399
400   Float_t bSign = 0;
401   
402   if (inputEvent)
403   {
404     fHistos->SetRunNumber(inputEvent->GetRunNumber());
405     bSign = (inputEvent->GetMagneticField() > 0) ? 1 : -1;
406   }
407     
408   TObject* mc = fArrayMC;
409   if (!mc)
410     mc = fMcEvent;
411   
412   // count all events
413   fHistos->FillEvent(centrality, -1);
414   
415   if (centrality < 0)
416     return;
417
418   // Only consider MC events within the vtx-z region used also as cut on the reconstructed vertex
419   TObject* vertexSupplier = fMcEvent;
420   if (fAOD) // AOD
421     vertexSupplier = fAOD->FindListObject(AliAODMCHeader::StdBranchName());
422     
423   if (!fAnalyseUE->VertexSelection(vertexSupplier, 0, fZVertex)) 
424     return;
425   
426   Float_t zVtx = 0;
427   if (fAOD)
428     zVtx = ((AliAODMCHeader*) vertexSupplier)->GetVtxZ();
429   else
430     zVtx = fMcEvent->GetPrimaryVertex()->GetZ();
431   Float_t weight = 1;
432   if (fFillpT)
433     weight = -1;
434   
435   // For productions with injected signals, figure out above which label to skip particles/tracks
436   Int_t skipParticlesAbove = 0;
437   if (fInjectedSignals)
438   {
439     AliGenEventHeader* eventHeader = 0;
440     Int_t headers = 0;
441
442     if (fMcEvent)
443     {
444       // ESD
445       AliHeader* header = (AliHeader*) fMcEvent->Header();
446       if (!header)
447         AliFatal("fInjectedSignals set but no MC header found");
448         
449       AliGenCocktailEventHeader* cocktailHeader = dynamic_cast<AliGenCocktailEventHeader*> (header->GenEventHeader());
450       if (!cocktailHeader)
451       {
452         header->Dump();
453         AliFatal("fInjectedSignals set but no MC cocktail header found");
454       }
455
456       headers = cocktailHeader->GetHeaders()->GetEntries();
457       eventHeader = dynamic_cast<AliGenEventHeader*> (cocktailHeader->GetHeaders()->First());
458     }
459     else
460     {
461       // AOD
462       AliAODMCHeader* header = (AliAODMCHeader*) fAOD->GetList()->FindObject(AliAODMCHeader::StdBranchName());
463       if (!header)
464         AliFatal("fInjectedSignals set but no MC header found");
465       
466       headers = header->GetNCocktailHeaders();
467       eventHeader = header->GetCocktailHeader(0);
468     }
469     
470     if (!eventHeader)
471     {
472       // We avoid AliFatal here, because the AOD productions sometimes have events where the MC header is missing 
473       // (due to unreadable Kinematics) and we don't want to loose the whole job because of a few events
474       AliError("First event header not found. Skipping this event.");
475       fHistos->FillEvent(centrality, AliUEHist::kCFStepAnaTopology);
476       return;
477     }
478     
479     skipParticlesAbove = eventHeader->NProduced();
480     AliInfo(Form("Injected signals in this event (%d headers). Keeping events of %s. Will skip particles/tracks above %d.", headers, eventHeader->ClassName(), skipParticlesAbove));
481   }
482   
483   // Get MC primaries
484   TObjArray* tmpList = fAnalyseUE->GetAcceptedParticles(mc, 0, kTRUE, -1, kTRUE);
485   if (fInjectedSignals)
486     fAnalyseUE->RemoveInjectedSignals(tmpList, mc, skipParticlesAbove);
487   if (fRemoveWeakDecays)
488     fAnalyseUE->RemoveWeakDecays(tmpList, mc);
489   TObjArray* tracksMC = CloneAndReduceTrackList(tmpList);
490   delete tmpList;
491   
492   /*
493   if (fAOD)
494   {
495     for (Int_t i=0; i<fArrayMC->GetEntriesFast(); i++)
496       ((TH1F*) fListOfHistos->FindObject("pids"))->Fill(((AliAODMCParticle*) fArrayMC->At(i))->PdgCode());
497   }
498   else
499   {
500     for (Int_t i=0; i<fMcEvent->GetNumberOfTracks(); i++)
501       ((TH1F*) fListOfHistos->FindObject("pids"))->Fill(fMcEvent->GetTrack(i)->PdgCode());
502   }
503   */
504   
505   if (fFillOnlyStep0)
506     zVtx = 0;
507   
508   // (MC-true all particles)
509   // STEP 0
510   fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepAll, tracksMC, 0, weight);
511   
512   // mixed event
513   if (fFillMixed)
514   {
515     AliEventPool* pool = fPoolMgr->GetEventPool(centrality, zVtx);
516     //pool->PrintInfo();
517     if (pool->IsReady() || pool->NTracksInPool() > fMixingTracks / 10 || pool->GetCurrentNEvents() >= 5) 
518       for (Int_t jMix=0; jMix<pool->GetCurrentNEvents(); jMix++) 
519         fHistosMixed->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepAll, tracksMC, pool->GetEvent(jMix), 1.0 / pool->GetCurrentNEvents(), (jMix == 0));
520     pool->UpdatePool(CloneAndReduceTrackList(tracksMC));
521   }
522   
523 //   Printf("trigger: %d", ((AliInputEventHandler*)fInputHandler)->IsEventSelected());
524   
525   // Trigger selection ************************************************
526   if (!fFillOnlyStep0 && (fSkipTrigger || fAnalyseUE->TriggerSelection(fInputHandler)))
527   {  
528     // (MC-true all particles)
529     // STEP 1
530     if (!fReduceMemoryFootprint)
531       fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepTriggered, tracksMC, 0, weight);
532     else
533       fHistos->FillEvent(centrality, AliUEHist::kCFStepTriggered);
534       
535     if (!inputEvent) {
536       AliFatal("UNEXPECTED: inputEvent is 0. Trigger selection should have failed");
537       return;
538     }
539     
540     // Vertex selection *************************************************
541     if (fAnalyseUE->VertexSelection(inputEvent, fnTracksVertex, fZVertex))
542     {
543       // fill here for tracking efficiency
544       // loop over particle species
545       
546       for (Int_t particleSpecies = 0; particleSpecies < 4; particleSpecies++)
547       {
548         TObjArray* primMCParticles = fAnalyseUE->GetAcceptedParticles(mc, 0x0, kTRUE, particleSpecies, kTRUE);
549         TObjArray* primRecoTracksMatched = fAnalyseUE->GetAcceptedParticles(inputEvent, mc, kTRUE, particleSpecies, kTRUE);
550         TObjArray* allRecoTracksMatched = fAnalyseUE->GetAcceptedParticles(inputEvent, mc, kFALSE, particleSpecies, kTRUE);
551         
552         if (fInjectedSignals)
553         {
554           fAnalyseUE->RemoveInjectedSignals(primMCParticles, mc, skipParticlesAbove);
555           fAnalyseUE->RemoveInjectedSignals(primRecoTracksMatched, mc, skipParticlesAbove);
556           fAnalyseUE->RemoveInjectedSignals(allRecoTracksMatched, mc, skipParticlesAbove);
557         }
558         
559         if (fRemoveWeakDecays)
560         {
561           fAnalyseUE->RemoveWeakDecays(primMCParticles, mc);
562           fAnalyseUE->RemoveWeakDecays(primRecoTracksMatched, mc);
563           fAnalyseUE->RemoveWeakDecays(allRecoTracksMatched, mc);
564         }
565       
566         fHistos->FillTrackingEfficiency(primMCParticles, primRecoTracksMatched, allRecoTracksMatched, 0, particleSpecies, centrality, zVtx);
567         
568 //      Printf("%d --> %d %d %d", particleSpecies, primMCParticles->GetEntries(), primRecoTracksMatched->GetEntries(), allRecoTracksMatched->GetEntries());
569
570         delete primMCParticles;
571         delete primRecoTracksMatched;
572         delete allRecoTracksMatched;
573       }
574       TObjArray* fakeParticles = fAnalyseUE->GetFakeParticles(inputEvent, mc, kFALSE, -1, kTRUE);
575       if (fInjectedSignals)
576       {
577         fAnalyseUE->RemoveInjectedSignals((TObjArray*) fakeParticles->At(0), mc, skipParticlesAbove);
578         fAnalyseUE->RemoveInjectedSignals((TObjArray*) fakeParticles->At(1), mc, skipParticlesAbove);
579       }
580       if (fRemoveWeakDecays)
581       {
582         fAnalyseUE->RemoveWeakDecays((TObjArray*) fakeParticles->At(0), mc);
583         fAnalyseUE->RemoveWeakDecays((TObjArray*) fakeParticles->At(1), mc);
584       }
585       fHistos->FillTrackingEfficiency(0, 0, 0, (TObjArray*) fakeParticles->At(2), -1, centrality, zVtx);
586       fHistos->FillFakePt(fakeParticles, centrality);
587 //       Printf(">>>>> %d %d %d fakes", ((TObjArray*) fakeParticles->At(0))->GetEntriesFast(), ((TObjArray*) fakeParticles->At(1))->GetEntriesFast(), ((TObjArray*) fakeParticles->At(2))->GetEntriesFast());
588       delete fakeParticles;
589     
590       // (MC-true all particles)
591       // STEP 2
592       if (!fReduceMemoryFootprint)
593         fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepVertex, tracksMC, 0, weight);
594       else
595         fHistos->FillEvent(centrality, AliUEHist::kCFStepVertex);
596       
597       // Get MC primaries that match reconstructed track
598       TObjArray* tracksRecoMatchedPrim = fAnalyseUE->GetAcceptedParticles(inputEvent, mc, kTRUE, -1, kTRUE);
599       if (fInjectedSignals)
600         fAnalyseUE->RemoveInjectedSignals(tracksRecoMatchedPrim, mc, skipParticlesAbove);
601       if (fRemoveWeakDecays)
602         fAnalyseUE->RemoveWeakDecays(tracksRecoMatchedPrim, mc);
603       
604       // (RECO-matched (quantities from MC particle) primary particles)
605       // STEP 4
606       fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepTrackedOnlyPrim, tracksRecoMatchedPrim, 0, weight);
607
608       // mixed event
609       if (fFillMixed)
610       {
611         AliEventPool* pool = fPoolMgr->GetEventPool(centrality, zVtx + 200);
612         //pool->PrintInfo();
613         if (pool->IsReady() || pool->NTracksInPool() > fMixingTracks / 10 || pool->GetCurrentNEvents() >= 5) 
614           for (Int_t jMix=0; jMix<pool->GetCurrentNEvents(); jMix++) 
615             fHistosMixed->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepTrackedOnlyPrim, tracksRecoMatchedPrim, pool->GetEvent(jMix), 1.0 / pool->GetCurrentNEvents(), (jMix == 0));
616         pool->UpdatePool(CloneAndReduceTrackList(tracksRecoMatchedPrim));
617       }
618       
619       // Get MC primaries + secondaries that match reconstructed track
620       TObjArray* tracksRecoMatchedAll = fAnalyseUE->GetAcceptedParticles(inputEvent, mc, kFALSE, -1, kTRUE);
621       if (fInjectedSignals)
622         fAnalyseUE->RemoveInjectedSignals(tracksRecoMatchedAll, mc, skipParticlesAbove);
623       if (fRemoveWeakDecays)
624         fAnalyseUE->RemoveWeakDecays(tracksRecoMatchedAll, mc);
625      
626       // (RECO-matched (quantities from MC particle) all particles)
627       // STEP 5
628       fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepTracked, tracksRecoMatchedAll, 0, weight);
629       
630       // mixed event
631       if (fFillMixed)
632       {
633         AliEventPool* pool = fPoolMgr->GetEventPool(centrality, zVtx + 300);
634         //pool->PrintInfo();
635         if (pool->IsReady() || pool->NTracksInPool() > fMixingTracks / 10 || pool->GetCurrentNEvents() >= 5) 
636           for (Int_t jMix=0; jMix<pool->GetCurrentNEvents(); jMix++) 
637             fHistosMixed->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepTracked, tracksRecoMatchedAll, pool->GetEvent(jMix), 1.0 / pool->GetCurrentNEvents(), (jMix == 0));
638         pool->UpdatePool(CloneAndReduceTrackList(tracksRecoMatchedAll));
639       }
640       
641       // Get RECO tracks
642       TObjArray* tracks = fAnalyseUE->GetAcceptedParticles(inputEvent, 0, kTRUE, -1, kTRUE);
643       if (fInjectedSignals)
644         fAnalyseUE->RemoveInjectedSignals(tracks, mc, skipParticlesAbove);
645       if (fRemoveWeakDecays)
646         fAnalyseUE->RemoveWeakDecays(tracks, mc);
647      
648       // (RECO all tracks)
649       // STEP 6
650       if (!fSkipStep6)
651         fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepReconstructed, tracks, 0, weight);
652       
653       // two track cut, STEP 8
654       if (fTwoTrackEfficiencyCut > 0)
655         fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepBiasStudy, tracks, 0, weight, kTRUE, kTRUE, bSign, fTwoTrackEfficiencyCut);
656
657       // apply correction efficiency, STEP 10
658       if (fEfficiencyCorrection)
659       {
660         // with or without two track efficiency depending on if fTwoTrackEfficiencyCut is set
661         Bool_t twoTrackCut = (fTwoTrackEfficiencyCut > 0);
662         
663         fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepCorrected, tracks, 0, weight, kTRUE, twoTrackCut, bSign, fTwoTrackEfficiencyCut, kTRUE);
664       }
665
666       // mixed event
667       if (fFillMixed)
668       {
669         AliEventPool* pool2 = fPoolMgr->GetEventPool(centrality, zVtx + 100);
670         //pool2->PrintInfo();
671         if (pool2->IsReady() || pool2->NTracksInPool() > fMixingTracks / 10 || pool2->GetCurrentNEvents() >= 5) 
672         {
673           for (Int_t jMix=0; jMix<pool2->GetCurrentNEvents(); jMix++)
674           {
675             // STEP 6
676             if (!fSkipStep6)
677               fHistosMixed->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepReconstructed, tracks, pool2->GetEvent(jMix), 1.0 / pool2->GetCurrentNEvents(), (jMix == 0));
678             
679             // two track cut, STEP 8
680             if (fTwoTrackEfficiencyCut > 0)
681               fHistosMixed->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepBiasStudy, tracks, pool2->GetEvent(jMix), 1.0 / pool2->GetCurrentNEvents(), (jMix == 0), kTRUE, bSign, fTwoTrackEfficiencyCut);
682             
683             // apply correction efficiency, STEP 10
684             if (fEfficiencyCorrection)
685             {
686               // with or without two track efficiency depending on if fTwoTrackEfficiencyCut is set
687               Bool_t twoTrackCut = (fTwoTrackEfficiencyCut > 0);
688               
689               fHistosMixed->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepCorrected, tracks, pool2->GetEvent(jMix), 1.0 / pool2->GetCurrentNEvents(), (jMix == 0), twoTrackCut, bSign, fTwoTrackEfficiencyCut, kTRUE);
690             }
691           }
692         }
693         pool2->UpdatePool(CloneAndReduceTrackList(tracks));
694       }
695       
696       if (0 && !fReduceMemoryFootprint)
697       {
698         // make list of secondaries (matched with MC)
699         TObjArray* tracksRecoMatchedSecondaries = new TObjArray;
700         for (Int_t i=0; i<tracksRecoMatchedAll->GetEntriesFast(); i++)
701           if (((AliAODMCParticle*)tracksRecoMatchedAll->At(i))->IsPhysicalPrimary() == kFALSE)
702             tracksRecoMatchedSecondaries->Add(tracksRecoMatchedAll->At(i));
703       
704         // Study: Use only secondaries as trigger particles and plot the correlation vs. all particles; store in step 9
705         fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepBiasStudy2, tracksRecoMatchedSecondaries, tracksRecoMatchedAll, weight);
706         
707         // Study: Use only primaries as trigger particles and plot the correlation vs. secondaries; store in step 8
708         fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepBiasStudy, tracksRecoMatchedPrim, tracksRecoMatchedSecondaries, weight);
709       
710         // plot delta phi vs process id of secondaries
711         // trigger particles: primaries in 4 < pT < 10
712         // associated particles: secondaries in 1 < pT < 10
713         
714         for (Int_t i=0; i<tracksRecoMatchedPrim->GetEntriesFast(); i++)
715         {
716           AliVParticle* triggerParticle = (AliVParticle*) tracksRecoMatchedPrim->At(i);
717           
718           if (triggerParticle->Pt() < 4 || triggerParticle->Pt() > 10)
719             continue;
720           
721           for (Int_t j=0; j<tracksRecoMatchedSecondaries->GetEntriesFast(); j++)
722           {
723             AliAODMCParticle* particle = (AliAODMCParticle*) tracksRecoMatchedSecondaries->At(j);
724             
725             if (particle->Pt() < 1 || particle->Pt() > 10)
726               continue;
727             
728             if (particle->Pt() > triggerParticle->Pt())
729               continue;
730               
731             Double_t deltaPhi = triggerParticle->Phi() - particle->Phi();
732             if (deltaPhi > 1.5 * TMath::Pi()) 
733               deltaPhi -= TMath::TwoPi();
734             if (deltaPhi < -0.5 * TMath::Pi())
735               deltaPhi += TMath::TwoPi();
736               
737             Int_t processID = fMcEvent->Stack()->Particle(particle->GetLabel())->GetUniqueID();
738               
739             ((TH2F*) fListOfHistos->FindObject("processIDs"))->Fill(deltaPhi, processID);
740           }
741         }
742         
743         delete tracksRecoMatchedSecondaries;
744       }
745   
746       delete tracksRecoMatchedPrim;
747       delete tracksRecoMatchedAll;
748       delete tracks;
749     }
750   }
751   
752   delete tracksMC;
753 }
754
755 //____________________________________________________________________
756 void  AliAnalysisTaskPhiCorrelations::AnalyseDataMode()
757 {
758
759   // Run the analysis on DATA or MC to get raw distributions
760  
761   if ( fDebug > 3 ) AliInfo( " Processing event in Data mode ..." );
762
763   ((TH1F*) fListOfHistos->FindObject("eventStat"))->Fill(0);
764
765   if (!fInputHandler)
766     return;
767     
768   // skip not selected events here (the AOD is not updated for those)
769   if (!fSkipTrigger && !(fInputHandler->IsEventSelected() & fSelectBit))
770     return;
771
772   // Support for ESD and AOD based analysis
773   AliVEvent* inputEvent = fAOD;
774   if (!inputEvent)
775     inputEvent = fESD;
776
777   Double_t centrality = 0;
778   
779   AliCentrality *centralityObj = 0;
780   if (fCentralityMethod.Length() > 0)
781   {
782     if (fCentralityMethod == "ZNA_MANUAL")
783     {
784       Bool_t zna = kFALSE;
785       for(Int_t j = 0; j < 4; ++j) {
786         if (fESD->GetZDCData()->GetZDCTDCData(12,j) != 0) {
787           zna = kTRUE;
788         }
789       }
790
791 //       Printf("%d %f", zna, fZNAtower[0]);
792       if (zna)
793       {
794         // code from Chiara O (23.10.12)
795         const Double_t *fZNAtower = fESD->GetZDCData()->GetZN2TowerEnergy();
796         Float_t znacut[4] = {681., 563., 413., 191.};
797         
798         if(fZNAtower[0]>znacut[0]) centrality = 1;
799         else if(fZNAtower[0]>znacut[1]) centrality = 21;
800         else if(fZNAtower[0]>znacut[2]) centrality = 41;
801         else if(fZNAtower[0]>znacut[3]) centrality = 61;
802         else centrality = 81;
803       }
804       else
805         centrality = -1;
806     }
807     else if (fCentralityMethod == "TRACKS_MANUAL")
808     {
809       // for pp
810       TObjArray* tracks = fAnalyseUE->GetAcceptedParticles(inputEvent, 0, kTRUE, -1, kTRUE);
811       centrality = tracks->GetEntriesFast();
812       if (centrality > 40)
813         centrality = 41;
814 //       Printf("%d %f", tracks->GetEntriesFast(), centrality);
815       delete tracks;
816     }
817     else
818     {
819       if (fAOD)
820         centralityObj = fAOD->GetHeader()->GetCentralityP();
821       else if (fESD)
822         centralityObj = fESD->GetCentrality();
823       
824       if (centralityObj)
825         centrality = centralityObj->GetCentralityPercentile(fCentralityMethod);
826         //centrality = centralityObj->GetCentralityPercentileUnchecked(fCentralityMethod);
827       else
828         centrality = -1;
829
830       if (fAOD)
831       {
832         // remove outliers
833         if (centrality == 0)
834         {
835           if (fAOD->GetVZEROData())
836           {
837             Float_t multV0 = 0;
838             for (Int_t i=0; i<64; i++)
839               multV0 += fAOD->GetVZEROData()->GetMultiplicity(i);
840             if (multV0 < 19500)
841             {
842               centrality = -1;
843               AliInfo("Rejecting event due to too small V0 multiplicity");
844             }
845           }
846         }
847       }
848     }
849     
850     AliInfo(Form("Centrality is %f", centrality));
851   }
852   
853   Float_t bSign = (inputEvent->GetMagneticField() > 0) ? 1 : -1;
854
855   fHistos->SetRunNumber(inputEvent->GetRunNumber());
856   
857   // Fill the "event-counting-container", it is needed to get the number of events remaining after each event-selection cut
858   fHistos->FillEvent(centrality, AliUEHist::kCFStepAll);
859   
860   // Trigger selection ************************************************
861   if (!fSkipTrigger && !fAnalyseUE->TriggerSelection(fInputHandler)) return;
862   
863   // Fill the "event-counting-container", it is needed to get the number of events remaining after each event-selection cut
864   fHistos->FillEvent(centrality, AliUEHist::kCFStepTriggered);
865   
866   // Vertex selection *************************************************
867   if(!fAnalyseUE->VertexSelection(inputEvent, fnTracksVertex, fZVertex)) return;
868   
869   // Fill the "event-counting-container", it is needed to get the number of events remaining after each event-selection cut
870   fHistos->FillEvent(centrality, AliUEHist::kCFStepVertex);
871  
872   // optimization
873   if (centrality < 0 && !fCompareCentralities)
874     return;
875
876   TObjArray* tracks = fAnalyseUE->GetAcceptedParticles(inputEvent, 0, kTRUE, -1, kTRUE);
877   
878   // check for outlier in centrality vs number of tracks (rough constants extracted from correlation histgram)
879   Bool_t reject = kFALSE;
880   if (fRejectCentralityOutliers)
881   {
882     if (centrality > 40 && centrality <= 50 && tracks->GetEntriesFast() > 1160)
883       reject = kTRUE;
884     if (centrality > 50 && centrality <= 60 && tracks->GetEntriesFast() > 650)
885       reject = kTRUE;
886     if (centrality > 60 && centrality <= 70 && tracks->GetEntriesFast() > 370)
887       reject = kTRUE;
888     if (centrality > 70 && centrality <= 80 && tracks->GetEntriesFast() > 220)
889       reject = kTRUE;
890     if (centrality > 80 && centrality <= 90 && tracks->GetEntriesFast() > 130)
891       reject = kTRUE;
892     if (centrality > 90 && tracks->GetEntriesFast() > 75)
893       reject = kTRUE;
894   }
895   
896   if (reject)
897   {
898     AliInfo(Form("Rejecting event due to centrality vs tracks correlation: %f %d", centrality, tracks->GetEntriesFast()));
899     fHistos->FillEvent(centrality, AliUEHist::kCFStepAnaTopology);
900     delete tracks;
901     return;
902   }
903   
904   // reference multiplicity
905   Int_t referenceMultiplicity = -1;
906   if (fESD)
907     referenceMultiplicity = AliESDtrackCuts::GetReferenceMultiplicity(fESD);
908
909   ((TH2F*) fListOfHistos->FindObject("referenceMultiplicity"))->Fill(centrality, referenceMultiplicity);
910   
911   // create a list of reduced objects. This speeds up processing and reduces memory consumption for the event pool
912   TObjArray* tracksClone = CloneAndReduceTrackList(tracks);
913   delete tracks;
914   
915   //Printf("Accepted %d tracks", tracks->GetEntries());
916   
917   const AliVVertex* vertex = inputEvent->GetPrimaryVertex();
918   Double_t zVtx = vertex->GetZ();
919   
920   Float_t weight = 1;
921   if (fFillpT)
922     weight = -1;
923
924   // fill two different centralities (syst study)
925   // the zvtx axis is used to distinguish the results of both centralities: configured centrality in zvtx = 0, SPD in zvtx = 2
926   if (fCompareCentralities)
927     zVtx = 0;
928   
929   // Fill containers at STEP 6 (reconstructed)
930   if (centrality >= 0)
931   {
932     if (!fSkipStep6)
933       fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepReconstructed, tracksClone, 0, weight, kTRUE, kFALSE, 0, 0.02, kTRUE);
934     
935     ((TH1F*) fListOfHistos->FindObject("eventStat"))->Fill(1);
936     
937     if (fTwoTrackEfficiencyCut > 0)
938       fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepBiasStudy, tracksClone, 0, weight, kTRUE, kTRUE, bSign, fTwoTrackEfficiencyCut, kTRUE);
939   }
940
941   // fill second time with SPD centrality
942   if (fCompareCentralities && centralityObj)
943   {
944     centrality = centralityObj->GetCentralityPercentile("CL1");
945     if (centrality >= 0 && !fSkipStep6)
946       fHistos->FillCorrelations(centrality, 2, AliUEHist::kCFStepReconstructed, tracksClone, 0, weight, kTRUE, kFALSE, 0, 0.02, kTRUE);
947   }
948   
949   if (fFillMixed)
950   {
951     // event mixing
952     
953     // 1. First get an event pool corresponding in mult (cent) and
954     //    zvertex to the current event. Once initialized, the pool
955     //    should contain nMix (reduced) events. This routine does not
956     //    pre-scan the chain. The first several events of every chain
957     //    will be skipped until the needed pools are filled to the
958     //    specified depth. If the pool categories are not too rare, this
959     //    should not be a problem. If they are rare, you could lose
960     //    statistics.
961
962     // 2. Collect the whole pool's content of tracks into one TObjArray
963     //    (bgTracks), which is effectively a single background super-event.
964
965     // 3. The reduced and bgTracks arrays must both be passed into
966     //    FillCorrelations(). Also nMix should be passed in, so a weight
967     //    of 1./nMix can be applied.
968
969     AliEventPool* pool = fPoolMgr->GetEventPool(centrality, zVtx);
970     
971     if (!pool)
972       AliFatal(Form("No pool found for centrality = %f, zVtx = %f", centrality, zVtx));
973     
974     //pool->SetDebug(1);
975      
976     if (pool->IsReady() || pool->NTracksInPool() > fMixingTracks / 10 || pool->GetCurrentNEvents() >= 5) 
977     {
978       
979       Int_t nMix = pool->GetCurrentNEvents();
980 //       cout << "nMix = " << nMix << " tracks in pool = " << pool->NTracksInPool() << endl;
981       
982       ((TH1F*) fListOfHistos->FindObject("eventStat"))->Fill(2);
983       ((TH2F*) fListOfHistos->FindObject("mixedDist"))->Fill(centrality, pool->NTracksInPool());
984       if (pool->IsReady())
985         ((TH1F*) fListOfHistos->FindObject("eventStat"))->Fill(3);
986     
987       // Fill mixed-event histos here  
988       for (Int_t jMix=0; jMix<nMix; jMix++) 
989       {
990         TObjArray* bgTracks = pool->GetEvent(jMix);
991         
992         if (!fSkipStep6)
993           fHistosMixed->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepReconstructed, tracksClone, bgTracks, 1.0 / nMix, (jMix == 0), kFALSE, 0, 0.02, kTRUE);
994
995         if (fTwoTrackEfficiencyCut > 0)
996           fHistosMixed->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepBiasStudy, tracksClone, bgTracks, 1.0 / nMix, (jMix == 0), kTRUE, bSign, fTwoTrackEfficiencyCut, kTRUE);
997       }
998     }
999     
1000     // ownership is with the pool now
1001     pool->UpdatePool(tracksClone);
1002     //pool->PrintInfo();
1003   }
1004   else
1005     delete tracksClone;
1006 }
1007
1008 TObjArray* AliAnalysisTaskPhiCorrelations::CloneAndReduceTrackList(TObjArray* tracks)
1009 {
1010   // clones a track list by using AliDPhiBasicParticle which uses much less memory (used for event mixing)
1011   
1012   TObjArray* tracksClone = new TObjArray;
1013   tracksClone->SetOwner(kTRUE);
1014   
1015   for (Int_t i=0; i<tracks->GetEntriesFast(); i++)
1016   {
1017     AliVParticle* particle = (AliVParticle*) tracks->At(i);
1018     tracksClone->Add(new AliDPhiBasicParticle(particle->Eta(), particle->Phi(), particle->Pt(), particle->Charge()));
1019   }
1020   
1021   return tracksClone;
1022 }
1023
1024 //____________________________________________________________________
1025 void  AliAnalysisTaskPhiCorrelations::Initialize()
1026 {
1027   // input handler
1028   fInputHandler = (AliInputEventHandler*)
1029          ((AliAnalysisManager::GetAnalysisManager())->GetInputEventHandler());
1030   // MC handler
1031   fMcHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
1032 }