]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGJE/UserTasks/AliAnalysisTaskPIDV0base.cxx
- Coverity fixes
[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"
16
17#include "AliVVertex.h"
18#include "AliAnalysisFilter.h"
19#include "AliPID.h"
20#include "AliPIDResponse.h"
21#include "AliESDv0KineCuts.h"
22#include "AliESDv0.h"
23
24#include "AliAnalysisTaskPIDV0base.h"
25
26/*
27This class is a base class for all other
28analysis tasks that use V0's.
29It provides basics for V0 identification.
30In addition, some further basic functions are provided.
31
32Class written by Benjamin Hess.
33Contact: bhess@cern.ch
34*/
35
36ClassImp(AliAnalysisTaskPIDV0base)
37
38//________________________________________________________________________
39AliAnalysisTaskPIDV0base::AliAnalysisTaskPIDV0base()
40 : AliAnalysisTaskSE()
41 , fEvent(0x0)
42 , fESD(0x0)
43 , fMC(0x0)
44 , fPIDResponse(0x0)
45 , fV0KineCuts(0x0)
46 , fIsPbpOrpPb(kFALSE)
47 , fUsePhiCut(kFALSE)
48 , fZvtxCutEvent(10.0)
49 , fEtaCut(0.9)
50 , fPhiCutLow(0x0)
51 , fPhiCutHigh(0x0)
52 , fRandom(0x0)
53 , fTrackFilter(0x0)
54 , fNumTagsStored(0)
55 , fV0tags(0x0)
56 , fStoreMotherIndex(kFALSE)
57 , fV0motherIndex(0x0)
58{
59 // default Constructor
60
61 fRandom = new TRandom3(0); // 0 means random seed
62
63
64 // Question: Is this the right place to initialize these functions?
65 // Will it work on proof? i.e. will they be streamed to the workers?
66 // Also one should add getters and setters
67 fPhiCutLow = new TF1("StdPhiCutLow", "0.1/x/x+pi/18.0-0.025", 0, 100);
68 fPhiCutHigh = new TF1("StandardPhiCutHigh", "0.12/x+pi/18.0+0.035", 0, 100);
69}
70
71//________________________________________________________________________
72AliAnalysisTaskPIDV0base::AliAnalysisTaskPIDV0base(const char *name)
73 : AliAnalysisTaskSE(name)
74 , fEvent(0x0)
75 , fESD(0x0)
76 , fMC(0x0)
77 , fPIDResponse(0x0)
78 , fV0KineCuts(0x0)
79 , fIsPbpOrpPb(kFALSE)
80 , fUsePhiCut(kFALSE)
81 , fZvtxCutEvent(10.0)
82 , fEtaCut(0.9)
83 , fPhiCutLow(0x0)
84 , fPhiCutHigh(0x0)
85 , fRandom(0x0)
86 , fTrackFilter(0x0)
87 , fNumTagsStored(0)
88 , fV0tags(0x0)
89 , fStoreMotherIndex(kFALSE)
90 , fV0motherIndex(0x0)
91{
92 // Constructor
93
94 fRandom = new TRandom3(0); // 0 means random seed
95
96
97 // Question: Is this the right place to initialize these functions?
98 // Will it work on proof? i.e. will they be streamed to the workers?
99 // Also one should add getters and setters
100 fPhiCutLow = new TF1("StdPhiCutLow", "0.1/x/x+pi/18.0-0.025", 0, 100);
101 fPhiCutHigh = new TF1("StandardPhiCutHigh", "0.12/x+pi/18.0+0.035", 0, 100);
102
103 DefineInput (0, TChain::Class());
104 DefineOutput(0, TTree::Class());
105}
106
107
108//________________________________________________________________________
109AliAnalysisTaskPIDV0base::~AliAnalysisTaskPIDV0base()
110{
111 // dtor
112
113 delete fPhiCutLow;
114 fPhiCutLow = 0;
115
116 delete fPhiCutHigh;
117 fPhiCutHigh = 0;
118
119 delete fTrackFilter;
120 fTrackFilter = 0;
121
122 delete fRandom;
123 fRandom = 0;
124
125 delete fV0KineCuts;
126 fV0KineCuts = 0;
127
128 delete fV0tags;
129 fV0tags = 0;
130 fNumTagsStored = 0;
131
132 delete fV0motherIndex;
133 fV0motherIndex = 0;
134}
135
136
137//________________________________________________________________________
138void AliAnalysisTaskPIDV0base::UserCreateOutputObjects()
139{
140 // Create histograms
141 // Called once
142
143 // Input hander
144 AliAnalysisManager* man = AliAnalysisManager::GetAnalysisManager();
145 AliInputEventHandler* inputHandler = dynamic_cast<AliInputEventHandler*>(man->GetInputEventHandler());
146
c4856fb1 147 if (!inputHandler) {
e131b05f 148 AliFatal("Input handler needed");
c4856fb1 149 fPIDResponse = 0x0;
150
151 return;
152 }
e131b05f 153
154 // PID response object
155 fPIDResponse = inputHandler->GetPIDResponse();
156 if (!fPIDResponse)
157 AliError("PIDResponse object was not created");
158
159 // V0 Kine cuts
160 fV0KineCuts = new AliESDv0KineCuts;
161 fV0KineCuts->SetGammaCutChi2NDF(5.);
162 // Only accept V0el with prod. radius within 45 cm -> PID will by systematically biased for larger values!
163 Float_t gammaProdVertexRadiusCuts[2] = { 3.0, 45. };
164 fV0KineCuts->SetGammaCutVertexR(&gammaProdVertexRadiusCuts[0]);
165}
166
167
168//________________________________________________________________________
169void AliAnalysisTaskPIDV0base::UserExec(Option_t *)
170{
171 // Main loop
172 // Called for each event
173}
174
175//________________________________________________________________________
176void AliAnalysisTaskPIDV0base::Terminate(const Option_t *)
177{
178 // Called once at the end of the query
179}
180
181
182//_____________________________________________________________________________
183Double_t AliAnalysisTaskPIDV0base::GetPhiPrime(Double_t phi, Double_t magField, Int_t charge) const
184{
185 // Get phiPrime which is the cut variable to reject high pT tracks near edges
186
187 if(magField < 0) // for negatve polarity field
188 phi = TMath::TwoPi() - phi;
189
190 if(charge < 0) // for negatve charge
191 phi = TMath::TwoPi() - phi;
192
193 phi += TMath::Pi() / 18.0; // to center gap in the middle
194 phi = fmod(phi, TMath::Pi() / 9.0);
195 return phi;
196}
197
198
199//______________________________________________________________________________
200Bool_t AliAnalysisTaskPIDV0base::PhiPrimeCut(Double_t trackPt, Double_t trackPhi, Short_t trackCharge, Double_t magField) const
201{
202 // Apply phi' cut to given track parameters
203
204 if (trackPt < 2.0)
205 return kTRUE;
206
207 Double_t phiPrime = GetPhiPrime(trackPhi, magField, trackCharge);
208
209 if (phiPrime < fPhiCutHigh->Eval(trackPt) && phiPrime > fPhiCutLow->Eval(trackPt))
210 return kFALSE; // reject track
211
212 return kTRUE;
213}
214
215
216//______________________________________________________________________________
217Bool_t AliAnalysisTaskPIDV0base::PhiPrimeCut(const AliVTrack* track, Double_t magField) const
218{
219 return PhiPrimeCut(track->Pt(), track->Phi(), track->Charge(), magField);
220}
221
222
223//______________________________________________________________________________
224Bool_t AliAnalysisTaskPIDV0base::GetVertexIsOk(AliVEvent* event) const
225{
226 // Check whether vertex ful-fills quality requirements
227
228 AliAODEvent* aod = 0x0;
229 AliESDEvent* esd = 0x0;
230
231 aod = dynamic_cast<AliAODEvent*>(event);
232 if (!aod) {
233 esd = dynamic_cast<AliESDEvent*>(event);
234
235 if (!esd) {
236 AliError("Event seems to be neither AOD nor ESD!");
237 return kFALSE;
238 }
239 }
240
241 if (fIsPbpOrpPb) {
242 const AliVVertex* trkVtx = (aod ? dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertex()) :
243 dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertex()));
244
245 if (!trkVtx || trkVtx->GetNContributors() <= 0)
246 return kFALSE;
247
248 TString vtxTtl = trkVtx->GetTitle();
249 if (!vtxTtl.Contains("VertexerTracks"))
250 return kFALSE;
251
252 Float_t zvtx = trkVtx->GetZ();
253 const AliVVertex* spdVtx = (aod ? dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertexSPD()) :
254 dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertexSPD()));
255 if (spdVtx->GetNContributors() <= 0)
256 return kFALSE;
257
258 TString vtxTyp = spdVtx->GetTitle();
259 Double_t cov[6] = {0};
260 spdVtx->GetCovarianceMatrix(cov);
261 Double_t zRes = TMath::Sqrt(cov[5]);
262 if (vtxTyp.Contains("vertexer:Z") && (zRes > 0.25))
263 return kFALSE;
264
265 if (TMath::Abs(spdVtx->GetZ() - trkVtx->GetZ()) > 0.5)
266 return kFALSE;
267
268 if (TMath::Abs(zvtx) > fZvtxCutEvent) //Default: 10 cm
269 return kFALSE;
270
271 return kTRUE;
272 }
273
274
275 // pp and PbPb
276 const AliVVertex* primaryVertex = (aod ? dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertex()) :
277 dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertexTracks()));
278
279 if (!primaryVertex || primaryVertex->GetNContributors() <= 0)
280 return kFALSE;
281
282 if (TMath::Abs(primaryVertex->GetZ()) >= fZvtxCutEvent) //Default: 10 cm
283 return kFALSE;
284
285 return kTRUE;
286}
287
288
289//______________________________________________________________________________
290void AliAnalysisTaskPIDV0base::FillV0PIDlist(AliESDEvent* event)
291{
292 //
293 // Fill the PID tag list
294 //
295
296 // If no event forwarded as parameter (default), cast current input event.
297 // Dynamic cast to ESD events (DO NOTHING for AOD events)
298 if (!event)
299 event = dynamic_cast<AliESDEvent *>(InputEvent());
300
301 // If this fails, do nothing
302 if (!event) {
303 AliError("Failed to retrieve ESD event. No V0's processed (only works for ESDs by now).");
304 return;
305 }
306
307 if (!fV0KineCuts) {
308 AliError("V0KineCuts not available!");
309 return;
310 }
311
312 TString beamType(event->GetBeamType());
313
314 if (beamType.CompareTo("Pb-Pb") == 0 || beamType.CompareTo("A-A") == 0) {
315 fV0KineCuts->SetMode(AliESDv0KineCuts::kPurity, AliESDv0KineCuts::kPbPb);
316 }
317 else {
318 fV0KineCuts->SetMode(AliESDv0KineCuts::kPurity, AliESDv0KineCuts::kPP);
319 }
320
321 // V0 selection
322 // set event
323 fV0KineCuts->SetEvent(event);
324
325 const Int_t numTracks = event->GetNumberOfTracks();
326 fV0tags = new Char_t[numTracks];
327 for (Int_t i = 0; i < numTracks; i++)
328 fV0tags[i] = 0;
329
330 if (fStoreMotherIndex) {
331 fV0motherIndex = new Int_t[numTracks];
332 for (Int_t i = 0; i < numTracks; i++)
333 fV0motherIndex[i] = 0;
334 }
335
336 fNumTagsStored = numTracks;
337
338 // loop over V0 particles
339 for (Int_t iv0 = 0; iv0 < event->GetNumberOfV0s(); iv0++) {
340 AliESDv0* v0 = (AliESDv0*)event->GetV0(iv0);
341
342 if (!v0)
343 continue;
344
345 // Reject onFly V0's <-> Only take V0's from offline V0 finder
346 if (v0->GetOnFlyStatus())
347 continue;
348
349 // Get the particle selection
350 Bool_t foundV0 = kFALSE;
351 Int_t pdgV0 = 0, pdgP = 0, pdgN = 0;
352
353 foundV0 = fV0KineCuts->ProcessV0(v0, pdgV0, pdgP, pdgN);
354 if (!foundV0)
355 continue;
356
357 Int_t iTrackP = v0->GetPindex(); // positive track
358 Int_t iTrackN = v0->GetNindex(); // negative track
359
360
361 // Fill the Object arrays
362 // positive particles
363 if (pdgP == -11) {
364 fV0tags[iTrackP] = 14;
365 }
366 else if (pdgP == 211) {
367 fV0tags[iTrackP] = 15;
368 }
369 else if(pdgP == 2212) {
370 fV0tags[iTrackP] = 16;
371 }
372
373 if (fStoreMotherIndex)
374 fV0motherIndex[iTrackP] = iv0;
375
376 // negative particles
377 if( pdgN == 11){
378 fV0tags[iTrackN] = -14;
379 }
380 else if( pdgN == -211){
381 fV0tags[iTrackN] = -15;
382 }
383 else if( pdgN == -2212){
384 fV0tags[iTrackN] = -16;
385 }
386
387 if (fStoreMotherIndex)
388 fV0motherIndex[iTrackN] = iv0;
389 }
390}
391
392
393//______________________________________________________________________________
394void AliAnalysisTaskPIDV0base::ClearV0PIDlist()
395{
396 //
397 // Clear the PID tag list
398 //
399
400 delete fV0tags;
401 fV0tags = 0;
402
403 delete fV0motherIndex;
404 fV0motherIndex = 0;
405
406 fNumTagsStored = 0;
407}
408
409
410//______________________________________________________________________________
411Char_t AliAnalysisTaskPIDV0base::GetV0tag(Int_t trackIndex) const
412{
413 //
414 // Get the tag for the corresponding trackIndex. Returns -99 in case of invalid index/tag list.
415 //
416
417 if (trackIndex < 0 || trackIndex >= fNumTagsStored || !fV0tags)
418 return -99;
419
420 return fV0tags[trackIndex];
421}
422
423
424//______________________________________________________________________________
425Int_t AliAnalysisTaskPIDV0base::GetV0motherIndex(Int_t trackIndex) const
426{
427 //
428 // Get the index of the V0 mother for the corresponding trackIndex. Returns -99 in case of invalid index/mother index list.
429 //
430
431 if (!fStoreMotherIndex || trackIndex < 0 || trackIndex >= fNumTagsStored || !fV0motherIndex)
432 return -99;
433
434 return fV0motherIndex[trackIndex];
435}