1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
28 #include "AliAnalysisTaskPhiCorrelations.h"
29 #include "AliAnalyseLeadingTrackUE.h"
30 #include "AliUEHistograms.h"
31 #include "AliUEHist.h"
33 #include "AliAnalysisManager.h"
34 #include "AliAODHandler.h"
35 #include "AliAODInputHandler.h"
36 #include "AliAODMCParticle.h"
37 #include "AliInputEventHandler.h"
39 #include "AliMCEventHandler.h"
40 #include "AliVParticle.h"
41 #include "AliCFContainer.h"
43 #include "AliESDEvent.h"
44 #include "AliESDInputHandler.h"
45 #include "AliMultiplicity.h"
46 #include "AliCentrality.h"
48 #include "AliAODMCHeader.h"
49 #include "AliGenCocktailEventHeader.h"
50 #include "AliGenEventHeader.h"
52 #include "AliEventPoolManager.h"
54 #include "AliESDZDC.h"
55 #include "AliESDtrackCuts.h"
58 ////////////////////////////////////////////////////////////////////////
60 // Analysis class for azimuthal correlation studies
61 // Based on the UE task from Sara Vallero and Jan Fiete
63 // This class needs input AODs.
64 // The output is a list of analysis-specific containers.
66 // The AOD can be either connected to the InputEventHandler
67 // for a chain of AOD files
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
74 // Jan Fiete Grosse-Oetringhaus
76 ////////////////////////////////////////////////////////////////////////
79 ClassImp( AliAnalysisTaskPhiCorrelations )
80 ClassImp( AliDPhiBasicParticle )
82 //____________________________________________________________________
83 AliAnalysisTaskPhiCorrelations:: AliAnalysisTaskPhiCorrelations(const char* name):
84 AliAnalysisTask(name,""),
85 // general configuration
88 fReduceMemoryFootprint(kFALSE),
91 fCompareCentralities(kFALSE),
92 fTwoTrackEfficiencyStudy(kFALSE),
93 fTwoTrackEfficiencyCut(0),
95 fCourseCentralityBinning(kFALSE),
97 fInjectedSignals(kFALSE),
98 // pointers to UE classes
102 fEfficiencyCorrection(0),
103 fCorrectTriggers(kFALSE),
104 // handlers and events
112 // histogram settings
115 fnTracksVertex(1), // QA tracks pointing to principal vertex (= 3 default)
117 fCentralityMethod("V0M"),
123 fSelectBit(AliVEvent::kMB|AliVEvent::kUserDefined),
124 fUseChargeHadrons(kFALSE),
126 fTriggerSelectCharge(0),
127 fTriggerRestrictEta(-1),
128 fEtaOrdering(kFALSE),
129 fCutConversions(kFALSE),
130 fCutResonances(kFALSE),
131 fFillOnlyStep0(kFALSE),
133 fRejectCentralityOutliers(kFALSE),
134 fRemoveWeakDecays(kFALSE),
135 fRemoveDuplicates(kFALSE),
136 fSkipFastCluster(kFALSE),
139 // Default constructor
140 // Define input and output slots here
141 // Input slot #0 works with a TChain
142 DefineInput(0, TChain::Class());
143 // Output slot #0 writes into a TList container
144 DefineOutput(0, TList::Class());
147 AliAnalysisTaskPhiCorrelations::~AliAnalysisTaskPhiCorrelations()
151 if (fListOfHistos && !AliAnalysisManager::GetAnalysisManager()->IsProofMode())
152 delete fListOfHistos;
155 //____________________________________________________________________
156 void AliAnalysisTaskPhiCorrelations::ConnectInputData(Option_t* /*option*/)
159 // Connect the input data
160 if (fDebug > 1) AliInfo("ConnectInputData() ");
162 // Since AODs can either be connected to the InputEventHandler
163 // or to the OutputEventHandler ( the AOD is created by a previus task in the train )
164 // we need to get the pointer to the AODEvent correctly.
166 // Delta AODs are also accepted.
168 TObject* handler = AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
170 if( handler && handler->InheritsFrom("AliAODInputHandler") )
172 fAOD = ((AliAODInputHandler*)handler)->GetEvent();
173 if (fDebug > 1) AliInfo(" ==== Tracks and Jets from AliAODInputHandler");
177 handler = AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler();
178 if (handler && handler->InheritsFrom("AliAODHandler") )
180 fAOD = ((AliAODHandler*)handler)->GetAOD();
181 if (fDebug > 1) AliInfo(" ==== Tracks and Jets from AliAODHandler");
185 AliWarning("I can't get any AOD Event Handler");
189 if (handler && handler->InheritsFrom("AliESDInputHandler") )
191 // pointer received per event in ::Exec
192 if (fDebug > 1) AliInfo(" ==== Tracks and Jets from AliESDInputHandler");
195 // Initialize common pointers
199 //____________________________________________________________________
200 void AliAnalysisTaskPhiCorrelations::CreateOutputObjects()
202 // Create the output container
204 if (fDebug > 1) AliInfo("CreateOutputObjects()");
206 // Initialize class with main algorithms, event and track selection.
207 fAnalyseUE = new AliAnalyseLeadingTrackUE();
208 fAnalyseUE->SetParticleSelectionCriteria(fFilterBit, fUseChargeHadrons, fTrackEtaCut, fPtMin);
209 fAnalyseUE->SetDebug(fDebug);
210 fAnalyseUE->DefineESDCuts(fFilterBit);
211 fAnalyseUE->SetEventSelection(fSelectBit);
213 // Initialize output list of containers
214 if (fListOfHistos != NULL){
215 delete fListOfHistos;
216 fListOfHistos = NULL;
219 fListOfHistos = new TList();
220 fListOfHistos->SetOwner(kTRUE);
223 // Initialize class to handle histograms
224 TString histType = "4R";
225 if (fUseVtxAxis == 1)
227 else if (fUseVtxAxis == 2)
229 if (fCourseCentralityBinning)
231 fHistos = new AliUEHistograms("AliUEHistogramsSame", histType);
232 fHistosMixed = new AliUEHistograms("AliUEHistogramsMixed", histType);
234 fHistos->SetSelectCharge(fSelectCharge);
235 fHistosMixed->SetSelectCharge(fSelectCharge);
237 fHistos->SetSelectTriggerCharge(fTriggerSelectCharge);
238 fHistosMixed->SetSelectTriggerCharge(fTriggerSelectCharge);
240 fHistos->SetTriggerRestrictEta(fTriggerRestrictEta);
241 fHistosMixed->SetTriggerRestrictEta(fTriggerRestrictEta);
243 fHistos->SetOnlyOneEtaSide(fOnlyOneEtaSide);
244 fHistosMixed->SetOnlyOneEtaSide(fOnlyOneEtaSide);
246 fHistos->SetEtaOrdering(fEtaOrdering);
247 fHistosMixed->SetEtaOrdering(fEtaOrdering);
249 fHistos->SetPairCuts(fCutConversions, fCutResonances);
250 fHistosMixed->SetPairCuts(fCutConversions, fCutResonances);
252 fHistos->SetTrackEtaCut(fTrackEtaCut);
253 fHistosMixed->SetTrackEtaCut(fTrackEtaCut);
255 if (fEfficiencyCorrection)
257 fHistos->SetEfficiencyCorrection(fEfficiencyCorrection, fCorrectTriggers);
258 fHistosMixed->SetEfficiencyCorrection((THnF*) fEfficiencyCorrection->Clone(), fCorrectTriggers);
261 // add histograms to list
262 fListOfHistos->Add(fHistos);
263 fListOfHistos->Add(fHistosMixed);
265 fListOfHistos->Add(new TH2F("trackletsVsV0Cent", ";L1 clusters;v0 centrality", 100, -0.5, 9999.5, 101, 0, 101));
266 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));
267 fListOfHistos->Add(new TH1F("eventStat", ";;events", 4, -0.5, 3.5));
268 fListOfHistos->Add(new TH2F("mixedDist", ";centrality;tracks;events", 101, 0, 101, 200, 0, fMixingTracks * 1.5));
269 fListOfHistos->Add(new TH1F("pids", ";pdg;tracks", 2001, -1000.5, 1000.5));
270 fListOfHistos->Add(new TH2F("referenceMultiplicity", ";centrality;tracks;events", 101, 0, 101, 200, 0, 200));
272 PostData(0,fListOfHistos);
274 // Add task configuration to output list
278 Int_t trackDepth = fMixingTracks;
279 Int_t poolsize = 1000; // Maximum number of events, ignored in the present implemented of AliEventPoolManager
281 Int_t nCentralityBins = fHistos->GetUEHist(2)->GetEventHist()->GetNBins(1);
282 Double_t* centralityBins = (Double_t*) fHistos->GetUEHist(2)->GetEventHist()->GetAxis(1, 0)->GetXbins()->GetArray();
284 const Int_t kNZvtxBins = 10+(1+10)*4;
285 // bins for further buffers are shifted by 100 cm
286 Double_t vertexBins[kNZvtxBins+1] = { -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10,
287 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110,
288 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210,
289 290, 292, 294, 296, 298, 300, 302, 304, 306, 308, 310,
290 390, 392, 394, 396, 398, 400, 402, 404, 406, 408, 410 };
292 Int_t nZvtxBins = kNZvtxBins;
293 Double_t* zvtxbin = vertexBins;
295 if (fMode == 0 && fHistos->GetUEHist(2)->GetEventHist()->GetNVar() > 2)
297 nZvtxBins = fHistos->GetUEHist(2)->GetEventHist()->GetNBins(2);
298 zvtxbin = (Double_t*) fHistos->GetUEHist(2)->GetEventHist()->GetAxis(2, 0)->GetXbins()->GetArray();
301 fPoolMgr = new AliEventPoolManager(poolsize, trackDepth, nCentralityBins, centralityBins, nZvtxBins, zvtxbin);
304 //____________________________________________________________________
305 void AliAnalysisTaskPhiCorrelations::Exec(Option_t */*option*/)
307 // receive ESD pointer if we are not running AOD analysis
310 AliVEventHandler* handler = AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
311 if (handler && handler->InheritsFrom("AliESDInputHandler"))
312 fESD = ((AliESDInputHandler*)handler)->GetEvent();
320 fMcEvent = fMcHandler->MCEvent();
324 // array of MC particles
325 fArrayMC = dynamic_cast<TClonesArray*>(fAOD->FindListObject(AliAODMCParticle::StdBranchName()));
327 AliFatal("No array of MC particles found !!!");
330 AnalyseCorrectionMode();
332 else AnalyseDataMode();
335 /******************** ANALYSIS METHODS *****************************/
337 //____________________________________________________________________
338 void AliAnalysisTaskPhiCorrelations::AddSettingsTree()
340 //Write settings to output list
341 TTree *settingsTree = new TTree("UEAnalysisSettings","Analysis Settings in UE estimation");
342 settingsTree->Branch("fnTracksVertex", &fnTracksVertex,"nTracksVertex/I");
343 settingsTree->Branch("fZVertex", &fZVertex,"ZVertex/D");
344 //settingsTree->Branch("fCentralityMethod", fCentralityMethod.Data(),"CentralityMethod/C");
345 settingsTree->Branch("fTrackEtaCut", &fTrackEtaCut, "TrackEtaCut/D");
346 settingsTree->Branch("fOnlyOneEtaSide", &fOnlyOneEtaSide,"OnlyOneEtaSide/I");
347 settingsTree->Branch("fPtMin", &fPtMin, "PtMin/D");
348 settingsTree->Branch("fFilterBit", &fFilterBit,"FilterBit/I");
349 settingsTree->Branch("fSelectBit", &fSelectBit,"EventSelectionBit/I");
350 settingsTree->Branch("fUseChargeHadrons", &fUseChargeHadrons,"UseChHadrons/O");
351 settingsTree->Branch("fSelectCharge", &fSelectCharge,"SelectCharge/I");
352 settingsTree->Branch("fTriggerSelectCharge", &fTriggerSelectCharge,"TriggerSelectCharge/I");
353 settingsTree->Branch("fTriggerRestrictEta", &fTriggerRestrictEta,"TriggerRestrictEta/D");
354 settingsTree->Branch("fEtaOrdering", &fEtaOrdering,"EtaOrdering/O");
355 settingsTree->Branch("fCutConversions", &fCutConversions,"CutConversions/O");
356 settingsTree->Branch("fCutResonances", &fCutResonances,"CutResonances/O");
357 settingsTree->Branch("fFillpT", &fFillpT,"FillpT/O");
358 settingsTree->Branch("fMixingTracks", &fMixingTracks,"MixingTracks/I");
359 settingsTree->Branch("fSkipTrigger", &fSkipTrigger,"SkipTrigger/O");
360 settingsTree->Branch("fInjectedSignals", &fInjectedSignals,"SkipTrigger/O");
361 settingsTree->Branch("fRejectCentralityOutliers", &fRejectCentralityOutliers,"RejectCentralityOutliers/O");
362 settingsTree->Branch("fRemoveWeakDecays", &fRemoveWeakDecays,"RemoveWeakDecays/O");
363 settingsTree->Branch("fRemoveDuplicates", &fRemoveDuplicates,"RemoveDuplicates/O");
364 settingsTree->Branch("fSkipFastCluster", &fSkipFastCluster,"SkipFastCluster/O");
365 settingsTree->Branch("fCorrectTriggers", &fCorrectTriggers,"CorrectTriggers/O");
367 settingsTree->Fill();
368 fListOfHistos->Add(settingsTree);
371 //____________________________________________________________________
372 void AliAnalysisTaskPhiCorrelations::AnalyseCorrectionMode()
374 // Run the analysis on MC to get the correction maps
377 if ( fDebug > 3 ) AliInfo( " Processing event in Corrections mode ..." );
379 Double_t centrality = 0;
381 if (fCentralityMethod.Length() > 0)
383 AliCentrality *centralityObj = 0;
385 centralityObj = fAOD->GetHeader()->GetCentralityP();
387 centralityObj = fESD->GetCentrality();
391 centrality = centralityObj->GetCentralityPercentileUnchecked(fCentralityMethod);
392 AliInfo(Form("Centrality is %f", centrality));
396 Printf("WARNING: Centrality object is 0");
401 // Support for ESD and AOD based analysis
402 AliVEvent* inputEvent = fAOD;
410 fHistos->SetRunNumber(inputEvent->GetRunNumber());
411 bSign = (inputEvent->GetMagneticField() > 0) ? 1 : -1;
414 TObject* mc = fArrayMC;
419 fHistos->FillEvent(centrality, -1);
424 // Only consider MC events within the vtx-z region used also as cut on the reconstructed vertex
425 TObject* vertexSupplier = fMcEvent;
427 vertexSupplier = fAOD->FindListObject(AliAODMCHeader::StdBranchName());
429 if (!fAnalyseUE->VertexSelection(vertexSupplier, 0, fZVertex))
434 zVtx = ((AliAODMCHeader*) vertexSupplier)->GetVtxZ();
436 zVtx = fMcEvent->GetPrimaryVertex()->GetZ();
441 // For productions with injected signals, figure out above which label to skip particles/tracks
442 Int_t skipParticlesAbove = 0;
443 if (fInjectedSignals)
445 AliGenEventHeader* eventHeader = 0;
451 AliHeader* header = (AliHeader*) fMcEvent->Header();
453 AliFatal("fInjectedSignals set but no MC header found");
455 AliGenCocktailEventHeader* cocktailHeader = dynamic_cast<AliGenCocktailEventHeader*> (header->GenEventHeader());
459 AliFatal("fInjectedSignals set but no MC cocktail header found");
462 headers = cocktailHeader->GetHeaders()->GetEntries();
463 eventHeader = dynamic_cast<AliGenEventHeader*> (cocktailHeader->GetHeaders()->First());
468 AliAODMCHeader* header = (AliAODMCHeader*) fAOD->GetList()->FindObject(AliAODMCHeader::StdBranchName());
470 AliFatal("fInjectedSignals set but no MC header found");
472 headers = header->GetNCocktailHeaders();
473 eventHeader = header->GetCocktailHeader(0);
478 // We avoid AliFatal here, because the AOD productions sometimes have events where the MC header is missing
479 // (due to unreadable Kinematics) and we don't want to loose the whole job because of a few events
480 AliError("First event header not found. Skipping this event.");
481 fHistos->FillEvent(centrality, AliUEHist::kCFStepAnaTopology);
485 skipParticlesAbove = eventHeader->NProduced();
486 AliInfo(Form("Injected signals in this event (%d headers). Keeping events of %s. Will skip particles/tracks above %d.", headers, eventHeader->ClassName(), skipParticlesAbove));
490 TObjArray* tmpList = fAnalyseUE->GetAcceptedParticles(mc, 0, kTRUE, -1, kTRUE);
491 if (fInjectedSignals)
492 fAnalyseUE->RemoveInjectedSignals(tmpList, mc, skipParticlesAbove);
493 if (fRemoveWeakDecays)
494 fAnalyseUE->RemoveWeakDecays(tmpList, mc);
495 TObjArray* tracksMC = CloneAndReduceTrackList(tmpList);
501 for (Int_t i=0; i<fArrayMC->GetEntriesFast(); i++)
502 ((TH1F*) fListOfHistos->FindObject("pids"))->Fill(((AliAODMCParticle*) fArrayMC->At(i))->PdgCode());
506 for (Int_t i=0; i<fMcEvent->GetNumberOfTracks(); i++)
507 ((TH1F*) fListOfHistos->FindObject("pids"))->Fill(fMcEvent->GetTrack(i)->PdgCode());
514 // (MC-true all particles)
516 fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepAll, tracksMC, 0, weight);
521 AliEventPool* pool = fPoolMgr->GetEventPool(centrality, zVtx);
523 if (pool->IsReady() || pool->NTracksInPool() > fMixingTracks / 10 || pool->GetCurrentNEvents() >= 5)
524 for (Int_t jMix=0; jMix<pool->GetCurrentNEvents(); jMix++)
525 fHistosMixed->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepAll, tracksMC, pool->GetEvent(jMix), 1.0 / pool->GetCurrentNEvents(), (jMix == 0));
526 pool->UpdatePool(CloneAndReduceTrackList(tracksMC));
529 // Printf("trigger: %d", ((AliInputEventHandler*)fInputHandler)->IsEventSelected());
531 // Trigger selection ************************************************
532 if (!fFillOnlyStep0 && (fSkipTrigger || fAnalyseUE->TriggerSelection(fInputHandler)))
534 // (MC-true all particles)
536 if (!fReduceMemoryFootprint)
537 fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepTriggered, tracksMC, 0, weight);
539 fHistos->FillEvent(centrality, AliUEHist::kCFStepTriggered);
542 AliFatal("UNEXPECTED: inputEvent is 0. Trigger selection should have failed");
546 // Vertex selection *************************************************
547 if (fAnalyseUE->VertexSelection(inputEvent, fnTracksVertex, fZVertex))
549 // fill here for tracking efficiency
550 // loop over particle species
552 for (Int_t particleSpecies = 0; particleSpecies < 4; particleSpecies++)
554 TObjArray* primMCParticles = fAnalyseUE->GetAcceptedParticles(mc, 0x0, kTRUE, particleSpecies, kTRUE);
555 TObjArray* primRecoTracksMatched = fAnalyseUE->GetAcceptedParticles(inputEvent, mc, kTRUE, particleSpecies, kTRUE);
556 TObjArray* allRecoTracksMatched = fAnalyseUE->GetAcceptedParticles(inputEvent, mc, kFALSE, particleSpecies, kTRUE);
558 if (fInjectedSignals)
560 fAnalyseUE->RemoveInjectedSignals(primMCParticles, mc, skipParticlesAbove);
561 fAnalyseUE->RemoveInjectedSignals(primRecoTracksMatched, mc, skipParticlesAbove);
562 fAnalyseUE->RemoveInjectedSignals(allRecoTracksMatched, mc, skipParticlesAbove);
565 if (fRemoveWeakDecays)
567 fAnalyseUE->RemoveWeakDecays(primMCParticles, mc);
568 fAnalyseUE->RemoveWeakDecays(primRecoTracksMatched, mc);
569 fAnalyseUE->RemoveWeakDecays(allRecoTracksMatched, mc);
572 fHistos->FillTrackingEfficiency(primMCParticles, primRecoTracksMatched, allRecoTracksMatched, 0, particleSpecies, centrality, zVtx);
574 // Printf("%d --> %d %d %d", particleSpecies, primMCParticles->GetEntries(), primRecoTracksMatched->GetEntries(), allRecoTracksMatched->GetEntries());
576 delete primMCParticles;
577 delete primRecoTracksMatched;
578 delete allRecoTracksMatched;
580 TObjArray* fakeParticles = fAnalyseUE->GetFakeParticles(inputEvent, mc, kFALSE, -1, kTRUE);
581 if (fInjectedSignals)
583 fAnalyseUE->RemoveInjectedSignals((TObjArray*) fakeParticles->At(0), mc, skipParticlesAbove);
584 fAnalyseUE->RemoveInjectedSignals((TObjArray*) fakeParticles->At(1), mc, skipParticlesAbove);
586 if (fRemoveWeakDecays)
588 fAnalyseUE->RemoveWeakDecays((TObjArray*) fakeParticles->At(0), mc);
589 fAnalyseUE->RemoveWeakDecays((TObjArray*) fakeParticles->At(1), mc);
591 fHistos->FillTrackingEfficiency(0, 0, 0, (TObjArray*) fakeParticles->At(2), -1, centrality, zVtx);
592 fHistos->FillFakePt(fakeParticles, centrality);
593 // Printf(">>>>> %d %d %d fakes", ((TObjArray*) fakeParticles->At(0))->GetEntriesFast(), ((TObjArray*) fakeParticles->At(1))->GetEntriesFast(), ((TObjArray*) fakeParticles->At(2))->GetEntriesFast());
594 delete fakeParticles;
596 // (MC-true all particles)
598 if (!fReduceMemoryFootprint)
599 fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepVertex, tracksMC, 0, weight);
601 fHistos->FillEvent(centrality, AliUEHist::kCFStepVertex);
603 // Get MC primaries that match reconstructed track
604 TObjArray* tracksRecoMatchedPrim = fAnalyseUE->GetAcceptedParticles(inputEvent, mc, kTRUE, -1, kTRUE);
605 if (fInjectedSignals)
606 fAnalyseUE->RemoveInjectedSignals(tracksRecoMatchedPrim, mc, skipParticlesAbove);
607 if (fRemoveWeakDecays)
608 fAnalyseUE->RemoveWeakDecays(tracksRecoMatchedPrim, mc);
609 if (fRemoveDuplicates)
610 RemoveDuplicates(tracksRecoMatchedPrim);
612 // (RECO-matched (quantities from MC particle) primary particles)
614 fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepTrackedOnlyPrim, tracksRecoMatchedPrim, 0, weight);
619 AliEventPool* pool = fPoolMgr->GetEventPool(centrality, zVtx + 200);
621 if (pool->IsReady() || pool->NTracksInPool() > fMixingTracks / 10 || pool->GetCurrentNEvents() >= 5)
622 for (Int_t jMix=0; jMix<pool->GetCurrentNEvents(); jMix++)
623 fHistosMixed->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepTrackedOnlyPrim, tracksRecoMatchedPrim, pool->GetEvent(jMix), 1.0 / pool->GetCurrentNEvents(), (jMix == 0));
624 pool->UpdatePool(CloneAndReduceTrackList(tracksRecoMatchedPrim));
627 // Get MC primaries + secondaries that match reconstructed track
628 TObjArray* tracksRecoMatchedAll = fAnalyseUE->GetAcceptedParticles(inputEvent, mc, kFALSE, -1, kTRUE);
629 if (fInjectedSignals)
630 fAnalyseUE->RemoveInjectedSignals(tracksRecoMatchedAll, mc, skipParticlesAbove);
631 if (fRemoveWeakDecays)
632 fAnalyseUE->RemoveWeakDecays(tracksRecoMatchedAll, mc);
633 if (fRemoveDuplicates)
634 RemoveDuplicates(tracksRecoMatchedAll);
636 // (RECO-matched (quantities from MC particle) all particles)
638 fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepTracked, tracksRecoMatchedAll, 0, weight);
643 AliEventPool* pool = fPoolMgr->GetEventPool(centrality, zVtx + 300);
645 if (pool->IsReady() || pool->NTracksInPool() > fMixingTracks / 10 || pool->GetCurrentNEvents() >= 5)
646 for (Int_t jMix=0; jMix<pool->GetCurrentNEvents(); jMix++)
647 fHistosMixed->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepTracked, tracksRecoMatchedAll, pool->GetEvent(jMix), 1.0 / pool->GetCurrentNEvents(), (jMix == 0));
648 pool->UpdatePool(CloneAndReduceTrackList(tracksRecoMatchedAll));
652 TObjArray* tracks = fAnalyseUE->GetAcceptedParticles(inputEvent, 0, kTRUE, -1, kTRUE);
653 if (fInjectedSignals)
654 fAnalyseUE->RemoveInjectedSignals(tracks, mc, skipParticlesAbove);
655 if (fRemoveWeakDecays)
656 fAnalyseUE->RemoveWeakDecays(tracks, mc);
661 fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepReconstructed, tracks, 0, weight);
663 // two track cut, STEP 8
664 if (fTwoTrackEfficiencyCut > 0)
665 fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepBiasStudy, tracks, 0, weight, kTRUE, kTRUE, bSign, fTwoTrackEfficiencyCut);
667 // apply correction efficiency, STEP 10
668 if (fEfficiencyCorrection)
670 // with or without two track efficiency depending on if fTwoTrackEfficiencyCut is set
671 Bool_t twoTrackCut = (fTwoTrackEfficiencyCut > 0);
673 fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepCorrected, tracks, 0, weight, kTRUE, twoTrackCut, bSign, fTwoTrackEfficiencyCut, kTRUE);
679 AliEventPool* pool2 = fPoolMgr->GetEventPool(centrality, zVtx + 100);
680 //pool2->PrintInfo();
681 if (pool2->IsReady() || pool2->NTracksInPool() > fMixingTracks / 10 || pool2->GetCurrentNEvents() >= 5)
683 for (Int_t jMix=0; jMix<pool2->GetCurrentNEvents(); jMix++)
687 fHistosMixed->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepReconstructed, tracks, pool2->GetEvent(jMix), 1.0 / pool2->GetCurrentNEvents(), (jMix == 0));
689 // two track cut, STEP 8
690 if (fTwoTrackEfficiencyCut > 0)
691 fHistosMixed->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepBiasStudy, tracks, pool2->GetEvent(jMix), 1.0 / pool2->GetCurrentNEvents(), (jMix == 0), kTRUE, bSign, fTwoTrackEfficiencyCut);
693 // apply correction efficiency, STEP 10
694 if (fEfficiencyCorrection)
696 // with or without two track efficiency depending on if fTwoTrackEfficiencyCut is set
697 Bool_t twoTrackCut = (fTwoTrackEfficiencyCut > 0);
699 fHistosMixed->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepCorrected, tracks, pool2->GetEvent(jMix), 1.0 / pool2->GetCurrentNEvents(), (jMix == 0), twoTrackCut, bSign, fTwoTrackEfficiencyCut, kTRUE);
703 pool2->UpdatePool(CloneAndReduceTrackList(tracks));
706 if (0 && !fReduceMemoryFootprint)
708 // make list of secondaries (matched with MC)
709 TObjArray* tracksRecoMatchedSecondaries = new TObjArray;
710 for (Int_t i=0; i<tracksRecoMatchedAll->GetEntriesFast(); i++)
711 if (((AliAODMCParticle*)tracksRecoMatchedAll->At(i))->IsPhysicalPrimary() == kFALSE)
712 tracksRecoMatchedSecondaries->Add(tracksRecoMatchedAll->At(i));
714 // Study: Use only secondaries as trigger particles and plot the correlation vs. all particles; store in step 9
715 fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepBiasStudy2, tracksRecoMatchedSecondaries, tracksRecoMatchedAll, weight);
717 // Study: Use only primaries as trigger particles and plot the correlation vs. secondaries; store in step 8
718 fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepBiasStudy, tracksRecoMatchedPrim, tracksRecoMatchedSecondaries, weight);
720 // plot delta phi vs process id of secondaries
721 // trigger particles: primaries in 4 < pT < 10
722 // associated particles: secondaries in 1 < pT < 10
724 for (Int_t i=0; i<tracksRecoMatchedPrim->GetEntriesFast(); i++)
726 AliVParticle* triggerParticle = (AliVParticle*) tracksRecoMatchedPrim->At(i);
728 if (triggerParticle->Pt() < 4 || triggerParticle->Pt() > 10)
731 for (Int_t j=0; j<tracksRecoMatchedSecondaries->GetEntriesFast(); j++)
733 AliAODMCParticle* particle = (AliAODMCParticle*) tracksRecoMatchedSecondaries->At(j);
735 if (particle->Pt() < 1 || particle->Pt() > 10)
738 if (particle->Pt() > triggerParticle->Pt())
741 Double_t deltaPhi = triggerParticle->Phi() - particle->Phi();
742 if (deltaPhi > 1.5 * TMath::Pi())
743 deltaPhi -= TMath::TwoPi();
744 if (deltaPhi < -0.5 * TMath::Pi())
745 deltaPhi += TMath::TwoPi();
747 Int_t processID = fMcEvent->Stack()->Particle(particle->GetLabel())->GetUniqueID();
749 ((TH2F*) fListOfHistos->FindObject("processIDs"))->Fill(deltaPhi, processID);
753 delete tracksRecoMatchedSecondaries;
756 delete tracksRecoMatchedPrim;
757 delete tracksRecoMatchedAll;
765 //____________________________________________________________________
766 void AliAnalysisTaskPhiCorrelations::AnalyseDataMode()
769 // Run the analysis on DATA or MC to get raw distributions
771 if ( fDebug > 3 ) AliInfo( " Processing event in Data mode ..." );
773 ((TH1F*) fListOfHistos->FindObject("eventStat"))->Fill(0);
778 // skip not selected events here (the AOD is not updated for those)
779 if (!fSkipTrigger && !(fInputHandler->IsEventSelected() & fSelectBit))
782 // skip fast cluster events here if requested
783 if (!fSkipFastCluster && (fInputHandler->IsEventSelected() & AliVEvent::kFastOnly))
786 // Support for ESD and AOD based analysis
787 AliVEvent* inputEvent = fAOD;
791 Double_t centrality = 0;
793 AliCentrality *centralityObj = 0;
794 if (fCentralityMethod.Length() > 0)
796 if (fCentralityMethod == "ZNA_MANUAL")
799 for(Int_t j = 0; j < 4; ++j) {
800 if (fESD->GetZDCData()->GetZDCTDCData(12,j) != 0) {
805 // Printf("%d %f", zna, fZNAtower[0]);
808 // code from Chiara O (23.10.12)
809 const Double_t *fZNAtower = fESD->GetZDCData()->GetZN2TowerEnergy();
810 Float_t znacut[4] = {681., 563., 413., 191.};
812 if(fZNAtower[0]>znacut[0]) centrality = 1;
813 else if(fZNAtower[0]>znacut[1]) centrality = 21;
814 else if(fZNAtower[0]>znacut[2]) centrality = 41;
815 else if(fZNAtower[0]>znacut[3]) centrality = 61;
816 else centrality = 81;
821 else if (fCentralityMethod == "TRACKS_MANUAL")
824 TObjArray* tracks = fAnalyseUE->GetAcceptedParticles(inputEvent, 0, kTRUE, -1, kTRUE);
825 centrality = tracks->GetEntriesFast();
828 // Printf("%d %f", tracks->GetEntriesFast(), centrality);
834 centralityObj = fAOD->GetHeader()->GetCentralityP();
836 centralityObj = fESD->GetCentrality();
839 centrality = centralityObj->GetCentralityPercentile(fCentralityMethod);
840 //centrality = centralityObj->GetCentralityPercentileUnchecked(fCentralityMethod);
849 if (fAOD->GetVZEROData())
852 for (Int_t i=0; i<64; i++)
853 multV0 += fAOD->GetVZEROData()->GetMultiplicity(i);
857 AliInfo("Rejecting event due to too small V0 multiplicity");
864 AliInfo(Form("Centrality is %f", centrality));
867 Float_t bSign = (inputEvent->GetMagneticField() > 0) ? 1 : -1;
869 fHistos->SetRunNumber(inputEvent->GetRunNumber());
871 // Fill the "event-counting-container", it is needed to get the number of events remaining after each event-selection cut
872 fHistos->FillEvent(centrality, AliUEHist::kCFStepAll);
874 // Trigger selection ************************************************
875 if (!fSkipTrigger && !fAnalyseUE->TriggerSelection(fInputHandler)) return;
877 // Fill the "event-counting-container", it is needed to get the number of events remaining after each event-selection cut
878 fHistos->FillEvent(centrality, AliUEHist::kCFStepTriggered);
880 // Vertex selection *************************************************
881 if(!fAnalyseUE->VertexSelection(inputEvent, fnTracksVertex, fZVertex)) return;
883 // Fill the "event-counting-container", it is needed to get the number of events remaining after each event-selection cut
884 fHistos->FillEvent(centrality, AliUEHist::kCFStepVertex);
887 if (centrality < 0 && !fCompareCentralities)
890 TObjArray* tracks = fAnalyseUE->GetAcceptedParticles(inputEvent, 0, kTRUE, -1, kTRUE);
892 // check for outlier in centrality vs number of tracks (rough constants extracted from correlation histgram)
893 Bool_t reject = kFALSE;
894 if (fRejectCentralityOutliers)
896 if (centrality > 40 && centrality <= 50 && tracks->GetEntriesFast() > 1160)
898 if (centrality > 50 && centrality <= 60 && tracks->GetEntriesFast() > 650)
900 if (centrality > 60 && centrality <= 70 && tracks->GetEntriesFast() > 370)
902 if (centrality > 70 && centrality <= 80 && tracks->GetEntriesFast() > 220)
904 if (centrality > 80 && centrality <= 90 && tracks->GetEntriesFast() > 130)
906 if (centrality > 90 && tracks->GetEntriesFast() > 75)
912 AliInfo(Form("Rejecting event due to centrality vs tracks correlation: %f %d", centrality, tracks->GetEntriesFast()));
913 fHistos->FillEvent(centrality, AliUEHist::kCFStepAnaTopology);
918 // reference multiplicity
919 Int_t referenceMultiplicity = -1;
921 referenceMultiplicity = AliESDtrackCuts::GetReferenceMultiplicity(fESD);
923 ((TH2F*) fListOfHistos->FindObject("referenceMultiplicity"))->Fill(centrality, referenceMultiplicity);
925 // create a list of reduced objects. This speeds up processing and reduces memory consumption for the event pool
926 TObjArray* tracksClone = CloneAndReduceTrackList(tracks);
929 //Printf("Accepted %d tracks", tracks->GetEntries());
931 const AliVVertex* vertex = inputEvent->GetPrimaryVertex();
932 Double_t zVtx = vertex->GetZ();
938 // fill two different centralities (syst study)
939 // the zvtx axis is used to distinguish the results of both centralities: configured centrality in zvtx = 0, SPD in zvtx = 2
940 if (fCompareCentralities)
943 // Fill containers at STEP 6 (reconstructed)
947 fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepReconstructed, tracksClone, 0, weight, kTRUE, kFALSE, 0, 0.02, kTRUE);
949 ((TH1F*) fListOfHistos->FindObject("eventStat"))->Fill(1);
951 if (fTwoTrackEfficiencyCut > 0)
952 fHistos->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepBiasStudy, tracksClone, 0, weight, kTRUE, kTRUE, bSign, fTwoTrackEfficiencyCut, kTRUE);
955 // fill second time with SPD centrality
956 if (fCompareCentralities && centralityObj)
958 centrality = centralityObj->GetCentralityPercentile("CL1");
959 if (centrality >= 0 && !fSkipStep6)
960 fHistos->FillCorrelations(centrality, 2, AliUEHist::kCFStepReconstructed, tracksClone, 0, weight, kTRUE, kFALSE, 0, 0.02, kTRUE);
967 // 1. First get an event pool corresponding in mult (cent) and
968 // zvertex to the current event. Once initialized, the pool
969 // should contain nMix (reduced) events. This routine does not
970 // pre-scan the chain. The first several events of every chain
971 // will be skipped until the needed pools are filled to the
972 // specified depth. If the pool categories are not too rare, this
973 // should not be a problem. If they are rare, you could lose
976 // 2. Collect the whole pool's content of tracks into one TObjArray
977 // (bgTracks), which is effectively a single background super-event.
979 // 3. The reduced and bgTracks arrays must both be passed into
980 // FillCorrelations(). Also nMix should be passed in, so a weight
981 // of 1./nMix can be applied.
983 AliEventPool* pool = fPoolMgr->GetEventPool(centrality, zVtx);
986 AliFatal(Form("No pool found for centrality = %f, zVtx = %f", centrality, zVtx));
990 if (pool->IsReady() || pool->NTracksInPool() > fMixingTracks / 10 || pool->GetCurrentNEvents() >= 5)
993 Int_t nMix = pool->GetCurrentNEvents();
994 // cout << "nMix = " << nMix << " tracks in pool = " << pool->NTracksInPool() << endl;
996 ((TH1F*) fListOfHistos->FindObject("eventStat"))->Fill(2);
997 ((TH2F*) fListOfHistos->FindObject("mixedDist"))->Fill(centrality, pool->NTracksInPool());
999 ((TH1F*) fListOfHistos->FindObject("eventStat"))->Fill(3);
1001 // Fill mixed-event histos here
1002 for (Int_t jMix=0; jMix<nMix; jMix++)
1004 TObjArray* bgTracks = pool->GetEvent(jMix);
1007 fHistosMixed->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepReconstructed, tracksClone, bgTracks, 1.0 / nMix, (jMix == 0), kFALSE, 0, 0.02, kTRUE);
1009 if (fTwoTrackEfficiencyCut > 0)
1010 fHistosMixed->FillCorrelations(centrality, zVtx, AliUEHist::kCFStepBiasStudy, tracksClone, bgTracks, 1.0 / nMix, (jMix == 0), kTRUE, bSign, fTwoTrackEfficiencyCut, kTRUE);
1014 // ownership is with the pool now
1015 pool->UpdatePool(tracksClone);
1016 //pool->PrintInfo();
1022 TObjArray* AliAnalysisTaskPhiCorrelations::CloneAndReduceTrackList(TObjArray* tracks)
1024 // clones a track list by using AliDPhiBasicParticle which uses much less memory (used for event mixing)
1026 TObjArray* tracksClone = new TObjArray;
1027 tracksClone->SetOwner(kTRUE);
1029 for (Int_t i=0; i<tracks->GetEntriesFast(); i++)
1031 AliVParticle* particle = (AliVParticle*) tracks->At(i);
1032 tracksClone->Add(new AliDPhiBasicParticle(particle->Eta(), particle->Phi(), particle->Pt(), particle->Charge()));
1038 //____________________________________________________________________
1039 void AliAnalysisTaskPhiCorrelations::Initialize()
1042 fInputHandler = (AliInputEventHandler*)
1043 ((AliAnalysisManager::GetAnalysisManager())->GetInputEventHandler());
1045 fMcHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
1048 //____________________________________________________________________
1049 void AliAnalysisTaskPhiCorrelations::RemoveDuplicates(TObjArray* tracks)
1051 // remove particles with the same label
1053 Int_t before = tracks->GetEntriesFast();
1055 for (Int_t i=0; i<before; ++i)
1057 AliVParticle* part = (AliVParticle*) tracks->At(i);
1059 for (Int_t j=i+1; j<before; ++j)
1061 AliVParticle* part2 = (AliVParticle*) tracks->At(j);
1063 if (part->GetLabel() == part2->GetLabel())
1065 Printf("Removing %d with label %d (duplicated in %d)", i, part->GetLabel(), j); part->Dump(); part2->Dump();
1066 TObject* object = tracks->RemoveAt(i);
1067 if (tracks->IsOwner())
1076 if (before > tracks->GetEntriesFast())
1077 AliInfo(Form("Reduced from %d to %d", before, tracks->GetEntriesFast()));