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