]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGJE/UserTasks/AliAnalysisTaskPIDV0base.cxx
add correation with V0mult to Rho task
[u/mrichter/AliRoot.git] / PWGJE / UserTasks / AliAnalysisTaskPIDV0base.cxx
CommitLineData
e131b05f 1#include "TChain.h"
2#include "TF1.h"
3#include "TRandom3.h"
4
5#include "AliMCParticle.h"
6
7#include "AliAnalysisTask.h"
8#include "AliAnalysisManager.h"
9
10#include "AliVEvent.h"
11#include "AliESDEvent.h"
12#include "AliAODEvent.h"
13#include "AliMCEvent.h"
14#include "AliESDInputHandler.h"
15#include "AliInputEventHandler.h"
a6852ea8 16#include "AliVTrack.h"
17#include "AliExternalTrackParam.h"
e131b05f 18#include "AliVVertex.h"
19#include "AliAnalysisFilter.h"
20#include "AliPID.h"
21#include "AliPIDResponse.h"
22#include "AliESDv0KineCuts.h"
23#include "AliESDv0.h"
24
25#include "AliAnalysisTaskPIDV0base.h"
26
27/*
28This class is a base class for all other
29analysis tasks that use V0's.
30It provides basics for V0 identification.
31In addition, some further basic functions are provided.
32
33Class written by Benjamin Hess.
34Contact: bhess@cern.ch
35*/
36
37ClassImp(AliAnalysisTaskPIDV0base)
38
a6852ea8 39Double_t AliAnalysisTaskPIDV0base::fgCutGeo = 1.;
40Double_t AliAnalysisTaskPIDV0base::fgCutNcr = 0.85;
41Double_t AliAnalysisTaskPIDV0base::fgCutNcl = 0.7;
42
493982d9
ML
43UShort_t AliAnalysisTaskPIDV0base::fgCutPureNcl = 60;
44
e131b05f 45//________________________________________________________________________
46AliAnalysisTaskPIDV0base::AliAnalysisTaskPIDV0base()
47 : AliAnalysisTaskSE()
48 , fEvent(0x0)
49 , fESD(0x0)
50 , fMC(0x0)
51 , fPIDResponse(0x0)
52 , fV0KineCuts(0x0)
1a8d4484 53 , fAnaUtils(0x0)
e131b05f 54 , fIsPbpOrpPb(kFALSE)
55 , fUsePhiCut(kFALSE)
493982d9 56 , fTPCcutType(kNoCut)
e131b05f 57 , fZvtxCutEvent(10.0)
58 , fEtaCut(0.9)
59 , fPhiCutLow(0x0)
60 , fPhiCutHigh(0x0)
61 , fRandom(0x0)
62 , fTrackFilter(0x0)
63 , fNumTagsStored(0)
64 , fV0tags(0x0)
65 , fStoreMotherIndex(kFALSE)
66 , fV0motherIndex(0x0)
67{
68 // default Constructor
69
70 fRandom = new TRandom3(0); // 0 means random seed
71
72
73 // Question: Is this the right place to initialize these functions?
74 // Will it work on proof? i.e. will they be streamed to the workers?
75 // Also one should add getters and setters
76 fPhiCutLow = new TF1("StdPhiCutLow", "0.1/x/x+pi/18.0-0.025", 0, 100);
77 fPhiCutHigh = new TF1("StandardPhiCutHigh", "0.12/x+pi/18.0+0.035", 0, 100);
78}
79
80//________________________________________________________________________
81AliAnalysisTaskPIDV0base::AliAnalysisTaskPIDV0base(const char *name)
82 : AliAnalysisTaskSE(name)
83 , fEvent(0x0)
84 , fESD(0x0)
85 , fMC(0x0)
86 , fPIDResponse(0x0)
87 , fV0KineCuts(0x0)
1a8d4484 88 , fAnaUtils(0x0)
e131b05f 89 , fIsPbpOrpPb(kFALSE)
90 , fUsePhiCut(kFALSE)
493982d9 91 , fTPCcutType(kNoCut)
e131b05f 92 , fZvtxCutEvent(10.0)
93 , fEtaCut(0.9)
94 , fPhiCutLow(0x0)
95 , fPhiCutHigh(0x0)
96 , fRandom(0x0)
97 , fTrackFilter(0x0)
98 , fNumTagsStored(0)
99 , fV0tags(0x0)
100 , fStoreMotherIndex(kFALSE)
101 , fV0motherIndex(0x0)
102{
103 // Constructor
104
105 fRandom = new TRandom3(0); // 0 means random seed
106
107
108 // Question: Is this the right place to initialize these functions?
109 // Will it work on proof? i.e. will they be streamed to the workers?
110 // Also one should add getters and setters
111 fPhiCutLow = new TF1("StdPhiCutLow", "0.1/x/x+pi/18.0-0.025", 0, 100);
112 fPhiCutHigh = new TF1("StandardPhiCutHigh", "0.12/x+pi/18.0+0.035", 0, 100);
113
114 DefineInput (0, TChain::Class());
115 DefineOutput(0, TTree::Class());
116}
117
118
119//________________________________________________________________________
120AliAnalysisTaskPIDV0base::~AliAnalysisTaskPIDV0base()
121{
122 // dtor
123
124 delete fPhiCutLow;
125 fPhiCutLow = 0;
126
127 delete fPhiCutHigh;
128 fPhiCutHigh = 0;
129
130 delete fTrackFilter;
131 fTrackFilter = 0;
132
133 delete fRandom;
134 fRandom = 0;
135
136 delete fV0KineCuts;
137 fV0KineCuts = 0;
138
139 delete fV0tags;
140 fV0tags = 0;
141 fNumTagsStored = 0;
142
143 delete fV0motherIndex;
144 fV0motherIndex = 0;
1a8d4484 145
146 delete fAnaUtils;
147 fAnaUtils = 0;
e131b05f 148}
149
150
151//________________________________________________________________________
152void AliAnalysisTaskPIDV0base::UserCreateOutputObjects()
153{
154 // Create histograms
155 // Called once
156
157 // Input hander
158 AliAnalysisManager* man = AliAnalysisManager::GetAnalysisManager();
159 AliInputEventHandler* inputHandler = dynamic_cast<AliInputEventHandler*>(man->GetInputEventHandler());
160
c4856fb1 161 if (!inputHandler) {
e131b05f 162 AliFatal("Input handler needed");
c4856fb1 163 fPIDResponse = 0x0;
164
165 return;
166 }
e131b05f 167
168 // PID response object
169 fPIDResponse = inputHandler->GetPIDResponse();
170 if (!fPIDResponse)
171 AliError("PIDResponse object was not created");
172
173 // V0 Kine cuts
174 fV0KineCuts = new AliESDv0KineCuts;
175 fV0KineCuts->SetGammaCutChi2NDF(5.);
176 // Only accept V0el with prod. radius within 45 cm -> PID will by systematically biased for larger values!
177 Float_t gammaProdVertexRadiusCuts[2] = { 3.0, 45. };
178 fV0KineCuts->SetGammaCutVertexR(&gammaProdVertexRadiusCuts[0]);
1a8d4484 179
180 // Default analysis utils
181 fAnaUtils = new AliAnalysisUtils();
e72b99b6 182
183 // Not used yet, but to be save, forward vertex z cut to analysis utils object
184 fAnaUtils->SetMaxVtxZ(fZvtxCutEvent);
e131b05f 185}
186
187
188//________________________________________________________________________
189void AliAnalysisTaskPIDV0base::UserExec(Option_t *)
190{
191 // Main loop
192 // Called for each event
193}
194
195//________________________________________________________________________
196void AliAnalysisTaskPIDV0base::Terminate(const Option_t *)
197{
198 // Called once at the end of the query
199}
200
201
202//_____________________________________________________________________________
203Double_t AliAnalysisTaskPIDV0base::GetPhiPrime(Double_t phi, Double_t magField, Int_t charge) const
204{
205 // Get phiPrime which is the cut variable to reject high pT tracks near edges
206
207 if(magField < 0) // for negatve polarity field
208 phi = TMath::TwoPi() - phi;
209
210 if(charge < 0) // for negatve charge
211 phi = TMath::TwoPi() - phi;
212
213 phi += TMath::Pi() / 18.0; // to center gap in the middle
214 phi = fmod(phi, TMath::Pi() / 9.0);
215 return phi;
216}
217
218
219//______________________________________________________________________________
220Bool_t AliAnalysisTaskPIDV0base::PhiPrimeCut(Double_t trackPt, Double_t trackPhi, Short_t trackCharge, Double_t magField) const
221{
222 // Apply phi' cut to given track parameters
223
224 if (trackPt < 2.0)
225 return kTRUE;
226
227 Double_t phiPrime = GetPhiPrime(trackPhi, magField, trackCharge);
228
229 if (phiPrime < fPhiCutHigh->Eval(trackPt) && phiPrime > fPhiCutLow->Eval(trackPt))
230 return kFALSE; // reject track
231
232 return kTRUE;
233}
234
235
236//______________________________________________________________________________
237Bool_t AliAnalysisTaskPIDV0base::PhiPrimeCut(const AliVTrack* track, Double_t magField) const
238{
239 return PhiPrimeCut(track->Pt(), track->Phi(), track->Charge(), magField);
240}
241
242
243//______________________________________________________________________________
4b4d71d4 244Bool_t AliAnalysisTaskPIDV0base::GetVertexIsOk(AliVEvent* event, Bool_t doVtxZcut) const
e131b05f 245{
4b4d71d4 246 // Check whether vertex ful-fills quality requirements.
247 // Apply cut on z-position of vertex if doVtxZcut = kTRUE.
e131b05f 248
249 AliAODEvent* aod = 0x0;
250 AliESDEvent* esd = 0x0;
251
252 aod = dynamic_cast<AliAODEvent*>(event);
253 if (!aod) {
254 esd = dynamic_cast<AliESDEvent*>(event);
255
256 if (!esd) {
257 AliError("Event seems to be neither AOD nor ESD!");
258 return kFALSE;
259 }
260 }
261
262 if (fIsPbpOrpPb) {
263 const AliVVertex* trkVtx = (aod ? dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertex()) :
264 dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertex()));
265
266 if (!trkVtx || trkVtx->GetNContributors() <= 0)
267 return kFALSE;
268
269 TString vtxTtl = trkVtx->GetTitle();
270 if (!vtxTtl.Contains("VertexerTracks"))
271 return kFALSE;
272
273 Float_t zvtx = trkVtx->GetZ();
274 const AliVVertex* spdVtx = (aod ? dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertexSPD()) :
275 dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertexSPD()));
276 if (spdVtx->GetNContributors() <= 0)
277 return kFALSE;
278
279 TString vtxTyp = spdVtx->GetTitle();
280 Double_t cov[6] = {0};
281 spdVtx->GetCovarianceMatrix(cov);
282 Double_t zRes = TMath::Sqrt(cov[5]);
283 if (vtxTyp.Contains("vertexer:Z") && (zRes > 0.25))
284 return kFALSE;
285
286 if (TMath::Abs(spdVtx->GetZ() - trkVtx->GetZ()) > 0.5)
287 return kFALSE;
4b4d71d4 288
289 if (doVtxZcut) {
290 if (TMath::Abs(zvtx) > fZvtxCutEvent) //Default: 10 cm
291 return kFALSE;
292 }
e131b05f 293
294 return kTRUE;
295 }
296
297
298 // pp and PbPb
4bf52f22 299 const AliVVertex* primaryVertex = 0x0;
300 if (aod) {
301 primaryVertex = dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertex());
302 if (!primaryVertex || primaryVertex->GetNContributors() <= 0)
303 return kFALSE;
304
305 // Reject TPC vertices
306 TString primVtxTitle(primaryVertex->GetTitle());
307 if (primVtxTitle.Contains("TPCVertex",TString::kIgnoreCase))
308 return kFALSE;
309 }
310 else {
311 primaryVertex = dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertexTracks());
312 if (!primaryVertex)
313 return kFALSE;
e131b05f 314
4bf52f22 315 if (primaryVertex->GetNContributors() <= 0) {
316 // Try SPD vertex
317 primaryVertex = dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertexSPD());
318 if (!primaryVertex || primaryVertex->GetNContributors() <= 0)
319 return kFALSE;
320 }
321 }
4b4d71d4 322
323 if (doVtxZcut) {
324 if (TMath::Abs(primaryVertex->GetZ()) > fZvtxCutEvent) //Default: 10 cm
325 return kFALSE;
326 }
e131b05f 327
328 return kTRUE;
329}
330
331
1a8d4484 332//______________________________________________________________________________
333Bool_t AliAnalysisTaskPIDV0base::GetIsPileUp(AliVEvent* event, AliAnalysisTaskPIDV0base::PileUpRejectionType pileUpRejectionType) const
334{
335 // Check whether event is a pile-up event according to current AnalysisUtils object.
336 // If rejection type is kPileUpRejectionOff, kFALSE is returned.
337 // In case of errors, the error is displayed and kTRUE is returned.
338
339 if (pileUpRejectionType == kPileUpRejectionOff)
340 return kFALSE;
341
342 if (!event) {
343 AliError("No event!");
344 return kTRUE;
345 }
346
347 if (!fAnaUtils) {
348 AliError("AnalysisUtils object not available!");
349 return kTRUE;
350 }
351
352 if (pileUpRejectionType == kPileUpRejectionSPD)
353 return fAnaUtils->IsPileUpSPD(event);
354 else if (pileUpRejectionType == kPileUpRejectionMV)
355 return fAnaUtils->IsPileUpMV(event);
356
357 return kTRUE;
358}
359
360
e131b05f 361//______________________________________________________________________________
362void AliAnalysisTaskPIDV0base::FillV0PIDlist(AliESDEvent* event)
363{
364 //
365 // Fill the PID tag list
366 //
367
368 // If no event forwarded as parameter (default), cast current input event.
369 // Dynamic cast to ESD events (DO NOTHING for AOD events)
370 if (!event)
371 event = dynamic_cast<AliESDEvent *>(InputEvent());
372
373 // If this fails, do nothing
374 if (!event) {
375 AliError("Failed to retrieve ESD event. No V0's processed (only works for ESDs by now).");
376 return;
377 }
378
379 if (!fV0KineCuts) {
380 AliError("V0KineCuts not available!");
381 return;
382 }
383
384 TString beamType(event->GetBeamType());
385
386 if (beamType.CompareTo("Pb-Pb") == 0 || beamType.CompareTo("A-A") == 0) {
387 fV0KineCuts->SetMode(AliESDv0KineCuts::kPurity, AliESDv0KineCuts::kPbPb);
388 }
389 else {
390 fV0KineCuts->SetMode(AliESDv0KineCuts::kPurity, AliESDv0KineCuts::kPP);
391 }
392
393 // V0 selection
394 // set event
395 fV0KineCuts->SetEvent(event);
396
397 const Int_t numTracks = event->GetNumberOfTracks();
398 fV0tags = new Char_t[numTracks];
399 for (Int_t i = 0; i < numTracks; i++)
400 fV0tags[i] = 0;
401
402 if (fStoreMotherIndex) {
403 fV0motherIndex = new Int_t[numTracks];
404 for (Int_t i = 0; i < numTracks; i++)
78e564b5 405 fV0motherIndex[i] = -1;
e131b05f 406 }
407
408 fNumTagsStored = numTracks;
409
410 // loop over V0 particles
411 for (Int_t iv0 = 0; iv0 < event->GetNumberOfV0s(); iv0++) {
412 AliESDv0* v0 = (AliESDv0*)event->GetV0(iv0);
413
414 if (!v0)
415 continue;
416
417 // Reject onFly V0's <-> Only take V0's from offline V0 finder
418 if (v0->GetOnFlyStatus())
419 continue;
420
421 // Get the particle selection
422 Bool_t foundV0 = kFALSE;
423 Int_t pdgV0 = 0, pdgP = 0, pdgN = 0;
424
425 foundV0 = fV0KineCuts->ProcessV0(v0, pdgV0, pdgP, pdgN);
426 if (!foundV0)
427 continue;
428
429 Int_t iTrackP = v0->GetPindex(); // positive track
430 Int_t iTrackN = v0->GetNindex(); // negative track
431
432
433 // Fill the Object arrays
434 // positive particles
435 if (pdgP == -11) {
436 fV0tags[iTrackP] = 14;
437 }
438 else if (pdgP == 211) {
439 fV0tags[iTrackP] = 15;
440 }
441 else if(pdgP == 2212) {
442 fV0tags[iTrackP] = 16;
443 }
444
445 if (fStoreMotherIndex)
446 fV0motherIndex[iTrackP] = iv0;
447
448 // negative particles
449 if( pdgN == 11){
450 fV0tags[iTrackN] = -14;
451 }
452 else if( pdgN == -211){
453 fV0tags[iTrackN] = -15;
454 }
455 else if( pdgN == -2212){
456 fV0tags[iTrackN] = -16;
457 }
458
459 if (fStoreMotherIndex)
460 fV0motherIndex[iTrackN] = iv0;
461 }
462}
463
464
465//______________________________________________________________________________
466void AliAnalysisTaskPIDV0base::ClearV0PIDlist()
467{
468 //
469 // Clear the PID tag list
470 //
471
472 delete fV0tags;
473 fV0tags = 0;
474
475 delete fV0motherIndex;
476 fV0motherIndex = 0;
477
478 fNumTagsStored = 0;
479}
480
481
482//______________________________________________________________________________
483Char_t AliAnalysisTaskPIDV0base::GetV0tag(Int_t trackIndex) const
484{
485 //
486 // Get the tag for the corresponding trackIndex. Returns -99 in case of invalid index/tag list.
487 //
488
489 if (trackIndex < 0 || trackIndex >= fNumTagsStored || !fV0tags)
490 return -99;
491
492 return fV0tags[trackIndex];
493}
494
495
496//______________________________________________________________________________
497Int_t AliAnalysisTaskPIDV0base::GetV0motherIndex(Int_t trackIndex) const
498{
499 //
500 // Get the index of the V0 mother for the corresponding trackIndex. Returns -99 in case of invalid index/mother index list.
501 //
502
503 if (!fStoreMotherIndex || trackIndex < 0 || trackIndex >= fNumTagsStored || !fV0motherIndex)
504 return -99;
505
506 return fV0motherIndex[trackIndex];
507}
a6852ea8 508
509
510//________________________________________________________________________
511Bool_t AliAnalysisTaskPIDV0base::TPCCutMIGeo(const AliVTrack* track, const AliVEvent* evt, TTreeStream* streamer)
512{
513 //
514 // TPC Cut MIGeo
515 //
516
517 if (!track || !evt)
518 return kFALSE;
519
520 const Short_t sign = track->Charge();
521 Double_t xyz[50];
522 Double_t pxpypz[50];
523 Double_t cv[100];
524
525 track->GetXYZ(xyz);
526 track->GetPxPyPz(pxpypz);
527
528 AliExternalTrackParam* par = new AliExternalTrackParam(xyz, pxpypz, cv, sign);
529 const AliESDtrack dummy;
530
531 const Double_t magField = evt->GetMagneticField();
532 Double_t varGeom = dummy.GetLengthInActiveZone(par, 3, 236, magField, 0, 0);
533 Double_t varNcr = track->GetTPCClusterInfo(3, 1);
534 Double_t varNcls = track->GetTPCsignalN();
535
536 const Double_t varEval = 130. - 5. * TMath::Abs(1. / track->Pt());
537 Bool_t cutGeom = varGeom > fgCutGeo * varEval;
538 Bool_t cutNcr = varNcr > fgCutNcr * varEval;
539 Bool_t cutNcls = varNcls > fgCutNcl * varEval;
540
541 Bool_t kout = cutGeom && cutNcr && cutNcls;
542
543 if (streamer) {
544 Double_t dedx = track->GetTPCsignal();
545
546 (*streamer)<<"tree"<<
547 "param.="<< par<<
548 "varGeom="<<varGeom<<
549 "varNcr="<<varNcr<<
550 "varNcls="<<varNcls<<
551
552 "cutGeom="<<cutGeom<<
553 "cutNcr="<<cutNcr<<
554 "cutNcls="<<cutNcls<<
555
556 "kout="<<kout<<
557 "dedx="<<dedx<<
558
559 "\n";
560 }
561
562 delete par;
563
564 return kout;
565}
493982d9
ML
566
567
568//________________________________________________________________________
569Bool_t AliAnalysisTaskPIDV0base::TPCnclCut(const AliVTrack* track)
570{
571 //
572 // TPC Cut on TPCsignalN() only
573 //
574
575 if (!track)
576 return kFALSE;
577
578 return (track->GetTPCsignalN() >= fgCutPureNcl);
579}