]>
Commit | Line | Data |
---|---|---|
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 | /* | |
27 | This class is a base class for all other | |
28 | analysis tasks that use V0's. | |
29 | It provides basics for V0 identification. | |
30 | In addition, some further basic functions are provided. | |
31 | ||
32 | Class written by Benjamin Hess. | |
33 | Contact: bhess@cern.ch | |
34 | */ | |
35 | ||
36 | ClassImp(AliAnalysisTaskPIDV0base) | |
37 | ||
38 | //________________________________________________________________________ | |
39 | AliAnalysisTaskPIDV0base::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 | //________________________________________________________________________ | |
72 | AliAnalysisTaskPIDV0base::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 | //________________________________________________________________________ | |
109 | AliAnalysisTaskPIDV0base::~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 | //________________________________________________________________________ | |
138 | void 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 | //________________________________________________________________________ | |
169 | void AliAnalysisTaskPIDV0base::UserExec(Option_t *) | |
170 | { | |
171 | // Main loop | |
172 | // Called for each event | |
173 | } | |
174 | ||
175 | //________________________________________________________________________ | |
176 | void AliAnalysisTaskPIDV0base::Terminate(const Option_t *) | |
177 | { | |
178 | // Called once at the end of the query | |
179 | } | |
180 | ||
181 | ||
182 | //_____________________________________________________________________________ | |
183 | Double_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 | //______________________________________________________________________________ | |
200 | Bool_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 | //______________________________________________________________________________ | |
217 | Bool_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 | //______________________________________________________________________________ | |
224 | Bool_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 | //______________________________________________________________________________ | |
290 | void 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 | //______________________________________________________________________________ | |
394 | void 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 | //______________________________________________________________________________ | |
411 | Char_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 | //______________________________________________________________________________ | |
425 | Int_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 | } |