5 #include "AliMCParticle.h"
7 #include "AliAnalysisTask.h"
8 #include "AliAnalysisManager.h"
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 #include "AliVTrack.h"
17 #include "AliExternalTrackParam.h"
18 #include "AliVVertex.h"
19 #include "AliAnalysisFilter.h"
21 #include "AliPIDResponse.h"
22 #include "AliESDv0KineCuts.h"
25 #include "AliAnalysisTaskPIDV0base.h"
28 This class is a base class for all other
29 analysis tasks that use V0's.
30 It provides basics for V0 identification.
31 In addition, some further basic functions are provided.
33 Class written by Benjamin Hess.
34 Contact: bhess@cern.ch
37 ClassImp(AliAnalysisTaskPIDV0base)
39 Double_t AliAnalysisTaskPIDV0base::fgCutGeo = 1.;
40 Double_t AliAnalysisTaskPIDV0base::fgCutNcr = 0.85;
41 Double_t AliAnalysisTaskPIDV0base::fgCutNcl = 0.7;
43 UShort_t AliAnalysisTaskPIDV0base::fgCutPureNcl = 60;
45 //________________________________________________________________________
46 AliAnalysisTaskPIDV0base::AliAnalysisTaskPIDV0base()
65 , fStoreMotherIndex(kFALSE)
68 // default Constructor
70 fRandom = new TRandom3(0); // 0 means random seed
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);
80 //________________________________________________________________________
81 AliAnalysisTaskPIDV0base::AliAnalysisTaskPIDV0base(const char *name)
82 : AliAnalysisTaskSE(name)
100 , fStoreMotherIndex(kFALSE)
101 , fV0motherIndex(0x0)
105 fRandom = new TRandom3(0); // 0 means random seed
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);
114 DefineInput (0, TChain::Class());
115 DefineOutput(0, TTree::Class());
119 //________________________________________________________________________
120 AliAnalysisTaskPIDV0base::~AliAnalysisTaskPIDV0base()
143 delete [] fV0motherIndex;
151 //________________________________________________________________________
152 void AliAnalysisTaskPIDV0base::UserCreateOutputObjects()
158 AliAnalysisManager* man = AliAnalysisManager::GetAnalysisManager();
159 AliInputEventHandler* inputHandler = dynamic_cast<AliInputEventHandler*>(man->GetInputEventHandler());
162 AliFatal("Input handler needed");
168 // PID response object
169 fPIDResponse = inputHandler->GetPIDResponse();
171 AliError("PIDResponse object was not created");
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]);
180 // Default analysis utils
181 fAnaUtils = new AliAnalysisUtils();
183 // Not used yet, but to be save, forward vertex z cut to analysis utils object
184 fAnaUtils->SetMaxVtxZ(fZvtxCutEvent);
188 //________________________________________________________________________
189 void AliAnalysisTaskPIDV0base::UserExec(Option_t *)
192 // Called for each event
195 //________________________________________________________________________
196 void AliAnalysisTaskPIDV0base::Terminate(const Option_t *)
198 // Called once at the end of the query
202 //_____________________________________________________________________________
203 Double_t AliAnalysisTaskPIDV0base::GetPhiPrime(Double_t phi, Double_t magField, Int_t charge) const
205 // Get phiPrime which is the cut variable to reject high pT tracks near edges
207 if(magField < 0) // for negatve polarity field
208 phi = TMath::TwoPi() - phi;
210 if(charge < 0) // for negatve charge
211 phi = TMath::TwoPi() - phi;
213 phi += TMath::Pi() / 18.0; // to center gap in the middle
214 phi = fmod(phi, TMath::Pi() / 9.0);
219 //______________________________________________________________________________
220 Bool_t AliAnalysisTaskPIDV0base::PhiPrimeCut(Double_t trackPt, Double_t trackPhi, Short_t trackCharge, Double_t magField) const
222 // Apply phi' cut to given track parameters
227 Double_t phiPrime = GetPhiPrime(trackPhi, magField, trackCharge);
229 if (phiPrime < fPhiCutHigh->Eval(trackPt) && phiPrime > fPhiCutLow->Eval(trackPt))
230 return kFALSE; // reject track
236 //______________________________________________________________________________
237 Bool_t AliAnalysisTaskPIDV0base::PhiPrimeCut(const AliVTrack* track, Double_t magField) const
239 return PhiPrimeCut(track->Pt(), track->Phi(), track->Charge(), magField);
243 //______________________________________________________________________________
244 Bool_t AliAnalysisTaskPIDV0base::GetVertexIsOk(AliVEvent* event, Bool_t doVtxZcut) const
246 // Check whether vertex ful-fills quality requirements.
247 // Apply cut on z-position of vertex if doVtxZcut = kTRUE.
249 AliAODEvent* aod = 0x0;
250 AliESDEvent* esd = 0x0;
252 aod = dynamic_cast<AliAODEvent*>(event);
254 esd = dynamic_cast<AliESDEvent*>(event);
257 AliError("Event seems to be neither AOD nor ESD!");
263 const AliVVertex* trkVtx = (aod ? dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertex()) :
264 dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertex()));
266 if (!trkVtx || trkVtx->GetNContributors() <= 0)
269 TString vtxTtl = trkVtx->GetTitle();
270 if (!vtxTtl.Contains("VertexerTracks"))
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)
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))
286 if (TMath::Abs(spdVtx->GetZ() - trkVtx->GetZ()) > 0.5)
290 if (TMath::Abs(zvtx) > fZvtxCutEvent) //Default: 10 cm
299 const AliVVertex* primaryVertex = 0x0;
301 primaryVertex = dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertex());
302 if (!primaryVertex || primaryVertex->GetNContributors() <= 0)
305 // Reject TPC vertices
306 TString primVtxTitle(primaryVertex->GetTitle());
307 if (primVtxTitle.Contains("TPCVertex",TString::kIgnoreCase))
311 primaryVertex = dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertexTracks());
315 if (primaryVertex->GetNContributors() <= 0) {
317 primaryVertex = dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertexSPD());
318 if (!primaryVertex || primaryVertex->GetNContributors() <= 0)
324 if (TMath::Abs(primaryVertex->GetZ()) > fZvtxCutEvent) //Default: 10 cm
332 //______________________________________________________________________________
333 Bool_t AliAnalysisTaskPIDV0base::GetIsPileUp(AliVEvent* event, AliAnalysisTaskPIDV0base::PileUpRejectionType pileUpRejectionType) const
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.
339 if (pileUpRejectionType == kPileUpRejectionOff)
343 AliError("No event!");
348 AliError("AnalysisUtils object not available!");
352 if (pileUpRejectionType == kPileUpRejectionSPD)
353 return fAnaUtils->IsPileUpSPD(event);
354 else if (pileUpRejectionType == kPileUpRejectionMV)
355 return fAnaUtils->IsPileUpMV(event);
361 //______________________________________________________________________________
362 void AliAnalysisTaskPIDV0base::FillV0PIDlist(AliESDEvent* event)
365 // Fill the PID tag list
368 // If no event forwarded as parameter (default), cast current input event.
369 // Dynamic cast to ESD events (DO NOTHING for AOD events)
371 event = dynamic_cast<AliESDEvent *>(InputEvent());
373 // If this fails, do nothing
375 AliError("Failed to retrieve ESD event. No V0's processed (only works for ESDs by now).");
380 AliError("V0KineCuts not available!");
384 TString beamType(event->GetBeamType());
386 if (beamType.CompareTo("Pb-Pb") == 0 || beamType.CompareTo("A-A") == 0) {
387 fV0KineCuts->SetMode(AliESDv0KineCuts::kPurity, AliESDv0KineCuts::kPbPb);
390 fV0KineCuts->SetMode(AliESDv0KineCuts::kPurity, AliESDv0KineCuts::kPP);
395 fV0KineCuts->SetEvent(event);
397 const Int_t numTracks = event->GetNumberOfTracks();
398 fV0tags = new Char_t[numTracks];
399 for (Int_t i = 0; i < numTracks; i++)
402 if (fStoreMotherIndex) {
403 fV0motherIndex = new Int_t[numTracks];
404 for (Int_t i = 0; i < numTracks; i++)
405 fV0motherIndex[i] = -1;
408 fNumTagsStored = numTracks;
410 // loop over V0 particles
411 for (Int_t iv0 = 0; iv0 < event->GetNumberOfV0s(); iv0++) {
412 AliESDv0* v0 = (AliESDv0*)event->GetV0(iv0);
417 // Reject onFly V0's <-> Only take V0's from offline V0 finder
418 if (v0->GetOnFlyStatus())
421 // Get the particle selection
422 Bool_t foundV0 = kFALSE;
423 Int_t pdgV0 = 0, pdgP = 0, pdgN = 0;
425 foundV0 = fV0KineCuts->ProcessV0(v0, pdgV0, pdgP, pdgN);
429 Int_t iTrackP = v0->GetPindex(); // positive track
430 Int_t iTrackN = v0->GetNindex(); // negative track
433 // Fill the Object arrays
434 // positive particles
436 fV0tags[iTrackP] = 14;
438 else if (pdgP == 211) {
439 fV0tags[iTrackP] = 15;
441 else if(pdgP == 2212) {
442 fV0tags[iTrackP] = 16;
445 if (fStoreMotherIndex)
446 fV0motherIndex[iTrackP] = iv0;
448 // negative particles
450 fV0tags[iTrackN] = -14;
452 else if( pdgN == -211){
453 fV0tags[iTrackN] = -15;
455 else if( pdgN == -2212){
456 fV0tags[iTrackN] = -16;
459 if (fStoreMotherIndex)
460 fV0motherIndex[iTrackN] = iv0;
465 //______________________________________________________________________________
466 void AliAnalysisTaskPIDV0base::ClearV0PIDlist()
469 // Clear the PID tag list
475 delete [] fV0motherIndex;
482 //______________________________________________________________________________
483 Char_t AliAnalysisTaskPIDV0base::GetV0tag(Int_t trackIndex) const
486 // Get the tag for the corresponding trackIndex. Returns -99 in case of invalid index/tag list.
489 if (trackIndex < 0 || trackIndex >= fNumTagsStored || !fV0tags)
492 return fV0tags[trackIndex];
496 //______________________________________________________________________________
497 Int_t AliAnalysisTaskPIDV0base::GetV0motherIndex(Int_t trackIndex) const
500 // Get the index of the V0 mother for the corresponding trackIndex. Returns -99 in case of invalid index/mother index list.
503 if (!fStoreMotherIndex || trackIndex < 0 || trackIndex >= fNumTagsStored || !fV0motherIndex)
506 return fV0motherIndex[trackIndex];
510 //________________________________________________________________________
511 Bool_t AliAnalysisTaskPIDV0base::TPCCutMIGeo(const AliVTrack* track, const AliVEvent* evt, TTreeStream* streamer)
520 const Short_t sign = track->Charge();
526 track->GetPxPyPz(pxpypz);
528 AliExternalTrackParam* par = new AliExternalTrackParam(xyz, pxpypz, cv, sign);
529 const AliESDtrack dummy;
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();
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;
541 Bool_t kout = cutGeom && cutNcr && cutNcls;
544 Double_t dedx = track->GetTPCsignal();
546 (*streamer)<<"tree"<<
548 "varGeom="<<varGeom<<
550 "varNcls="<<varNcls<<
552 "cutGeom="<<cutGeom<<
554 "cutNcls="<<cutNcls<<
568 //________________________________________________________________________
569 Bool_t AliAnalysisTaskPIDV0base::TPCnclCut(const AliVTrack* track)
572 // TPC Cut on TPCsignalN() only
578 return (track->GetTPCsignalN() >= fgCutPureNcl);