1 // -------------------------------------------------------------------------
3 // -------------------------------------------------------------------------
15 #include "TObjArray.h"
18 #include "AliAnalysisManager.h"
19 #include "AliInputEventHandler.h"
21 // Event pool includes.
22 #include "AliEventPoolManager.h"
25 #include "AliPIDResponse.h"
28 #include "AliAODEvent.h"
29 #include "AliAODTrack.h"
30 #include "AliAODHandler.h"
31 #include "AliAODVertex.h"
32 #include "AliAODInputHandler.h"
33 #include "AliAODMCParticle.h"
34 #include "AliAODMCHeader.h"
36 // Additional includes.
37 #include "AliTrackDiHadronPID.h"
38 #include "AliAODTrackCutsDiHadronPID.h"
39 #include "AliAODEventCutsDiHadronPID.h"
40 #include "AliHistToolsDiHadronPID.h"
42 // AnalysisTask headers.
43 #include "AliAnalysisTaskSE.h"
44 #include "AliAnalysisTaskDiHadronPID.h"
48 ClassImp(AliAnalysisTaskDiHadronPID);
50 // -------------------------------------------------------------------------
51 AliAnalysisTaskDiHadronPID::AliAnalysisTaskDiHadronPID():
55 fTrackCutsTrigger(0x0),
56 fTrackCutsAssociated(0x0),
59 fAssociatedTracks(0x0),
60 fCurrentAODEvent(0x0),
68 fMinNEventsForMixing(5),
69 fPoolTrackDepth(2000),
71 fCalculateTOFmismatch(kTRUE),
74 fLvsEtaProjections(0x0),
80 // Default Constructor.
83 if (fDebug > 0) {AliInfo("AliAnalysisTaskDiHadronPID Default Constructor.");}
85 for (Int_t iPtClass = 0; iPtClass < 5; iPtClass++) {
86 for (Int_t iSpecies = 0; iSpecies < 3; iSpecies++) {
87 fCorrelationsTOF[iPtClass][iSpecies] = 0x0;
88 fCorrelationsTOFTPC[iPtClass][iSpecies] = 0x0;
95 // -------------------------------------------------------------------------
96 AliAnalysisTaskDiHadronPID::AliAnalysisTaskDiHadronPID(const char* name):
97 AliAnalysisTaskSE(name),
100 fTrackCutsTrigger(0x0),
101 fTrackCutsAssociated(0x0),
104 fAssociatedTracks(0x0),
105 fCurrentAODEvent(0x0),
113 fMinNEventsForMixing(5),
114 fPoolTrackDepth(2000),
116 fCalculateTOFmismatch(kTRUE),
119 fLvsEtaProjections(0x0),
125 // Named Constructor.
128 if (fDebug > 0) {AliInfo("AliAnalysisTaskDiHadronPID Named Constructor.");}
129 if (fDebug) {cout << Form("File: %s, Line: %i, Function: %s",__FILE__,__LINE__,__func__) << endl;}
131 for (Int_t iPtClass = 0; iPtClass < 5; iPtClass++) {
132 for (Int_t iSpecies = 0; iSpecies < 3; iSpecies++) {
133 fCorrelationsTOF[iPtClass][iSpecies] = 0x0;
134 fCorrelationsTOFTPC[iPtClass][iSpecies] = 0x0;
138 DefineInput(0,TChain::Class());
139 DefineOutput(1,TList::Class());
143 // -------------------------------------------------------------------------
144 AliAnalysisTaskDiHadronPID::~AliAnalysisTaskDiHadronPID() {;
150 if (fDebug > 0) {AliInfo("AliAnalysisTaskDiHadronPID Destructor.");}
151 if (fDebug) {cout << Form("File: %s, Line: %i, Function: %s",__FILE__,__LINE__,__func__) << endl;}
155 // -------------------------------------------------------------------------
156 void AliAnalysisTaskDiHadronPID::UserCreateOutputObjects() {
159 // Create Output objects.
162 if (fDebug > 0) {AliInfo("UserCreateOutputObjects()");}
163 if (fDebug) {cout << Form("File: %s, Line: %i, Function: %s",__FILE__,__LINE__,__func__) << endl;}
165 // --- BEGIN: Initialization on the worker nodes ---
166 AliAnalysisManager* manager = AliAnalysisManager::GetAnalysisManager();
167 AliInputEventHandler* inputHandler = dynamic_cast<AliInputEventHandler*> (manager->GetInputEventHandler());
169 // Getting the pointer to the PID response object.
170 fPIDResponse = inputHandler->GetPIDResponse();
172 // Not very neat - only set up for 0-5% analysis.
173 Int_t nCentralityBins = 5;
174 Double_t centralityBins[] = {0.,1.,2.,3.,4.,5.};
177 Double_t vertexBins[] = {-7.,-5.,-3.,-1.,1.,3.,5.,7.};
179 fPoolMgr = new AliEventPoolManager(fPoolSize, fPoolTrackDepth, nCentralityBins, (Double_t*) centralityBins, nZvtxBins, (Double_t*) vertexBins);
182 // Create the output list.
183 fOutputList = new TList();
184 fOutputList->SetOwner(kTRUE);
186 // Creating all requested histograms locally.
187 fEventCuts->CreateHistos();
188 fOutputList->Add(fEventCuts);
190 fTrackCutsTrigger->CreateHistos();
191 fOutputList->Add(fTrackCutsTrigger);
193 fTrackCutsAssociated->CreateHistos();
194 fOutputList->Add(fTrackCutsAssociated);
196 // Get the pT axis for the PID histograms.
197 Float_t* ptaxis = fTrackCutsAssociated->GetPtAxisPID();
198 Int_t nptbins = fTrackCutsAssociated->GetNPtBinsPID();
200 // Create Pt spectrum histogram.
201 fPtSpectrum = new TH1F("fPtSpectrum","p_{T} Spectrum;p_{T} (GeV/c);Count",nptbins,ptaxis);
202 fOutputList->Add(fPtSpectrum);
204 // Create unidentified correlations histogram.
205 fCorrelations = AliHistToolsDiHadronPID::MakeHist3D("fCorrelations","Correlations;#Delta#phi;#Delta#eta;p_{T} (GeV/c)",
206 fNDPhiBins,-TMath::Pi()/2.,3.*TMath::Pi()/2.,
209 fOutputList->Add(fCorrelations);
211 // Create unidentified mixed events histogram.
212 fMixedEvents = AliHistToolsDiHadronPID::MakeHist3D("fMixedEvents","Mixed Events;#Delta#phi;#Delta#eta;p_{T} (GeV/c)",
213 fNDPhiBins,-TMath::Pi()/2.,3.*TMath::Pi()/2.,
216 fOutputList->Add(fMixedEvents);
218 // Create TOF correlations histograms (DPhi,DEta,pt,TOF).
219 fTOFhistos = new TObjArray(15);
220 fTOFhistos->SetName("CorrelationsTOF");
222 Int_t nbins[4] = {fNDPhiBins,fNDEtaBins,0.,0.};
223 Double_t min[4] = {-TMath::Pi()/2.,-1.6,0.,0.};
224 Double_t max[4] = {3.*TMath::Pi()/2.,1.6,0.,0.};
226 for (Int_t iPtClass = 0; iPtClass < 5; iPtClass++) {
228 nbins[2] = fTrackCutsAssociated->GetNPtBinsPID(iPtClass);
229 min[2] = fTrackCutsAssociated->GetPtClassMin(iPtClass);
230 max[2] = fTrackCutsAssociated->GetPtClassMax(iPtClass);
232 for (Int_t iSpecies = 0; iSpecies < 3; iSpecies++) {
234 nbins[3] = fTrackCutsAssociated->GetNTOFbins(iPtClass,iSpecies);
235 min[3] = fTrackCutsAssociated->GetTOFmin(iPtClass,iSpecies);
236 max[3] = fTrackCutsAssociated->GetTOFmax(iPtClass,iSpecies);
238 fCorrelationsTOF[iPtClass][iSpecies] = new THnF(
239 Form("fCorrelationsTOF_%i_%i",iPtClass,iSpecies),
240 Form("CorrelationsTOF_%i_%i",iPtClass,iSpecies),
243 fTOFhistos->Add(fCorrelationsTOF[iPtClass][iSpecies]);
248 fOutputList->Add(fTOFhistos);
250 // TODO: Create TOF/TPC correlations histogram.
252 // Load external TOF histograms if flag is set.
253 if (fCalculateTOFmismatch) {LoadExtMismatchHistos();}
255 PostData(1,fOutputList);
259 // -------------------------------------------------------------------------
260 void AliAnalysisTaskDiHadronPID::LocalInit() {
263 // Initialize on the client. (or on my computer?? - I think so...)
266 if (fDebug > 0) {AliInfo("LocalInit()");}
267 if (fDebug) {cout << Form("File: %s, Line: %i, Function: %s",__FILE__,__LINE__,__func__) << endl;}
271 // -------------------------------------------------------------------------
272 void AliAnalysisTaskDiHadronPID::UserExec(Option_t*) {
278 if (fDebug > 0) {AliInfo("UserExec()");}
279 if (fDebug) {cout << Form("File: %s, Line: %i, Function: %s",__FILE__,__LINE__,__func__) << endl;}
281 // Input Current Event.
282 fCurrentAODEvent = dynamic_cast<AliAODEvent*>(InputEvent());
283 if (!fCurrentAODEvent) AliFatal("No Event Found!");
285 if (!fEventCuts->IsSelected(fCurrentAODEvent)) {return;}
287 // Fill the global tracks array. - NOT NEEDED I THINK, since we're not using
288 // bit 1<<7 for the associated tracks!
290 // Let the track cut objects know that a new event will start.
291 fTrackCutsTrigger->StartNewEvent();
292 fTrackCutsAssociated->StartNewEvent();
294 // Create arrays for trigger/associated particles.
295 fTriggerTracks = new TObjArray(350);
296 fTriggerTracks->SetOwner(kTRUE);
298 fAssociatedTracks = new TObjArray(3500);
299 fAssociatedTracks->SetOwner(kTRUE);
301 for (Int_t iTrack = 0; iTrack < fCurrentAODEvent->GetNumberOfTracks(); iTrack++) {
303 AliAODTrack* track = (AliAODTrack*)fCurrentAODEvent->GetTrack(iTrack);
304 AliTrackDiHadronPID* pidtrack = new AliTrackDiHadronPID(track,0x0,0x0,fPIDResponse);
305 pidtrack->ForgetAboutPointers();
306 pidtrack->SetDebugLevel(fDebug);
308 Double_t rndhittime = -1.e21;
309 if (fCalculateTOFmismatch) rndhittime = GenerateRandomHit(pidtrack->Eta());
311 // Fill p_T spectrum.
312 fPtSpectrum->Fill(pidtrack->Pt());
314 // Fill the trigger/associated tracks array.
315 if (fTrackCutsTrigger->IsSelectedData(pidtrack,rndhittime)) {fTriggerTracks->AddLast(pidtrack);}
316 else if (fTrackCutsAssociated->IsSelectedData(pidtrack,rndhittime)) {fAssociatedTracks->AddLast(pidtrack);}
317 else {delete pidtrack;}
321 // Fill Correlation histograms.
322 for (Int_t iTrigger = 0; iTrigger < fTriggerTracks->GetEntriesFast(); iTrigger++) {
323 AliTrackDiHadronPID* triggertrack = (AliTrackDiHadronPID*)fTriggerTracks->At(iTrigger);
325 for (Int_t iAssociated = 0; iAssociated < fAssociatedTracks->GetEntriesFast(); iAssociated++) {
326 AliTrackDiHadronPID* associatedtrack = (AliTrackDiHadronPID*)fAssociatedTracks->At(iAssociated);
328 Double_t DPhi = triggertrack->Phi() - associatedtrack->Phi();
329 if (DPhi < -TMath::Pi()/2.) {DPhi += 2.*TMath::Pi();}
330 if (DPhi > 3.*TMath::Pi()/2.) {DPhi -= 2.*TMath::Pi();}
332 Double_t DEta = triggertrack->Eta() - associatedtrack->Eta();
333 fCorrelations->Fill(DPhi,DEta,associatedtrack->Pt());
335 Double_t tofhistfill[4] = {DPhi,DEta,associatedtrack->Pt(),-999.};
337 for (Int_t iSpecies = 0; iSpecies < 3; iSpecies++) {
338 tofhistfill[3] = associatedtrack->GetTOFsignalMinusExpected(iSpecies);
340 for (Int_t iPtClass = 0; iPtClass < 5; iPtClass++) {
342 // prevent under/over-flow bins to be filled.
343 Double_t ptmin = fTrackCutsAssociated->GetPtClassMin(iPtClass);
344 Double_t ptmax = fTrackCutsAssociated->GetPtClassMax(iPtClass);
345 Double_t apt = associatedtrack->Pt();
347 if ( (apt > ptmin) && (apt < ptmax) ) {
348 fCorrelationsTOF[iPtClass][iSpecies]->Fill(tofhistfill);
356 cout<<"Triggers: "<<fTriggerTracks->GetEntriesFast()<<" Associateds: "<<fAssociatedTracks->GetEntriesFast()<<endl;
358 // Determine centrality of current event.
359 TString centralityestimator = fEventCuts->GetCentralityEstimator();
360 AliCentrality* currentcentrality = fCurrentAODEvent->GetCentrality();
361 Float_t percentile = currentcentrality->GetCentralityPercentile(centralityestimator.Data());
363 // Determine vtxz of current event.
364 AliAODVertex* currentprimaryvertex = fCurrentAODEvent->GetPrimaryVertex();
365 Double_t vtxz = currentprimaryvertex->GetZ();
367 // Obtain event pool for current centrality/ vtxz.
368 AliEventPool* poolin = fPoolMgr->GetEventPool(percentile, vtxz);
369 if (!poolin) {AliFatal(Form("No pool found for centrality = %f, vtxz = %f", percentile, vtxz));}
370 // TObjArray* fGlobalTracksArray;
372 // Mix events if there are enough events in the pool. (TODO: should be a data member.)
373 if (poolin->GetCurrentNEvents() >= fMinNEventsForMixing) {
374 if (fDebug) {AliInfo("Mixing Events.");}
376 // Loop over all triggers in this event.
377 for (Int_t iTrigger = 0; iTrigger < fTriggerTracks->GetEntriesFast(); iTrigger++) {
378 AliTrackDiHadronPID* triggertrack = (AliTrackDiHadronPID*)fTriggerTracks->At(iTrigger);
380 // Loop over all events in the event pool.
381 for (Int_t iMixEvent = 0; iMixEvent < poolin->GetCurrentNEvents(); iMixEvent++) {
382 TObjArray* mixtracks = poolin->GetEvent(iMixEvent);
384 // Loop over all mixed tracks.
385 for (Int_t iMixTrack = 0; iMixTrack < mixtracks->GetEntriesFast(); iMixTrack++) {
386 AliTrackDiHadronPID* mixtrack = (AliTrackDiHadronPID*)mixtracks->At(iMixTrack);
388 Double_t DPhi = triggertrack->Phi() - mixtrack->Phi();
389 if (DPhi < -TMath::Pi()/2.) {DPhi += 2.*TMath::Pi();}
390 if (DPhi > 3.*TMath::Pi()/2.) {DPhi -= 2.*TMath::Pi();}
392 Double_t DEta = triggertrack->Eta() - mixtrack->Eta();
393 fMixedEvents->Fill(DPhi,DEta,mixtrack->Pt());
400 // Update the event pool.
401 AliEventPool* poolout = fPoolMgr->GetEventPool(percentile, vtxz); // Get the buffer associated with the current centrality and z-vtx
402 if (!poolout) AliFatal(Form("No pool found for centrality = %f, vtx_z = %f", percentile, vtxz));
404 // Q: is it a problem that the fAssociatedTracks array can be bigger than the number of tracks inside?
405 poolout->UpdatePool(fAssociatedTracks);
407 // Delete trigger array and its contents. Set pointer to zero.
408 // Don't delete the associated array, since ownership has been transferred to the pool manager. Set pointer to zero.
409 fTriggerTracks->Delete();
410 delete fTriggerTracks;
411 fTriggerTracks = 0x0;
412 fAssociatedTracks = 0x0;
414 // Tell the track cut object that the event is done.
415 fTrackCutsTrigger->EventIsDone(0);
416 fTrackCutsAssociated->EventIsDone(0);
418 PostData(1,fOutputList);
422 // -------------------------------------------------------------------------
423 Bool_t AliAnalysisTaskDiHadronPID::LoadExtMismatchHistos() {
426 // Attempting to load a root file containing information needed
427 // to generate random TOF hits.
430 if (fDebug) {cout << Form("File: %s, Line: %i, Function: %s",__FILE__,__LINE__,__func__) << endl;}
432 // Opening external TOF file.
433 if (fDebug > 0) cout<<"Trying to open TOFmismatchHistos.root ..."<<endl;
435 fin = TFile::Open("alien:///alice/cern.ch/user/m/mveldhoe/rootfiles/TOFmismatchHistos.root");
437 AliWarning("Couln't open TOFmismatchHistos, will not calculate mismatches...");
438 fCalculateTOFmismatch = kFALSE;
442 // Check if the required histograms are present.
443 TH1F* tmp1 = (TH1F*)fin->Get("hNewT0Fill");
445 AliWarning("Couln't find hNewT0Fill, will not calculate mismatches...");
446 fCalculateTOFmismatch = kFALSE;
449 TH2F* tmp2 = (TH2F*)fin->Get("hLvsEta");
451 AliWarning("Couln't find hLvsEta, will not calculate mismatches...");
452 fCalculateTOFmismatch = kFALSE;
456 // Make a deep copy of the files in the histogram.
457 fT0Fill = (TH1F*)tmp1->Clone("fT0Fill");
458 fLvsEta = (TH2F*)tmp2->Clone("fLvsEta");
460 // Close the external file.
461 AliInfo("Closing external file.");
464 // Creating a TObjArray for LvsEta projections.
465 const Int_t nbinseta = fLvsEta->GetNbinsX();
466 fLvsEtaProjections = new TObjArray(nbinseta);
467 fLvsEtaProjections->SetOwner(kTRUE);
469 // Making the projections needed (excluding underflow/ overflow).
470 for (Int_t iEtaBin = 1; iEtaBin < (nbinseta + 1); iEtaBin++) {
471 TH1F* tmp = (TH1F*)fLvsEta->ProjectionY(Form("LvsEtaProjection_%i",iEtaBin),iEtaBin,iEtaBin);
472 tmp->SetDirectory(0);
473 fLvsEtaProjections->AddAt(tmp,iEtaBin);
480 // -------------------------------------------------------------------------
481 Double_t AliAnalysisTaskDiHadronPID::GenerateRandomHit(Double_t eta) {
484 // Returns a random TOF time.
487 if (fDebug) {cout << Form("File: %s, Line: %i, Function: %s",__FILE__,__LINE__,__func__) << endl;}
489 // Default (error) value:
490 Double_t rndhittime = -1.e21;
492 // TOF mismatch flag is not turned on.
493 if (!fCalculateTOFmismatch) {
494 AliFatal("Called GenerateRandomHit() method, but flag fCalculateTOFmismatch not set.");
498 // TOF doesn't extend much further than 0.8.
499 if (TMath::Abs(eta) > 0.8) {
500 if (fDebug) {AliInfo("Tried to get a random hit for a track with eta > 0.8.");}
504 // Finding the bin of the eta.
505 TAxis* etaAxis = fLvsEta->GetXaxis();
506 Int_t etaBin = etaAxis->FindBin(eta);
507 //cout<<"Eta: "<<eta<<" bin: "<<etaBin<<endl;
508 const TH1F* lengthDistribution = (const TH1F*)fLvsEtaProjections->At(etaBin);
510 if (!lengthDistribution) {
511 AliFatal("length Distribution not found.");
515 Double_t currentRndLength = lengthDistribution->GetRandom(); // in cm.
517 // Similar to Roberto's code.
518 Double_t currentRndTime = currentRndLength / (TMath::C() * 1.e2 / 1.e12);
519 Double_t t0fill = -1.26416e+04;
520 rndhittime = fT0Fill->GetRandom() - t0fill + currentRndTime;
526 // -------------------------------------------------------------------------
527 void AliAnalysisTaskDiHadronPID::Terminate(Option_t*) {;
530 // Called when task is done.
533 if (fDebug > 0) {AliInfo("Terminate()");}
534 if (fDebug) {cout << Form("File: %s, Line: %i, Function: %s",__FILE__,__LINE__,__func__) << endl;}
540 delete fLvsEtaProjections;
541 fLvsEtaProjections = 0x0;