]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG3/hfe/AliHFEV0pid.cxx
Commit modifications done to take care of the problems
[u/mrichter/AliRoot.git] / PWG3 / hfe / AliHFEV0pid.cxx
CommitLineData
70da6c5a 1/*************************************************************************
2* Copyright(c) 1998-1999, 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// Utility class for V0 PID
17// Identifies Electrons, Pions and Protons using gamma conversions and
18// the decays of K0s and Lambdas
19// Containers with samples of Electrons, Pions and Protons can be accessed
20// via GetListOfElectrons() etc.
21//
22// Authors:
23// Matus Kalisky <matus.kalisky@cern.ch>
24// Markus Heide <mheide@uni-muenster.de>
25// Markus Fasel <M.Fasel@gsi.de>
26//
70da6c5a 27#include <TObjArray.h>
70da6c5a 28
29#include "AliAODEvent.h"
70da6c5a 30#include "AliAODv0.h"
70da6c5a 31#include "AliESDEvent.h"
32#include "AliESDtrack.h"
33#include "AliESDv0.h"
70da6c5a 34#include "AliKFVertex.h"
35#include "AliVEvent.h"
36#include "AliVTrack.h"
3a72645a 37#include "AliMCParticle.h"
38#include "AliStack.h"
39#include "AliMCEvent.h"
70da6c5a 40
faee3b18 41#include "AliHFEV0cuts.h"
42#include "AliHFEV0info.h"
43#include "AliHFEcollection.h"
44
70da6c5a 45#include "AliHFEV0pid.h"
46ClassImp(AliHFEV0pid)
47
48//____________________________________________________________
49AliHFEV0pid::AliHFEV0pid():
50 TObject()
51 , fInputEvent(NULL)
3a72645a 52 , fNtracks(0)
53 , fMCEvent(NULL)
54 , fMCon(kFALSE)
70da6c5a 55 , fPrimaryVertex(NULL)
56 , fElectrons(NULL)
57 , fPionsK0(NULL)
58 , fPionsL(NULL)
59 , fKaons(NULL)
60 , fProtons(NULL)
faee3b18 61 , fGammas(NULL)
62 , fK0s(NULL)
63 , fLambdas(NULL)
64 , fAntiLambdas(NULL)
70da6c5a 65 , fIndices(NULL)
66 , fQA(NULL)
faee3b18 67 , fV0cuts(NULL)
68 , fOutput(NULL)
70da6c5a 69{
70 //
71 // Default constructor
72 //
73 fElectrons = new TObjArray();
74 fPionsK0 = new TObjArray();
75 fPionsL = new TObjArray();
76 fKaons = new TObjArray();
77 fProtons = new TObjArray();
faee3b18 78
79 fElectrons->SetOwner();
80 fPionsK0->SetOwner();
81 fProtons->SetOwner();
82 fPionsL->SetOwner();
83 fKaons->SetOwner();
84
85 fGammas = new TObjArray();
86 fK0s = new TObjArray();
87 fLambdas = new TObjArray();
88 fAntiLambdas = new TObjArray();
89
90 fIndices = new AliHFEV0pidTrackIndex();
91
70da6c5a 92}
93
94//____________________________________________________________
95AliHFEV0pid::~AliHFEV0pid(){
96 //
97 // Destructor
98 // Remove Containers
99 //
70da6c5a 100 if(fElectrons) delete fElectrons;
101 if(fPionsK0) delete fPionsK0;
102 if(fPionsL) delete fPionsL;
103 if(fKaons) delete fKaons;
104 if(fProtons) delete fProtons;
faee3b18 105
106 if(fGammas) delete fGammas;
107 if(fK0s) delete fK0s;
108 if(fLambdas) delete fLambdas;
109 if(fAntiLambdas) delete fAntiLambdas;
110
70da6c5a 111 if(fIndices) delete fIndices;
112 if(fQA) delete fQA;
faee3b18 113 if(fV0cuts) delete fV0cuts;
114 if(fOutput) delete fOutput;
70da6c5a 115}
116
117//____________________________________________________________
118void AliHFEV0pid::InitQA(){
119 //
120 // Initialize QA histograms
121 //
faee3b18 122
123 fOutput = new TList();
124
125 fV0cuts = new AliHFEV0cuts();
126 fV0cuts->Init("V0cuts");
127
70da6c5a 128 if(!fQA){
3a72645a 129 fQA = new AliHFEcollection("v0pidQA", "QA histograms for V0 selection");
70da6c5a 130
faee3b18 131 fQA->CreateTH1F("h_nV0s", "No. of found and accepted V0s", 5, -0.5, 4.5);
70da6c5a 132
133 // QA histograms for invariant mass
91c7e1ec 134 fQA->CreateTH1F("h_InvMassGamma", "Gamma invariant mass; inv mass [GeV/c^{2}]; counts", 100, 0, 0.25);
faee3b18 135 fQA->CreateTH1F("h_InvMassK0s", "K0s invariant mass; inv mass [GeV/c^{2}]; counts", 200, 0.4, 0.65);
3a72645a 136 fQA->CreateTH1F("h_InvMassL", "Lambda invariant mass; inv mass [GeV/c^{2}]; counts", 100, 1.05, 1.15);
137 fQA->CreateTH1F("h_InvMassAL", "Lambda invariant mass; inv mass [GeV/c^{2}]; counts", 100, 1.05, 1.15);
70da6c5a 138
91c7e1ec 139 // QA histograms for p distribution (of the daughters)
140 fQA->CreateTH1F("h_P_electron", "P distribution of the gamma electrons; p (GeV/c); counts", 100, 0.1, 10);
141 fQA->CreateTH1F("h_P_K0pion", "P distribution of the K0 pions; p (GeV/c); counts", 100, 0.1, 10);
142 fQA->CreateTH1F("h_P_Lpion", "P distribution of the Lambda pions; p (GeV/c); counts", 100, 0.1, 10);
143 fQA->CreateTH1F("h_P_Lproton", "P distribution of the Lambda protons; p (GeV/c); counts", 100, 0.1, 10);
144
70da6c5a 145 // QA pt of the V0
146 fQA->CreateTH1F("h_Pt_Gamma", "Pt of the gamma conversion; p_{T} (GeV/c); counts", 100, 0, 10);
147 fQA->CreateTH1F("h_Pt_K0", "Pt of the K0; p_{T} (GeV/c); counts", 100, 0, 10);
3a72645a 148 fQA->CreateTH1F("h_Pt_L", "Pt of the Lambda; p_{T} (GeV/c); counts", 100, 0, 10);
149 fQA->CreateTH1F("h_Pt_AL", "Pt of the Lambda; p_{T} (GeV/c); counts", 100, 0, 10);
faee3b18 150
3a72645a 151 // Armenteros plot V0 preselection
152 fQA->CreateTH2F("h_AP_all_V0s", "armenteros plot for all V0 candidates; #alpha; Q_{T}", 200, -1, 1, 200, 0, 0.25);
153 fQA->CreateTH2F("h_AP_selected_V0s", "armenteros plot for all V0 candidates; #alpha; Q_{T}", 200, -1, 1, 200, 0, 0.25);
154
155 //
156 // !!! MC plots !!!
157 //
158 fQA->CreateTH2F("h_AP_MC_all_V0s", "armenteros plot for all MC tagged V0s; #alpha; Q_{T}", 200, -1, 1, 200, 0, 0.25);
159 fQA->CreateTH2F("h_AP_MC_Gamma", "armenteros plot for MC tagged Gammas; #alpha; Q_{T}", 200, -1, 1, 200, 0, 0.25);
160 fQA->CreateTH2F("h_AP_MC_K0", "armenteros plot for MC tagged K0s; #alpha; Q_{T}", 200, -1, 1, 200, 0, 0.25);
161 fQA->CreateTH2F("h_AP_MC_Lambda", "armenteros plot for MC tagged Lambdas; #alpha; Q_{T}", 200, -1, 1, 200, 0, 0.25);
162 fQA->CreateTH2F("h_AP_MC_ALambda", "armenteros plot for MC tagged A-Lambdass; #alpha; Q_{T}", 200, -1, 1, 200, 0, 0.25);
163
164
165
166 // armenteros plots for different V0 momenta - MC signal only
167 fQA->CreateTH2Fvector1(12, "h_AP_MC_Gamma_p", "armenteros plot for MC tagged Gammas; #alpha; Q_{T}", 200, -1., 1., 200, 0., 0.25);
168 fQA->CreateTH2Fvector1(12, "h_AP_MC_K0_p", "armenteros plot for MC tagged K0s; #alpha; Q_{T}", 200, -1., 1., 200, 0., 0.25);
169 fQA->CreateTH2Fvector1(12, "h_AP_MC_Lambda_p", "armenteros plot for MC tagged Lambdas; #alpha; Q_{T}", 200, -1., 1., 200, 0., 0.25);
170 //
171
70da6c5a 172
70da6c5a 173 }
174}
175
176//____________________________________________________________
177void AliHFEV0pid::Process(AliVEvent * const inputEvent){
178
179 //
180 // Find protons, pions and electrons using V0 decays and
181 // store the pointers in the TObjArray
182 //
faee3b18 183
70da6c5a 184 Int_t nGamma = 0, nK0s = 0, nLambda = 0, nPhi = 0;
185 fInputEvent = inputEvent;
3a72645a 186 fNtracks = fInputEvent->GetNumberOfTracks();
70da6c5a 187 fIndices->Init(fInputEvent->GetNumberOfV0s() * 2);
188 fPrimaryVertex = new AliKFVertex(*(fInputEvent->GetPrimaryVertex()));
faee3b18 189 if(!fPrimaryVertex) return;
190 fV0cuts->SetInputEvent(fInputEvent);
191 fV0cuts->SetPrimaryVertex(fPrimaryVertex);
3a72645a 192 if(fMCEvent) fV0cuts->SetMCEvent(fMCEvent);
70da6c5a 193 Int_t v0status = 0;
194 for(Int_t iv0 = 0; iv0 < fInputEvent->GetNumberOfV0s(); iv0++){
195 if(!TString(fInputEvent->IsA()->GetName()).CompareTo("AliESDEvent")){
196 // case ESD
197 SetESDanalysis();
bf892a6a 198 AliESDv0 *esdV0 = (static_cast<AliESDEvent *>(fInputEvent))->GetV0(iv0);
faee3b18 199 if(!esdV0) continue;
70da6c5a 200 if(!esdV0->GetOnFlyStatus()) continue; // Take only V0s from the On-the-fly v0 finder
201 v0status = ProcessV0(esdV0);
202 } else {
203 // case AOD
204 SetAODanalysis();
bf892a6a 205 AliAODv0 *aodV0 = (static_cast<AliAODEvent *>(fInputEvent))->GetV0(iv0);
70da6c5a 206 if(aodV0->GetOnFlyStatus()) continue; // Take only V0s from the On-the-fly v0 finder
207 v0status = ProcessV0(aodV0);
3a72645a 208 if(AliHFEV0cuts::kUndef != v0status){
faee3b18 209 }
70da6c5a 210 }
211 switch(v0status){
3a72645a 212 case AliHFEV0cuts::kRecoGamma: nGamma++; break;
213 case AliHFEV0cuts::kRecoK0: nK0s++; break;
214 case AliHFEV0cuts::kRecoPhi: nPhi++; break;
215 case AliHFEV0cuts::kRecoLambda: nLambda++; break;
70da6c5a 216 };
217 }
218
faee3b18 219
70da6c5a 220 AliDebug(1, Form("Number of gammas : %d", nGamma));
221 AliDebug(1, Form("Number of K0s : %d", nK0s));
222 AliDebug(1, Form("Number of Phis : %d", nPhi));
223 AliDebug(1, Form("Number of Lambdas : %d", nLambda));
224
225 AliDebug(1, "Number of stored tracks:");
226 AliDebug(1, Form("Number of electrons : %d", fElectrons->GetEntries()));
227 AliDebug(1, Form("Number of K0 pions : %d", fPionsK0->GetEntries()));
228 AliDebug(1, Form("Number of Lambda pions : %d", fPionsL->GetEntries()));
229 AliDebug(1, Form("Number of Phi kaons : %d", fKaons->GetEntries()));
230 AliDebug(1, Form("Number of protons : %d", fProtons->GetEntries()));
231
232 delete fPrimaryVertex;
233}
234
235//____________________________________________________________
236Int_t AliHFEV0pid::ProcessV0(TObject *v0){
237 //
238 // Process single V0
239 // Apply general cut and special cuts for gamma, K0s, Lambda
240 //
bf892a6a 241 if(!v0) return AliHFEV0cuts::kUndef;
70da6c5a 242 AliVTrack* daughter[2];
bf892a6a 243 daughter[0] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack((static_cast<AliESDv0 *>(v0))->GetPindex()));
244 daughter[1] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack((static_cast<AliESDv0 *>(v0))->GetNindex()));
3a72645a 245 if(!daughter[0] || !daughter[1]) return AliHFEV0cuts::kUndef;
246
bf892a6a 247 if(fMCEvent != NULL) fMCon = kTRUE;
3a72645a 248 //printf("-D: fMCEvent %x, fMCon: %i\n", fMCEvent, fMCon);
249
250 Int_t dMC[2] = {-1, -1};
251 Int_t idMC = AliHFEV0cuts::kUndef;
70da6c5a 252
253 if(IsESDanalysis()){
3a72645a 254 if(fMCon){
255 idMC = IdentifyV0(v0, dMC);
256 //printf("--D: V0 pid: %i, P: %i, N: %i\n", id, d[0], d[1]);
257 fV0cuts->SetCurrentV0id(idMC);
258 fV0cuts->SetDaughtersID(dMC);
259 }
260 // check common single track cuts
70da6c5a 261 for(Int_t i=0; i<2; ++i){
bf892a6a 262 if(!fV0cuts->TrackCutsCommon(static_cast<AliESDtrack*>(daughter[i]))) return AliHFEV0cuts::kUndef;
3a72645a 263 }
faee3b18 264 // check commom V0 cuts
3a72645a 265 if(!fV0cuts->V0CutsCommon(dynamic_cast<AliESDv0 *>(v0))) return AliHFEV0cuts::kUndef;
70da6c5a 266 }
267
3a72645a 268 // preselect the V0 candidates based on the Armenteros plot
269 Int_t id = PreselectV0((dynamic_cast<AliESDv0 *>(v0)), idMC);
faee3b18 270
271 // store the resutls
3a72645a 272 if(AliHFEV0cuts::kRecoGamma == id && IsGammaConv(v0)){
273 fQA->Fill("h_nV0s", AliHFEV0cuts::kRecoGamma);
274 return AliHFEV0cuts::kRecoGamma;
faee3b18 275 }
3a72645a 276 else if(AliHFEV0cuts::kRecoK0 == id && IsK0s(v0)){
277 fQA->Fill("h_nV0s", AliHFEV0cuts::kRecoK0);
278 return AliHFEV0cuts::kRecoK0;
faee3b18 279 }
3a72645a 280 else if(AliHFEV0cuts::kRecoLambda == TMath::Abs(id) && IsLambda(v0)){
281 fQA->Fill("h_nV0s", AliHFEV0cuts::kRecoLambda);
282 return AliHFEV0cuts::kRecoLambda;
faee3b18 283 }
3a72645a 284 else return AliHFEV0cuts::kUndef;
faee3b18 285
70da6c5a 286}
287//____________________________________________________________
288void AliHFEV0pid::Flush(){
289 //
290 // Clear the Lists
291 //
292 AliDebug(1, "Flushing containers");
faee3b18 293 fProtons->Delete();
294 fPionsK0->Delete();
295 fPionsL->Delete();
296 fElectrons->Delete();
70da6c5a 297 fIndices->Flush();
298}
70da6c5a 299//____________________________________________________________
3a72645a 300Int_t AliHFEV0pid::PreselectV0(AliESDv0 * const v0, Int_t idMC){
301 //
302 // Based on Armenteros plot preselet the possible identity of the V0 candidate
303 //
304
305 if(!v0) return -1;
306
307 // momentum dependent armenteros plots
308 ArmenterosPlotMC(v0, idMC);
309
310 // comupte the armenteros variables
311 Float_t ar[2];
312 fV0cuts->Armenteros(v0, ar);
313 // for clarity
314 const Float_t alpha = ar[0];
315 const Float_t qt = ar[1];
316 //printf(" -D: Alpha: %f, QT: %f \n", alpha, qt);
317
318 if(TMath::Abs(alpha) > 1) return AliHFEV0cuts::kUndef;
319
320 fQA->Fill("h_AP_all_V0s", alpha, qt);
321
322 // fill a few MC tagged histograms - AP plots
323 if(fMCEvent){
324 switch(idMC){
325 case AliHFEV0cuts::kRecoGamma :
326 fQA->Fill("h_AP_MC_all_V0s", alpha, qt);
327 fQA->Fill("h_AP_MC_Gamma", alpha, qt);
328 break;
329 case AliHFEV0cuts::kRecoK0 :
330 fQA->Fill("h_AP_MC_all_V0s", alpha, qt);
331 fQA->Fill("h_AP_MC_K0", alpha, qt);
332 break;
333 case AliHFEV0cuts::kRecoLambda :
334 fQA->Fill("h_AP_MC_all_V0s", alpha, qt);
335 fQA->Fill("h_AP_MC_Lambda", alpha, qt);
336 break;
337 case AliHFEV0cuts::kRecoALambda :
338 fQA->Fill("h_AP_MC_all_V0s", alpha, qt);
339 fQA->Fill("h_AP_MC_ALambda", alpha, qt);
340 break;
341 }
342 }
343
344 // Gamma cuts
345 const Double_t cutAlphaG = 0.35;
346 const Double_t cutQTG = 0.05;
347 const Double_t cutAlphaG2[2] = {0.6, 0.8};
348 const Double_t cutQTG2 = 0.04;
349
350 // K0 cuts
351 const Float_t cutQTK0[2] = {0.1075, 0.215};
352 const Float_t cutAPK0[2] = {0.199, 0.8}; // parameters for curved QT cut
353
354 // Lambda & A-Lambda cuts
355 const Float_t cutQTL = 0.03;
356 const Float_t cutAlphaL[2] = {0.35, 0.7};
357 const Float_t cutAlphaAL[2] = {-0.7, -0.35};
358 const Float_t cutAPL[3] = {0.107, -0.69, 0.5}; // parameters fir curved QT cut
359
360
361 // Check for Gamma candidates
362 if(qt < cutQTG){
363 if( (TMath::Abs(alpha) < cutAlphaG) ){
364 fQA->Fill("h_AP_selected_V0s", alpha, qt);
365 return AliHFEV0cuts::kRecoGamma;
366 }
367 }
368 // additional region - should help high pT gammas
369 if(qt < cutQTG2){
370 if( (TMath::Abs(alpha) > cutAlphaG2[0]) && (TMath::Abs(alpha) < cutAlphaG2[1]) ){
371 fQA->Fill("h_AP_selected_V0s", alpha, qt);
372 return AliHFEV0cuts::kRecoGamma;
373 }
374 }
375
376
377 // Check for K0 candidates
378 Float_t q = cutAPK0[0] * TMath::Sqrt(TMath::Abs(1 - alpha*alpha/(cutAPK0[1]*cutAPK0[1])));
379 if( (qt > cutQTK0[0]) && (qt < cutQTK0[1]) && (qt > q) ){
380 fQA->Fill("h_AP_selected_V0s", alpha, qt);
381 return AliHFEV0cuts::kRecoK0;
382 }
383
384 if( (alpha > 0) && (alpha > cutAlphaL[0]) && (alpha < cutAlphaL[1]) && (qt > cutQTL)){
385 q = cutAPL[0] * TMath::Sqrt(1 - ( (alpha + cutAPL[1]) * (alpha + cutAPL[1])) / (cutAPL[2]*cutAPL[2]) );
386 if( qt < q ){
387 fQA->Fill("h_AP_selected_V0s", alpha, qt);
388 return AliHFEV0cuts::kRecoLambda;
389 }
390 }
391
392 // Check for A-Lambda candidates
393 if( (alpha < 0) && (alpha > cutAlphaAL[0]) && (alpha < cutAlphaAL[1]) && (qt > cutQTL)){
394 q = cutAPL[0] * TMath::Sqrt(1 - ( (alpha - cutAPL[1]) * (alpha - cutAPL[1]) ) / (cutAPL[2]*cutAPL[2]) );
395 if( qt < q ){
396 fQA->Fill("h_AP_selected_V0s", alpha, qt);
397 return AliHFEV0cuts::kRecoLambda;
398 }
399 }
400
401 return AliHFEV0cuts::kUndef;
402
403}
404//____________________________________________________________
70da6c5a 405Bool_t AliHFEV0pid::IsGammaConv(TObject *v0){
406 //
407 // Identify Gamma
408 //
bf892a6a 409
410 if(!v0) return kFALSE;
411
70da6c5a 412 AliVTrack* daughter[2];
413 Int_t pIndex = 0, nIndex = 0;
414 Double_t invMass = 0.;
faee3b18 415 Double_t mPt = 0.;
416 Int_t v0id = -1;
70da6c5a 417 if(IsESDanalysis()){
418 // ESD - cut V0
bf892a6a 419 AliESDv0 *esdV0 = static_cast<AliESDv0 *>(v0);
faee3b18 420 v0id = esdV0->GetLabel();
421 // apply FULL gamma cuts
422 if(!fV0cuts->GammaCuts(esdV0)) return kFALSE;
423 invMass = esdV0->GetEffMass(AliPID::kElectron, AliPID::kElectron);
70da6c5a 424 pIndex = esdV0->GetPindex();
425 nIndex = esdV0->GetNindex();
faee3b18 426 mPt = esdV0->Pt();
70da6c5a 427 } else {
428 // AOD Analysis - not possible to cut
bf892a6a 429 AliAODv0 *aodV0 = static_cast<AliAODv0 *>(v0);
faee3b18 430 v0id = aodV0->GetID();
70da6c5a 431 pIndex = aodV0->GetPosID();
432 nIndex = aodV0->GetNegID();
433 invMass = aodV0->InvMass2Prongs(0, 1, kElectron, kElectron);
434 }
435 daughter[0] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack(pIndex));
436 daughter[1] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack(nIndex));
437 if(!daughter[0] || !daughter[1]) return kFALSE;
faee3b18 438
439 // DEBUG
440 AliDebug(1, Form("Gamma identified, daughter IDs: %d,%d", daughter[0]->GetID(), daughter[1]->GetID()));
70da6c5a 441
faee3b18 442 // AFTER all gamma cuts
70da6c5a 443 fQA->Fill("h_Pt_Gamma", mPt);
faee3b18 444 fQA->Fill("h_InvMassGamma", invMass);
70da6c5a 445
70da6c5a 446 // Identified gamma - store tracks in the electron containers
447 if(!fIndices->Find(daughter[0]->GetID())){
448 AliDebug(1, Form("Gamma identified, daughter IDs: %d,%d", daughter[0]->GetID(), daughter[1]->GetID()));
faee3b18 449 fElectrons->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id));
3a72645a 450 fIndices->Add(daughter[0]->GetID(), AliHFEV0cuts::kRecoElectron);
70da6c5a 451 }
452 if(!fIndices->Find(daughter[1]->GetID())){
453 AliDebug(1, Form("Gamma identified, daughter IDs: %d,%d", daughter[1]->GetID(), daughter[1]->GetID()));
faee3b18 454 fElectrons->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id));
3a72645a 455 fIndices->Add(daughter[1]->GetID(), AliHFEV0cuts::kRecoElectron);
70da6c5a 456 }
faee3b18 457 fGammas->Add(v0);
458
70da6c5a 459 return kTRUE;
460}
70da6c5a 461//____________________________________________________________
462Bool_t AliHFEV0pid::IsK0s(TObject *v0){
463 //
464 // Identify K0s
465 //
bf892a6a 466
467 if(!v0) return kFALSE;
468
70da6c5a 469 AliVTrack* daughter[2];
470 Int_t pIndex = 0, nIndex = 0;
faee3b18 471 Int_t v0id = -1;
70da6c5a 472 Double_t invMass = 0.;
faee3b18 473 Double_t mPt = 0.;
70da6c5a 474 if(IsESDanalysis()){
475 // ESD - cut V0
bf892a6a 476 AliESDv0 *esdV0 = static_cast<AliESDv0 *>(v0);
faee3b18 477 if(!fV0cuts->K0Cuts(esdV0)) return kFALSE;
478 v0id = esdV0->GetLabel();
70da6c5a 479 pIndex = esdV0->GetPindex();
480 nIndex = esdV0->GetNindex();
faee3b18 481 invMass = esdV0->GetEffMass(AliPID::kPion, AliPID::kPion);
482 mPt = esdV0->Pt();
70da6c5a 483 } else {
484 // AOD Analysis - not possible to cut
bf892a6a 485 AliAODv0 *aodV0 = static_cast<AliAODv0 *>(v0);
faee3b18 486 aodV0->GetID();
70da6c5a 487 pIndex = aodV0->GetPosID();
488 nIndex = aodV0->GetNegID();
489 invMass = aodV0->MassK0Short();
490 }
491 daughter[0] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack(pIndex));
492 daughter[1] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack(nIndex));
493 if(!daughter[0] || !daughter[1]) return kFALSE;
494
70da6c5a 495 fQA->Fill("h_Pt_K0", mPt);
faee3b18 496 fQA->Fill("h_InvMassK0s", invMass);
70da6c5a 497
70da6c5a 498 AliDebug(1, Form("K0 identified, daughter IDs: %d,%d", daughter[0]->GetID(), daughter[1]->GetID()));
499
faee3b18 500 // AFTER all K0 cuts
70da6c5a 501 // Identified gamma - store tracks in the electron containers
502 if(!fIndices->Find(daughter[0]->GetID())){
503 AliDebug(1, Form("Adding K0 Pion track with ID %d", daughter[0]->GetID()));
faee3b18 504 fPionsK0->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id));
3a72645a 505 fIndices->Add(daughter[0]->GetID(), AliHFEV0cuts::kRecoPionK0);
70da6c5a 506 }
507 if(!fIndices->Find(daughter[1]->GetID())){
508 AliDebug(1, Form("Adding K0 Pion track with ID %d", daughter[1]->GetID()));
faee3b18 509 fPionsK0->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id));
3a72645a 510 fIndices->Add(daughter[1]->GetID(), AliHFEV0cuts::kRecoPionK0);
70da6c5a 511 }
faee3b18 512 fK0s->Add(v0);
70da6c5a 513 return kTRUE;
514}
515
516//____________________________________________________________
517Bool_t AliHFEV0pid::IsPhi(TObject *v0){
518 //
519 // Identify Phi - very preliminary - requires diffrent approach (V0 fnder is not effective)
520 //
521
522 //const Double_t kPhiMass=TDatabasePDG::Instance()->GetParticle(333)->Mass(); // PDG phi mass
523 //AliVTrack* daughter[2];
70da6c5a 524 //Double_t invMass = 0.;
bf892a6a 525
526 if(!v0) return kFALSE;
70da6c5a 527
528 Int_t pIndex = 0, nIndex = 0;
529 if(IsESDanalysis()){
530 // ESD - cut V0
bf892a6a 531 AliESDv0 *esdV0 = static_cast<AliESDv0 *>(v0);
70da6c5a 532 pIndex = esdV0->GetPindex();
533 nIndex = esdV0->GetNindex();
534 } else {
535 // PRELIMINARY - !!!
536 // AOD Analysis - not possible to cut
537 }
538
539 return kTRUE;
540}
541
542//____________________________________________________________
543Bool_t AliHFEV0pid::IsLambda(TObject *v0){
544 //
545 // Identify Lambda
546 //
bf892a6a 547
548 if(!v0) return kFALSE;
549
70da6c5a 550 AliVTrack* daughter[2];
551 Int_t pIndex = 0, nIndex = 0;
70da6c5a 552 Double_t invMass = 0.;
faee3b18 553 Bool_t isLambda = kTRUE; // Lambda - kTRUE, Anti Lambda - kFALSE
3a72645a 554 Double_t mPt = 0.;
faee3b18 555 Int_t v0id = -1;
70da6c5a 556 if(IsESDanalysis()){
557 // ESD - cut V0
bf892a6a 558 AliESDv0 *esdV0 = static_cast<AliESDv0 *>(v0);
faee3b18 559 v0id = esdV0->GetLabel();
560 if(!fV0cuts->LambdaCuts(esdV0,isLambda)) return kFALSE;
3a72645a 561 mPt = esdV0->Pt();
faee3b18 562 if(fV0cuts->CheckSigns(esdV0)){
563 pIndex = esdV0->GetPindex();
564 nIndex = esdV0->GetNindex();
565 }
566 else{
567 pIndex = esdV0->GetNindex();
568 nIndex = esdV0->GetPindex();
569 }
70da6c5a 570 } else {
571 // PRELIMINARY - !!!
572 // AOD Analysis - not possible to cut
573
574 // again - two cases as above
bf892a6a 575 AliAODv0 *aodV0 = static_cast<AliAODv0 *>(v0);
faee3b18 576 v0id = aodV0->GetID();
70da6c5a 577 pIndex = aodV0->GetPosID();
578 nIndex = aodV0->GetNegID();
faee3b18 579 invMass = aodV0->MassLambda();
580 }
581
70da6c5a 582 daughter[0] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack(pIndex));
583 daughter[1] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack(nIndex));
584 if(!daughter[0] || !daughter[1]) return kFALSE;
faee3b18 585
586 // lambda
587 if(isLambda){
3a72645a 588 fQA->Fill("h_Pt_L", mPt);
589 fQA->Fill("h_InvMassL", invMass);
590
faee3b18 591 if(!fIndices->Find(daughter[0]->GetID())){
592 fProtons->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id));
3a72645a 593 fIndices->Add(daughter[0]->GetID(), AliHFEV0cuts::kRecoProton);
70da6c5a 594 }
faee3b18 595 if(!fIndices->Find(daughter[1]->GetID())){
596 fPionsL->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id));
3a72645a 597 fIndices->Add(daughter[1]->GetID(), AliHFEV0cuts::kRecoPionL);
70da6c5a 598 }
70da6c5a 599 }
faee3b18 600 // antilambda
601 else{
3a72645a 602 fQA->Fill("h_Pt_AL", mPt);
603 fQA->Fill("h_InvMassAL", invMass);
faee3b18 604 if(!fIndices->Find(daughter [1]->GetID())){
605 fProtons->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id));
3a72645a 606 fIndices->Add(daughter[1]->GetID(), AliHFEV0cuts::kRecoProton);
faee3b18 607 }
608 if(!fIndices->Find(daughter [0]->GetID())){
609 fPionsL->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id));
3a72645a 610 fIndices->Add(daughter [0]->GetID(), AliHFEV0cuts::kRecoPionL);
70da6c5a 611 }
70da6c5a 612 }
faee3b18 613 if(isLambda) fLambdas->Add(v0);
614 else fAntiLambdas->Add(v0);
70da6c5a 615
70da6c5a 616 return kTRUE;
617}
618
3a72645a 619//____________________________________________________________
620Int_t AliHFEV0pid::IdentifyV0(TObject *esdV0, Int_t d[2]){
621 //
622 // for MC only, returns the V0 Id
623 //
624
625 //
626 // be carefull about changing the return values - they are used later selectively
627 // In particulra "-2" means that identity of either of the daughters could not be
628 // estimated
629 //
630
631 AliESDv0 *v0 = dynamic_cast<AliESDv0 *>(esdV0);
632
633 if(!v0) return -1;
634 AliESDtrack* dN, *dP;
635 Int_t iN, iP;
636 iN = iP = -1;
637 iP = v0->GetPindex();
638 iN = v0->GetNindex();
639 if(iN < 0 || iP < 0) return -1;
640 if(iN >= fNtracks || iP >= fNtracks) return -1;
641 dP = dynamic_cast<AliESDtrack *>(fInputEvent->GetTrack(iP));
642 dN = dynamic_cast<AliESDtrack *>(fInputEvent->GetTrack(iN));
643 if(!dN || !dP) return -1;
644
645 // as of 26/10/2010
646 // there is still a problem with wrong assignment of positive and negative
647 // V0 daughter in V0 finder - a check is necessary
648 // if the V0 daughters are miss-assigned - swap their labels
649 Bool_t sign = fV0cuts->CheckSigns(v0);
650
651 // get the MC labels
652 Int_t lN, lP;
653 if(sign){
654 lN = dN->GetLabel();
655 lP = dP->GetLabel();
656 }
657 else{
658 lP = dN->GetLabel();
659 lN = dP->GetLabel();
660 }
661 if(lN < 0 || lP < 0) return -2;
662 // get the associated MC particles
663 AliMCParticle *mcP, *mcN;
664 mcP = dynamic_cast<AliMCParticle*>(fMCEvent->GetTrack(lP));
665 mcN = dynamic_cast<AliMCParticle*>(fMCEvent->GetTrack(lN));
666 if(!mcP || !mcN) return -2;
667
668 // identify the daughter tracks and their mothers
669 Int_t pdgP, pdgN;
670 pdgP = TMath::Abs(mcP->PdgCode());
671 pdgN = TMath::Abs(mcN->PdgCode());
672 // store the daughter ID for later use
673 d[0] = pdgP;
674 d[1] = pdgN;
675 //printf(" -D: pdgP: %i, pdgN: %i\n", pdgP, pdgN);
676 // lablel of the mother particle
677 // -1 may mean it was a primary particle
678 Int_t lPm, lNm;
679 lPm = mcP->GetMother();
680 lNm = mcN->GetMother();
681 if(-1==lPm || -1==lNm) return -3;
682
683 // return if mothers are not the same particle
684 if(lPm != lNm) return -3;
685 // get MC mother particle - now we need only 1
686 AliMCParticle *m = dynamic_cast<AliMCParticle*>(fMCEvent->GetTrack(lPm));
687 if(!m) return -2;
688 // mother PDG
689 Int_t pdgM = m->PdgCode();
690
691 // if(3122 == TMath::Abs(pdgM)){
692 // printf("-D: v0 signs: %i\n", fV0cuts->CheckSigns(v0));
693 // printf("-D: pdgM: %i, pdgN: %i, pdgP: %i \n", pdgM, pdgN, pdgP);
694 // }
695
696
697 // now check the mother and daughters identity
698 if(22 == TMath::Abs(pdgM) && 11 == pdgN && 11 == pdgP) return AliHFEV0cuts::kRecoGamma;
699 if(310 == TMath::Abs(pdgM) && 211 == pdgN && 211 == pdgP) return AliHFEV0cuts::kRecoK0;
700 if(-3122 == pdgM && 2212 == pdgN && 211 == pdgP) return AliHFEV0cuts::kRecoALambda;
701 if(3122 == pdgM && 211 == pdgN && 2212 == pdgP) return AliHFEV0cuts::kRecoLambda;
702
703 return AliHFEV0cuts::kUndef;
704
705}
706//____________________________________________________________
707void AliHFEV0pid::ArmenterosPlotMC(AliESDv0 * const v0, Int_t idMC){
708 //
709 // Armenteros plots as a function of Mohter Momentum
710 //
711 //const Float_t minP = 0.1;
712 //const Float_t maxP = 10.;
713 // approx log bins - over the 0.1 - 10 GeV/c
714 const Float_t bins[13] = {0.1, 0.1468, 0.2154, 0.3162, 0.4642, 0.6813, 1.0, 1.4678, 2.1544, 3.1623, 4.6416, 6.8129, 10.0};
715
716 Float_t ar[2];
717 fV0cuts->Armenteros(v0, ar);
718 Float_t p = v0->P();
719
720 if( (p <= bins[0]) || (p >= bins[12])) return;
721
722 Int_t pBin = 0;
723 Float_t tmp = bins[0];
724 while(tmp < p){
725 ++pBin;
726 tmp = bins[pBin];
727 }
728 pBin--;
729
730 if(AliHFEV0cuts::kRecoGamma == idMC) fQA->Fill("h_AP_MC_Gamma_p", pBin, ar[0], ar[1]);
731 if(AliHFEV0cuts::kRecoK0 == idMC) fQA->Fill("h_AP_MC_K0_p", pBin, ar[0], ar[1]);
732 if(AliHFEV0cuts::kRecoLambda == TMath::Abs(idMC)) fQA->Fill("h_AP_MC_Lambda_p", pBin, ar[0], ar[1]);
733
734
735
736}
70da6c5a 737//____________________________________________________________
738AliHFEV0pid::AliHFEV0pidTrackIndex::AliHFEV0pidTrackIndex():
739 fNElectrons(0)
740 , fNPionsK0(0)
741 , fNPionsL(0)
742 , fNKaons(0)
743 , fNProtons(0)
744 , fIndexElectron(NULL)
745 , fIndexPionK0(NULL)
746 , fIndexPionL(NULL)
747 , fIndexKaon(NULL)
748 , fIndexProton(NULL)
749{
750 //
751 // Default Constructor
752 //
753}
754
755//____________________________________________________________
756AliHFEV0pid::AliHFEV0pidTrackIndex::~AliHFEV0pidTrackIndex(){
757 //
758 // Destructor
759 //
760 if(fIndexElectron) delete[] fIndexElectron;
761 if(fIndexPionK0) delete[] fIndexPionK0;
762 if(fIndexPionL) delete[] fIndexPionL;
763 if(fIndexProton) delete[] fIndexProton;
764}
765
766//____________________________________________________________
767void AliHFEV0pid::AliHFEV0pidTrackIndex::Flush(){
768 //
769 // Reset containers
770 //
771
772 if(fIndexElectron) delete[] fIndexElectron;
773 fIndexElectron = NULL;
774 if(fIndexPionK0) delete[] fIndexPionK0;
775 fIndexPionK0 = NULL;
776 if(fIndexPionL) delete[] fIndexPionL;
777 fIndexPionL = NULL;
778 if(fIndexKaon) delete[] fIndexKaon;
779 fIndexKaon = NULL;
780 if(fIndexProton) delete[] fIndexProton;
781 fIndexProton = NULL;
782
783 fNElectrons = 0;
784 fNPionsK0 = 0;
785 fNPionsL = 0;
786 fNKaons = 0;
787 fNProtons = 0;
788}
789
790//____________________________________________________________
791void AliHFEV0pid::AliHFEV0pidTrackIndex::Init(Int_t capacity){
792 //
793 // Initialize container
794 //
795 fIndexElectron = new Int_t[capacity];
796 fIndexPionK0 = new Int_t[capacity];
797 fIndexPionL = new Int_t[capacity];
798 fIndexProton = new Int_t[capacity];
799}
800
801//____________________________________________________________
802void AliHFEV0pid::AliHFEV0pidTrackIndex::Add(Int_t index, Int_t species){
803 //
804 // Add new index to the list of identified particles
805 //
806 switch(species){
3a72645a 807 case AliHFEV0cuts::kRecoElectron:
70da6c5a 808 fIndexElectron[fNElectrons++] = index;
809 break;
3a72645a 810 case AliHFEV0cuts::kRecoPionK0:
70da6c5a 811 fIndexPionK0[fNPionsK0++] = index;
812 break;
3a72645a 813 case AliHFEV0cuts::kRecoPionL:
70da6c5a 814 fIndexPionL[fNPionsL++] = index;
815 break;
3a72645a 816 case AliHFEV0cuts::kRecoProton:
70da6c5a 817 fIndexProton[fNProtons++] = index;
818 break;
819 };
820}
821
822//____________________________________________________________
823Bool_t AliHFEV0pid::AliHFEV0pidTrackIndex::Find(Int_t index, Int_t species) const {
824 //
825 // Find track index in the specific sample of particles
826 //
827
828 Int_t *container = NULL; Int_t n = 0;
829 switch(species){
3a72645a 830 case AliHFEV0cuts::kRecoElectron:
70da6c5a 831 container = fIndexElectron;
832 n = fNElectrons;
833 break;
3a72645a 834 case AliHFEV0cuts::kRecoPionK0:
70da6c5a 835 container = fIndexPionK0;
836 n = fNPionsK0;
837 break;
3a72645a 838 case AliHFEV0cuts::kRecoPionL:
70da6c5a 839 container = fIndexPionL;
840 n = fNPionsL;
841 break;
3a72645a 842 case AliHFEV0cuts::kRecoProton:
70da6c5a 843 container = fIndexProton;
844 n = fNProtons;
845 break;
846 }
847 if(!container) return kFALSE;
848 if(n == 0) return kFALSE;
849 Bool_t found = kFALSE;
850 for(Int_t i = 0; i < n; i++){
851 if(container[i] == index){
852 found = kTRUE;
853 break;
854 }
855 }
856 return found;
857}
858
859//____________________________________________________________
860Bool_t AliHFEV0pid::AliHFEV0pidTrackIndex::Find(Int_t index) const {
861 //
862 // Find index in all samples
863 //
3a72645a 864 if(Find(index, AliHFEV0cuts::kRecoElectron)) return kTRUE;
865 else if(Find(index, AliHFEV0cuts::kRecoPionK0)) return kTRUE;
866 else if(Find(index, AliHFEV0cuts::kRecoPionL)) return kTRUE;
867 else return Find(index, AliHFEV0cuts::kRecoProton);
70da6c5a 868}
869
870//____________________________________________________________
faee3b18 871TList *AliHFEV0pid::GetListOfQAhistograms(){
70da6c5a 872 //
faee3b18 873 // Getter for V0 PID QA histograms
70da6c5a 874 //
3a72645a 875
faee3b18 876 TList *tmp = fV0cuts->GetList();
877 tmp->SetName("V0cuts");
878 fOutput->Add(tmp);
879 if(fQA){
880 tmp = 0x0;
881 tmp = fQA->GetList();
882 tmp->SetName("V0pid");
883 fOutput->Add(tmp);
884 }
3a72645a 885 tmp = 0x0;
886 tmp = fV0cuts->GetListMC();
887 tmp->SetName("V0cutsMC");
888 //printf(" -D: adding MC V0 cuts stuff\n");
889 fOutput->Add(tmp);
890
faee3b18 891 return fOutput;
70da6c5a 892}