1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 /* $Id: AliESDtrackCuts.cxx 24534 2008-03-16 22:22:11Z fca $ */
18 #include "AliESDtrackCuts.h"
20 #include <AliESDtrack.h>
21 #include <AliESDVertex.h>
22 #include <AliESDEvent.h>
23 #include <AliMultiplicity.h>
28 #include <TDirectory.h>
32 //____________________________________________________________________
33 ClassImp(AliESDtrackCuts)
36 const Char_t* AliESDtrackCuts::fgkCutNames[kNCuts] = {
38 "require TPC standalone",
42 "#Chi^{2}/cluster TPC",
43 "#Chi^{2}/cluster ITS",
59 "trk-to-vtx max dca 2D absolute",
60 "trk-to-vtx max dca xy absolute",
61 "trk-to-vtx max dca z absolute",
62 "trk-to-vtx min dca 2D absolute",
63 "trk-to-vtx min dca xy absolute",
64 "trk-to-vtx min dca z absolute",
65 "SPD cluster requirement",
66 "SDD cluster requirement",
67 "SSD cluster requirement",
68 "require ITS stand-alone",
69 "rel 1/pt uncertainty",
70 "TPC n shared clusters",
71 "TPC rel shared clusters",
74 "n crossed rows / n findable clusters",
76 "#Chi^{2} TPC constrained vs. global"
79 AliESDtrackCuts* AliESDtrackCuts::fgMultEstTrackCuts[AliESDtrackCuts::kNMultEstTrackCuts] = { 0, 0, 0, 0 };
81 //____________________________________________________________________
82 AliESDtrackCuts::AliESDtrackCuts(const Char_t* name, const Char_t* title) : AliAnalysisCuts(name,title),
83 fCutMinNClusterTPC(0),
84 fCutMinNClusterITS(0),
85 fCutMinNCrossedRowsTPC(0),
86 fCutMinRatioCrossedRowsOverFindableClustersTPC(0),
87 f1CutMinNClustersTPCPtDep(0x0),
88 fCutMaxPtDepNClustersTPC(0),
89 fCutMaxChi2PerClusterTPC(0),
90 fCutMaxChi2PerClusterITS(0),
91 fCutMaxChi2TPCConstrainedVsGlobal(0),
92 fCutMaxChi2TPCConstrainedVsGlobalVertexType(kVertexTracks | kVertexSPD),
93 fCutMaxMissingITSPoints(0),
99 fCutMaxRel1PtUncertainty(0),
100 fCutAcceptKinkDaughters(0),
101 fCutAcceptSharedTPCClusters(0),
102 fCutMaxFractionSharedTPCClusters(0),
103 fCutRequireTPCRefit(0),
104 fCutRequireTPCStandAlone(0),
105 fCutRequireITSRefit(0),
106 fCutRequireITSPid(0),
107 fCutRequireITSStandAlone(0),
108 fCutRequireITSpureSA(0),
109 fCutNsigmaToVertex(0),
110 fCutSigmaToVertexRequired(0),
111 fCutMaxDCAToVertexXY(0),
112 fCutMaxDCAToVertexZ(0),
113 fCutMinDCAToVertexXY(0),
114 fCutMinDCAToVertexZ(0),
115 fCutMaxDCAToVertexXYPtDep(""),
116 fCutMaxDCAToVertexZPtDep(""),
117 fCutMinDCAToVertexXYPtDep(""),
118 fCutMinDCAToVertexZPtDep(""),
119 f1CutMaxDCAToVertexXYPtDep(0x0),
120 f1CutMaxDCAToVertexZPtDep(0x0),
121 f1CutMinDCAToVertexXYPtDep(0x0),
122 f1CutMinDCAToVertexZPtDep(0x0),
123 fCutDCAToVertex2D(0),
149 //##############################################################################
150 // setting default cuts
151 SetMinNClustersTPC();
152 SetMinNClustersITS();
153 SetMinNCrossedRowsTPC();
154 SetMinRatioCrossedRowsOverFindableClustersTPC();
155 SetMaxChi2PerClusterTPC();
156 SetMaxChi2PerClusterITS();
157 SetMaxChi2TPCConstrainedGlobal();
158 SetMaxChi2TPCConstrainedGlobalVertexType();
159 SetMaxNOfMissingITSPoints();
160 SetMaxCovDiagonalElements();
161 SetMaxRel1PtUncertainty();
162 SetRequireTPCRefit();
163 SetRequireTPCStandAlone();
164 SetRequireITSRefit();
165 SetRequireITSPid(kFALSE);
166 SetRequireITSStandAlone(kFALSE);
167 SetRequireITSPureStandAlone(kFALSE);
168 SetAcceptKinkDaughters();
169 SetAcceptSharedTPCClusters();
170 SetMaxFractionSharedTPCClusters();
171 SetMaxNsigmaToVertex();
172 SetMaxDCAToVertexXY();
173 SetMaxDCAToVertexZ();
175 SetMinDCAToVertexXY();
176 SetMinDCAToVertexZ();
184 SetClusterRequirementITS(kSPD);
185 SetClusterRequirementITS(kSDD);
186 SetClusterRequirementITS(kSSD);
191 //_____________________________________________________________________________
192 AliESDtrackCuts::AliESDtrackCuts(const AliESDtrackCuts &c) : AliAnalysisCuts(c),
193 fCutMinNClusterTPC(0),
194 fCutMinNClusterITS(0),
195 fCutMinNCrossedRowsTPC(0),
196 fCutMinRatioCrossedRowsOverFindableClustersTPC(0),
197 f1CutMinNClustersTPCPtDep(0x0),
198 fCutMaxPtDepNClustersTPC(0),
199 fCutMaxChi2PerClusterTPC(0),
200 fCutMaxChi2PerClusterITS(0),
201 fCutMaxChi2TPCConstrainedVsGlobal(0),
202 fCutMaxChi2TPCConstrainedVsGlobalVertexType(kVertexTracks | kVertexSPD),
203 fCutMaxMissingITSPoints(0),
209 fCutMaxRel1PtUncertainty(0),
210 fCutAcceptKinkDaughters(0),
211 fCutAcceptSharedTPCClusters(0),
212 fCutMaxFractionSharedTPCClusters(0),
213 fCutRequireTPCRefit(0),
214 fCutRequireTPCStandAlone(0),
215 fCutRequireITSRefit(0),
216 fCutRequireITSPid(0),
217 fCutRequireITSStandAlone(0),
218 fCutRequireITSpureSA(0),
219 fCutNsigmaToVertex(0),
220 fCutSigmaToVertexRequired(0),
221 fCutMaxDCAToVertexXY(0),
222 fCutMaxDCAToVertexZ(0),
223 fCutMinDCAToVertexXY(0),
224 fCutMinDCAToVertexZ(0),
225 fCutMaxDCAToVertexXYPtDep(""),
226 fCutMaxDCAToVertexZPtDep(""),
227 fCutMinDCAToVertexXYPtDep(""),
228 fCutMinDCAToVertexZPtDep(""),
229 f1CutMaxDCAToVertexXYPtDep(0x0),
230 f1CutMaxDCAToVertexZPtDep(0x0),
231 f1CutMinDCAToVertexXYPtDep(0x0),
232 f1CutMinDCAToVertexZPtDep(0x0),
233 fCutDCAToVertex2D(0),
257 ((AliESDtrackCuts &) c).Copy(*this);
260 AliESDtrackCuts::~AliESDtrackCuts()
266 for (Int_t i=0; i<2; i++) {
268 if (fhNClustersITS[i])
269 delete fhNClustersITS[i];
270 if (fhNClustersTPC[i])
271 delete fhNClustersTPC[i];
272 if (fhNSharedClustersTPC[i])
273 delete fhNSharedClustersTPC[i];
274 if (fhNCrossedRowsTPC[i])
275 delete fhNCrossedRowsTPC[i];
276 if (fhRatioCrossedRowsOverFindableClustersTPC[i])
277 delete fhRatioCrossedRowsOverFindableClustersTPC[i];
278 if (fhChi2PerClusterITS[i])
279 delete fhChi2PerClusterITS[i];
280 if (fhChi2PerClusterTPC[i])
281 delete fhChi2PerClusterTPC[i];
282 if (fhChi2TPCConstrainedVsGlobal[i])
283 delete fhChi2TPCConstrainedVsGlobal[i];
284 if(fhNClustersForITSPID[i])
285 delete fhNClustersForITSPID[i];
286 if(fhNMissingITSPoints[i])
287 delete fhNMissingITSPoints[i];
299 if (fhRel1PtUncertainty[i])
300 delete fhRel1PtUncertainty[i];
311 if (fhDXYNormalized[i])
312 delete fhDXYNormalized[i];
313 if (fhDZNormalized[i])
314 delete fhDZNormalized[i];
315 if (fhDXYvsDZNormalized[i])
316 delete fhDXYvsDZNormalized[i];
317 if (fhNSigmaToVertex[i])
318 delete fhNSigmaToVertex[i];
325 if(f1CutMaxDCAToVertexXYPtDep)delete f1CutMaxDCAToVertexXYPtDep;
326 f1CutMaxDCAToVertexXYPtDep = 0;
327 if( f1CutMaxDCAToVertexZPtDep) delete f1CutMaxDCAToVertexZPtDep;
328 f1CutMaxDCAToVertexZPtDep = 0;
329 if( f1CutMinDCAToVertexXYPtDep)delete f1CutMinDCAToVertexXYPtDep;
330 f1CutMinDCAToVertexXYPtDep = 0;
331 if(f1CutMinDCAToVertexZPtDep)delete f1CutMinDCAToVertexZPtDep;
332 f1CutMinDCAToVertexZPtDep = 0;
336 delete ffDTheoretical;
339 delete fhCutStatistics;
340 if (fhCutCorrelation)
341 delete fhCutCorrelation;
343 if(f1CutMinNClustersTPCPtDep)
344 delete f1CutMinNClustersTPCPtDep;
348 void AliESDtrackCuts::Init()
351 // sets everything to zero
354 fCutMinNClusterTPC = 0;
355 fCutMinNClusterITS = 0;
357 fCutMaxChi2PerClusterTPC = 0;
358 fCutMaxChi2PerClusterITS = 0;
359 fCutMaxChi2TPCConstrainedVsGlobal = 0;
360 fCutMaxChi2TPCConstrainedVsGlobalVertexType = kVertexTracks | kVertexSPD;
361 fCutMaxMissingITSPoints = 0;
363 for (Int_t i = 0; i < 3; i++)
364 fCutClusterRequirementITS[i] = kOff;
372 fCutMaxRel1PtUncertainty = 0;
374 fCutAcceptKinkDaughters = 0;
375 fCutAcceptSharedTPCClusters = 0;
376 fCutMaxFractionSharedTPCClusters = 0;
377 fCutRequireTPCRefit = 0;
378 fCutRequireTPCStandAlone = 0;
379 fCutRequireITSRefit = 0;
380 fCutRequireITSPid = 0;
381 fCutRequireITSStandAlone = 0;
382 fCutRequireITSpureSA = 0;
384 fCutNsigmaToVertex = 0;
385 fCutSigmaToVertexRequired = 0;
386 fCutMaxDCAToVertexXY = 0;
387 fCutMaxDCAToVertexZ = 0;
388 fCutDCAToVertex2D = 0;
389 fCutMinDCAToVertexXY = 0;
390 fCutMinDCAToVertexZ = 0;
391 fCutMaxDCAToVertexXYPtDep = "";
392 fCutMaxDCAToVertexZPtDep = "";
393 fCutMinDCAToVertexXYPtDep = "";
394 fCutMinDCAToVertexZPtDep = "";
396 if(f1CutMaxDCAToVertexXYPtDep)delete f1CutMaxDCAToVertexXYPtDep;
397 f1CutMaxDCAToVertexXYPtDep = 0;
398 if( f1CutMaxDCAToVertexXYPtDep) delete f1CutMaxDCAToVertexXYPtDep;
399 f1CutMaxDCAToVertexXYPtDep = 0;
400 if( f1CutMaxDCAToVertexZPtDep) delete f1CutMaxDCAToVertexZPtDep;
401 f1CutMaxDCAToVertexZPtDep = 0;
402 if( f1CutMinDCAToVertexXYPtDep)delete f1CutMinDCAToVertexXYPtDep;
403 f1CutMinDCAToVertexXYPtDep = 0;
404 if(f1CutMinDCAToVertexZPtDep)delete f1CutMinDCAToVertexZPtDep;
405 f1CutMinDCAToVertexZPtDep = 0;
423 fHistogramsOn = kFALSE;
425 for (Int_t i=0; i<2; ++i)
427 fhNClustersITS[i] = 0;
428 fhNClustersTPC[i] = 0;
429 fhNSharedClustersTPC[i] = 0;
430 fhNCrossedRowsTPC[i] = 0;
431 fhRatioCrossedRowsOverFindableClustersTPC[i] = 0;
433 fhChi2PerClusterITS[i] = 0;
434 fhChi2PerClusterTPC[i] = 0;
435 fhChi2TPCConstrainedVsGlobal[i] = 0;
436 fhNClustersForITSPID[i] = 0;
437 fhNMissingITSPoints[i] = 0;
445 fhRel1PtUncertainty[i] = 0;
452 fhDXYNormalized[i] = 0;
453 fhDZNormalized[i] = 0;
454 fhDXYvsDZNormalized[i] = 0;
455 fhNSigmaToVertex[i] = 0;
463 fhCutCorrelation = 0;
466 //_____________________________________________________________________________
467 AliESDtrackCuts &AliESDtrackCuts::operator=(const AliESDtrackCuts &c)
470 // Assignment operator
473 if (this != &c) ((AliESDtrackCuts &) c).Copy(*this);
477 //_____________________________________________________________________________
478 void AliESDtrackCuts::Copy(TObject &c) const
484 AliESDtrackCuts& target = (AliESDtrackCuts &) c;
488 target.fCutMinNClusterTPC = fCutMinNClusterTPC;
489 target.fCutMinNClusterITS = fCutMinNClusterITS;
490 target.fCutMinNCrossedRowsTPC = fCutMinNCrossedRowsTPC;
491 target.fCutMinRatioCrossedRowsOverFindableClustersTPC = fCutMinRatioCrossedRowsOverFindableClustersTPC;
492 if(f1CutMinNClustersTPCPtDep){
493 target.f1CutMinNClustersTPCPtDep = (TFormula*) f1CutMinNClustersTPCPtDep->Clone("f1CutMinNClustersTPCPtDep");
495 target.fCutMaxPtDepNClustersTPC = fCutMaxPtDepNClustersTPC;
497 target.fCutMaxChi2PerClusterTPC = fCutMaxChi2PerClusterTPC;
498 target.fCutMaxChi2PerClusterITS = fCutMaxChi2PerClusterITS;
499 target.fCutMaxChi2TPCConstrainedVsGlobal = fCutMaxChi2TPCConstrainedVsGlobal;
500 target.fCutMaxChi2TPCConstrainedVsGlobalVertexType = fCutMaxChi2TPCConstrainedVsGlobalVertexType;
501 target.fCutMaxMissingITSPoints = fCutMaxMissingITSPoints;
503 for (Int_t i = 0; i < 3; i++)
504 target.fCutClusterRequirementITS[i] = fCutClusterRequirementITS[i];
506 target.fCutMaxC11 = fCutMaxC11;
507 target.fCutMaxC22 = fCutMaxC22;
508 target.fCutMaxC33 = fCutMaxC33;
509 target.fCutMaxC44 = fCutMaxC44;
510 target.fCutMaxC55 = fCutMaxC55;
512 target.fCutMaxRel1PtUncertainty = fCutMaxRel1PtUncertainty;
514 target.fCutAcceptKinkDaughters = fCutAcceptKinkDaughters;
515 target.fCutAcceptSharedTPCClusters = fCutAcceptSharedTPCClusters;
516 target.fCutMaxFractionSharedTPCClusters = fCutMaxFractionSharedTPCClusters;
517 target.fCutRequireTPCRefit = fCutRequireTPCRefit;
518 target.fCutRequireTPCStandAlone = fCutRequireTPCStandAlone;
519 target.fCutRequireITSRefit = fCutRequireITSRefit;
520 target.fCutRequireITSPid = fCutRequireITSPid;
521 target.fCutRequireITSStandAlone = fCutRequireITSStandAlone;
522 target.fCutRequireITSpureSA = fCutRequireITSpureSA;
524 target.fCutNsigmaToVertex = fCutNsigmaToVertex;
525 target.fCutSigmaToVertexRequired = fCutSigmaToVertexRequired;
526 target.fCutMaxDCAToVertexXY = fCutMaxDCAToVertexXY;
527 target.fCutMaxDCAToVertexZ = fCutMaxDCAToVertexZ;
528 target.fCutDCAToVertex2D = fCutDCAToVertex2D;
529 target.fCutMinDCAToVertexXY = fCutMinDCAToVertexXY;
530 target.fCutMinDCAToVertexZ = fCutMinDCAToVertexZ;
532 target.fCutMaxDCAToVertexXYPtDep = fCutMaxDCAToVertexXYPtDep;
533 target.SetMaxDCAToVertexXYPtDep(fCutMaxDCAToVertexXYPtDep.Data());
535 target.fCutMaxDCAToVertexZPtDep = fCutMaxDCAToVertexZPtDep;
536 target.SetMaxDCAToVertexZPtDep(fCutMaxDCAToVertexZPtDep.Data());
538 target.fCutMinDCAToVertexXYPtDep = fCutMinDCAToVertexXYPtDep;
539 target.SetMinDCAToVertexXYPtDep(fCutMinDCAToVertexXYPtDep.Data());
541 target.fCutMinDCAToVertexZPtDep = fCutMinDCAToVertexZPtDep;
542 target.SetMinDCAToVertexZPtDep(fCutMinDCAToVertexZPtDep.Data());
544 target.fPMin = fPMin;
545 target.fPMax = fPMax;
546 target.fPtMin = fPtMin;
547 target.fPtMax = fPtMax;
548 target.fPxMin = fPxMin;
549 target.fPxMax = fPxMax;
550 target.fPyMin = fPyMin;
551 target.fPyMax = fPyMax;
552 target.fPzMin = fPzMin;
553 target.fPzMax = fPzMax;
554 target.fEtaMin = fEtaMin;
555 target.fEtaMax = fEtaMax;
556 target.fRapMin = fRapMin;
557 target.fRapMax = fRapMax;
559 target.fHistogramsOn = fHistogramsOn;
561 for (Int_t i=0; i<2; ++i)
563 if (fhNClustersITS[i]) target.fhNClustersITS[i] = (TH1F*) fhNClustersITS[i]->Clone();
564 if (fhNClustersTPC[i]) target.fhNClustersTPC[i] = (TH1F*) fhNClustersTPC[i]->Clone();
565 if (fhNSharedClustersTPC[i]) target.fhNSharedClustersTPC[i] = (TH1F*) fhNSharedClustersTPC[i]->Clone();
566 if (fhNCrossedRowsTPC[i]) target.fhNCrossedRowsTPC[i] = (TH1F*) fhNCrossedRowsTPC[i]->Clone();
567 if (fhRatioCrossedRowsOverFindableClustersTPC[i]) target.fhRatioCrossedRowsOverFindableClustersTPC[i] = (TH1F*) fhRatioCrossedRowsOverFindableClustersTPC[i]->Clone();
569 if (fhChi2PerClusterITS[i]) target.fhChi2PerClusterITS[i] = (TH1F*) fhChi2PerClusterITS[i]->Clone();
570 if (fhChi2PerClusterTPC[i]) target.fhChi2PerClusterTPC[i] = (TH1F*) fhChi2PerClusterTPC[i]->Clone();
571 if (fhChi2TPCConstrainedVsGlobal[i]) target.fhChi2TPCConstrainedVsGlobal[i] = (TH1F*) fhChi2TPCConstrainedVsGlobal[i]->Clone();
572 if (fhNClustersForITSPID[i]) target.fhNClustersForITSPID[i] = (TH1F*) fhNClustersForITSPID[i]->Clone();
573 if (fhNMissingITSPoints[i]) target.fhNMissingITSPoints[i] = (TH1F*) fhNMissingITSPoints[i]->Clone();
575 if (fhC11[i]) target.fhC11[i] = (TH1F*) fhC11[i]->Clone();
576 if (fhC22[i]) target.fhC22[i] = (TH1F*) fhC22[i]->Clone();
577 if (fhC33[i]) target.fhC33[i] = (TH1F*) fhC33[i]->Clone();
578 if (fhC44[i]) target.fhC44[i] = (TH1F*) fhC44[i]->Clone();
579 if (fhC55[i]) target.fhC55[i] = (TH1F*) fhC55[i]->Clone();
581 if (fhRel1PtUncertainty[i]) target.fhRel1PtUncertainty[i] = (TH1F*) fhRel1PtUncertainty[i]->Clone();
583 if (fhDXY[i]) target.fhDXY[i] = (TH1F*) fhDXY[i]->Clone();
584 if (fhDZ[i]) target.fhDZ[i] = (TH1F*) fhDZ[i]->Clone();
585 if (fhDXYDZ[i]) target.fhDXYDZ[i] = (TH1F*) fhDXYDZ[i]->Clone();
586 if (fhDXYvsDZ[i]) target.fhDXYvsDZ[i] = (TH2F*) fhDXYvsDZ[i]->Clone();
588 if (fhDXYNormalized[i]) target.fhDXYNormalized[i] = (TH1F*) fhDXYNormalized[i]->Clone();
589 if (fhDZNormalized[i]) target.fhDZNormalized[i] = (TH1F*) fhDZNormalized[i]->Clone();
590 if (fhDXYvsDZNormalized[i]) target.fhDXYvsDZNormalized[i] = (TH2F*) fhDXYvsDZNormalized[i]->Clone();
591 if (fhNSigmaToVertex[i]) target.fhNSigmaToVertex[i] = (TH1F*) fhNSigmaToVertex[i]->Clone();
593 if (fhPt[i]) target.fhPt[i] = (TH1F*) fhPt[i]->Clone();
594 if (fhEta[i]) target.fhEta[i] = (TH1F*) fhEta[i]->Clone();
596 if (ffDTheoretical) target.ffDTheoretical = (TF1*) ffDTheoretical->Clone();
598 if (fhCutStatistics) target.fhCutStatistics = (TH1F*) fhCutStatistics->Clone();
599 if (fhCutCorrelation) target.fhCutCorrelation = (TH2F*) fhCutCorrelation->Clone();
604 //_____________________________________________________________________________
605 Long64_t AliESDtrackCuts::Merge(TCollection* list) {
606 // Merge a list of AliESDtrackCuts objects with this (needed for PROOF)
607 // Returns the number of merged objects (including this)
614 TIterator* iter = list->MakeIterator();
617 // collection of measured and generated histograms
619 while ((obj = iter->Next())) {
621 AliESDtrackCuts* entry = dynamic_cast<AliESDtrackCuts*>(obj);
625 if (!entry->fHistogramsOn)
628 for (Int_t i=0; i<2; i++) {
630 fhNClustersITS[i] ->Add(entry->fhNClustersITS[i] );
631 fhNClustersTPC[i] ->Add(entry->fhNClustersTPC[i] );
632 if (fhNSharedClustersTPC[i])
633 fhNSharedClustersTPC[i] ->Add(entry->fhNSharedClustersTPC[i] );
634 if (fhNCrossedRowsTPC[i])
635 fhNCrossedRowsTPC[i] ->Add(entry->fhNCrossedRowsTPC[i] );
636 if (fhRatioCrossedRowsOverFindableClustersTPC[i])
637 fhRatioCrossedRowsOverFindableClustersTPC[i] ->Add(entry->fhRatioCrossedRowsOverFindableClustersTPC[i] );
639 fhChi2PerClusterITS[i] ->Add(entry->fhChi2PerClusterITS[i]);
640 fhChi2PerClusterTPC[i] ->Add(entry->fhChi2PerClusterTPC[i]);
641 if (fhChi2TPCConstrainedVsGlobal[i])
642 fhChi2TPCConstrainedVsGlobal[i]->Add(entry->fhChi2TPCConstrainedVsGlobal[i]);
643 if (fhNClustersForITSPID[i])
644 fhNClustersForITSPID[i]->Add(entry->fhNClustersForITSPID[i]);
645 if (fhNMissingITSPoints[i])
646 fhNMissingITSPoints[i] ->Add(entry->fhNMissingITSPoints[i]);
648 fhC11[i] ->Add(entry->fhC11[i] );
649 fhC22[i] ->Add(entry->fhC22[i] );
650 fhC33[i] ->Add(entry->fhC33[i] );
651 fhC44[i] ->Add(entry->fhC44[i] );
652 fhC55[i] ->Add(entry->fhC55[i] );
654 fhRel1PtUncertainty[i] ->Add(entry->fhRel1PtUncertainty[i]);
656 fhDXY[i] ->Add(entry->fhDXY[i] );
657 fhDZ[i] ->Add(entry->fhDZ[i] );
658 fhDXYDZ[i] ->Add(entry->fhDXYDZ[i] );
659 fhDXYvsDZ[i] ->Add(entry->fhDXYvsDZ[i] );
661 fhDXYNormalized[i] ->Add(entry->fhDXYNormalized[i] );
662 fhDZNormalized[i] ->Add(entry->fhDZNormalized[i] );
663 fhDXYvsDZNormalized[i] ->Add(entry->fhDXYvsDZNormalized[i]);
664 fhNSigmaToVertex[i] ->Add(entry->fhNSigmaToVertex[i]);
666 fhPt[i] ->Add(entry->fhPt[i]);
667 fhEta[i] ->Add(entry->fhEta[i]);
670 fhCutStatistics ->Add(entry->fhCutStatistics);
671 fhCutCorrelation ->Add(entry->fhCutCorrelation);
678 void AliESDtrackCuts::SetMinNClustersTPCPtDep(TFormula *f1, Float_t ptmax)
681 // Sets the pT dependent NClustersTPC cut
685 delete f1CutMinNClustersTPCPtDep;
686 f1CutMinNClustersTPCPtDep = (TFormula*)f1->Clone("f1CutMinNClustersTPCPtDep");
688 fCutMaxPtDepNClustersTPC=ptmax;
691 //____________________________________________________________________
692 AliESDtrackCuts* AliESDtrackCuts::GetStandardTPCOnlyTrackCuts()
694 // creates an AliESDtrackCuts object and fills it with standard (pre data-taking) values for TPC-only cuts
696 AliInfoClass("Creating track cuts for TPC-only.");
698 AliESDtrackCuts* esdTrackCuts = new AliESDtrackCuts;
700 esdTrackCuts->SetMinNClustersTPC(50);
701 esdTrackCuts->SetMaxChi2PerClusterTPC(4);
702 esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
704 esdTrackCuts->SetMaxDCAToVertexZ(3.2);
705 esdTrackCuts->SetMaxDCAToVertexXY(2.4);
706 esdTrackCuts->SetDCAToVertex2D(kTRUE);
711 //____________________________________________________________________
712 AliESDtrackCuts* AliESDtrackCuts::GetStandardITSTPCTrackCuts2009(Bool_t selPrimaries)
714 // creates an AliESDtrackCuts object and fills it with standard values for ITS-TPC cuts for pp 2009 data
716 AliInfoClass("Creating track cuts for ITS+TPC (2009 definition).");
718 AliESDtrackCuts* esdTrackCuts = new AliESDtrackCuts;
721 esdTrackCuts->SetRequireTPCStandAlone(kTRUE); // to get chi2 and ncls of kTPCin
722 esdTrackCuts->SetMinNClustersTPC(70);
723 esdTrackCuts->SetMaxChi2PerClusterTPC(4);
724 esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
725 esdTrackCuts->SetRequireTPCRefit(kTRUE);
727 esdTrackCuts->SetRequireITSRefit(kTRUE);
728 esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,
729 AliESDtrackCuts::kAny);
731 // 7*(0.0050+0.0060/pt^0.9)
732 esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
733 esdTrackCuts->SetMaxChi2TPCConstrainedGlobal(36);
735 esdTrackCuts->SetMaxDCAToVertexZ(1.e6);
736 esdTrackCuts->SetDCAToVertex2D(kFALSE);
737 esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
738 //esdTrackCuts->SetEtaRange(-0.8,+0.8);
740 esdTrackCuts->SetMaxChi2PerClusterITS(36);
745 //____________________________________________________________________
746 AliESDtrackCuts* AliESDtrackCuts::GetStandardITSTPCTrackCuts2010(Bool_t selPrimaries,Int_t clusterCut)
748 // creates an AliESDtrackCuts object and fills it with standard values for ITS-TPC cuts for pp 2010 data
749 // if clusterCut = 1, the cut on the number of clusters is replaced by
750 // a cut on the number of crossed rows and on the ration crossed
751 // rows/findable clusters
753 AliInfoClass("Creating track cuts for ITS+TPC (2010 definition).");
755 AliESDtrackCuts* esdTrackCuts = new AliESDtrackCuts;
758 if(clusterCut == 0) esdTrackCuts->SetMinNClustersTPC(70);
759 else if (clusterCut == 1) {
760 esdTrackCuts->SetMinNCrossedRowsTPC(70);
761 esdTrackCuts->SetMinRatioCrossedRowsOverFindableClustersTPC(0.8);
764 AliWarningClass(Form("Wrong value of the clusterCut parameter (%d), using cut on Nclusters",clusterCut));
765 esdTrackCuts->SetMinNClustersTPC(70);
767 esdTrackCuts->SetMaxChi2PerClusterTPC(4);
768 esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
769 esdTrackCuts->SetRequireTPCRefit(kTRUE);
771 esdTrackCuts->SetRequireITSRefit(kTRUE);
772 esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,
773 AliESDtrackCuts::kAny);
775 // 7*(0.0026+0.0050/pt^1.01)
776 esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0182+0.0350/pt^1.01");
777 esdTrackCuts->SetMaxChi2TPCConstrainedGlobal(36);
779 esdTrackCuts->SetMaxDCAToVertexZ(2);
780 esdTrackCuts->SetDCAToVertex2D(kFALSE);
781 esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
783 esdTrackCuts->SetMaxChi2PerClusterITS(36);
788 //____________________________________________________________________
789 AliESDtrackCuts* AliESDtrackCuts::GetStandardITSPureSATrackCuts2009(Bool_t selPrimaries, Bool_t useForPid)
791 // creates an AliESDtrackCuts object and fills it with standard values for ITS pure SA tracks
793 AliESDtrackCuts* esdTrackCuts = new AliESDtrackCuts;
794 esdTrackCuts->SetRequireITSPureStandAlone(kTRUE);
795 esdTrackCuts->SetRequireITSRefit(kTRUE);
796 esdTrackCuts->SetMinNClustersITS(4);
797 esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,
798 AliESDtrackCuts::kAny);
799 esdTrackCuts->SetMaxChi2PerClusterITS(1.);
802 // 7*(0.0085+0.0026/pt^1.55)
803 esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0595+0.0182/pt^1.55");
806 esdTrackCuts->SetRequireITSPid(kTRUE);
811 //____________________________________________________________________
812 AliESDtrackCuts* AliESDtrackCuts::GetStandardITSPureSATrackCuts2010(Bool_t selPrimaries, Bool_t useForPid)
814 // creates an AliESDtrackCuts object and fills it with standard values for ITS pure SA tracks - pp 2010
816 AliESDtrackCuts* esdTrackCuts = new AliESDtrackCuts;
817 esdTrackCuts->SetRequireITSPureStandAlone(kTRUE);
818 esdTrackCuts->SetRequireITSRefit(kTRUE);
819 esdTrackCuts->SetMinNClustersITS(4);
820 esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,
821 AliESDtrackCuts::kAny);
822 esdTrackCuts->SetMaxChi2PerClusterITS(2.5);
825 // 7*(0.0033+0.0045/pt^1.3)
826 esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0231+0.0315/pt^1.3");
829 esdTrackCuts->SetRequireITSPid(kTRUE);
834 //____________________________________________________________________
835 AliESDtrackCuts* AliESDtrackCuts::GetStandardITSSATrackCuts2009(Bool_t selPrimaries, Bool_t useForPid)
837 // creates an AliESDtrackCuts object and fills it with standard values for ITS pure SA tracks
839 AliESDtrackCuts* esdTrackCuts = new AliESDtrackCuts;
840 esdTrackCuts->SetRequireITSStandAlone(kTRUE);
841 esdTrackCuts->SetRequireITSPureStandAlone(kFALSE);
842 esdTrackCuts->SetRequireITSRefit(kTRUE);
843 esdTrackCuts->SetMinNClustersITS(4);
844 esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,
845 AliESDtrackCuts::kAny);
846 esdTrackCuts->SetMaxChi2PerClusterITS(1.);
849 // 7*(0.0085+0.0026/pt^1.55)
850 esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0595+0.0182/pt^1.55");
853 esdTrackCuts->SetRequireITSPid(kTRUE);
858 //____________________________________________________________________
859 AliESDtrackCuts* AliESDtrackCuts::GetStandardITSSATrackCuts2010(Bool_t selPrimaries, Bool_t useForPid)
861 // creates an AliESDtrackCuts object and fills it with standard values for ITS pure SA tracks --pp 2010
863 AliESDtrackCuts* esdTrackCuts = new AliESDtrackCuts;
864 esdTrackCuts->SetRequireITSStandAlone(kTRUE);
865 esdTrackCuts->SetRequireITSPureStandAlone(kFALSE);
866 esdTrackCuts->SetRequireITSRefit(kTRUE);
867 esdTrackCuts->SetMinNClustersITS(4);
868 esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,
869 AliESDtrackCuts::kAny);
870 esdTrackCuts->SetMaxChi2PerClusterITS(2.5);
873 // 7*(0.0033+0.0045/pt^1.3)
874 esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0231+0.0315/pt^1.3");
877 esdTrackCuts->SetRequireITSPid(kTRUE);
882 //____________________________________________________________________
883 AliESDtrackCuts* AliESDtrackCuts::GetStandardITSSATrackCutsPbPb2010(Bool_t selPrimaries, Bool_t useForPid)
885 // creates an AliESDtrackCuts object and fills it with standard values for ITS pure SA tracks -- PbPb 2010
887 AliESDtrackCuts* esdTrackCuts = GetStandardITSSATrackCuts2010(selPrimaries, useForPid);
888 esdTrackCuts->SetMaxNOfMissingITSPoints(1);
892 //____________________________________________________________________
894 AliESDtrackCuts* AliESDtrackCuts::GetStandardV0DaughterCuts()
896 // creates a AliESDtrackCuts object and fills it with standard cuts for V0 daughters
897 AliESDtrackCuts* esdTrackCuts = new AliESDtrackCuts;
898 esdTrackCuts->SetRequireTPCRefit(kTRUE);
899 esdTrackCuts->SetMinNClustersTPC(70);
900 esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
904 //____________________________________________________________________
905 Int_t AliESDtrackCuts::GetReferenceMultiplicity(const AliESDEvent* esd, Bool_t tpcOnly)
907 // Gets reference multiplicity following the standard cuts and a defined fiducial volume
908 // tpcOnly = kTRUE -> consider TPC-only tracks
909 // = kFALSE -> consider global tracks
911 // DEPRECATED Use GetReferenceMultiplicity with the enum as second argument instead
915 AliErrorClass("Not implemented for global tracks!");
919 static AliESDtrackCuts* esdTrackCuts = 0;
922 esdTrackCuts = GetStandardTPCOnlyTrackCuts();
923 esdTrackCuts->SetEtaRange(-0.8, 0.8);
924 esdTrackCuts->SetPtRange(0.15);
927 Int_t nTracks = esdTrackCuts->CountAcceptedTracks(esd);
932 //____________________________________________________________________
933 Float_t AliESDtrackCuts::GetSigmaToVertex(const AliESDtrack* const esdTrack)
935 // Calculates the number of sigma to the vertex.
940 esdTrack->GetImpactParameters(b,bCov);
942 if (bCov[0]<=0 || bCov[2]<=0) {
943 AliDebugClass(1, "Estimated b resolution lower or equal zero!");
944 bCov[0]=0; bCov[2]=0;
946 bRes[0] = TMath::Sqrt(bCov[0]);
947 bRes[1] = TMath::Sqrt(bCov[2]);
949 // -----------------------------------
950 // How to get to a n-sigma cut?
952 // The accumulated statistics from 0 to d is
954 // -> Erf(d/Sqrt(2)) for a 1-dim gauss (d = n_sigma)
955 // -> 1 - Exp(-d**2) for a 2-dim gauss (d*d = dx*dx + dy*dy != n_sigma)
957 // It means that for a 2-dim gauss: n_sigma(d) = Sqrt(2)*ErfInv(1 - Exp((-d**2)/2)
958 // Can this be expressed in a different way?
960 if (bRes[0] == 0 || bRes[1] ==0)
963 Float_t d = TMath::Sqrt(TMath::Power(b[0]/bRes[0],2) + TMath::Power(b[1]/bRes[1],2));
965 // work around precision problem
966 // if d is too big, TMath::Exp(...) gets 0, and TMath::ErfInverse(1) that should be infinite, gets 0 :(
967 // 1e-15 corresponds to nsigma ~ 7.7
968 if (TMath::Exp(-d * d / 2) < 1e-15)
971 Float_t nSigma = TMath::ErfInverse(1 - TMath::Exp(-d * d / 2)) * TMath::Sqrt(2);
975 void AliESDtrackCuts::EnableNeededBranches(TTree* tree)
977 // enables the branches needed by AcceptTrack, for a list see comment of AcceptTrack
979 tree->SetBranchStatus("fTracks.fFlags", 1);
980 tree->SetBranchStatus("fTracks.fITSncls", 1);
981 tree->SetBranchStatus("fTracks.fTPCncls", 1);
982 tree->SetBranchStatus("fTracks.fITSchi2", 1);
983 tree->SetBranchStatus("fTracks.fTPCchi2", 1);
984 tree->SetBranchStatus("fTracks.fC*", 1);
985 tree->SetBranchStatus("fTracks.fD", 1);
986 tree->SetBranchStatus("fTracks.fZ", 1);
987 tree->SetBranchStatus("fTracks.fCdd", 1);
988 tree->SetBranchStatus("fTracks.fCdz", 1);
989 tree->SetBranchStatus("fTracks.fCzz", 1);
990 tree->SetBranchStatus("fTracks.fP*", 1);
991 tree->SetBranchStatus("fTracks.fR*", 1);
992 tree->SetBranchStatus("fTracks.fKinkIndexes*", 1);
995 //____________________________________________________________________
996 Bool_t AliESDtrackCuts::AcceptTrack(const AliESDtrack* esdTrack)
999 // figure out if the tracks survives all the track cuts defined
1001 // the different quality parameter and kinematic values are first
1002 // retrieved from the track. then it is found out what cuts the
1003 // track did not survive and finally the cuts are imposed.
1005 // this function needs the following branches:
1011 // fTracks.fC //GetExternalCovariance
1012 // fTracks.fD //GetImpactParameters
1013 // fTracks.fZ //GetImpactParameters
1014 // fTracks.fCdd //GetImpactParameters
1015 // fTracks.fCdz //GetImpactParameters
1016 // fTracks.fCzz //GetImpactParameters
1017 // fTracks.fP //GetPxPyPz
1018 // fTracks.fR //GetMass
1019 // fTracks.fP //GetMass
1020 // fTracks.fKinkIndexes
1022 // esdEvent is only required for the MaxChi2TPCConstrainedVsGlobal
1024 UInt_t status = esdTrack->GetStatus();
1026 // getting quality parameters from the ESD track
1027 Int_t nClustersITS = esdTrack->GetITSclusters(0);
1028 Int_t nClustersTPC = -1;
1029 if(fCutRequireTPCStandAlone) {
1030 nClustersTPC = esdTrack->GetTPCNclsIter1();
1033 nClustersTPC = esdTrack->GetTPCclusters(0);
1036 //Pt dependent NClusters Cut
1037 if(f1CutMinNClustersTPCPtDep) {
1038 if(esdTrack->Pt()<fCutMaxPtDepNClustersTPC)
1039 fCutMinNClusterTPC = f1CutMinNClustersTPCPtDep->Eval(esdTrack->Pt());
1041 fCutMinNClusterTPC = f1CutMinNClustersTPCPtDep->Eval(fCutMaxPtDepNClustersTPC);
1044 Float_t nCrossedRowsTPC = esdTrack->GetTPCCrossedRows();
1045 Float_t ratioCrossedRowsOverFindableClustersTPC = 1.0;
1046 if (esdTrack->GetTPCNclsF()>0) {
1047 ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC / esdTrack->GetTPCNclsF();
1050 Int_t nClustersTPCShared = esdTrack->GetTPCnclsS();
1051 Float_t fracClustersTPCShared = -1.;
1053 Float_t chi2PerClusterITS = -1;
1054 Float_t chi2PerClusterTPC = -1;
1055 if (nClustersITS!=0)
1056 chi2PerClusterITS = esdTrack->GetITSchi2()/Float_t(nClustersITS);
1057 if (nClustersTPC!=0) {
1058 if(fCutRequireTPCStandAlone) {
1059 chi2PerClusterTPC = esdTrack->GetTPCchi2Iter1()/Float_t(nClustersTPC);
1061 chi2PerClusterTPC = esdTrack->GetTPCchi2()/Float_t(nClustersTPC);
1063 fracClustersTPCShared = Float_t(nClustersTPCShared)/Float_t(nClustersTPC);
1066 Double_t extCov[15];
1067 esdTrack->GetExternalCovariance(extCov);
1071 esdTrack->GetImpactParameters(b,bCov);
1072 if (bCov[0]<=0 || bCov[2]<=0) {
1073 AliDebug(1, "Estimated b resolution lower or equal zero!");
1074 bCov[0]=0; bCov[2]=0;
1078 // set pt-dependent DCA cuts, if requested
1079 SetPtDepDCACuts(esdTrack->Pt());
1082 Float_t dcaToVertexXY = b[0];
1083 Float_t dcaToVertexZ = b[1];
1085 Float_t dcaToVertex = -1;
1087 if (fCutDCAToVertex2D)
1089 dcaToVertex = TMath::Sqrt(dcaToVertexXY*dcaToVertexXY/fCutMaxDCAToVertexXY/fCutMaxDCAToVertexXY + dcaToVertexZ*dcaToVertexZ/fCutMaxDCAToVertexZ/fCutMaxDCAToVertexZ);
1092 dcaToVertex = TMath::Sqrt(dcaToVertexXY*dcaToVertexXY + dcaToVertexZ*dcaToVertexZ);
1094 // getting the kinematic variables of the track
1095 // (assuming the mass is known)
1097 esdTrack->GetPxPyPz(p);
1099 Float_t momentum = TMath::Sqrt(TMath::Power(p[0],2) + TMath::Power(p[1],2) + TMath::Power(p[2],2));
1100 Float_t pt = TMath::Sqrt(TMath::Power(p[0],2) + TMath::Power(p[1],2));
1101 Float_t energy = TMath::Sqrt(TMath::Power(esdTrack->GetMass(),2) + TMath::Power(momentum,2));
1103 //y-eta related calculations
1104 Float_t eta = -100.;
1106 if((momentum != TMath::Abs(p[2]))&&(momentum != 0))
1107 eta = 0.5*TMath::Log((momentum + p[2])/(momentum - p[2]));
1108 if((energy != TMath::Abs(p[2]))&&(momentum != 0))
1109 y = 0.5*TMath::Log((energy + p[2])/(energy - p[2]));
1113 AliWarning(Form("GetSigma1Pt2() returns negative value for external covariance matrix element fC[14]: %f. Corrupted track information, track will not be accepted!", extCov[14]));
1116 Float_t relUncertainty1Pt = TMath::Sqrt(extCov[14])*pt;
1118 //########################################################################
1121 Bool_t cuts[kNCuts];
1122 for (Int_t i=0; i<kNCuts; i++) cuts[i]=kFALSE;
1124 // track quality cuts
1125 if (fCutRequireTPCRefit && (status&AliESDtrack::kTPCrefit)==0)
1127 if (fCutRequireTPCStandAlone && (status&AliESDtrack::kTPCin)==0)
1129 if (fCutRequireITSRefit && (status&AliESDtrack::kITSrefit)==0)
1131 if (nClustersTPC<fCutMinNClusterTPC)
1133 if (nClustersITS<fCutMinNClusterITS)
1135 if (chi2PerClusterTPC>fCutMaxChi2PerClusterTPC)
1137 if (chi2PerClusterITS>fCutMaxChi2PerClusterITS)
1139 if (extCov[0] > fCutMaxC11)
1141 if (extCov[2] > fCutMaxC22)
1143 if (extCov[5] > fCutMaxC33)
1145 if (extCov[9] > fCutMaxC44)
1147 if (extCov[14] > fCutMaxC55)
1150 // cut 12 and 13 see below
1152 if (!fCutAcceptKinkDaughters && esdTrack->GetKinkIndex(0)>0)
1154 // track kinematics cut
1155 if((momentum < fPMin) || (momentum > fPMax))
1157 if((pt < fPtMin) || (pt > fPtMax))
1159 if((p[0] < fPxMin) || (p[0] > fPxMax))
1161 if((p[1] < fPyMin) || (p[1] > fPyMax))
1163 if((p[2] < fPzMin) || (p[2] > fPzMax))
1165 if((eta < fEtaMin) || (eta > fEtaMax))
1167 if((y < fRapMin) || (y > fRapMax))
1169 if (fCutDCAToVertex2D && dcaToVertex > 1)
1171 if (!fCutDCAToVertex2D && TMath::Abs(dcaToVertexXY) > fCutMaxDCAToVertexXY)
1173 if (!fCutDCAToVertex2D && TMath::Abs(dcaToVertexZ) > fCutMaxDCAToVertexZ)
1175 if (fCutDCAToVertex2D && fCutMinDCAToVertexXY > 0 && fCutMinDCAToVertexZ > 0 && dcaToVertexXY*dcaToVertexXY/fCutMinDCAToVertexXY/fCutMinDCAToVertexXY + dcaToVertexZ*dcaToVertexZ/fCutMinDCAToVertexZ/fCutMinDCAToVertexZ < 1)
1177 if (!fCutDCAToVertex2D && TMath::Abs(dcaToVertexXY) < fCutMinDCAToVertexXY)
1179 if (!fCutDCAToVertex2D && TMath::Abs(dcaToVertexZ) < fCutMinDCAToVertexZ)
1182 for (Int_t i = 0; i < 3; i++)
1183 cuts[28+i] = !CheckITSClusterRequirement(fCutClusterRequirementITS[i], esdTrack->HasPointOnITSLayer(i*2), esdTrack->HasPointOnITSLayer(i*2+1));
1185 if(fCutRequireITSStandAlone || fCutRequireITSpureSA){
1186 if ((status & AliESDtrack::kITSin) == 0 || (status & AliESDtrack::kTPCin)){
1190 // ITS standalone tracks
1191 if(fCutRequireITSStandAlone && !fCutRequireITSpureSA){
1192 if(status & AliESDtrack::kITSpureSA) cuts[31] = kTRUE;
1193 }else if(fCutRequireITSpureSA){
1194 if(!(status & AliESDtrack::kITSpureSA)) cuts[31] = kTRUE;
1199 if (relUncertainty1Pt > fCutMaxRel1PtUncertainty)
1202 if (!fCutAcceptSharedTPCClusters && nClustersTPCShared!=0)
1205 if (fracClustersTPCShared > fCutMaxFractionSharedTPCClusters)
1208 Int_t nITSPointsForPid=0;
1209 UChar_t clumap=esdTrack->GetITSClusterMap();
1210 for(Int_t i=2; i<6; i++){
1211 if(clumap&(1<<i)) ++nITSPointsForPid;
1213 if(fCutRequireITSPid && nITSPointsForPid<3) cuts[35] = kTRUE;
1216 if (nCrossedRowsTPC<fCutMinNCrossedRowsTPC)
1218 if (ratioCrossedRowsOverFindableClustersTPC<fCutMinRatioCrossedRowsOverFindableClustersTPC)
1221 Int_t nMissITSpts=0;
1222 Int_t idet,statusLay;
1224 for(Int_t iLay=0; iLay<6; iLay++){
1225 Bool_t retc=esdTrack->GetITSModuleIndexInfo(iLay,idet,statusLay,xloc,zloc);
1226 if(retc && statusLay==5) ++nMissITSpts;
1228 if(nMissITSpts>fCutMaxMissingITSPoints) cuts[38] = kTRUE;
1231 for (Int_t i=0; i<kNCuts; i++)
1232 if (cuts[i]) {cut = kTRUE;}
1234 // for performance evaluate the CPU intensive cuts only when the others have passed, and when they are requested
1235 Double_t chi2TPCConstrainedVsGlobal = -2;
1236 Float_t nSigmaToVertex = -2;
1239 // getting the track to vertex parameters
1240 if (fCutSigmaToVertexRequired)
1242 nSigmaToVertex = GetSigmaToVertex(esdTrack);
1243 if (nSigmaToVertex > fCutNsigmaToVertex && fCutSigmaToVertexRequired)
1248 // if n sigma could not be calculated
1249 if (nSigmaToVertex<0 && fCutSigmaToVertexRequired)
1256 // max chi2 TPC constrained vs global track only if track passed the other cut
1257 if (fCutMaxChi2TPCConstrainedVsGlobal < 1e9)
1259 const AliESDEvent* esdEvent = esdTrack->GetESDEvent();
1262 AliFatal("fCutMaxChi2TPCConstrainedVsGlobal set but ESD event not set in AliESDTrack. Use AliESDTrack::SetESDEvent before calling AliESDtrackCuts.");
1265 const AliESDVertex* vertex = 0;
1266 if (fCutMaxChi2TPCConstrainedVsGlobalVertexType & kVertexTracks)
1267 vertex = esdEvent->GetPrimaryVertexTracks();
1269 if ((!vertex || !vertex->GetStatus()) && fCutMaxChi2TPCConstrainedVsGlobalVertexType & kVertexSPD)
1270 vertex = esdEvent->GetPrimaryVertexSPD();
1272 if ((!vertex || !vertex->GetStatus()) && fCutMaxChi2TPCConstrainedVsGlobalVertexType & kVertexTPC)
1273 vertex = esdEvent->GetPrimaryVertexTPC();
1275 if (vertex->GetStatus())
1276 chi2TPCConstrainedVsGlobal = esdTrack->GetChi2TPCConstrainedVsGlobal(vertex);
1278 if (chi2TPCConstrainedVsGlobal < 0 || chi2TPCConstrainedVsGlobal > fCutMaxChi2TPCConstrainedVsGlobal)
1286 //########################################################################
1287 // filling histograms
1288 if (fHistogramsOn) {
1289 fhCutStatistics->Fill(fhCutStatistics->GetBinCenter(fhCutStatistics->GetXaxis()->FindBin("n tracks")));
1291 fhCutStatistics->Fill(fhCutStatistics->GetBinCenter(fhCutStatistics->GetXaxis()->FindBin("n cut tracks")));
1293 for (Int_t i=0; i<kNCuts; i++) {
1294 if (fhCutStatistics->GetXaxis()->FindBin(fgkCutNames[i]) < 1)
1295 AliFatal(Form("Inconsistency! Cut %d with name %s not found", i, fgkCutNames[i]));
1298 fhCutStatistics->Fill(fhCutStatistics->GetBinCenter(fhCutStatistics->GetXaxis()->FindBin(fgkCutNames[i])));
1300 for (Int_t j=i; j<kNCuts; j++) {
1301 if (cuts[i] && cuts[j]) {
1302 Float_t xC = fhCutCorrelation->GetXaxis()->GetBinCenter(fhCutCorrelation->GetXaxis()->FindBin(fgkCutNames[i]));
1303 Float_t yC = fhCutCorrelation->GetYaxis()->GetBinCenter(fhCutCorrelation->GetYaxis()->FindBin(fgkCutNames[j]));
1304 fhCutCorrelation->Fill(xC, yC);
1310 // now we loop over the filling of the histograms twice: once "before" the cut, once "after"
1311 // the code is not in a function due to too many local variables that would need to be passed
1313 for (Int_t id = 0; id < 2; id++)
1315 // id = 0 --> before cut
1316 // id = 1 --> after cut
1320 fhNClustersITS[id]->Fill(nClustersITS);
1321 fhNClustersTPC[id]->Fill(nClustersTPC);
1322 fhNSharedClustersTPC[id]->Fill(nClustersTPCShared);
1323 fhNCrossedRowsTPC[id]->Fill(nCrossedRowsTPC);
1324 fhRatioCrossedRowsOverFindableClustersTPC[id]->Fill(ratioCrossedRowsOverFindableClustersTPC);
1325 fhChi2PerClusterITS[id]->Fill(chi2PerClusterITS);
1326 fhChi2PerClusterTPC[id]->Fill(chi2PerClusterTPC);
1327 fhChi2TPCConstrainedVsGlobal[id]->Fill(chi2TPCConstrainedVsGlobal);
1328 fhNClustersForITSPID[id]->Fill(nITSPointsForPid);
1329 fhNMissingITSPoints[id]->Fill(nMissITSpts);
1331 fhC11[id]->Fill(extCov[0]);
1332 fhC22[id]->Fill(extCov[2]);
1333 fhC33[id]->Fill(extCov[5]);
1334 fhC44[id]->Fill(extCov[9]);
1335 fhC55[id]->Fill(extCov[14]);
1337 fhRel1PtUncertainty[id]->Fill(relUncertainty1Pt);
1340 fhEta[id]->Fill(eta);
1343 bRes[0] = TMath::Sqrt(bCov[0]);
1344 bRes[1] = TMath::Sqrt(bCov[2]);
1346 fhDZ[id]->Fill(b[1]);
1347 fhDXY[id]->Fill(b[0]);
1348 fhDXYDZ[id]->Fill(dcaToVertex);
1349 fhDXYvsDZ[id]->Fill(b[1],b[0]);
1351 if (bRes[0]!=0 && bRes[1]!=0) {
1352 fhDZNormalized[id]->Fill(b[1]/bRes[1]);
1353 fhDXYNormalized[id]->Fill(b[0]/bRes[0]);
1354 fhDXYvsDZNormalized[id]->Fill(b[1]/bRes[1], b[0]/bRes[0]);
1355 fhNSigmaToVertex[id]->Fill(nSigmaToVertex);
1367 //____________________________________________________________________
1368 Bool_t AliESDtrackCuts::CheckITSClusterRequirement(ITSClusterRequirement req, Bool_t clusterL1, Bool_t clusterL2)
1370 // checks if the cluster requirement is fullfilled (in this case: return kTRUE)
1374 case kOff: return kTRUE;
1375 case kNone: return !clusterL1 && !clusterL2;
1376 case kAny: return clusterL1 || clusterL2;
1377 case kFirst: return clusterL1;
1378 case kOnlyFirst: return clusterL1 && !clusterL2;
1379 case kSecond: return clusterL2;
1380 case kOnlySecond: return clusterL2 && !clusterL1;
1381 case kBoth: return clusterL1 && clusterL2;
1387 //____________________________________________________________________
1388 AliESDtrack* AliESDtrackCuts::GetTPCOnlyTrack(const AliESDEvent* esd, Int_t iTrack)
1390 // Utility function to create a TPC only track from the given esd track
1392 // IMPORTANT: The track has to be deleted by the user
1394 // NB. most of the functionality to get a TPC only track from an ESD track is in AliESDtrack, where it should be
1395 // there are only missing propagations here that are needed for old data
1396 // this function will therefore become obsolete
1398 // adapted from code provided by CKB
1400 if (!esd->GetPrimaryVertexTPC())
1401 return 0; // No TPC vertex no TPC tracks
1403 if(!esd->GetPrimaryVertexTPC()->GetStatus())
1404 return 0; // TPC Vertex is created by default in AliESDEvent, do not use in this case
1406 AliESDtrack* track = esd->GetTrack(iTrack);
1410 AliESDtrack *tpcTrack = new AliESDtrack();
1412 // only true if we have a tpc track
1413 if (!track->FillTPCOnlyTrack(*tpcTrack))
1422 //____________________________________________________________________
1423 TObjArray* AliESDtrackCuts::GetAcceptedTracks(const AliESDEvent* esd, Bool_t bTPC)
1426 // returns an array of all tracks that pass the cuts
1427 // or an array of TPC only tracks (propagated to the TPC vertex during reco)
1428 // tracks that pass the cut
1430 // NOTE: List has to be deleted by the user
1432 TObjArray* acceptedTracks = new TObjArray();
1434 // loop over esd tracks
1435 for (Int_t iTrack = 0; iTrack < esd->GetNumberOfTracks(); iTrack++) {
1437 if(!esd->GetPrimaryVertexTPC())return acceptedTracks; // No TPC vertex no TPC tracks
1438 if(!esd->GetPrimaryVertexTPC()->GetStatus())return acceptedTracks; // No proper TPC vertex, only the default
1440 AliESDtrack *tpcTrack = GetTPCOnlyTrack(esd, iTrack);
1444 if (AcceptTrack(tpcTrack)) {
1445 acceptedTracks->Add(tpcTrack);
1452 AliESDtrack* track = esd->GetTrack(iTrack);
1453 if(AcceptTrack(track))
1454 acceptedTracks->Add(track);
1457 if(bTPC)acceptedTracks->SetOwner(kTRUE);
1458 return acceptedTracks;
1461 //____________________________________________________________________
1462 Int_t AliESDtrackCuts::CountAcceptedTracks(const AliESDEvent* const esd)
1465 // returns an the number of tracks that pass the cuts
1470 // loop over esd tracks
1471 for (Int_t iTrack = 0; iTrack < esd->GetNumberOfTracks(); iTrack++) {
1472 AliESDtrack* track = esd->GetTrack(iTrack);
1473 if (AcceptTrack(track))
1480 //____________________________________________________________________
1481 void AliESDtrackCuts::DefineHistograms(Int_t color) {
1483 // diagnostics histograms are defined
1486 fHistogramsOn=kTRUE;
1488 Bool_t oldStatus = TH1::AddDirectoryStatus();
1489 TH1::AddDirectory(kFALSE);
1491 //###################################################################################
1492 // defining histograms
1494 fhCutStatistics = new TH1F("cut_statistics","cut statistics",kNCuts+4,-0.5,kNCuts+3.5);
1496 fhCutStatistics->GetXaxis()->SetBinLabel(1,"n tracks");
1497 fhCutStatistics->GetXaxis()->SetBinLabel(2,"n cut tracks");
1499 fhCutCorrelation = new TH2F("cut_correlation","cut correlation",kNCuts,-0.5,kNCuts-0.5,kNCuts,-0.5,kNCuts-0.5);;
1501 for (Int_t i=0; i<kNCuts; i++) {
1502 fhCutStatistics->GetXaxis()->SetBinLabel(i+4,fgkCutNames[i]);
1503 fhCutCorrelation->GetXaxis()->SetBinLabel(i+1,fgkCutNames[i]);
1504 fhCutCorrelation->GetYaxis()->SetBinLabel(i+1,fgkCutNames[i]);
1507 fhCutStatistics ->SetLineColor(color);
1508 fhCutCorrelation ->SetLineColor(color);
1509 fhCutStatistics ->SetLineWidth(2);
1510 fhCutCorrelation ->SetLineWidth(2);
1512 for (Int_t i=0; i<2; i++) {
1513 fhNClustersITS[i] = new TH1F("nClustersITS" ,"",8,-0.5,7.5);
1514 fhNClustersTPC[i] = new TH1F("nClustersTPC" ,"",165,-0.5,164.5);
1515 fhNSharedClustersTPC[i] = new TH1F("nSharedClustersTPC" ,"",165,-0.5,164.5);
1516 fhNCrossedRowsTPC[i] = new TH1F("nCrossedRowsTPC" ,"",165,-0.5,164.5);
1517 fhRatioCrossedRowsOverFindableClustersTPC[i] = new TH1F("ratioCrossedRowsOverFindableClustersTPC" ,"",60,0,1.5);
1518 fhChi2PerClusterITS[i] = new TH1F("chi2PerClusterITS","",500,0,10);
1519 fhChi2PerClusterTPC[i] = new TH1F("chi2PerClusterTPC","",500,0,10);
1520 fhChi2TPCConstrainedVsGlobal[i] = new TH1F("chi2TPCConstrainedVsGlobal","",600,-2,50);
1521 fhNClustersForITSPID[i] = new TH1F("nPointsForITSpid","",5,-0.5,4.5);
1522 fhNMissingITSPoints[i] = new TH1F("nMissingITSClusters","",7,-0.5,6.5);
1524 fhC11[i] = new TH1F("covMatrixDiagonal11","",2000,0,20);
1525 fhC22[i] = new TH1F("covMatrixDiagonal22","",2000,0,20);
1526 fhC33[i] = new TH1F("covMatrixDiagonal33","",1000,0,0.1);
1527 fhC44[i] = new TH1F("covMatrixDiagonal44","",1000,0,0.1);
1528 fhC55[i] = new TH1F("covMatrixDiagonal55","",1000,0,5);
1530 fhRel1PtUncertainty[i] = new TH1F("rel1PtUncertainty","",1000,0,5);
1532 fhDXY[i] = new TH1F("dXY" ,"",500,-10,10);
1533 fhDZ[i] = new TH1F("dZ" ,"",500,-10,10);
1534 fhDXYDZ[i] = new TH1F("dXYDZ" ,"",500,0,10);
1535 fhDXYvsDZ[i] = new TH2F("dXYvsDZ","",200,-10,10,200,-10,10);
1537 fhDXYNormalized[i] = new TH1F("dXYNormalized" ,"",500,-10,10);
1538 fhDZNormalized[i] = new TH1F("dZNormalized" ,"",500,-10,10);
1539 fhDXYvsDZNormalized[i] = new TH2F("dXYvsDZNormalized","",200,-10,10,200,-10,10);
1541 fhNSigmaToVertex[i] = new TH1F("nSigmaToVertex","",500,0,10);
1543 fhPt[i] = new TH1F("pt" ,"p_{T} distribution;p_{T} (GeV/c)", 800, 0.0, 10.0);
1544 fhEta[i] = new TH1F("eta" ,"#eta distribution;#eta",40,-2.0,2.0);
1546 fhNClustersITS[i]->SetTitle("n ITS clusters");
1547 fhNClustersTPC[i]->SetTitle("n TPC clusters");
1548 fhNSharedClustersTPC[i]->SetTitle("n TPC shared clusters");
1549 fhChi2PerClusterITS[i]->SetTitle("#Chi^{2} per ITS cluster");
1550 fhChi2PerClusterTPC[i]->SetTitle("#Chi^{2} per TPC cluster");
1551 fhChi2TPCConstrainedVsGlobal[i]->SetTitle("#Chi^{2} TPC constrained track vs global track");
1552 fhNClustersForITSPID[i]->SetTitle("n ITS points for PID");
1553 fhNMissingITSPoints[i]->SetTitle("n ITS layers with missing cluster");
1555 fhC11[i]->SetTitle("cov 11 : #sigma_{y}^{2} [cm^{2}]");
1556 fhC22[i]->SetTitle("cov 22 : #sigma_{z}^{2} [cm^{2}]");
1557 fhC33[i]->SetTitle("cov 33 : #sigma_{sin(#phi)}^{2}");
1558 fhC44[i]->SetTitle("cov 44 : #sigma_{tan(#theta_{dip})}^{2}");
1559 fhC55[i]->SetTitle("cov 55 : #sigma_{1/p_{T}}^{2} [(c/GeV)^2]");
1561 fhRel1PtUncertainty[i]->SetTitle("rel. uncertainty of 1/p_{T}");
1563 fhDXY[i]->SetXTitle("transverse impact parameter (cm)");
1564 fhDZ[i]->SetXTitle("longitudinal impact parameter (cm)");
1565 fhDXYDZ[i]->SetTitle("absolute impact parameter;sqrt(dXY**2 + dZ**2) (cm)");
1566 fhDXYvsDZ[i]->SetXTitle("longitudinal impact parameter (cm)");
1567 fhDXYvsDZ[i]->SetYTitle("transverse impact parameter (cm)");
1569 fhDXYNormalized[i]->SetTitle("normalized trans impact par (n#sigma)");
1570 fhDZNormalized[i]->SetTitle("normalized long impact par (n#sigma)");
1571 fhDXYvsDZNormalized[i]->SetTitle("normalized long impact par (n#sigma)");
1572 fhDXYvsDZNormalized[i]->SetYTitle("normalized trans impact par (n#sigma)");
1573 fhNSigmaToVertex[i]->SetTitle("n #sigma to vertex");
1575 fhNClustersITS[i]->SetLineColor(color); fhNClustersITS[i]->SetLineWidth(2);
1576 fhNClustersTPC[i]->SetLineColor(color); fhNClustersTPC[i]->SetLineWidth(2);
1577 fhNSharedClustersTPC[i]->SetLineColor(color); fhNSharedClustersTPC[i]->SetLineWidth(2);
1578 fhChi2PerClusterITS[i]->SetLineColor(color); fhChi2PerClusterITS[i]->SetLineWidth(2);
1579 fhChi2PerClusterTPC[i]->SetLineColor(color); fhChi2PerClusterTPC[i]->SetLineWidth(2);
1580 fhChi2TPCConstrainedVsGlobal[i]->SetLineColor(color); fhChi2TPCConstrainedVsGlobal[i]->SetLineWidth(2);
1581 fhNClustersForITSPID[i]->SetLineColor(color); fhNClustersForITSPID[i]->SetLineWidth(2);
1582 fhNMissingITSPoints[i]->SetLineColor(color); fhNMissingITSPoints[i]->SetLineWidth(2);
1584 fhC11[i]->SetLineColor(color); fhC11[i]->SetLineWidth(2);
1585 fhC22[i]->SetLineColor(color); fhC22[i]->SetLineWidth(2);
1586 fhC33[i]->SetLineColor(color); fhC33[i]->SetLineWidth(2);
1587 fhC44[i]->SetLineColor(color); fhC44[i]->SetLineWidth(2);
1588 fhC55[i]->SetLineColor(color); fhC55[i]->SetLineWidth(2);
1590 fhRel1PtUncertainty[i]->SetLineColor(color); fhRel1PtUncertainty[i]->SetLineWidth(2);
1592 fhDXY[i]->SetLineColor(color); fhDXY[i]->SetLineWidth(2);
1593 fhDZ[i]->SetLineColor(color); fhDZ[i]->SetLineWidth(2);
1594 fhDXYDZ[i]->SetLineColor(color); fhDXYDZ[i]->SetLineWidth(2);
1596 fhDXYNormalized[i]->SetLineColor(color); fhDXYNormalized[i]->SetLineWidth(2);
1597 fhDZNormalized[i]->SetLineColor(color); fhDZNormalized[i]->SetLineWidth(2);
1598 fhNSigmaToVertex[i]->SetLineColor(color); fhNSigmaToVertex[i]->SetLineWidth(2);
1601 // The number of sigmas to the vertex is per definition gaussian
1602 ffDTheoretical = new TF1("nSigmaToVertexTheoretical","([0]/2.506628274)*exp(-(x**2)/2)",0,50);
1603 ffDTheoretical->SetParameter(0,1);
1605 TH1::AddDirectory(oldStatus);
1608 //____________________________________________________________________
1609 Bool_t AliESDtrackCuts::LoadHistograms(const Char_t* dir)
1612 // loads the histograms from a file
1613 // if dir is empty a directory with the name of this object is taken (like in SaveHistogram)
1619 if (!gDirectory->cd(dir))
1622 ffDTheoretical = dynamic_cast<TF1*> (gDirectory->Get("nSigmaToVertexTheory"));
1624 fhCutStatistics = dynamic_cast<TH1F*> (gDirectory->Get("cut_statistics"));
1625 fhCutCorrelation = dynamic_cast<TH2F*> (gDirectory->Get("cut_correlation"));
1627 for (Int_t i=0; i<2; i++) {
1630 gDirectory->cd("before_cuts");
1633 gDirectory->cd("after_cuts");
1635 fhNClustersITS[i] = dynamic_cast<TH1F*> (gDirectory->Get("nClustersITS" ));
1636 fhNClustersTPC[i] = dynamic_cast<TH1F*> (gDirectory->Get("nClustersTPC" ));
1637 fhNSharedClustersTPC[i] = dynamic_cast<TH1F*> (gDirectory->Get("nSharedClustersTPC" ));
1638 fhNCrossedRowsTPC[i] = dynamic_cast<TH1F*> (gDirectory->Get("nCrossedRowsTPC" ));
1639 fhRatioCrossedRowsOverFindableClustersTPC[i] = dynamic_cast<TH1F*> (gDirectory->Get("ratioCrossedRowsOverFindableClustersTPC" ));
1640 fhChi2PerClusterITS[i] = dynamic_cast<TH1F*> (gDirectory->Get("chi2PerClusterITS"));
1641 fhChi2PerClusterTPC[i] = dynamic_cast<TH1F*> (gDirectory->Get("chi2PerClusterTPC"));
1642 fhChi2TPCConstrainedVsGlobal[i] = dynamic_cast<TH1F*> (gDirectory->Get("fhChi2TPCConstrainedVsGlobal"));
1643 fhNClustersForITSPID[i] = dynamic_cast<TH1F*> (gDirectory->Get("nPointsForITSpid"));
1644 fhNMissingITSPoints[i] = dynamic_cast<TH1F*> (gDirectory->Get("nMissingITSClusters"));
1646 fhC11[i] = dynamic_cast<TH1F*> (gDirectory->Get("covMatrixDiagonal11"));
1647 fhC22[i] = dynamic_cast<TH1F*> (gDirectory->Get("covMatrixDiagonal22"));
1648 fhC33[i] = dynamic_cast<TH1F*> (gDirectory->Get("covMatrixDiagonal33"));
1649 fhC44[i] = dynamic_cast<TH1F*> (gDirectory->Get("covMatrixDiagonal44"));
1650 fhC55[i] = dynamic_cast<TH1F*> (gDirectory->Get("covMatrixDiagonal55"));
1652 fhRel1PtUncertainty[i] = dynamic_cast<TH1F*> (gDirectory->Get("rel1PtUncertainty"));
1654 fhDXY[i] = dynamic_cast<TH1F*> (gDirectory->Get("dXY" ));
1655 fhDZ[i] = dynamic_cast<TH1F*> (gDirectory->Get("dZ" ));
1656 fhDXYDZ[i] = dynamic_cast<TH1F*> (gDirectory->Get("dXYDZ"));
1657 fhDXYvsDZ[i] = dynamic_cast<TH2F*> (gDirectory->Get("dXYvsDZ"));
1659 fhDXYNormalized[i] = dynamic_cast<TH1F*> (gDirectory->Get("dXYNormalized" ));
1660 fhDZNormalized[i] = dynamic_cast<TH1F*> (gDirectory->Get("dZNormalized" ));
1661 fhDXYvsDZNormalized[i] = dynamic_cast<TH2F*> (gDirectory->Get("dXYvsDZNormalized"));
1662 fhNSigmaToVertex[i] = dynamic_cast<TH1F*> (gDirectory->Get("nSigmaToVertex"));
1664 fhPt[i] = dynamic_cast<TH1F*> (gDirectory->Get("pt"));
1665 fhEta[i] = dynamic_cast<TH1F*> (gDirectory->Get("eta"));
1667 gDirectory->cd("../");
1670 gDirectory->cd("..");
1675 //____________________________________________________________________
1676 void AliESDtrackCuts::SaveHistograms(const Char_t* dir) {
1678 // saves the histograms in a directory (dir)
1681 if (!fHistogramsOn) {
1682 AliDebug(0, "Histograms not on - cannot save histograms!!!");
1689 gDirectory->mkdir(dir);
1690 gDirectory->cd(dir);
1692 gDirectory->mkdir("before_cuts");
1693 gDirectory->mkdir("after_cuts");
1695 // a factor of 2 is needed since n sigma is positive
1696 ffDTheoretical->SetParameter(0,2*fhNSigmaToVertex[0]->Integral("width"));
1697 ffDTheoretical->Write("nSigmaToVertexTheory");
1699 fhCutStatistics->Write();
1700 fhCutCorrelation->Write();
1702 for (Int_t i=0; i<2; i++) {
1704 gDirectory->cd("before_cuts");
1706 gDirectory->cd("after_cuts");
1708 fhNClustersITS[i] ->Write();
1709 fhNClustersTPC[i] ->Write();
1710 fhNSharedClustersTPC[i] ->Write();
1711 fhNCrossedRowsTPC[i] ->Write();
1712 fhRatioCrossedRowsOverFindableClustersTPC[i] ->Write();
1713 fhChi2PerClusterITS[i] ->Write();
1714 fhChi2PerClusterTPC[i] ->Write();
1715 fhChi2TPCConstrainedVsGlobal[i] ->Write();
1716 fhNClustersForITSPID[i] ->Write();
1717 fhNMissingITSPoints[i] ->Write();
1725 fhRel1PtUncertainty[i] ->Write();
1729 fhDXYDZ[i] ->Write();
1730 fhDXYvsDZ[i] ->Write();
1732 fhDXYNormalized[i] ->Write();
1733 fhDZNormalized[i] ->Write();
1734 fhDXYvsDZNormalized[i] ->Write();
1735 fhNSigmaToVertex[i] ->Write();
1740 gDirectory->cd("../");
1743 gDirectory->cd("../");
1746 //____________________________________________________________________
1747 void AliESDtrackCuts::DrawHistograms()
1749 // draws some histograms
1751 TCanvas* canvas1 = new TCanvas(Form("%s_1", GetName()), "Track Quality Results1", 800, 800);
1752 canvas1->Divide(2, 2);
1755 fhNClustersTPC[0]->SetStats(kFALSE);
1756 fhNClustersTPC[0]->Draw();
1759 fhChi2PerClusterTPC[0]->SetStats(kFALSE);
1760 fhChi2PerClusterTPC[0]->Draw();
1763 fhNSigmaToVertex[0]->SetStats(kFALSE);
1764 fhNSigmaToVertex[0]->GetXaxis()->SetRangeUser(0, 10);
1765 fhNSigmaToVertex[0]->Draw();
1767 canvas1->SaveAs(Form("%s_%s.gif", GetName(), canvas1->GetName()));
1769 TCanvas* canvas2 = new TCanvas(Form("%s_2", GetName()), "Track Quality Results2", 1200, 800);
1770 canvas2->Divide(3, 2);
1773 fhC11[0]->SetStats(kFALSE);
1778 fhC22[0]->SetStats(kFALSE);
1783 fhC33[0]->SetStats(kFALSE);
1788 fhC44[0]->SetStats(kFALSE);
1793 fhC55[0]->SetStats(kFALSE);
1798 fhRel1PtUncertainty[0]->SetStats(kFALSE);
1800 fhRel1PtUncertainty[0]->Draw();
1802 canvas2->SaveAs(Form("%s_%s.gif", GetName(), canvas2->GetName()));
1804 TCanvas* canvas3 = new TCanvas(Form("%s_3", GetName()), "Track Quality Results3", 1200, 800);
1805 canvas3->Divide(3, 2);
1808 fhDXY[0]->SetStats(kFALSE);
1813 fhDZ[0]->SetStats(kFALSE);
1818 fhDXYvsDZ[0]->SetStats(kFALSE);
1820 gPad->SetRightMargin(0.15);
1821 fhDXYvsDZ[0]->Draw("COLZ");
1824 fhDXYNormalized[0]->SetStats(kFALSE);
1826 fhDXYNormalized[0]->Draw();
1829 fhDZNormalized[0]->SetStats(kFALSE);
1831 fhDZNormalized[0]->Draw();
1834 fhDXYvsDZNormalized[0]->SetStats(kFALSE);
1836 gPad->SetRightMargin(0.15);
1837 fhDXYvsDZNormalized[0]->Draw("COLZ");
1839 canvas3->SaveAs(Form("%s_%s.gif", GetName(), canvas3->GetName()));
1841 TCanvas* canvas4 = new TCanvas(Form("%s_4", GetName()), "Track Quality Results4", 800, 500);
1842 canvas4->Divide(2, 1);
1845 fhCutStatistics->SetStats(kFALSE);
1846 fhCutStatistics->LabelsOption("v");
1847 gPad->SetBottomMargin(0.3);
1848 fhCutStatistics->Draw();
1851 fhCutCorrelation->SetStats(kFALSE);
1852 fhCutCorrelation->LabelsOption("v");
1853 gPad->SetBottomMargin(0.3);
1854 gPad->SetLeftMargin(0.3);
1855 fhCutCorrelation->Draw("COLZ");
1857 canvas4->SaveAs(Form("%s_%s.gif", GetName(), canvas4->GetName()));
1860 fhDXYvsDZNormalized[0]->SetStats(kFALSE);
1861 fhDXYvsDZNormalized[0]->DrawCopy("COLZ");
1864 fhNClustersTPC[0]->SetStats(kFALSE);
1865 fhNClustersTPC[0]->DrawCopy();
1868 fhChi2PerClusterITS[0]->SetStats(kFALSE);
1869 fhChi2PerClusterITS[0]->DrawCopy();
1870 fhChi2PerClusterITS[1]->SetLineColor(2);
1871 fhChi2PerClusterITS[1]->DrawCopy("SAME");
1874 fhChi2PerClusterTPC[0]->SetStats(kFALSE);
1875 fhChi2PerClusterTPC[0]->DrawCopy();
1876 fhChi2PerClusterTPC[1]->SetLineColor(2);
1877 fhChi2PerClusterTPC[1]->DrawCopy("SAME");*/
1879 //--------------------------------------------------------------------------
1880 void AliESDtrackCuts::SetPtDepDCACuts(Double_t pt) {
1882 // set the pt-dependent DCA cuts
1885 if(f1CutMaxDCAToVertexXYPtDep) {
1886 fCutMaxDCAToVertexXY=f1CutMaxDCAToVertexXYPtDep->Eval(pt);
1889 if(f1CutMaxDCAToVertexZPtDep) {
1890 fCutMaxDCAToVertexZ=f1CutMaxDCAToVertexZPtDep->Eval(pt);
1893 if(f1CutMinDCAToVertexXYPtDep) {
1894 fCutMinDCAToVertexXY=f1CutMinDCAToVertexXYPtDep->Eval(pt);
1897 if(f1CutMinDCAToVertexZPtDep) {
1898 fCutMinDCAToVertexZ=f1CutMinDCAToVertexZPtDep->Eval(pt);
1907 //--------------------------------------------------------------------------
1908 Bool_t AliESDtrackCuts::CheckPtDepDCA(TString dist,Bool_t print) const {
1910 // Check the correctness of the string syntax
1912 Bool_t retval=kTRUE;
1914 if(!dist.Contains("pt")) {
1915 if(print) AliError("string must contain \"pt\"");
1921 void AliESDtrackCuts::SetMaxDCAToVertexXYPtDep(const char *dist){
1923 if(f1CutMaxDCAToVertexXYPtDep){
1924 delete f1CutMaxDCAToVertexXYPtDep;
1926 f1CutMaxDCAToVertexXYPtDep = 0;
1927 fCutMaxDCAToVertexXYPtDep = "";
1929 if(!CheckPtDepDCA(dist,kTRUE)){
1932 fCutMaxDCAToVertexXYPtDep = dist;
1934 tmp.ReplaceAll("pt","x");
1935 f1CutMaxDCAToVertexXYPtDep = new TFormula("f1CutMaxDCAToVertexXYPtDep",tmp.Data());
1939 void AliESDtrackCuts::SetMaxDCAToVertexZPtDep(const char *dist){
1942 if(f1CutMaxDCAToVertexZPtDep){
1943 delete f1CutMaxDCAToVertexZPtDep;
1945 f1CutMaxDCAToVertexZPtDep = 0;
1946 fCutMaxDCAToVertexZPtDep = "";
1948 if(!CheckPtDepDCA(dist,kTRUE))return;
1950 fCutMaxDCAToVertexZPtDep = dist;
1952 tmp.ReplaceAll("pt","x");
1953 f1CutMaxDCAToVertexZPtDep = new TFormula("f1CutMaxDCAToVertexZPtDep",tmp.Data());
1959 void AliESDtrackCuts::SetMinDCAToVertexXYPtDep(const char *dist){
1962 if(f1CutMinDCAToVertexXYPtDep){
1963 delete f1CutMinDCAToVertexXYPtDep;
1965 f1CutMinDCAToVertexXYPtDep = 0;
1966 fCutMinDCAToVertexXYPtDep = "";
1968 if(!CheckPtDepDCA(dist,kTRUE))return;
1970 fCutMinDCAToVertexXYPtDep = dist;
1972 tmp.ReplaceAll("pt","x");
1973 f1CutMinDCAToVertexXYPtDep = new TFormula("f1CutMinDCAToVertexXYPtDep",tmp.Data());
1978 void AliESDtrackCuts::SetMinDCAToVertexZPtDep(const char *dist){
1982 if(f1CutMinDCAToVertexZPtDep){
1983 delete f1CutMinDCAToVertexZPtDep;
1985 f1CutMinDCAToVertexZPtDep = 0;
1986 fCutMinDCAToVertexZPtDep = "";
1988 if(!CheckPtDepDCA(dist,kTRUE))return;
1989 fCutMinDCAToVertexZPtDep = dist;
1991 tmp.ReplaceAll("pt","x");
1992 f1CutMinDCAToVertexZPtDep = new TFormula("f1CutMinDCAToVertexZPtDep",tmp.Data());
1995 AliESDtrackCuts* AliESDtrackCuts::GetMultEstTrackCuts(MultEstTrackCuts cut)
1997 // returns the multiplicity estimator track cuts objects to allow for user configuration
1998 // upon first call the objects are created
2000 // the cut defined here correspond to GetStandardITSTPCTrackCuts2010 (apart from the one for without SPD)
2002 if (!fgMultEstTrackCuts[kMultEstTrackCutGlobal])
2004 // quality cut on ITS+TPC tracks
2005 fgMultEstTrackCuts[kMultEstTrackCutGlobal] = new AliESDtrackCuts();
2006 fgMultEstTrackCuts[kMultEstTrackCutGlobal]->SetMinNClustersTPC(70);
2007 fgMultEstTrackCuts[kMultEstTrackCutGlobal]->SetMaxChi2PerClusterTPC(4);
2008 fgMultEstTrackCuts[kMultEstTrackCutGlobal]->SetAcceptKinkDaughters(kFALSE);
2009 fgMultEstTrackCuts[kMultEstTrackCutGlobal]->SetRequireTPCRefit(kTRUE);
2010 fgMultEstTrackCuts[kMultEstTrackCutGlobal]->SetRequireITSRefit(kTRUE);
2011 //multiplicity underestimate if we use global tracks with |eta| > 0.9
2012 fgMultEstTrackCuts[kMultEstTrackCutGlobal]->SetEtaRange(-0.9, 0.9);
2014 // quality cut on ITS_SA tracks (complementary to ITS+TPC)
2015 fgMultEstTrackCuts[kMultEstTrackCutITSSA] = new AliESDtrackCuts();
2016 fgMultEstTrackCuts[kMultEstTrackCutITSSA]->SetRequireITSRefit(kTRUE);
2018 // primary selection for tracks with SPD hits
2019 fgMultEstTrackCuts[kMultEstTrackCutDCAwSPD] = new AliESDtrackCuts();
2020 fgMultEstTrackCuts[kMultEstTrackCutDCAwSPD]->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kAny);
2021 fgMultEstTrackCuts[kMultEstTrackCutDCAwSPD]->SetMaxDCAToVertexXYPtDep("0.0182+0.0350/pt^1.01");
2022 fgMultEstTrackCuts[kMultEstTrackCutDCAwSPD]->SetMaxDCAToVertexZ(2);
2024 // primary selection for tracks w/o SPD hits
2025 fgMultEstTrackCuts[kMultEstTrackCutDCAwoSPD] = new AliESDtrackCuts();
2026 fgMultEstTrackCuts[kMultEstTrackCutDCAwoSPD]->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kNone);
2027 fgMultEstTrackCuts[kMultEstTrackCutDCAwoSPD]->SetMaxDCAToVertexXYPtDep("1.5*(0.0182+0.0350/pt^1.01)");
2028 fgMultEstTrackCuts[kMultEstTrackCutDCAwoSPD]->SetMaxDCAToVertexZ(2);
2031 return fgMultEstTrackCuts[cut];
2034 Int_t AliESDtrackCuts::GetReferenceMultiplicity(const AliESDEvent* esd, MultEstTrackType trackType, Float_t etaRange)
2036 // Get multiplicity estimate based on TPC/ITS tracks and tracklets
2037 // Adapted for AliESDtrackCuts from a version developed by: Ruben Shahoyan, Anton Alkin, Arvinder Palaha
2039 // Returns a negative value if no reliable estimate can be provided:
2040 // -1 SPD vertex missing
2041 // -2 SPD VertexerZ dispersion too large
2042 // -3 Track vertex missing (not checked for kTracklets)
2043 // -4 Distance between SPD and track vertices too large (not checked for kTracklets)
2045 // WARNING This functions does not cut on the z vtx. Depending on the eta range requested, you need to restrict your z vertex range!
2047 // Strategy for combined estimators
2048 // 1. Count global tracks and flag them
2049 // 2. Count ITSSA as complementaries for ITSTPC+ or as main tracks
2050 // 3. Count the complementary SPD tracklets
2052 const AliESDVertex* vertices[2];
2053 vertices[0] = esd->GetPrimaryVertexSPD();
2054 vertices[1] = esd->GetPrimaryVertexTracks();
2056 if (!vertices[0]->GetStatus())
2058 AliDebugClass(AliLog::kDebug, "No SPD vertex. Not able to make a reliable multiplicity estimate.");
2062 if (vertices[0]->IsFromVertexerZ() && vertices[0]->GetDispersion() > 0.02)
2064 AliDebugClass(AliLog::kDebug, "Vertexer z dispersion > 0.02. Not able to make a reliable multiplicity estimate.");
2068 Int_t multiplicityEstimate = 0;
2070 // SPD tracklet-only estimate
2071 if (trackType == kTracklets)
2073 const AliMultiplicity* spdmult = esd->GetMultiplicity(); // spd multiplicity object
2074 for (Int_t i=0; i<spdmult->GetNumberOfTracklets(); ++i)
2076 if (TMath::Abs(spdmult->GetEta(i)) > etaRange)
2077 continue; // eta selection for tracklets
2078 multiplicityEstimate++;
2080 return multiplicityEstimate;
2083 if (!vertices[1]->GetStatus())
2085 AliDebugClass(AliLog::kDebug, "No track vertex. Not able to make a reliable multiplicity estimate.");
2089 // TODO value of displacement to be studied
2090 const Float_t maxDisplacement = 0.5;
2091 //check for displaced vertices
2092 Double_t displacement = TMath::Abs(vertices[0]->GetZ() - vertices[1]->GetZ());
2093 if (displacement > maxDisplacement)
2095 AliDebugClass(AliLog::kDebug, Form("Displaced vertices %f > %f",displacement,maxDisplacement));
2099 // update eta range in track cuts
2100 GetMultEstTrackCuts(kMultEstTrackCutITSSA)->SetEtaRange(-etaRange, etaRange);
2101 GetMultEstTrackCuts(kMultEstTrackCutDCAwSPD)->SetEtaRange(-etaRange, etaRange);
2102 GetMultEstTrackCuts(kMultEstTrackCutDCAwoSPD)->SetEtaRange(-etaRange, etaRange);
2104 //*******************************************************************************************************
2105 //set counters to initial zeros
2106 Int_t tracksITSTPC = 0; //number of global tracks for a given event
2107 Int_t tracksITSSA = 0; //number of ITS standalone tracks for a given event
2108 Int_t tracksITSTPCSA_complementary = 0; //number of ITS standalone tracks complementary to TPC for a given event
2109 Int_t trackletsITSTPC_complementary = 0;//number of SPD tracklets complementary to global/ITSSA tracks for a given events
2110 Int_t trackletsITSSA_complementary = 0; //number of SPD tracklets complementary to ITSSA tracks for a given event
2112 const Int_t nESDTracks = esd->GetNumberOfTracks();
2113 Int_t highestID = 0;
2115 // flags for secondary and rejected tracks
2116 const Int_t kRejBit = BIT(15); // set this bit in global tracks if it is rejected by a cut
2117 const Int_t kSecBit = BIT(16); // set this bit in global tracks if it is secondary according to a cut
2119 for(Int_t itracks=0; itracks < nESDTracks; itracks++) {
2120 if(esd->GetTrack(itracks)->GetLabel() > highestID) highestID = esd->GetTrack(itracks)->GetLabel();
2121 esd->GetTrack(itracks)->ResetBit(kSecBit|kRejBit); //reset bits used for flagging secondaries and rejected tracks in case they were changed before this analysis
2123 const Int_t maxid = highestID+1; // used to define bool array for check multiple associations of tracklets to one track. array starts at 0.
2125 // bit mask for esd tracks, to check if multiple tracklets are associated to it
2126 Bool_t globalBits[maxid], pureITSBits[maxid];
2127 for(Int_t i=0; i<maxid; i++){ // set all bools to false
2128 globalBits[i]=kFALSE;
2129 pureITSBits[i]=kFALSE;
2132 //*******************************************************************************************************
2133 // get multiplicity from global tracks
2134 for(Int_t itracks = 0; itracks < nESDTracks; itracks++) { // flag the tracks
2135 AliESDtrack* track = esd->GetTrack(itracks);
2137 // if track is a secondary from a V0, flag as a secondary
2138 if (track->IsOn(AliESDtrack::kMultInV0)) {
2139 track->SetBit(kSecBit);
2144 if (track->IsOn(AliESDtrack::kMultSec)) {
2145 track->SetBit(kSecBit);
2149 // check tracks with ITS part
2150 //*******************************************************************************************************
2151 if (track->IsOn(AliESDtrack::kITSin) && !track->IsOn(AliESDtrack::kITSpureSA) && trackType == kTrackletsITSTPC) { // track has ITS part but is not an ITS_SA
2152 //*******************************************************************************************************
2154 if (track->IsOn(AliESDtrack::kTPCin)) { // Global track, has ITS and TPC contributions
2155 if (fgMultEstTrackCuts[kMultEstTrackCutGlobal]->AcceptTrack(track)) { // good ITSTPC track
2156 if (fgMultEstTrackCuts[kMultEstTrackCutDCAwSPD]->AcceptTrack(track) || fgMultEstTrackCuts[kMultEstTrackCutDCAwoSPD]->AcceptTrack(track)) {
2157 tracksITSTPC++; //global track counted
2158 globalBits[itracks] = kTRUE;
2160 else track->SetBit(kSecBit); // large DCA -> secondary, don't count either track not associated tracklet
2162 else track->SetBit(kRejBit); // bad quality, don't count the track, but may count tracklet if associated
2164 //*******************************************************************************************************
2165 // ITS complementary
2166 else if (fgMultEstTrackCuts[kMultEstTrackCutITSSA]->AcceptTrack(track)) { // good ITS complementary track
2167 if (fgMultEstTrackCuts[kMultEstTrackCutDCAwSPD]->AcceptTrack(track) || fgMultEstTrackCuts[kMultEstTrackCutDCAwoSPD]->AcceptTrack(track)) {
2168 tracksITSTPCSA_complementary++;
2169 globalBits[itracks] = kTRUE;
2171 else track->SetBit(kSecBit); // large DCA -> secondary, don't count either track not associated tracklet
2173 else track->SetBit(kRejBit); // bad quality, don't count the track, but may count tracklet if associated
2175 //*******************************************************************************************************
2176 // check tracks from ITS_SA_PURE
2177 if (track->IsOn(AliESDtrack::kITSin) && track->IsOn(AliESDtrack::kITSpureSA) && trackType == kTrackletsITSSA){
2178 if (fgMultEstTrackCuts[kMultEstTrackCutITSSA]->AcceptTrack(track)) { // good ITSSA track
2179 if (fgMultEstTrackCuts[kMultEstTrackCutDCAwSPD]->AcceptTrack(track) || fgMultEstTrackCuts[kMultEstTrackCutDCAwoSPD]->AcceptTrack(track)) {
2181 pureITSBits[itracks] = kTRUE;
2183 else track->SetBit(kRejBit);
2185 else track->SetBit(kRejBit);
2187 }//ESD tracks counted
2189 //*******************************************************************************************************
2190 // get multiplicity from ITS tracklets to complement TPC+ITS, and ITSpureSA
2191 const AliMultiplicity* spdmult = esd->GetMultiplicity(); // spd multiplicity object
2192 for (Int_t i=0; i<spdmult->GetNumberOfTracklets(); ++i) {
2193 if (TMath::Abs(spdmult->GetEta(i)) > etaRange) continue; // eta selection for tracklets
2195 // if counting tracks+tracklets, check if clusters were already used in tracks
2196 Int_t id1,id2,id3,id4;
2197 spdmult->GetTrackletTrackIDs(i,0,id1,id2); // references for eventual Global/ITS_SA tracks
2198 AliESDtrack* tr1 = id1>=0 ? esd->GetTrack(id1) : 0;
2199 spdmult->GetTrackletTrackIDs(i,1,id3,id4); // references for eventual ITS_SA_pure tracks
2200 AliESDtrack* tr3 = id3>=0 ? esd->GetTrack(id3) : 0;
2202 // are both clusters from the same tracks? If not, skip the tracklet (shouldn't change things much)
2203 if ((id1!=id2 && id1>=0 && id2>=0) || (id3!=id4 && id3>=0 && id4>=0)) continue;
2205 Bool_t bUsedInGlobal = (id1 != -1) ? globalBits[id1] : 0;// has associated global track been associated to a previous tracklet?
2206 Bool_t bUsedInPureITS = (id3 != -1) ? pureITSBits[id3] : 0;// has associated pure ITS track been associated to a previous tracklet?
2207 //*******************************************************************************************************
2208 if (trackType == kTrackletsITSTPC) {
2209 // count tracklets towards global+complementary tracks
2210 if ( (tr1 && !tr1->TestBit(kSecBit)) && // reject as secondary
2211 (tr1 && tr1->TestBit(kRejBit)) ) { // count tracklet as bad quality track
2213 ++trackletsITSTPC_complementary;
2214 if(id1>0) globalBits[id1] = kTRUE; // mark global track linked to this tracklet as "associated"
2218 ++trackletsITSTPC_complementary; // if no associated track, count the tracklet
2221 // count tracklets towards ITS_SA_pure tracks
2222 if ( (tr3 && !tr3->TestBit(kSecBit)) && // reject as secondary
2223 (tr3 && tr3->TestBit(kRejBit)) ) { // count tracklet as bad quality track
2224 if(!bUsedInPureITS) {
2225 ++trackletsITSSA_complementary;
2226 if(id3>0) pureITSBits[id3] = kTRUE; // mark global track linked to this tracklet as "associated"
2230 ++trackletsITSSA_complementary; // if no associated track, count the tracklet
2235 //*******************************************************************************************************
2236 if (trackType == kTrackletsITSTPC)
2237 multiplicityEstimate = tracksITSTPC + tracksITSTPCSA_complementary + trackletsITSTPC_complementary;
2239 multiplicityEstimate = tracksITSSA + trackletsITSSA_complementary;
2241 return multiplicityEstimate;