1 /**************************************************************************
2 * Copyright(c) 1998-2009, 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 **************************************************************************/
17 // Base class for Heavy Flavour Correlations Analysis
18 // Single Event and Mixed Event Analysis are implemented
20 //-----------------------------------------------------------------------
23 // Author S.Bjelogrlic
25 // sandro.bjelogrlic@cern.ch
27 //-----------------------------------------------------------------------
31 #include <TParticle.h>
35 #include "AliHFCorrelator.h"
36 #include "AliRDHFCutsDStartoKpipi.h"
37 #include "AliHFAssociatedTrackCuts.h"
38 #include "AliEventPoolManager.h"
39 #include "AliReducedParticle.h"
40 #include "AliCentrality.h"
42 //_____________________________________________________
43 AliHFCorrelator::AliHFCorrelator() :
45 // default constructor
52 fAssociatedTracks(0x0),
62 fUseImpactParameter(0),
81 // default constructor
86 //_____________________________________________________
87 AliHFCorrelator::AliHFCorrelator(const Char_t* name, AliHFAssociatedTrackCuts *cuts, Bool_t ppOrPbPb) :
93 fAssociatedTracks(0x0),
103 fUseImpactParameter(0),
124 //_____________________________________________________
125 AliHFCorrelator::~AliHFCorrelator()
131 if(fPoolMgr) {delete fPoolMgr; fPoolMgr=0;}
132 if(fPool) {delete fPool; fPool=0;}
133 if(fhadcuts) {delete fhadcuts; fhadcuts=0;}
134 if(fAODEvent) {delete fAODEvent; fAODEvent=0;}
135 if(fAssociatedTracks) {delete fAssociatedTracks; fAssociatedTracks=0;}
136 if(fmcArray) {delete fmcArray; fmcArray=0;}
137 if(fReducedPart) {delete fReducedPart; fReducedPart=0;}
138 if(fD0cand) {delete fD0cand; fD0cand=0;}
141 if(fNofTracks) fNofTracks = 0;
143 if(fPhiMin) fPhiMin = 0;
144 if(fPhiMax) fPhiMax = 0;
146 if(fPtTrigger) fPtTrigger=0;
147 if(fPhiTrigger) fPhiTrigger=0;
148 if(fEtaTrigger) fEtaTrigger=0;
150 if(fDeltaPhi) fDeltaPhi=0;
151 if(fDeltaEta) fDeltaEta=0;
153 if(fk0InvMass) fk0InvMass=0;
156 //_____________________________________________________
157 Bool_t AliHFCorrelator::DefineEventPool(){
158 // definition of the Pool Manager for Event Mixing
161 Int_t MaxNofEvents = fhadcuts->GetMaxNEventsInPool();
162 Int_t MinNofTracks = fhadcuts->GetMinNTracksInPool();
163 Int_t NofCentBins = fhadcuts->GetNCentPoolBins();
164 Double_t * CentBins = fhadcuts->GetCentPoolBins();
165 Int_t NofZVrtxBins = fhadcuts->GetNZvtxPoolBins();
166 Double_t *ZVrtxBins = fhadcuts->GetZvtxPoolBins();
169 fPoolMgr = new AliEventPoolManager(MaxNofEvents, MinNofTracks, NofCentBins, CentBins, NofZVrtxBins, ZVrtxBins);
170 if(!fPoolMgr) return kFALSE;
173 //_____________________________________________________
174 Bool_t AliHFCorrelator::Initialize(){
176 cout << "AliHFCorrelator::Initialize"<< endl;
177 if(!fAODEvent) cout << "No AOD event" << endl;
179 AliCentrality *centralityObj = 0;
180 Int_t multiplicity = -1;
181 Double_t MultipOrCent = -1;
183 // initialize the pool for event mixing
185 multiplicity = fAODEvent->GetNTracks();
186 MultipOrCent = multiplicity; // convert from Int_t to Double_t
190 centralityObj = fAODEvent->GetHeader()->GetCentralityP();
191 MultipOrCent = centralityObj->GetCentralityPercentileUnchecked("V0M");
192 AliInfo(Form("Centrality is %f", MultipOrCent));
195 AliAODVertex *vtx = fAODEvent->GetPrimaryVertex();
196 Double_t zvertex = vtx->GetZ(); // zvertex
197 Double_t * CentBins = fhadcuts->GetCentPoolBins();
198 Double_t poolmin=CentBins[0];
199 Double_t poolmax=CentBins[fhadcuts->GetNCentPoolBins()];
200 cout << "pool limits in centr/multipl " << poolmin << " - " << poolmax << endl;
201 /* for (Int_t iM=0; iM<nMultBins; iM++) {
202 std::vector<AliEventPool*> evp;
203 for (Int_t iZ=0; iZ<nZvtxBins; iZ++) {
204 evp.push_back(new AliEventPool(depth,
205 multbin[iM], multbin[iM+1],
206 zvtxbin[iZ], zvtxbin[iZ+1] ));
208 fEvPool.push_back(evp);
210 // if(TMath::Abs(zvertex)>=10 || multip>500 || multip == 0) {
211 // AliInfo(Form("Event with Zvertex = %.2f cm and multiplicity = %.0f out of pool bounds, SKIPPING",zvertex,multip));
215 if(TMath::Abs(zvertex)>=10 || MultipOrCent>poolmax || MultipOrCent < poolmin) {
216 if(!fsystem)AliInfo(Form("pp Event with Zvertex = %.2f cm and multiplicity = %.0f out of pool bounds, SKIPPING",zvertex,MultipOrCent));
217 else AliInfo(Form("PbPb Event with Zvertex = %.2f cm and centrality = %.1f out of pool bounds, SKIPPING",zvertex,MultipOrCent));
222 fPool = fPoolMgr->GetEventPool(MultipOrCent, zvertex);
225 AliInfo(Form("No pool found for multiplicity = %f, zVtx = %f cm", MultipOrCent, zvertex));
232 //_____________________________________________________
233 Bool_t AliHFCorrelator::ProcessEventPool(){
234 // analysis on Mixed Events
235 cout << "AliHFCorrelator::ProcessEventPool"<< endl;
236 if(!fmixing) return kFALSE;
237 if(!fPool->IsReady()) return kFALSE;
238 if(fPool->GetCurrentNEvents()<fhadcuts->GetMinEventsToMix()) return kFALSE;
240 fPoolContent = fPool->GetCurrentNEvents();
246 //_____________________________________________________
247 Bool_t AliHFCorrelator::ProcessAssociatedTracks(Int_t EventLoopIndex){
249 fAssociatedTracks = new TObjArray();
251 if(!fmixing){ // analysis on Single Event
254 if(fselect==1 || fselect ==2) fAssociatedTracks = AcceptAndReduceTracks(fAODEvent);
255 if(fselect==3) {fAssociatedTracks = AcceptAndReduceKZero(fAODEvent);}
260 if(fmixing) { // analysis on Mixed Events
263 fAssociatedTracks = fPool->GetEvent(EventLoopIndex);
270 if(!fAssociatedTracks) return kFALSE;
272 fNofTracks = fAssociatedTracks->GetEntriesFast();
277 //_____________________________________________________
278 Bool_t AliHFCorrelator::Correlate(Int_t loopindex){
280 if(loopindex >= fNofTracks) return kFALSE;
281 if(!fAssociatedTracks) return kFALSE;
283 fReducedPart = (AliReducedParticle*)fAssociatedTracks->At(loopindex);
286 fDeltaPhi = SetCorrectPhiRange(fPhiTrigger - fReducedPart->Phi());
288 fDeltaEta = fEtaTrigger - fReducedPart->Eta();
294 //_____________________________________________________
295 Bool_t AliHFCorrelator::PoolUpdate(){
297 if(!fmixing) return kFALSE;
298 if(!fPool) return kFALSE;
299 if(fmixing) { // update the pool for Event Mixing
300 if(fselect==1 || fselect==2)fPool->UpdatePool(AcceptAndReduceTracks(fAODEvent)); // updating the pool for hadrons
301 if(fselect==3) fPool->UpdatePool(AcceptAndReduceKZero(fAODEvent)); // updating the pool for K0s
307 //_____________________________________________________
308 Double_t AliHFCorrelator::SetCorrectPhiRange(Double_t phi){
309 Double_t pi = TMath::Pi();
311 if(phi<fPhiMin) phi = phi + 2*pi;
312 if(phi>fPhiMax) phi = phi - 2*pi;
317 //_____________________________________________________
318 TObjArray* AliHFCorrelator::AcceptAndReduceTracks(AliAODEvent* inputEvent){
320 Int_t nTracks = inputEvent->GetNTracks();
321 AliAODVertex * vtx = inputEvent->GetPrimaryVertex();
322 Double_t Bz = inputEvent->GetMagneticField();
325 TObjArray* tracksClone = new TObjArray;
326 tracksClone->SetOwner(kTRUE);
327 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
329 AliAODTrack* track = inputEvent->GetTrack(iTrack);
330 if (!track) continue;
331 if(!fhadcuts->IsHadronSelected(track)) continue; // apply ESD level selections
333 Double_t pT = track->Pt();
335 //compute impact parameter
336 Double_t d0z0[2],covd0z0[3];
337 Double_t d0=-999999.;
338 if(fUseImpactParameter) track->PropagateToDCA(vtx,Bz,100,d0z0,covd0z0);
339 else d0z0[0] = 1. ; // random number - be careful with the cuts you applied
341 if(fUseImpactParameter==1) d0 = TMath::Abs(d0z0[0]); // use impact parameter
342 if(fUseImpactParameter==2) { // use impact parameter over resolution
343 if(TMath::Abs(covd0z0[0])>0.00000001) d0 = TMath::Abs(d0z0[0])/TMath::Abs(covd0z0[0]);
344 else d0 = -1.; // if the resoultion is Zero, rejects the track - to be on the safe side
351 if(!fhadcuts->CheckHadronKinematic(pT,d0))continue; // apply kinematic cuts
352 Bool_t rejectsoftpi = kFALSE;
353 if(fD0cand) rejectsoftpi = fhadcuts->InvMassDstarRejection(fD0cand,track,fhypD0);
357 if(!fhadcuts->CheckKaonCompatibility(track,fmontecarlo,fmcArray,fPIDmode)) continue; // check if it is a Kaon - data and MC
360 //AliVParticle * part = (AliVParticle*)track;
361 tracksClone->Add(new AliReducedParticle(track->Eta(), track->Phi(), pT,track->GetLabel(),track->GetID(),d0,rejectsoftpi));
368 //_____________________________________________________
369 TObjArray* AliHFCorrelator::AcceptAndReduceKZero(AliAODEvent* inputEvent){
371 Int_t nOfVZeros = inputEvent->GetNumberOfV0s();
372 TObjArray* KZeroClone = new TObjArray;
373 AliAODVertex *vertex1 = (AliAODVertex*)inputEvent->GetPrimaryVertex();
375 Int_t pdgDgK0toPipi[2] = {211,211};
376 Double_t mPDGK0=0.497614;//TDatabasePDG::Instance()->GetParticle(310)->Mass();
377 const Int_t size = inputEvent->GetNumberOfV0s();
378 Int_t prevnegID[size];
379 Int_t prevposID[size];
380 for(Int_t iv0 =0; iv0< nOfVZeros; iv0++){// loop on all v0 candidates
381 AliAODv0 *v0 = (static_cast<AliAODEvent*> (inputEvent))->GetV0(iv0);
382 if(!v0) {cout << "is not a v0 at step " << iv0 << endl; continue;}
384 if(!fhadcuts->IsKZeroSelected(v0,vertex1)) continue; // check if it is a k0
386 // checks to avoid double counting
390 prevnegID[iv0] = -997;
391 prevposID[iv0]= -996;
392 negID = v0->GetNegID();
393 posID = v0->GetPosID();
394 Bool_t DoubleCounting = kFALSE;
396 for(Int_t k=0; k<iv0; k++){
397 if(((negID==prevnegID[k])&&(posID==prevposID[k]))||((negID==prevposID[k])&&(posID==prevnegID[k]))){
398 DoubleCounting = kTRUE;
404 if(DoubleCounting) {cout << "SKIPPING DOUBLE COUNTING" << endl;continue;}
405 else{ prevposID[iv0] = posID; prevnegID[iv0] = negID;}
407 if(fmontecarlo) v0label = v0->MatchToMC(310,fmcArray, 0, pdgDgK0toPipi); //match a K0 short
408 Double_t k0pt = v0->Pt();
409 Double_t k0eta = v0->Eta();
410 Double_t k0Phi = v0->Phi();
411 fk0InvMass = v0->MassK0Short();
413 //if (loopindex == 0) {
414 // if(!plotassociation) ((TH2F*)fOutput->FindObject("KZeroSpectra"))->Fill(k0InvMass,k0pt); // spectra for all k0
415 // if(plotassociation) ((TH2F*)fOutput->FindObject("KZeroSpectraifHF"))->Fill(k0InvMass,k0pt); // spectra for k0 in association with a D*
417 // if there are more D* candidates per event, loopindex == 0 makes sure you fill the mass spectra only once!
419 if(TMath::Abs(fk0InvMass-mPDGK0)>3*0.004) continue; // select candidates within 3 sigma
420 KZeroClone->Add(new AliReducedParticle(k0eta,k0Phi,k0pt,v0label));