]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGHF/correlationHF/AliHFCorrelator.cxx
Completed changes needed because of previous commit
[u/mrichter/AliRoot.git] / PWGHF / correlationHF / AliHFCorrelator.cxx
CommitLineData
c683985a 1/**************************************************************************
2 * Copyright(c) 1998-2009, 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//
17// Base class for Heavy Flavour Correlations Analysis
18// Single Event and Mixed Event Analysis are implemented
19//
20//-----------------------------------------------------------------------
21//
22//
23// Author S.Bjelogrlic
24// Utrecht University
25// sandro.bjelogrlic@cern.ch
26//
27//-----------------------------------------------------------------------
28
1b8b4a2c 29/* $Id: AliHFCorrelator.cxx 64115 2013-09-05 12:34:55Z arossi $ */
c683985a 30
31#include <TParticle.h>
32#include <TVector3.h>
33#include <TChain.h>
34#include "TROOT.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"
41#include "AliAODMCParticle.h"
42
43using std::cout;
44using std::endl;
45
46//_____________________________________________________
47AliHFCorrelator::AliHFCorrelator() :
48//
49// default constructor
50//
51TNamed(),
52fPoolMgr(0x0),
53fPool(0x0),
54fhadcuts(0x0),
55fAODEvent(0x0),
1b8b4a2c 56fDMesonCutObject(0x0),
c683985a 57fAssociatedTracks(0x0),
58fmcArray(0x0),
59fReducedPart(0x0),
60fD0cand(0x0),
61fhypD0(0),
62fDCharge(0),
63
64fmixing(kFALSE),
65fmontecarlo(kFALSE),
1b8b4a2c 66fUseCentrality(kFALSE),
c683985a 67fUseReco(kTRUE),
68fselect(kUndefined),
69
70fUseImpactParameter(0),
71fPIDmode(0),
72
73fNofTracks(0),
74fPoolContent(0),
75
76fPhiMin(0),
77fPhiMax(0),
78
1b8b4a2c
EB
79fMultCentr(-1),
80
c683985a 81fPtTrigger(0),
82fPhiTrigger(0),
83fEtaTrigger(0),
84
85
86fDeltaPhi(0),
87fDeltaEta(0),
88fk0InvMass(0)
89
90{
91 // default constructor
92}
93
94
95
96//_____________________________________________________
1b8b4a2c 97AliHFCorrelator::AliHFCorrelator(const Char_t* name, AliHFAssociatedTrackCuts *cuts, Bool_t useCentrality) :
c683985a 98TNamed(name,"title"),
99fPoolMgr(0x0),
100fPool(0x0),
101fhadcuts(0x0),
102fAODEvent(0x0),
1b8b4a2c 103fDMesonCutObject(0x0),
c683985a 104fAssociatedTracks(0x0),
105fmcArray(0x0),
106fReducedPart(0x0),
107fD0cand(0x0),
108fhypD0(0),
109fDCharge(0),
110
111fmixing(kFALSE),
112fmontecarlo(kFALSE),
1b8b4a2c
EB
113fUseCentrality(useCentrality),
114fUseReco(kTRUE),
115fselect(kUndefined),
116fUseImpactParameter(0),
117fPIDmode(0),
118
119fNofTracks(0),
120fPoolContent(0),
121
122fPhiMin(0),
123fPhiMax(0),
124
125fMultCentr(-1),
126
127fPtTrigger(0),
128fPhiTrigger(0),
129fEtaTrigger(0),
130
131
132fDeltaPhi(0),
133fDeltaEta(0),
134fk0InvMass(0)
135{
136 fhadcuts = cuts;
137 if(!fDMesonCutObject) AliInfo("D meson cut object not loaded - if using centrality the estimator will be V0M!");
138}
139
140//_______________________________________________________________________________________
141AliHFCorrelator::AliHFCorrelator(const Char_t* name, AliHFAssociatedTrackCuts *cuts, Bool_t useCentrality, AliRDHFCuts * cutObject) :
142TNamed(name,"title"),
143fPoolMgr(0x0),
144fPool(0x0),
145fhadcuts(0x0),
146fAODEvent(0x0),
147fDMesonCutObject(0x0),
148fAssociatedTracks(0x0),
149fmcArray(0x0),
150fReducedPart(0x0),
151fD0cand(0x0),
152fhypD0(0),
153fDCharge(0),
154
155fmixing(kFALSE),
156fmontecarlo(kFALSE),
157fUseCentrality(useCentrality),
c683985a 158fUseReco(kTRUE),
159fselect(kUndefined),
160fUseImpactParameter(0),
161fPIDmode(0),
162
163fNofTracks(0),
164fPoolContent(0),
165
166fPhiMin(0),
167fPhiMax(0),
168
1b8b4a2c
EB
169fMultCentr(-1),
170
c683985a 171fPtTrigger(0),
172fPhiTrigger(0),
173fEtaTrigger(0),
174
175
176fDeltaPhi(0),
177fDeltaEta(0),
178fk0InvMass(0)
179{
1b8b4a2c
EB
180 fhadcuts = cuts;
181 fDMesonCutObject = cutObject;
182
183 if(!fDMesonCutObject) AliInfo("D meson cut object not implemented properly! Check your centrality estimators");
c683985a 184}
185
1b8b4a2c
EB
186
187
c683985a 188//_____________________________________________________
189AliHFCorrelator::~AliHFCorrelator()
190{
191//
192// destructor
193//
194
195 if(fPoolMgr) {delete fPoolMgr; fPoolMgr=0;}
196 if(fPool) {delete fPool; fPool=0;}
197 if(fhadcuts) {delete fhadcuts; fhadcuts=0;}
198 if(fAODEvent) {delete fAODEvent; fAODEvent=0;}
1b8b4a2c 199 if(fDMesonCutObject) {delete fDMesonCutObject; fDMesonCutObject=0;}
c683985a 200 if(fAssociatedTracks) {delete fAssociatedTracks; fAssociatedTracks=0;}
201 if(fmcArray) {delete fmcArray; fmcArray=0;}
202 if(fReducedPart) {delete fReducedPart; fReducedPart=0;}
203 if(fD0cand) {delete fD0cand; fD0cand=0;}
204
205
206 if(fNofTracks) fNofTracks = 0;
207
208 if(fPhiMin) fPhiMin = 0;
209 if(fPhiMax) fPhiMax = 0;
210
211 if(fPtTrigger) fPtTrigger=0;
212 if(fPhiTrigger) fPhiTrigger=0;
213 if(fEtaTrigger) fEtaTrigger=0;
214
215 if(fDeltaPhi) fDeltaPhi=0;
216 if(fDeltaEta) fDeltaEta=0;
217
218 if(fk0InvMass) fk0InvMass=0;
219
220}
221//_____________________________________________________
222Bool_t AliHFCorrelator::DefineEventPool(){
223 // definition of the Pool Manager for Event Mixing
224
225
226 Int_t MaxNofEvents = fhadcuts->GetMaxNEventsInPool();
227 Int_t MinNofTracks = fhadcuts->GetMinNTracksInPool();
228 Int_t NofCentBins = fhadcuts->GetNCentPoolBins();
229 Double_t * CentBins = fhadcuts->GetCentPoolBins();
230 Int_t NofZVrtxBins = fhadcuts->GetNZvtxPoolBins();
231 Double_t *ZVrtxBins = fhadcuts->GetZvtxPoolBins();
232
233
234 fPoolMgr = new AliEventPoolManager(MaxNofEvents, MinNofTracks, NofCentBins, CentBins, NofZVrtxBins, ZVrtxBins);
235 if(!fPoolMgr) return kFALSE;
236 return kTRUE;
237}
238//_____________________________________________________
239Bool_t AliHFCorrelator::Initialize(){
240
241 // std::cout << "AliHFCorrelator::Initialize"<< std::endl;
242// AliInfo("AliHFCorrelator::Initialize") ;
243 if(!fAODEvent){
244 AliInfo("No AOD event") ;
245 return kFALSE;
246 }
247 //std::cout << "No AOD event" << std::endl;
248
249 AliCentrality *centralityObj = 0;
250 //Int_t multiplicity = -1;
1b8b4a2c 251 //Double_t MultipOrCent = -1;
c683985a 252
253 // initialize the pool for event mixing
1b8b4a2c 254 if(!fUseCentrality){ // pp, pA
4640c275 255 //multiplicity = fAODEvent->GetNumberOfTracks();
1b8b4a2c
EB
256 //MultipOrCent = AliVertexingHFUtils::GetNumberOfTrackletsInEtaRange(fAODEvent,-1.,1.);
257 fMultCentr = AliVertexingHFUtils::GetNumberOfTrackletsInEtaRange(fAODEvent,-1.,1.);
c683985a 258 // MultipOrCent = multiplicity; // convert from Int_t to Double_t
259 // AliInfo(Form("Multiplicity is %f", MultipOrCent));
260 }
1b8b4a2c
EB
261 if(fUseCentrality){ // PbPb
262 if(!fDMesonCutObject){
263
0a918d8d 264 centralityObj = ((AliVAODHeader*)fAODEvent->GetHeader())->GetCentralityP();
1b8b4a2c
EB
265 fMultCentr = centralityObj->GetCentralityPercentileUnchecked("V0M");
266 }
267 else fMultCentr = fDMesonCutObject->GetCentrality(fAODEvent);
c683985a 268// AliInfo(Form("Centrality is %f", MultipOrCent));
269 }
270
271 AliAODVertex *vtx = fAODEvent->GetPrimaryVertex();
272 Double_t zvertex = vtx->GetZ(); // zvertex
273 Double_t * CentBins = fhadcuts->GetCentPoolBins();
274 Double_t poolmin=CentBins[0];
275 Double_t poolmax=CentBins[fhadcuts->GetNCentPoolBins()];
276
277
1b8b4a2c
EB
278 if(TMath::Abs(zvertex)>=10 || fMultCentr>poolmax || fMultCentr < poolmin) {
279 if(!fUseCentrality)AliInfo(Form("Event with Zvertex = %.2f cm and multiplicity = %.0f out of pool bounds, SKIPPING",zvertex,fMultCentr));
280 if(fUseCentrality) AliInfo(Form("Event with Zvertex = %.2f cm and centrality = %.1f out of pool bounds, SKIPPING",zvertex,fMultCentr));
c683985a 281
282 return kFALSE;
283 }
284
1b8b4a2c 285 fPool = fPoolMgr->GetEventPool(fMultCentr, zvertex);
c683985a 286
287 if (!fPool){
1b8b4a2c 288 AliInfo(Form("No pool found for multiplicity = %f, zVtx = %f cm", fMultCentr, zvertex));
c683985a 289 return kFALSE;
290 }
291 //fPool->PrintInfo();
292 return kTRUE;
293}
294
295//_____________________________________________________
296Bool_t AliHFCorrelator::ProcessEventPool(){
297 // analysis on Mixed Events
298 //cout << "AliHFCorrelator::ProcessEventPool"<< endl;
299 if(!fmixing) return kFALSE;
300 if(!fPool->IsReady()) return kFALSE;
301 if(fPool->GetCurrentNEvents()<fhadcuts->GetMinEventsToMix()) return kFALSE;
302 // fPool->PrintInfo();
303 fPoolContent = fPool->GetCurrentNEvents();
304
305 return kTRUE;
306
307}
308
309//_____________________________________________________
310Bool_t AliHFCorrelator::ProcessAssociatedTracks(Int_t EventLoopIndex, const TObjArray* associatedTracks){
311 // associatedTracks is not deleted, it should be (if needed) deleted in the user task
312
313 if(!fmixing){ // analysis on Single Event
314 if(fAssociatedTracks){
315 fAssociatedTracks->Delete();
316 delete fAssociatedTracks;
317 }
318 if(fselect==kHadron || fselect ==kKaon){
319 fAssociatedTracks = AcceptAndReduceTracks(fAODEvent);
320 fAssociatedTracks->SetOwner(kTRUE);
321 }
322 if(fselect==kKZero) {
323 fAssociatedTracks = AcceptAndReduceKZero(fAODEvent);
324 fAssociatedTracks->SetOwner(kTRUE);
325 }
326 if(fselect==kElectron && associatedTracks) {
327 fAssociatedTracks=new TObjArray(*associatedTracks);// Maybe better to call the copy constructor
328 fAssociatedTracks->SetOwner(kFALSE);
329 }
330
331 }
332
333 if(fmixing) { // analysis on Mixed Events
334
335
336 fAssociatedTracks = fPool->GetEvent(EventLoopIndex);
337
338
339
340
341 } // end if mixing
342
343 if(!fAssociatedTracks) return kFALSE;
344
345 fNofTracks = fAssociatedTracks->GetEntriesFast();
346
347 return kTRUE;
348
349}
350//_____________________________________________________
351Bool_t AliHFCorrelator::Correlate(Int_t loopindex){
352
353 if(loopindex >= fNofTracks) return kFALSE;
354 if(!fAssociatedTracks) return kFALSE;
355
356 fReducedPart = (AliReducedParticle*)fAssociatedTracks->At(loopindex);
357
358
359 fDeltaPhi = SetCorrectPhiRange(fPhiTrigger - fReducedPart->Phi());
360
361 fDeltaEta = fEtaTrigger - fReducedPart->Eta();
362
363 return kTRUE;
364
365}
366
367//_____________________________________________________
368Bool_t AliHFCorrelator::PoolUpdate(const TObjArray* associatedTracks){
369
370 if(!fmixing) return kFALSE;
371 if(!fPool) return kFALSE;
372 if(fmixing) { // update the pool for Event Mixing
373 TObjArray* objArr = NULL;
374 if(fselect==kHadron || fselect==kKaon) objArr = (TObjArray*)AcceptAndReduceTracks(fAODEvent);
375 else if(fselect==kKZero) objArr = (TObjArray*)AcceptAndReduceKZero(fAODEvent);
376 else if(fselect==kElectron && associatedTracks){
377 objArr = new TObjArray(*associatedTracks);
378 }
379 else return kFALSE;
380 if(objArr->GetEntriesFast()>0) fPool->UpdatePool(objArr); // updating the pool only if there are entries in the array
381 }
382
383 return kTRUE;
384
385}
386
387//_____________________________________________________
388Double_t AliHFCorrelator::SetCorrectPhiRange(Double_t phi){
389 Double_t pi = TMath::Pi();
390
391 if(phi<fPhiMin) phi = phi + 2*pi;
392 if(phi>fPhiMax) phi = phi - 2*pi;
393
394 return phi;
395}
396
397//_____________________________________________________
398TObjArray* AliHFCorrelator::AcceptAndReduceTracks(AliAODEvent* inputEvent){
399
400 Double_t weight=1.;
4640c275 401 Int_t nTracks = inputEvent->GetNumberOfTracks();
c683985a 402 AliAODVertex * vtx = inputEvent->GetPrimaryVertex();
403 Double_t pos[3],cov[6];
404 vtx->GetXYZ(pos);
405 vtx->GetCovarianceMatrix(cov);
406 const AliESDVertex vESD(pos,cov,100.,100);
407
408 Double_t Bz = inputEvent->GetMagneticField();
409
410
411 TObjArray* tracksClone = new TObjArray;
412 tracksClone->SetOwner(kTRUE);
413
414 //*******************************************************
415 // use reconstruction
416 if(fUseReco){
417 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
f15c1f69 418 AliAODTrack* track = dynamic_cast<AliAODTrack*>(inputEvent->GetTrack(iTrack));
c683985a 419 if (!track) continue;
420 if(!fhadcuts->IsHadronSelected(track,&vESD,Bz)) continue; // apply ESD level selections
421 if(!fhadcuts->Charge(fDCharge,track)) continue; // apply selection on charge, if required
422
423 Double_t pT = track->Pt();
424
425 //compute impact parameter
426 Double_t d0z0[2],covd0z0[3];
427 Double_t d0=-999999.;
428 if(fUseImpactParameter) track->PropagateToDCA(vtx,Bz,100,d0z0,covd0z0);
429 else d0z0[0] = 1. ; // random number - be careful with the cuts you applied
430
431 if(fUseImpactParameter==1) d0 = TMath::Abs(d0z0[0]); // use impact parameter
432 if(fUseImpactParameter==2) { // use impact parameter over resolution
433 if(TMath::Abs(covd0z0[0])>0.00000001) d0 = TMath::Abs(d0z0[0])/TMath::Sqrt(covd0z0[0]);
434 else d0 = -1.; // if the resoultion is Zero, rejects the track - to be on the safe side
435
436 }
437
438 if(fmontecarlo) {// THIS TO BE CHECKED
439 Int_t hadLabel = track->GetLabel();
440 if(hadLabel < 0) continue;
441 }
442
443 if(!fhadcuts->CheckHadronKinematic(pT,d0)) continue; // apply kinematic cuts
444 Bool_t rejectsoftpi = kTRUE;// TO BE CHECKED: DO WE WANT IT TO kTRUE AS A DEFAULT?
445 if(fD0cand && !fmixing) rejectsoftpi = fhadcuts->InvMassDstarRejection(fD0cand,track,fhypD0); // TO BE CHECKED: WHY NOT FOR EM?
446
447
448 if(fselect ==kKaon){
449 if(!fhadcuts->CheckKaonCompatibility(track,fmontecarlo,fmcArray,fPIDmode)) continue; // check if it is a Kaon - data and MC
450 }
451 weight=fhadcuts->GetTrackWeight(pT,track->Eta(),pos[2]);
452 tracksClone->Add(new AliReducedParticle(track->Eta(), track->Phi(), pT,track->GetLabel(),track->GetID(),d0,rejectsoftpi,track->Charge(),weight));
453 } // end loop on tracks
454 } // end if use reconstruction kTRUE
455
456 //*******************************************************
457
458 //use MC truth
459 if(fmontecarlo && !fUseReco){
460
461 for (Int_t iPart=0; iPart<fmcArray->GetEntriesFast(); iPart++) {
462 AliAODMCParticle* mcPart = dynamic_cast<AliAODMCParticle*>(fmcArray->At(iPart));
463 if (!mcPart) {
464 AliWarning("MC Particle not found in tree, skipping");
465 continue;
466 }
467 if(!mcPart->Charge()) continue; // consider only charged tracks
468
469 Int_t PDG =TMath::Abs(mcPart->PdgCode());
470if(fselect ==kHadron) {if(!((PDG==321)||(PDG==211)||(PDG==2212)||(PDG==13)||(PDG==11))) continue;} // select only if kaon, pion, proton, muon or electron
471 else if(fselect ==kKaon) {if(!(PDG==321)) continue;} // select only if kaon
472 else if(fselect ==kElectron) {if(!(PDG==11)) continue;} // select only if electron
473
474 Double_t pT = mcPart->Pt();
475 Double_t d0 =1; // set 1 fot the moment - no displacement calculation implemented yet
476 if(!fhadcuts->CheckHadronKinematic(pT,d0)) continue; // apply kinematic cuts
477
478 tracksClone->Add(new AliReducedParticle(mcPart->Eta(), mcPart->Phi(), pT,iPart,-1,d0,kFALSE,mcPart->Charge()));
479 }
480
481 } // end if use MC truth
482
483
484 return tracksClone;
485}
486
487//_____________________________________________________
488TObjArray* AliHFCorrelator::AcceptAndReduceKZero(AliAODEvent* inputEvent){
489
490 Int_t nOfVZeros = inputEvent->GetNumberOfV0s();
491 TObjArray* KZeroClone = new TObjArray;
492 AliAODVertex *vertex1 = (AliAODVertex*)inputEvent->GetPrimaryVertex();
493
494 // use reconstruction
495 if(fUseReco){
496 Int_t v0label = -1;
497 Int_t pdgDgK0toPipi[2] = {211,211};
498 Double_t mPDGK0=0.497614;//TDatabasePDG::Instance()->GetParticle(310)->Mass();
499 const Int_t size = inputEvent->GetNumberOfV0s();
500 Int_t prevnegID[size];
501 Int_t prevposID[size];
502 for(Int_t iv0 =0; iv0< nOfVZeros; iv0++){// loop on all v0 candidates
503 AliAODv0 *v0 = (static_cast<AliAODEvent*> (inputEvent))->GetV0(iv0);
504 if(!v0) {
505 AliInfo(Form("is not a v0 at step, %d", iv0)) ;
506 //cout << "is not a v0 at step " << iv0 << endl;
507 continue;
508 }
509
510 if(!fhadcuts->IsKZeroSelected(v0,vertex1)) continue; // check if it is a k0
511
512 // checks to avoid double counting
513 Int_t negID = -999;
514 Int_t posID = -998;
515 //Int_t a = 0;
516 prevnegID[iv0] = -997;
517 prevposID[iv0]= -996;
518 negID = v0->GetNegID();
519 posID = v0->GetPosID();
520 Bool_t DoubleCounting = kFALSE;
521
522 for(Int_t k=0; k<iv0; k++){
523 if(((negID==prevnegID[k])&&(posID==prevposID[k]))||((negID==prevposID[k])&&(posID==prevnegID[k]))){
524 DoubleCounting = kTRUE;
525 //a=k;
526 break;
527 }//end if
528 } // end for
529
530 if(DoubleCounting) continue;
531 else{
532 prevposID[iv0] = posID;
533 prevnegID[iv0] = negID;
534 }
535
536 if(fmontecarlo) v0label = v0->MatchToMC(310,fmcArray, 0, pdgDgK0toPipi); //match a K0 short
537 Double_t k0pt = v0->Pt();
538 Double_t k0eta = v0->Eta();
539 Double_t k0Phi = v0->Phi();
540 fk0InvMass = v0->MassK0Short();
541
542 //if (loopindex == 0) {
543 // if(!plotassociation) ((TH2F*)fOutput->FindObject("KZeroSpectra"))->Fill(k0InvMass,k0pt); // spectra for all k0
544 // if(plotassociation) ((TH2F*)fOutput->FindObject("KZeroSpectraifHF"))->Fill(k0InvMass,k0pt); // spectra for k0 in association with a D*
545 //}
546 // if there are more D* candidates per event, loopindex == 0 makes sure you fill the mass spectra only once!
547
548 if(TMath::Abs(fk0InvMass-mPDGK0)>3*0.004) continue; // select candidates within 3 sigma
549 KZeroClone->Add(new AliReducedParticle(k0eta,k0Phi,k0pt,v0label));
550
551 }
552 } // end if use reconstruction kTRUE
553
554
555
556//*********************************************************************//
557 //use MC truth
558 if(fmontecarlo && !fUseReco){
559
560 for (Int_t iPart=0; iPart<fmcArray->GetEntriesFast(); iPart++) {
561 AliAODMCParticle* mcPart = dynamic_cast<AliAODMCParticle*>(fmcArray->At(iPart));
562 if (!mcPart) {
563 AliWarning("MC Particle not found in tree, skipping");
564 continue;
565 }
566
567 Int_t PDG =TMath::Abs(mcPart->PdgCode());
568 if(!(PDG==310)) continue; // select only if k0 short
569
570 Double_t pT = mcPart->Pt();
571 Double_t d0 =1; // set 1 fot the moment - no displacement calculation implemented yet
572 if(!fhadcuts->CheckHadronKinematic(pT,d0)) continue; // apply kinematic cuts
573
574 KZeroClone->Add(new AliReducedParticle(mcPart->Eta(), mcPart->Phi(), pT,iPart,-1,d0,kTRUE,mcPart->Charge()));
575 }
576
577 } // end if use MC truth
578
579
580
581 return KZeroClone;
582}