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 "AliTPCPIDBase.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(AliTPCPIDBase)
39 Double_t AliTPCPIDBase::fgCutGeo = 1.;
40 Double_t AliTPCPIDBase::fgCutNcr = 0.85;
41 Double_t AliTPCPIDBase::fgCutNcl = 0.7;
43 UShort_t AliTPCPIDBase::fgCutPureNcl = 60;
45 //________________________________________________________________________
46 AliTPCPIDBase::AliTPCPIDBase()
64 , fStoreMotherIndex(kFALSE)
67 // default Constructor
69 fRandom = new TRandom3(0); // 0 means random seed
72 // Question: Is this the right place to initialize these functions?
73 // Will it work on proof? i.e. will they be streamed to the workers?
74 // Also one should add getters and setters
75 fPhiCutLow = new TF1("StdPhiCutLow", "0.1/x/x+pi/18.0-0.025", 0, 100);
76 fPhiCutHigh = new TF1("StandardPhiCutHigh", "0.12/x+pi/18.0+0.035", 0, 100);
79 //________________________________________________________________________
80 AliTPCPIDBase::AliTPCPIDBase(const char *name)
81 : AliAnalysisTaskSE(name)
98 , fStoreMotherIndex(kFALSE)
103 fRandom = new TRandom3(0); // 0 means random seed
106 // Question: Is this the right place to initialize these functions?
107 // Will it work on proof? i.e. will they be streamed to the workers?
108 // Also one should add getters and setters
109 fPhiCutLow = new TF1("StdPhiCutLow", "0.1/x/x+pi/18.0-0.025", 0, 100);
110 fPhiCutHigh = new TF1("StandardPhiCutHigh", "0.12/x+pi/18.0+0.035", 0, 100);
112 DefineInput (0, TChain::Class());
113 DefineOutput(0, TTree::Class());
117 //________________________________________________________________________
118 AliTPCPIDBase::~AliTPCPIDBase()
141 delete fV0motherIndex;
146 //________________________________________________________________________
147 void AliTPCPIDBase::UserCreateOutputObjects()
153 AliAnalysisManager* man = AliAnalysisManager::GetAnalysisManager();
154 AliInputEventHandler* inputHandler = dynamic_cast<AliInputEventHandler*>(man->GetInputEventHandler());
157 AliFatal("Input handler needed");
163 // PID response object
164 fPIDResponse = inputHandler->GetPIDResponse();
166 AliError("PIDResponse object was not created");
169 fV0KineCuts = new AliESDv0KineCuts;
170 fV0KineCuts->SetGammaCutChi2NDF(5.);
171 // Only accept V0el with prod. radius within 45 cm -> PID will by systematically biased for larger values!
172 Float_t gammaProdVertexRadiusCuts[2] = { 3.0, 45. };
173 fV0KineCuts->SetGammaCutVertexR(&gammaProdVertexRadiusCuts[0]);
177 //________________________________________________________________________
178 void AliTPCPIDBase::UserExec(Option_t *)
181 // Called for each event
184 //________________________________________________________________________
185 void AliTPCPIDBase::Terminate(const Option_t *)
187 // Called once at the end of the query
191 //_____________________________________________________________________________
192 Double_t AliTPCPIDBase::GetPhiPrime(Double_t phi, Double_t magField, Int_t charge) const
194 // Get phiPrime which is the cut variable to reject high pT tracks near edges
196 if(magField < 0) // for negatve polarity field
197 phi = TMath::TwoPi() - phi;
199 if(charge < 0) // for negatve charge
200 phi = TMath::TwoPi() - phi;
202 phi += TMath::Pi() / 18.0; // to center gap in the middle
203 phi = fmod(phi, TMath::Pi() / 9.0);
208 //______________________________________________________________________________
209 Bool_t AliTPCPIDBase::PhiPrimeCut(Double_t trackPt, Double_t trackPhi, Short_t trackCharge, Double_t magField) const
211 // Apply phi' cut to given track parameters
216 Double_t phiPrime = GetPhiPrime(trackPhi, magField, trackCharge);
218 if (phiPrime < fPhiCutHigh->Eval(trackPt) && phiPrime > fPhiCutLow->Eval(trackPt))
219 return kFALSE; // reject track
225 //______________________________________________________________________________
226 Bool_t AliTPCPIDBase::PhiPrimeCut(const AliVTrack* track, Double_t magField) const
228 return PhiPrimeCut(track->Pt(), track->Phi(), track->Charge(), magField);
232 //______________________________________________________________________________
233 Bool_t AliTPCPIDBase::GetVertexIsOk(AliVEvent* event, Bool_t doVtxZcut) const
235 // Check whether vertex ful-fills quality requirements.
236 // Apply cut on z-position of vertex if doVtxZcut = kTRUE.
238 AliAODEvent* aod = 0x0;
239 AliESDEvent* esd = 0x0;
241 aod = dynamic_cast<AliAODEvent*>(event);
243 esd = dynamic_cast<AliESDEvent*>(event);
246 AliError("Event seems to be neither AOD nor ESD!");
252 const AliVVertex* trkVtx = (aod ? dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertex()) :
253 dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertex()));
255 if (!trkVtx || trkVtx->GetNContributors() <= 0)
258 TString vtxTtl = trkVtx->GetTitle();
259 if (!vtxTtl.Contains("VertexerTracks"))
262 Float_t zvtx = trkVtx->GetZ();
263 const AliVVertex* spdVtx = (aod ? dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertexSPD()) :
264 dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertexSPD()));
265 if (spdVtx->GetNContributors() <= 0)
268 TString vtxTyp = spdVtx->GetTitle();
269 Double_t cov[6] = {0};
270 spdVtx->GetCovarianceMatrix(cov);
271 Double_t zRes = TMath::Sqrt(cov[5]);
272 if (vtxTyp.Contains("vertexer:Z") && (zRes > 0.25))
275 if (TMath::Abs(spdVtx->GetZ() - trkVtx->GetZ()) > 0.5)
279 if (TMath::Abs(zvtx) > fZvtxCutEvent) //Default: 10 cm
288 const AliVVertex* primaryVertex = (aod ? dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertex()) :
289 dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertexTracks()));
291 if (!primaryVertex || primaryVertex->GetNContributors() <= 0)
295 if (TMath::Abs(primaryVertex->GetZ()) > fZvtxCutEvent) //Default: 10 cm
303 //______________________________________________________________________________
304 void AliTPCPIDBase::FillV0PIDlist(AliESDEvent* event)
307 // Fill the PID tag list
310 // If no event forwarded as parameter (default), cast current input event.
311 // Dynamic cast to ESD events (DO NOTHING for AOD events)
313 event = dynamic_cast<AliESDEvent *>(InputEvent());
315 // If this fails, do nothing
317 AliError("Failed to retrieve ESD event. No V0's processed (only works for ESDs by now).");
322 AliError("V0KineCuts not available!");
326 TString beamType(event->GetBeamType());
328 if (beamType.CompareTo("Pb-Pb") == 0 || beamType.CompareTo("A-A") == 0) {
329 fV0KineCuts->SetMode(AliESDv0KineCuts::kPurity, AliESDv0KineCuts::kPbPb);
332 fV0KineCuts->SetMode(AliESDv0KineCuts::kPurity, AliESDv0KineCuts::kPP);
337 fV0KineCuts->SetEvent(event);
339 const Int_t numTracks = event->GetNumberOfTracks();
340 fV0tags = new Char_t[numTracks];
341 for (Int_t i = 0; i < numTracks; i++)
344 if (fStoreMotherIndex) {
345 fV0motherIndex = new Int_t[numTracks];
346 for (Int_t i = 0; i < numTracks; i++)
347 fV0motherIndex[i] = -1;
350 fNumTagsStored = numTracks;
352 // loop over V0 particles
353 for (Int_t iv0 = 0; iv0 < event->GetNumberOfV0s(); iv0++) {
354 AliESDv0* v0 = (AliESDv0*)event->GetV0(iv0);
359 // Reject onFly V0's <-> Only take V0's from offline V0 finder
360 if (v0->GetOnFlyStatus())
363 // Get the particle selection
364 Bool_t foundV0 = kFALSE;
365 Int_t pdgV0 = 0, pdgP = 0, pdgN = 0;
367 foundV0 = fV0KineCuts->ProcessV0(v0, pdgV0, pdgP, pdgN);
371 Int_t iTrackP = v0->GetPindex(); // positive track
372 Int_t iTrackN = v0->GetNindex(); // negative track
375 // Fill the Object arrays
376 // positive particles
378 fV0tags[iTrackP] = 14;
380 else if (pdgP == 211) {
381 fV0tags[iTrackP] = 15;
383 else if(pdgP == 2212) {
384 fV0tags[iTrackP] = 16;
387 if (fStoreMotherIndex)
388 fV0motherIndex[iTrackP] = iv0;
390 // negative particles
392 fV0tags[iTrackN] = -14;
394 else if( pdgN == -211){
395 fV0tags[iTrackN] = -15;
397 else if( pdgN == -2212){
398 fV0tags[iTrackN] = -16;
401 if (fStoreMotherIndex)
402 fV0motherIndex[iTrackN] = iv0;
407 //______________________________________________________________________________
408 void AliTPCPIDBase::ClearV0PIDlist()
411 // Clear the PID tag list
417 delete fV0motherIndex;
424 //______________________________________________________________________________
425 Char_t AliTPCPIDBase::GetV0tag(Int_t trackIndex) const
428 // Get the tag for the corresponding trackIndex. Returns -99 in case of invalid index/tag list.
431 if (trackIndex < 0 || trackIndex >= fNumTagsStored || !fV0tags)
434 return fV0tags[trackIndex];
438 //______________________________________________________________________________
439 Int_t AliTPCPIDBase::GetV0motherIndex(Int_t trackIndex) const
442 // Get the index of the V0 mother for the corresponding trackIndex. Returns -99 in case of invalid index/mother index list.
445 if (!fStoreMotherIndex || trackIndex < 0 || trackIndex >= fNumTagsStored || !fV0motherIndex)
448 return fV0motherIndex[trackIndex];
452 //________________________________________________________________________
453 Bool_t AliTPCPIDBase::TPCCutMIGeo(const AliVTrack* track, const AliVEvent* evt, TTreeStream* streamer)
462 const Short_t sign = track->Charge();
468 track->GetPxPyPz(pxpypz);
470 AliExternalTrackParam* par = new AliExternalTrackParam(xyz, pxpypz, cv, sign);
471 const AliESDtrack dummy;
473 const Double_t magField = evt->GetMagneticField();
474 Double_t varGeom = dummy.GetLengthInActiveZone(par, 3, 236, magField, 0, 0);
475 Double_t varNcr = track->GetTPCClusterInfo(3, 1);
476 Double_t varNcls = track->GetTPCsignalN();
478 const Double_t varEval = 130. - 5. * TMath::Abs(1. / track->Pt());
479 Bool_t cutGeom = varGeom > fgCutGeo * varEval;
480 Bool_t cutNcr = varNcr > fgCutNcr * varEval;
481 Bool_t cutNcls = varNcls > fgCutNcl * varEval;
483 Bool_t kout = cutGeom && cutNcr && cutNcls;
486 Double_t dedx = track->GetTPCsignal();
488 (*streamer)<<"tree"<<
490 "varGeom="<<varGeom<<
492 "varNcls="<<varNcls<<
494 "cutGeom="<<cutGeom<<
496 "cutNcls="<<cutNcls<<
510 //________________________________________________________________________
511 Bool_t AliTPCPIDBase::TPCnclCut(const AliVTrack* track)
514 // TPC Cut on TPCsignalN() only
520 return (track->GetTPCsignalN() >= fgCutPureNcl);