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),
73 fCalculateTOFmismatch(kTRUE),
76 fLvsEtaProjections(0x0),
82 // Default Constructor.
85 if (fDebug > 0) {AliInfo("AliAnalysisTaskDiHadronPID Default Constructor.");}
87 for (Int_t iPtClass = 0; iPtClass < 5; iPtClass++) {
88 for (Int_t iSpecies = 0; iSpecies < 3; iSpecies++) {
89 fCorrelationsTOF[iPtClass][iSpecies] = 0x0;
90 fCorrelationsTOFTPC[iPtClass][iSpecies] = 0x0;
97 // -------------------------------------------------------------------------
98 AliAnalysisTaskDiHadronPID::AliAnalysisTaskDiHadronPID(const char* name):
99 AliAnalysisTaskSE(name),
102 fTrackCutsTrigger(0x0),
103 fTrackCutsAssociated(0x0),
106 fAssociatedTracks(0x0),
107 fCurrentAODEvent(0x0),
115 fMinNEventsForMixing(5),
116 fPoolTrackDepth(2000),
119 fMixTriggers(kFALSE),
120 fCalculateTOFmismatch(kTRUE),
123 fLvsEtaProjections(0x0),
129 // Named Constructor.
132 if (fDebug > 0) {cout << Form("File: %s, Line: %i, Function: %s",__FILE__,__LINE__,__func__) << endl;}
134 for (Int_t iPtClass = 0; iPtClass < 5; iPtClass++) {
135 for (Int_t iSpecies = 0; iSpecies < 3; iSpecies++) {
136 fCorrelationsTOF[iPtClass][iSpecies] = 0x0;
137 fCorrelationsTOFTPC[iPtClass][iSpecies] = 0x0;
141 DefineInput(0,TChain::Class());
142 DefineOutput(1,TList::Class());
146 // -------------------------------------------------------------------------
147 AliAnalysisTaskDiHadronPID::~AliAnalysisTaskDiHadronPID() {;
153 if (fDebug > 0) {cout << Form("File: %s, Line: %i, Function: %s",__FILE__,__LINE__,__func__) << endl;}
157 // -------------------------------------------------------------------------
158 void AliAnalysisTaskDiHadronPID::UserCreateOutputObjects() {
161 // Create Output objects.
164 if (fDebug > 0) {cout << Form("File: %s, Line: %i, Function: %s",__FILE__,__LINE__,__func__) << endl;}
166 // --- BEGIN: Initialization on the worker nodes ---
167 AliAnalysisManager* manager = AliAnalysisManager::GetAnalysisManager();
168 AliInputEventHandler* inputHandler = dynamic_cast<AliInputEventHandler*> (manager->GetInputEventHandler());
170 // Getting the pointer to the PID response object.
171 fPIDResponse = inputHandler->GetPIDResponse();
173 // Not very neat - only set up for 0-5% analysis.
174 Int_t nCentralityBins = 5;
175 Double_t centralityBins[] = {0.,1.,2.,3.,4.,5.};
178 Double_t vertexBins[] = {-7.,-5.,-3.,-1.,1.,3.,5.,7.};
180 fPoolMgr = new AliEventPoolManager(fPoolSize, fPoolTrackDepth, nCentralityBins, (Double_t*) centralityBins, nZvtxBins, (Double_t*) vertexBins);
183 // Create the output list.
184 fOutputList = new TList();
185 fOutputList->SetOwner(kTRUE);
187 // Creating all requested histograms locally.
188 fEventCuts->CreateHistos();
189 fOutputList->Add(fEventCuts);
191 fTrackCutsTrigger->CreateHistos();
192 fOutputList->Add(fTrackCutsTrigger);
194 fTrackCutsAssociated->CreateHistos();
195 fOutputList->Add(fTrackCutsAssociated);
197 // Get the pT axis for the PID histograms.
198 Double_t* ptaxis = fTrackCutsAssociated->GetPtAxisPID();
199 Int_t nptbins = fTrackCutsAssociated->GetNPtBinsPID();
201 // Create Pt spectrum histogram.
202 fPtSpectrum = new TH1F("fPtSpectrum","p_{T} Spectrum;p_{T} (GeV/c);Count",nptbins,ptaxis);
203 fOutputList->Add(fPtSpectrum);
205 // Create unidentified correlations histogram.
206 fCorrelations = AliHistToolsDiHadronPID::MakeHist3D("fCorrelations","Correlations;#Delta#phi;#Delta#eta;p_{T} (GeV/c)",
207 fNDPhiBins,-TMath::Pi()/2.,3.*TMath::Pi()/2.,
210 fOutputList->Add(fCorrelations);
212 // Create unidentified mixed events histogram.
213 fMixedEvents = AliHistToolsDiHadronPID::MakeHist3D("fMixedEvents","Mixed Events;#Delta#phi;#Delta#eta;p_{T} (GeV/c)",
214 fNDPhiBins,-TMath::Pi()/2.,3.*TMath::Pi()/2.,
217 fOutputList->Add(fMixedEvents);
219 // Create TOF correlations histograms (DPhi,DEta,pt,TOF).
220 fTOFhistos = new TObjArray(15);
221 fTOFhistos->SetName("CorrelationsTOF");
222 fTOFhistos->SetOwner(kTRUE);
224 Int_t nbins[4] = {fNDPhiBins,fNDEtaBins,0,0};
225 Double_t min[4] = {-TMath::Pi()/2.,-1.6,0.,0.};
226 Double_t max[4] = {3.*TMath::Pi()/2.,1.6,0.,0.};
228 for (Int_t iPtClass = 0; iPtClass < 5; iPtClass++) {
230 nbins[2] = fTrackCutsAssociated->GetNPtBinsPID(iPtClass);
231 min[2] = fTrackCutsAssociated->GetPtClassMin(iPtClass);
232 max[2] = fTrackCutsAssociated->GetPtClassMax(iPtClass);
234 for (Int_t iSpecies = 0; iSpecies < 3; iSpecies++) {
236 nbins[3] = fTrackCutsAssociated->GetNTOFbins(iPtClass,iSpecies);
237 min[3] = fTrackCutsAssociated->GetTOFmin(iPtClass,iSpecies);
238 max[3] = fTrackCutsAssociated->GetTOFmax(iPtClass,iSpecies);
240 fCorrelationsTOF[iPtClass][iSpecies] = new THnF(
241 Form("fCorrelationsTOF_%i_%i",iPtClass,iSpecies),
242 Form("CorrelationsTOF_%i_%i",iPtClass,iSpecies),
245 fTOFhistos->Add(fCorrelationsTOF[iPtClass][iSpecies]);
250 fOutputList->Add(fTOFhistos);
252 // TODO: Create TOF/TPC correlations histogram.
254 // Load external TOF histograms if flag is set.
255 if (fCalculateTOFmismatch) {LoadExtMismatchHistos();}
257 PostData(1,fOutputList);
261 // -------------------------------------------------------------------------
262 void AliAnalysisTaskDiHadronPID::LocalInit() {
265 // Initialize on the client. (or on my computer?? - I think so...)
268 if (fDebug > 0) {cout << Form("File: %s, Line: %i, Function: %s",__FILE__,__LINE__,__func__) << endl;}
272 // -------------------------------------------------------------------------
273 void AliAnalysisTaskDiHadronPID::UserExec(Option_t*) {
279 if (fDebug > 0) {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 AliEventPool* poolin = fPoolMgr->GetEventPool(percentile, vtxz);
368 if (!poolin) {AliFatal(Form("No pool found for centrality = %f, vtxz = %f", percentile, vtxz));}
369 // TObjArray* fGlobalTracksArray;
371 // Give a print out of the pool manager's contents.
372 if (fDebug > 0) PrintPoolManagerContents();
374 // Mix events if there are enough events in the pool.
375 if (poolin->GetCurrentNEvents() >= fMinNEventsForMixing) {
376 {cout << "Mixing Events." << endl;}
378 // Loop over all events in the event pool.
379 for (Int_t iMixEvent = 0; iMixEvent < poolin->GetCurrentNEvents(); iMixEvent++) {
380 TObjArray* mixtracks = poolin->GetEvent(iMixEvent);
382 // Mix either the triggers or the associateds.
385 // Loop over all associateds in this event.
386 for (Int_t iAssociated = 0; iAssociated < fAssociatedTracks->GetEntriesFast(); iAssociated++) {
387 AliTrackDiHadronPID* associatedtrack = (AliTrackDiHadronPID*)fAssociatedTracks->At(iAssociated);
389 // Loop over all mixed tracks.
390 for (Int_t iMixTrack = 0; iMixTrack < mixtracks->GetEntriesFast(); iMixTrack++) {
391 AliTrackDiHadronPID* mixtrack = (AliTrackDiHadronPID*)mixtracks->At(iMixTrack);
393 Double_t DPhi = mixtrack->Phi() - associatedtrack->Phi();
394 if (DPhi < -TMath::Pi()/2.) {DPhi += 2.*TMath::Pi();}
395 if (DPhi > 3.*TMath::Pi()/2.) {DPhi -= 2.*TMath::Pi();}
397 Double_t DEta = mixtrack->Eta() - associatedtrack->Eta();
398 fMixedEvents->Fill(DPhi,DEta,associatedtrack->Pt());
405 // Loop over all triggers in this event.
406 for (Int_t iTrigger = 0; iTrigger < fTriggerTracks->GetEntriesFast(); iTrigger++) {
407 AliTrackDiHadronPID* triggertrack = (AliTrackDiHadronPID*)fTriggerTracks->At(iTrigger);
409 // Loop over all mixed tracks.
410 for (Int_t iMixTrack = 0; iMixTrack < mixtracks->GetEntriesFast(); iMixTrack++) {
411 AliTrackDiHadronPID* mixtrack = (AliTrackDiHadronPID*)mixtracks->At(iMixTrack);
413 Double_t DPhi = triggertrack->Phi() - mixtrack->Phi();
414 if (DPhi < -TMath::Pi()/2.) {DPhi += 2.*TMath::Pi();}
415 if (DPhi > 3.*TMath::Pi()/2.) {DPhi -= 2.*TMath::Pi();}
417 Double_t DEta = triggertrack->Eta() - mixtrack->Eta();
418 fMixedEvents->Fill(DPhi,DEta,mixtrack->Pt());
427 // Update the event pool.
428 AliEventPool* poolout = fPoolMgr->GetEventPool(percentile, vtxz); // Get the buffer associated with the current centrality and z-vtx
429 if (!poolout) AliFatal(Form("No pool found for centrality = %f, vtx_z = %f", percentile, vtxz));
431 // Q: is it a problem that the fAssociatedTracks array can be bigger than the number of tracks inside?
433 poolout->UpdatePool(fTriggerTracks);
434 fAssociatedTracks->Delete();
435 delete fAssociatedTracks;
438 poolout->UpdatePool(fAssociatedTracks);
439 fTriggerTracks->Delete();
440 delete fTriggerTracks;
443 fTriggerTracks = 0x0;
444 fAssociatedTracks = 0x0;
446 // Tell the track cut object that the event is done.
447 fTrackCutsTrigger->EventIsDone(0);
448 fTrackCutsAssociated->EventIsDone(0);
450 PostData(1,fOutputList);
454 // -------------------------------------------------------------------------
455 Bool_t AliAnalysisTaskDiHadronPID::LoadExtMismatchHistos() {
458 // Attempting to load a root file containing information needed
459 // to generate random TOF hits.
462 if (fDebug > 0) {cout << Form("File: %s, Line: %i, Function: %s",__FILE__,__LINE__,__func__) << endl;}
464 // Opening external TOF file.
465 if (fDebug > 0) cout<<"Trying to open TOFmismatchHistos.root ..."<<endl;
467 fin = TFile::Open("alien:///alice/cern.ch/user/m/mveldhoe/rootfiles/TOFmismatchHistos.root");
469 AliWarning("Couln't open TOFmismatchHistos, will not calculate mismatches...");
470 fCalculateTOFmismatch = kFALSE;
474 // Check if the required histograms are present.
475 TH1F* tmp1 = (TH1F*)fin->Get("hNewT0Fill");
477 AliWarning("Couln't find hNewT0Fill, will not calculate mismatches...");
478 fCalculateTOFmismatch = kFALSE;
481 TH2F* tmp2 = (TH2F*)fin->Get("hLvsEta");
483 AliWarning("Couln't find hLvsEta, will not calculate mismatches...");
484 fCalculateTOFmismatch = kFALSE;
488 // Make a deep copy of the files in the histogram.
489 fT0Fill = (TH1F*)tmp1->Clone("fT0Fill");
490 fLvsEta = (TH2F*)tmp2->Clone("fLvsEta");
492 // Close the external file.
493 AliInfo("Closing external file.");
496 // Creating a TObjArray for LvsEta projections.
497 const Int_t nbinseta = fLvsEta->GetNbinsX();
498 fLvsEtaProjections = new TObjArray(nbinseta);
499 fLvsEtaProjections->SetOwner(kTRUE);
501 // Making the projections needed (excluding underflow/ overflow).
502 for (Int_t iEtaBin = 1; iEtaBin < (nbinseta + 1); iEtaBin++) {
503 TH1F* tmp = (TH1F*)fLvsEta->ProjectionY(Form("LvsEtaProjection_%i",iEtaBin),iEtaBin,iEtaBin);
504 tmp->SetDirectory(0);
505 fLvsEtaProjections->AddAt(tmp,iEtaBin);
512 // -------------------------------------------------------------------------
513 Double_t AliAnalysisTaskDiHadronPID::GenerateRandomHit(Double_t eta) {
516 // Returns a random TOF time.
519 if (fDebug > 0) {cout << Form("File: %s, Line: %i, Function: %s",__FILE__,__LINE__,__func__) << endl;}
521 // Default (error) value:
522 Double_t rndhittime = -1.e21;
524 // TOF mismatch flag is not turned on.
525 if (!fCalculateTOFmismatch) {
526 AliFatal("Called GenerateRandomHit() method, but flag fCalculateTOFmismatch not set.");
530 // TOF doesn't extend much further than 0.8.
531 if (TMath::Abs(eta) > 0.8) {
532 if (fDebug) {AliInfo("Tried to get a random hit for a track with eta > 0.8.");}
536 // Finding the bin of the eta.
537 TAxis* etaAxis = fLvsEta->GetXaxis();
538 Int_t etaBin = etaAxis->FindBin(eta);
539 //cout<<"Eta: "<<eta<<" bin: "<<etaBin<<endl;
540 const TH1F* lengthDistribution = (const TH1F*)fLvsEtaProjections->At(etaBin);
542 if (!lengthDistribution) {
543 AliFatal("length Distribution not found.");
547 Double_t currentRndLength = lengthDistribution->GetRandom(); // in cm.
549 // Similar to Roberto's code.
550 Double_t currentRndTime = currentRndLength / (TMath::C() * 1.e2 / 1.e12);
551 Double_t t0fill = -1.26416e+04;
552 rndhittime = fT0Fill->GetRandom() - t0fill + currentRndTime;
558 // -------------------------------------------------------------------------
559 void AliAnalysisTaskDiHadronPID::PrintPoolManagerContents() {
562 // Prints out the current contents of the event pool manager.
565 // Determine the number of pools in the pool manager.
566 AliEventPool* poolin = fPoolMgr->GetEventPool(0,0);
567 Int_t NPoolsCentrality = 0;
570 poolin = fPoolMgr->GetEventPool(NPoolsCentrality,0);
573 poolin = fPoolMgr->GetEventPool(0,0);
574 Int_t NPoolsVtxZ = 0;
577 poolin = fPoolMgr->GetEventPool(0,NPoolsVtxZ);
580 // Loop over all Pools in the matrix of the pool manager.
581 cout<<" Pool manager contents: (Nevt,NTrack)"<<endl;
582 for (Int_t iCentrality = 0; iCentrality < NPoolsCentrality; iCentrality++) {
583 cout<<Form("Centrality Bin: %2i --> ", iCentrality);
585 for (Int_t iVtxZ = 0; iVtxZ < NPoolsVtxZ; iVtxZ++) {
587 poolin = fPoolMgr->GetEventPool(iCentrality, iVtxZ);
589 cout<<Form("(%2i,%4i) ",poolin->GetCurrentNEvents(), poolin->NTracksInPool());
598 // -------------------------------------------------------------------------
599 void AliAnalysisTaskDiHadronPID::Terminate(Option_t*) {;
602 // Called when task is done.
605 if (fDebug > 0) {cout << Form("File: %s, Line: %i, Function: %s",__FILE__,__LINE__,__func__) << endl;}
611 delete fLvsEtaProjections;
612 fLvsEtaProjections = 0x0;