#include <TDirectory.h>
#include <TH2F.h>
#include <TF1.h>
+#include <TBits.h>
//____________________________________________________________________
ClassImp(AliESDtrackCuts)
"require ITS Pid",
"n crossed rows TPC",
"n crossed rows / n findable clusters",
- "missing ITS points"
+ "missing ITS points",
+ "#Chi^{2} TPC constrained vs. global",
+ "require TOF out",
+ "TOF Distance cut",
+ "min length in active volume TPC"
};
AliESDtrackCuts* AliESDtrackCuts::fgMultEstTrackCuts[AliESDtrackCuts::kNMultEstTrackCuts] = { 0, 0, 0, 0 };
+Char_t AliESDtrackCuts::fgBeamTypeFlag = -1;
//____________________________________________________________________
AliESDtrackCuts::AliESDtrackCuts(const Char_t* name, const Char_t* title) : AliAnalysisCuts(name,title),
fCutMinNClusterITS(0),
fCutMinNCrossedRowsTPC(0),
fCutMinRatioCrossedRowsOverFindableClustersTPC(0),
+ f1CutMinNClustersTPCPtDep(0x0),
+ fCutMaxPtDepNClustersTPC(0),
+ fCutMinLengthActiveVolumeTPC(0),
fCutMaxChi2PerClusterTPC(0),
fCutMaxChi2PerClusterITS(0),
+ fCutMaxChi2TPCConstrainedVsGlobal(0),
+ fCutMaxChi2TPCConstrainedVsGlobalVertexType(kVertexTracks | kVertexSPD),
fCutMaxMissingITSPoints(0),
fCutMaxC11(0),
fCutMaxC22(0),
fEtaMax(0),
fRapMin(0),
fRapMax(0),
+ fCutRequireTOFout(kFALSE),
+ fFlagCutTOFdistance(kFALSE),
+ fCutTOFdistance(3.),
fHistogramsOn(0),
ffDTheoretical(0),
fhCutStatistics(0),
SetMinNCrossedRowsTPC();
SetMinRatioCrossedRowsOverFindableClustersTPC();
SetMaxChi2PerClusterTPC();
- SetMaxChi2PerClusterITS();
+ SetMaxChi2PerClusterITS();
+ SetMaxChi2TPCConstrainedGlobal();
+ SetMaxChi2TPCConstrainedGlobalVertexType();
SetMaxNOfMissingITSPoints();
SetMaxCovDiagonalElements();
SetMaxRel1PtUncertainty();
fCutMinNClusterITS(0),
fCutMinNCrossedRowsTPC(0),
fCutMinRatioCrossedRowsOverFindableClustersTPC(0),
+ f1CutMinNClustersTPCPtDep(0x0),
+ fCutMaxPtDepNClustersTPC(0),
+ fCutMinLengthActiveVolumeTPC(0),
fCutMaxChi2PerClusterTPC(0),
fCutMaxChi2PerClusterITS(0),
+ fCutMaxChi2TPCConstrainedVsGlobal(0),
+ fCutMaxChi2TPCConstrainedVsGlobalVertexType(kVertexTracks | kVertexSPD),
fCutMaxMissingITSPoints(0),
fCutMaxC11(0),
fCutMaxC22(0),
fEtaMax(0),
fRapMin(0),
fRapMax(0),
+ fCutRequireTOFout(kFALSE),
+ fFlagCutTOFdistance(kFALSE),
+ fCutTOFdistance(3.),
fHistogramsOn(0),
- ffDTheoretical(0),
- fhCutStatistics(0),
+ ffDTheoretical(0),
+ fhCutStatistics(0),
fhCutCorrelation(0)
{
//
delete fhChi2PerClusterITS[i];
if (fhChi2PerClusterTPC[i])
delete fhChi2PerClusterTPC[i];
+ if (fhChi2TPCConstrainedVsGlobal[i])
+ delete fhChi2TPCConstrainedVsGlobal[i];
if(fhNClustersForITSPID[i])
delete fhNClustersForITSPID[i];
if(fhNMissingITSPoints[i])
delete fhPt[i];
if (fhEta[i])
delete fhEta[i];
+ if (fhTOFdistance[i])
+ delete fhTOFdistance[i];
}
if(f1CutMaxDCAToVertexXYPtDep)delete f1CutMaxDCAToVertexXYPtDep;
if (fhCutStatistics)
delete fhCutStatistics;
if (fhCutCorrelation)
- delete fhCutCorrelation;
+ delete fhCutCorrelation;
+
+ if(f1CutMinNClustersTPCPtDep)
+ delete f1CutMinNClustersTPCPtDep;
+
}
void AliESDtrackCuts::Init()
fCutMaxChi2PerClusterTPC = 0;
fCutMaxChi2PerClusterITS = 0;
+ fCutMaxChi2TPCConstrainedVsGlobal = 0;
+ fCutMaxChi2TPCConstrainedVsGlobalVertexType = kVertexTracks | kVertexSPD;
fCutMaxMissingITSPoints = 0;
for (Int_t i = 0; i < 3; i++)
fhChi2PerClusterITS[i] = 0;
fhChi2PerClusterTPC[i] = 0;
+ fhChi2TPCConstrainedVsGlobal[i] = 0;
fhNClustersForITSPID[i] = 0;
fhNMissingITSPoints[i] = 0;
fhPt[i] = 0;
fhEta[i] = 0;
+ fhTOFdistance[i] = 0;
}
ffDTheoretical = 0;
target.fCutMinNClusterITS = fCutMinNClusterITS;
target.fCutMinNCrossedRowsTPC = fCutMinNCrossedRowsTPC;
target.fCutMinRatioCrossedRowsOverFindableClustersTPC = fCutMinRatioCrossedRowsOverFindableClustersTPC;
-
-
+ if(f1CutMinNClustersTPCPtDep){
+ target.f1CutMinNClustersTPCPtDep = (TFormula*) f1CutMinNClustersTPCPtDep->Clone("f1CutMinNClustersTPCPtDep");
+ }
+ target.fCutMaxPtDepNClustersTPC = fCutMaxPtDepNClustersTPC;
+ target.fCutMinLengthActiveVolumeTPC = fCutMinLengthActiveVolumeTPC;
+
target.fCutMaxChi2PerClusterTPC = fCutMaxChi2PerClusterTPC;
target.fCutMaxChi2PerClusterITS = fCutMaxChi2PerClusterITS;
+ target.fCutMaxChi2TPCConstrainedVsGlobal = fCutMaxChi2TPCConstrainedVsGlobal;
+ target.fCutMaxChi2TPCConstrainedVsGlobalVertexType = fCutMaxChi2TPCConstrainedVsGlobalVertexType;
target.fCutMaxMissingITSPoints = fCutMaxMissingITSPoints;
for (Int_t i = 0; i < 3; i++)
target.fCutMinDCAToVertexZ = fCutMinDCAToVertexZ;
target.fCutMaxDCAToVertexXYPtDep = fCutMaxDCAToVertexXYPtDep;
- target.SetMaxDCAToVertexXYPtDep(fCutMaxDCAToVertexXYPtDep.Data());
+ if(fCutMaxDCAToVertexXYPtDep.Length()>0)target.SetMaxDCAToVertexXYPtDep(fCutMaxDCAToVertexXYPtDep.Data());
target.fCutMaxDCAToVertexZPtDep = fCutMaxDCAToVertexZPtDep;
- target.SetMaxDCAToVertexZPtDep(fCutMaxDCAToVertexZPtDep.Data());
+ if(fCutMaxDCAToVertexZPtDep.Length()>0)target.SetMaxDCAToVertexZPtDep(fCutMaxDCAToVertexZPtDep.Data());
target.fCutMinDCAToVertexXYPtDep = fCutMinDCAToVertexXYPtDep;
- target.SetMinDCAToVertexXYPtDep(fCutMinDCAToVertexXYPtDep.Data());
+ if(fCutMinDCAToVertexXYPtDep.Length()>0)target.SetMinDCAToVertexXYPtDep(fCutMinDCAToVertexXYPtDep.Data());
target.fCutMinDCAToVertexZPtDep = fCutMinDCAToVertexZPtDep;
- target.SetMinDCAToVertexZPtDep(fCutMinDCAToVertexZPtDep.Data());
+ if(fCutMinDCAToVertexZPtDep.Length()>0)target.SetMinDCAToVertexZPtDep(fCutMinDCAToVertexZPtDep.Data());
target.fPMin = fPMin;
target.fPMax = fPMax;
target.fRapMin = fRapMin;
target.fRapMax = fRapMax;
+ target.fFlagCutTOFdistance = fFlagCutTOFdistance;
+ target.fCutTOFdistance = fCutTOFdistance;
+ target.fCutRequireTOFout = fCutRequireTOFout;
+
target.fHistogramsOn = fHistogramsOn;
for (Int_t i=0; i<2; ++i)
if (fhChi2PerClusterITS[i]) target.fhChi2PerClusterITS[i] = (TH1F*) fhChi2PerClusterITS[i]->Clone();
if (fhChi2PerClusterTPC[i]) target.fhChi2PerClusterTPC[i] = (TH1F*) fhChi2PerClusterTPC[i]->Clone();
+ if (fhChi2TPCConstrainedVsGlobal[i]) target.fhChi2TPCConstrainedVsGlobal[i] = (TH1F*) fhChi2TPCConstrainedVsGlobal[i]->Clone();
if (fhNClustersForITSPID[i]) target.fhNClustersForITSPID[i] = (TH1F*) fhNClustersForITSPID[i]->Clone();
if (fhNMissingITSPoints[i]) target.fhNMissingITSPoints[i] = (TH1F*) fhNMissingITSPoints[i]->Clone();
if (fhPt[i]) target.fhPt[i] = (TH1F*) fhPt[i]->Clone();
if (fhEta[i]) target.fhEta[i] = (TH1F*) fhEta[i]->Clone();
+ if (fhTOFdistance[i]) target.fhTOFdistance[i] = (TH2F*) fhTOFdistance[i]->Clone();
}
if (ffDTheoretical) target.ffDTheoretical = (TF1*) ffDTheoretical->Clone();
fhChi2PerClusterITS[i] ->Add(entry->fhChi2PerClusterITS[i]);
fhChi2PerClusterTPC[i] ->Add(entry->fhChi2PerClusterTPC[i]);
+ if (fhChi2TPCConstrainedVsGlobal[i])
+ fhChi2TPCConstrainedVsGlobal[i]->Add(entry->fhChi2TPCConstrainedVsGlobal[i]);
if (fhNClustersForITSPID[i])
fhNClustersForITSPID[i]->Add(entry->fhNClustersForITSPID[i]);
if (fhNMissingITSPoints[i])
fhPt[i] ->Add(entry->fhPt[i]);
fhEta[i] ->Add(entry->fhEta[i]);
+ fhTOFdistance[i] ->Add(entry->fhTOFdistance[i]);
}
fhCutStatistics ->Add(entry->fhCutStatistics);
return count+1;
}
+void AliESDtrackCuts::SetMinNClustersTPCPtDep(TFormula *f1, Float_t ptmax)
+{
+ //
+ // Sets the pT dependent NClustersTPC cut
+ //
+
+ if(f1){
+ delete f1CutMinNClustersTPCPtDep;
+ f1CutMinNClustersTPCPtDep = (TFormula*)f1->Clone("f1CutMinNClustersTPCPtDep");
+ }
+ fCutMaxPtDepNClustersTPC=ptmax;
+}
+
//____________________________________________________________________
AliESDtrackCuts* AliESDtrackCuts::GetStandardTPCOnlyTrackCuts()
{
if(selPrimaries) {
// 7*(0.0050+0.0060/pt^0.9)
esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+ esdTrackCuts->SetMaxChi2TPCConstrainedGlobal(36);
}
esdTrackCuts->SetMaxDCAToVertexZ(1.e6);
esdTrackCuts->SetDCAToVertex2D(kFALSE);
esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
//esdTrackCuts->SetEtaRange(-0.8,+0.8);
+ esdTrackCuts->SetMaxChi2PerClusterITS(36);
+
+ return esdTrackCuts;
+}
+
+//____________________________________________________________________
+AliESDtrackCuts* AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(Bool_t selPrimaries, Int_t clusterCut)
+{
+ // creates an AliESDtrackCuts object and fills it with standard values for ITS-TPC cuts for pp 2011 data
+ // if clusterCut = 1, the cut on the number of clusters is replaced by
+ // a cut on the number of crossed rows and on the ration crossed
+ // rows/findable clusters
+
+ AliInfoClass("Creating track cuts for ITS+TPC (2011 definition).");
+
+ AliESDtrackCuts* esdTrackCuts = new AliESDtrackCuts;
+
+ // TPC
+ if(clusterCut == 0) esdTrackCuts->SetMinNClustersTPC(50);
+ else if (clusterCut == 1) {
+ esdTrackCuts->SetMinNCrossedRowsTPC(70);
+ esdTrackCuts->SetMinRatioCrossedRowsOverFindableClustersTPC(0.8);
+ }
+ else {
+ AliWarningClass(Form("Wrong value of the clusterCut parameter (%d), using cut on Nclusters",clusterCut));
+ esdTrackCuts->SetMinNClustersTPC(50);
+ }
+ esdTrackCuts->SetMaxChi2PerClusterTPC(4);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kTRUE);
+ // ITS
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,
+ AliESDtrackCuts::kAny);
+ if(selPrimaries) {
+ // 7*(0.0015+0.0050/pt^1.1)
+ esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0105+0.0350/pt^1.1");
+ esdTrackCuts->SetMaxChi2TPCConstrainedGlobal(36);
+ }
+ esdTrackCuts->SetMaxDCAToVertexZ(2);
+ esdTrackCuts->SetDCAToVertex2D(kFALSE);
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+
+ esdTrackCuts->SetMaxChi2PerClusterITS(36);
+
return esdTrackCuts;
}
if(selPrimaries) {
// 7*(0.0026+0.0050/pt^1.01)
esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0182+0.0350/pt^1.01");
+ esdTrackCuts->SetMaxChi2TPCConstrainedGlobal(36);
}
esdTrackCuts->SetMaxDCAToVertexZ(2);
esdTrackCuts->SetDCAToVertex2D(kFALSE);
esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetMaxChi2PerClusterITS(36);
+
return esdTrackCuts;
}
-//____________________________________________________________________
-
-
-
//____________________________________________________________________
AliESDtrackCuts* AliESDtrackCuts::GetStandardITSPureSATrackCuts2009(Bool_t selPrimaries, Bool_t useForPid)
{
}
//____________________________________________________________________
-Float_t AliESDtrackCuts::GetSigmaToVertex(AliESDtrack* const esdTrack)
+Float_t AliESDtrackCuts::GetSigmaToVertex(const AliESDtrack* const esdTrack)
{
// Calculates the number of sigma to the vertex.
}
//____________________________________________________________________
-Bool_t AliESDtrackCuts::AcceptTrack(AliESDtrack* esdTrack)
+Bool_t AliESDtrackCuts::AcceptTrack(const AliESDtrack* esdTrack)
{
//
// figure out if the tracks survives all the track cuts defined
// fTracks.fR //GetMass
// fTracks.fP //GetMass
// fTracks.fKinkIndexes
+ //
+ // esdEvent is only required for the MaxChi2TPCConstrainedVsGlobal
UInt_t status = esdTrack->GetStatus();
else {
nClustersTPC = esdTrack->GetTPCclusters(0);
}
- Float_t nCrossedRowsTPC = esdTrack->GetTPCClusterInfo(2,1);
+
+ //Pt dependent NClusters Cut
+ if(f1CutMinNClustersTPCPtDep) {
+ if(esdTrack->Pt()<fCutMaxPtDepNClustersTPC)
+ fCutMinNClusterTPC = (Int_t)(f1CutMinNClustersTPCPtDep->Eval(esdTrack->Pt()));
+ else
+ fCutMinNClusterTPC = (Int_t)(f1CutMinNClustersTPCPtDep->Eval(fCutMaxPtDepNClustersTPC));
+ }
+
+ Float_t nCrossedRowsTPC = esdTrack->GetTPCCrossedRows();
Float_t ratioCrossedRowsOverFindableClustersTPC = 1.0;
if (esdTrack->GetTPCNclsF()>0) {
ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC / esdTrack->GetTPCNclsF();
Double_t extCov[15];
esdTrack->GetExternalCovariance(extCov);
- // getting the track to vertex parameters
- Float_t nSigmaToVertex = GetSigmaToVertex(esdTrack);
-
Float_t b[2];
Float_t bCov[3];
esdTrack->GetImpactParameters(b,bCov);
Double_t p[3];
esdTrack->GetPxPyPz(p);
- Float_t momentum = TMath::Sqrt(TMath::Power(p[0],2) + TMath::Power(p[1],2) + TMath::Power(p[2],2));
- Float_t pt = TMath::Sqrt(TMath::Power(p[0],2) + TMath::Power(p[1],2));
- Float_t energy = TMath::Sqrt(TMath::Power(esdTrack->GetMass(),2) + TMath::Power(momentum,2));
+ // Changed from float to double to prevent rounding errors leading to negative
+ // log arguments (M.G.)
+ Double_t momentum = TMath::Sqrt(p[0]*p[0] + p[1]*p[1] + p[2]*p[2]);
+ Double_t pt = TMath::Sqrt(p[0]*p[0] + p[1]*p[1]);
+ Double_t mass = esdTrack->GetMass();
+ Double_t energy = TMath::Sqrt(mass*mass + momentum*momentum);
//y-eta related calculations
Float_t eta = -100.;
cuts[10]=kTRUE;
if (extCov[14] > fCutMaxC55)
cuts[11]=kTRUE;
- if (nSigmaToVertex > fCutNsigmaToVertex && fCutSigmaToVertexRequired)
- cuts[12] = kTRUE;
- // if n sigma could not be calculated
- if (nSigmaToVertex<0 && fCutSigmaToVertexRequired)
- cuts[13]=kTRUE;
+
+ // cut 12 and 13 see below
+
if (!fCutAcceptKinkDaughters && esdTrack->GetKinkIndex(0)>0)
cuts[14]=kTRUE;
// track kinematics cut
if (!fCutDCAToVertex2D && TMath::Abs(dcaToVertexZ) < fCutMinDCAToVertexZ)
cuts[27] = kTRUE;
- for (Int_t i = 0; i < 3; i++)
- cuts[28+i] = !CheckITSClusterRequirement(fCutClusterRequirementITS[i], esdTrack->HasPointOnITSLayer(i*2), esdTrack->HasPointOnITSLayer(i*2+1));
+ for (Int_t i = 0; i < 3; i++) {
+ if(!(esdTrack->GetStatus()&AliESDtrack::kITSupg)) { // current ITS
+ cuts[28+i] = !CheckITSClusterRequirement(fCutClusterRequirementITS[i], esdTrack->HasPointOnITSLayer(i*2), esdTrack->HasPointOnITSLayer(i*2+1));
+ } else { // upgraded ITS (7 layers)
+ // at the moment, for L012 the layers 12 are considered together
+ if(i==0) { // L012
+ cuts[28+i] = !CheckITSClusterRequirement(fCutClusterRequirementITS[i], esdTrack->HasPointOnITSLayer(0), (esdTrack->HasPointOnITSLayer(1))&(esdTrack->HasPointOnITSLayer(2)));
+ } else { // L34 or L56
+ cuts[28+i] = !CheckITSClusterRequirement(fCutClusterRequirementITS[i], esdTrack->HasPointOnITSLayer(i*2+1), esdTrack->HasPointOnITSLayer(i*2+2));
+ }
+ }
+ }
if(fCutRequireITSStandAlone || fCutRequireITSpureSA){
if ((status & AliESDtrack::kITSin) == 0 || (status & AliESDtrack::kTPCin)){
if(retc && statusLay==5) ++nMissITSpts;
}
if(nMissITSpts>fCutMaxMissingITSPoints) cuts[38] = kTRUE;
-
+
+ //kTOFout
+ if (fCutRequireTOFout && (status&AliESDtrack::kTOFout)==0)
+ cuts[40]=kTRUE;
+
+ // TOF signal Dz cut
+ Float_t dxTOF = esdTrack->GetTOFsignalDx();
+ Float_t dzTOF = esdTrack->GetTOFsignalDz();
+ if (fFlagCutTOFdistance && (esdTrack->GetStatus() & AliESDtrack::kTOFout) == AliESDtrack::kTOFout){ // applying the TOF distance cut only if requested, and only on tracks that reached the TOF and where associated with a TOF hit
+ if (fgBeamTypeFlag < 0) { // the check on the beam type was not done yet
+ const AliESDEvent* event = esdTrack->GetESDEvent();
+ if (event){
+ TString beamTypeESD = event->GetBeamType();
+ AliDebug(2,Form("Beam type from ESD event = %s",beamTypeESD.Data()));
+ if (beamTypeESD.CompareTo("A-A",TString::kIgnoreCase) == 0){ // we are in PbPb collisions --> fgBeamTypeFlag will be set to 1, to apply the cut on TOF signal Dz
+ fgBeamTypeFlag = 1;
+ }
+ else { // we are NOT in PbPb collisions --> fgBeamTypeFlag will be set to 0, to NOT apply the cu6 on TOF signal Dz
+ fgBeamTypeFlag = 0;
+ }
+ }
+ else{
+ AliFatal("Beam type not available, but it is needed to apply the TOF cut!");
+ }
+ }
+
+ if (fgBeamTypeFlag == 1){ // we are in PbPb collisions --> apply the cut on TOF signal Dz
+ Float_t radiusTOF = TMath::Sqrt(dxTOF*dxTOF + dzTOF*dzTOF);
+ AliDebug(3,Form("TOF check (with fCutTOFdistance = %f) --> dx = %f, dz = %f, radius = %f", fCutTOFdistance, dxTOF, dzTOF, radiusTOF));
+ if (radiusTOF > fCutTOFdistance){
+ AliDebug(2, Form("************* the radius is outside the range! %f > %f, the track will be skipped", radiusTOF, fCutTOFdistance));
+ cuts[41] = kTRUE;
+ }
+ }
+ }
+
Bool_t cut=kFALSE;
for (Int_t i=0; i<kNCuts; i++)
if (cuts[i]) {cut = kTRUE;}
+ // for performance evaluate the CPU intensive cuts only when the others have passed, and when they are requested
+ Double_t chi2TPCConstrainedVsGlobal = -2;
+ Float_t nSigmaToVertex = -2;
+ if (!cut)
+ {
+ // getting the track to vertex parameters
+ if (fCutSigmaToVertexRequired)
+ {
+ nSigmaToVertex = GetSigmaToVertex(esdTrack);
+ if (nSigmaToVertex > fCutNsigmaToVertex && fCutSigmaToVertexRequired)
+ {
+ cuts[12] = kTRUE;
+ cut = kTRUE;
+ }
+ // if n sigma could not be calculated
+ if (nSigmaToVertex<0 && fCutSigmaToVertexRequired)
+ {
+ cuts[13] = kTRUE;
+ cut = kTRUE;
+ }
+ }
+
+ // max chi2 TPC constrained vs global track only if track passed the other cut
+ if (fCutMaxChi2TPCConstrainedVsGlobal < 1e9)
+ {
+ const AliESDEvent* esdEvent = esdTrack->GetESDEvent();
+
+ if (!esdEvent)
+ AliFatal("fCutMaxChi2TPCConstrainedVsGlobal set but ESD event not set in AliESDTrack. Use AliESDTrack::SetESDEvent before calling AliESDtrackCuts.");
+
+ // get vertex
+ const AliESDVertex* vertex = 0;
+ if (fCutMaxChi2TPCConstrainedVsGlobalVertexType & kVertexTracks)
+ vertex = esdEvent->GetPrimaryVertexTracks();
+
+ if ((!vertex || !vertex->GetStatus()) && fCutMaxChi2TPCConstrainedVsGlobalVertexType & kVertexSPD)
+ vertex = esdEvent->GetPrimaryVertexSPD();
+
+ if ((!vertex || !vertex->GetStatus()) && fCutMaxChi2TPCConstrainedVsGlobalVertexType & kVertexTPC)
+ vertex = esdEvent->GetPrimaryVertexTPC();
+
+ if (vertex->GetStatus())
+ chi2TPCConstrainedVsGlobal = esdTrack->GetChi2TPCConstrainedVsGlobal(vertex);
+
+ if (chi2TPCConstrainedVsGlobal < 0 || chi2TPCConstrainedVsGlobal > fCutMaxChi2TPCConstrainedVsGlobal)
+ {
+ cuts[39] = kTRUE;
+ cut = kTRUE;
+ }
+ }
+
+ // max length in active volume
+ Float_t lengthInActiveZoneTPC = -1;
+ if (fCutMinLengthActiveVolumeTPC > 1.) { // do the calculation only if needed to save cpu-time
+ if (esdTrack->GetESDEvent()) {
+ if (esdTrack->GetInnerParam()) lengthInActiveZoneTPC = esdTrack->GetLengthInActiveZone(1, 1.8, 220, esdTrack->GetESDEvent()->GetMagneticField());
+ //
+ if (lengthInActiveZoneTPC < fCutMinLengthActiveVolumeTPC ) {
+ cuts[42] = kTRUE;
+ cut = kTRUE;
+ }
+ }
+ }
+
+
+ }
//########################################################################
// filling histograms
fhRatioCrossedRowsOverFindableClustersTPC[id]->Fill(ratioCrossedRowsOverFindableClustersTPC);
fhChi2PerClusterITS[id]->Fill(chi2PerClusterITS);
fhChi2PerClusterTPC[id]->Fill(chi2PerClusterTPC);
+ fhChi2TPCConstrainedVsGlobal[id]->Fill(chi2TPCConstrainedVsGlobal);
fhNClustersForITSPID[id]->Fill(nITSPointsForPid);
fhNMissingITSPoints[id]->Fill(nMissITSpts);
fhPt[id]->Fill(pt);
fhEta[id]->Fill(eta);
+ fhTOFdistance[id]->Fill(dxTOF, dzTOF);
Float_t bRes[2];
bRes[0] = TMath::Sqrt(bCov[0]);
}
//____________________________________________________________________
-AliESDtrack* AliESDtrackCuts::GetTPCOnlyTrack(AliESDEvent* esd, Int_t iTrack)
+AliESDtrack* AliESDtrackCuts::GetTPCOnlyTrack(const AliESDEvent* esd, Int_t iTrack)
{
-
- // Utility function to
- // create a TPC only track from the given esd track
+ // Utility function to create a TPC only track from the given esd track
//
// IMPORTANT: The track has to be deleted by the user
//
return 0;
}
- // propagate to Vertex
- // not needed for normal reconstructed ESDs...
- // Double_t pTPC[2],covTPC[3];
- // tpcTrack->PropagateToDCA(esd->GetPrimaryVertexTPC(), esd->GetMagneticField(), 10000, pTPC, covTPC);
-
return tpcTrack;
}
//____________________________________________________________________
-TObjArray* AliESDtrackCuts::GetAcceptedTracks(AliESDEvent* esd,Bool_t bTPC)
+TObjArray* AliESDtrackCuts::GetAcceptedTracks(const AliESDEvent* esd, Bool_t bTPC)
{
//
// returns an array of all tracks that pass the cuts
fhRatioCrossedRowsOverFindableClustersTPC[i] = new TH1F("ratioCrossedRowsOverFindableClustersTPC" ,"",60,0,1.5);
fhChi2PerClusterITS[i] = new TH1F("chi2PerClusterITS","",500,0,10);
fhChi2PerClusterTPC[i] = new TH1F("chi2PerClusterTPC","",500,0,10);
+ fhChi2TPCConstrainedVsGlobal[i] = new TH1F("chi2TPCConstrainedVsGlobal","",600,-2,50);
fhNClustersForITSPID[i] = new TH1F("nPointsForITSpid","",5,-0.5,4.5);
fhNMissingITSPoints[i] = new TH1F("nMissingITSClusters","",7,-0.5,6.5);
fhPt[i] = new TH1F("pt" ,"p_{T} distribution;p_{T} (GeV/c)", 800, 0.0, 10.0);
fhEta[i] = new TH1F("eta" ,"#eta distribution;#eta",40,-2.0,2.0);
+ fhTOFdistance[i] = new TH2F("TOFdistance" ,"TOF distance;dx (cm};dz (cm)", 150, -15, 15, 150, -15, 15);
fhNClustersITS[i]->SetTitle("n ITS clusters");
fhNClustersTPC[i]->SetTitle("n TPC clusters");
fhNSharedClustersTPC[i]->SetTitle("n TPC shared clusters");
fhChi2PerClusterITS[i]->SetTitle("#Chi^{2} per ITS cluster");
fhChi2PerClusterTPC[i]->SetTitle("#Chi^{2} per TPC cluster");
+ fhChi2TPCConstrainedVsGlobal[i]->SetTitle("#Chi^{2} TPC constrained track vs global track");
fhNClustersForITSPID[i]->SetTitle("n ITS points for PID");
fhNMissingITSPoints[i]->SetTitle("n ITS layers with missing cluster");
fhNSharedClustersTPC[i]->SetLineColor(color); fhNSharedClustersTPC[i]->SetLineWidth(2);
fhChi2PerClusterITS[i]->SetLineColor(color); fhChi2PerClusterITS[i]->SetLineWidth(2);
fhChi2PerClusterTPC[i]->SetLineColor(color); fhChi2PerClusterTPC[i]->SetLineWidth(2);
+ fhChi2TPCConstrainedVsGlobal[i]->SetLineColor(color); fhChi2TPCConstrainedVsGlobal[i]->SetLineWidth(2);
fhNClustersForITSPID[i]->SetLineColor(color); fhNClustersForITSPID[i]->SetLineWidth(2);
fhNMissingITSPoints[i]->SetLineColor(color); fhNMissingITSPoints[i]->SetLineWidth(2);
fhRatioCrossedRowsOverFindableClustersTPC[i] = dynamic_cast<TH1F*> (gDirectory->Get("ratioCrossedRowsOverFindableClustersTPC" ));
fhChi2PerClusterITS[i] = dynamic_cast<TH1F*> (gDirectory->Get("chi2PerClusterITS"));
fhChi2PerClusterTPC[i] = dynamic_cast<TH1F*> (gDirectory->Get("chi2PerClusterTPC"));
+ fhChi2TPCConstrainedVsGlobal[i] = dynamic_cast<TH1F*> (gDirectory->Get("fhChi2TPCConstrainedVsGlobal"));
fhNClustersForITSPID[i] = dynamic_cast<TH1F*> (gDirectory->Get("nPointsForITSpid"));
fhNMissingITSPoints[i] = dynamic_cast<TH1F*> (gDirectory->Get("nMissingITSClusters"));
fhPt[i] = dynamic_cast<TH1F*> (gDirectory->Get("pt"));
fhEta[i] = dynamic_cast<TH1F*> (gDirectory->Get("eta"));
+ fhTOFdistance[i] = dynamic_cast<TH2F*> (gDirectory->Get("TOFdistance"));
gDirectory->cd("../");
}
fhRatioCrossedRowsOverFindableClustersTPC[i] ->Write();
fhChi2PerClusterITS[i] ->Write();
fhChi2PerClusterTPC[i] ->Write();
+ fhChi2TPCConstrainedVsGlobal[i] ->Write();
fhNClustersForITSPID[i] ->Write();
fhNMissingITSPoints[i] ->Write();
fhPt[i] ->Write();
fhEta[i] ->Write();
+ fhTOFdistance[i] ->Write();
gDirectory->cd("../");
}
Int_t trackletsITSSA_complementary = 0; //number of SPD tracklets complementary to ITSSA tracks for a given event
const Int_t nESDTracks = esd->GetNumberOfTracks();
- Int_t highestID = 0;
// flags for secondary and rejected tracks
const Int_t kRejBit = BIT(15); // set this bit in global tracks if it is rejected by a cut
const Int_t kSecBit = BIT(16); // set this bit in global tracks if it is secondary according to a cut
for(Int_t itracks=0; itracks < nESDTracks; itracks++) {
- if(esd->GetTrack(itracks)->GetLabel() > highestID) highestID = esd->GetTrack(itracks)->GetLabel();
esd->GetTrack(itracks)->ResetBit(kSecBit|kRejBit); //reset bits used for flagging secondaries and rejected tracks in case they were changed before this analysis
}
- const Int_t maxid = highestID+1; // used to define bool array for check multiple associations of tracklets to one track. array starts at 0.
+ const Int_t maxid = nESDTracks; // used to define bool array for check multiple associations of tracklets to one track. array starts at 0.
// bit mask for esd tracks, to check if multiple tracklets are associated to it
- Bool_t globalBits[maxid], pureITSBits[maxid];
- for(Int_t i=0; i<maxid; i++){ // set all bools to false
- globalBits[i]=kFALSE;
- pureITSBits[i]=kFALSE;
- }
+ TBits globalBits(maxid), pureITSBits(maxid);
+ // why labels are used with the data? RS
+ // Bool_t globalBits[maxid], pureITSBits[maxid];
+ // for(Int_t i=0; i<maxid; i++){ // set all bools to false
+ // globalBits[i]=kFALSE;
+ // pureITSBits[i]=kFALSE;
+ // }
//*******************************************************************************************************
// get multiplicity from global tracks
track->SetBit(kSecBit);
continue;
}
-
+ /* done via proper DCA cut
//secondary?
if (track->IsOn(AliESDtrack::kMultSec)) {
track->SetBit(kSecBit);
continue;
}
-
+ */
// check tracks with ITS part
//*******************************************************************************************************
if (track->IsOn(AliESDtrack::kITSin) && !track->IsOn(AliESDtrack::kITSpureSA) && trackType == kTrackletsITSTPC) { // track has ITS part but is not an ITS_SA
if (fgMultEstTrackCuts[kMultEstTrackCutGlobal]->AcceptTrack(track)) { // good ITSTPC track
if (fgMultEstTrackCuts[kMultEstTrackCutDCAwSPD]->AcceptTrack(track) || fgMultEstTrackCuts[kMultEstTrackCutDCAwoSPD]->AcceptTrack(track)) {
tracksITSTPC++; //global track counted
- globalBits[itracks] = kTRUE;
+ globalBits.SetBitNumber(itracks);
}
else track->SetBit(kSecBit); // large DCA -> secondary, don't count either track not associated tracklet
}
else if (fgMultEstTrackCuts[kMultEstTrackCutITSSA]->AcceptTrack(track)) { // good ITS complementary track
if (fgMultEstTrackCuts[kMultEstTrackCutDCAwSPD]->AcceptTrack(track) || fgMultEstTrackCuts[kMultEstTrackCutDCAwoSPD]->AcceptTrack(track)) {
tracksITSTPCSA_complementary++;
- globalBits[itracks] = kTRUE;
+ globalBits.SetBitNumber(itracks);
}
else track->SetBit(kSecBit); // large DCA -> secondary, don't count either track not associated tracklet
}
if (fgMultEstTrackCuts[kMultEstTrackCutITSSA]->AcceptTrack(track)) { // good ITSSA track
if (fgMultEstTrackCuts[kMultEstTrackCutDCAwSPD]->AcceptTrack(track) || fgMultEstTrackCuts[kMultEstTrackCutDCAwoSPD]->AcceptTrack(track)) {
tracksITSSA++;
- pureITSBits[itracks] = kTRUE;
+ pureITSBits.SetBitNumber(itracks);
}
- else track->SetBit(kRejBit);
+ else track->SetBit(kSecBit);
}
else track->SetBit(kRejBit);
}
if (TMath::Abs(spdmult->GetEta(i)) > etaRange) continue; // eta selection for tracklets
// if counting tracks+tracklets, check if clusters were already used in tracks
- Int_t id1,id2,id3,id4;
- spdmult->GetTrackletTrackIDs(i,0,id1,id2); // references for eventual Global/ITS_SA tracks
- AliESDtrack* tr1 = id1>=0 ? esd->GetTrack(id1) : 0;
- spdmult->GetTrackletTrackIDs(i,1,id3,id4); // references for eventual ITS_SA_pure tracks
- AliESDtrack* tr3 = id3>=0 ? esd->GetTrack(id3) : 0;
-
+ Int_t id1, id2, id3, id4;
+ spdmult->GetTrackletTrackIDs ( i, 0, id1, id2 ); // references for eventual Global/ITS_SA tracks
+ spdmult->GetTrackletTrackIDs ( i, 1, id3, id4 ); // references for eventual ITS_SA_pure tracks
+
// are both clusters from the same tracks? If not, skip the tracklet (shouldn't change things much)
- if ((id1!=id2 && id1>=0 && id2>=0) || (id3!=id4 && id3>=0 && id4>=0)) continue;
-
- Bool_t bUsedInGlobal = (id1 != -1) ? globalBits[id1] : 0;// has associated global track been associated to a previous tracklet?
- Bool_t bUsedInPureITS = (id3 != -1) ? pureITSBits[id3] : 0;// has associated pure ITS track been associated to a previous tracklet?
+ if ( ( id1 != id2 && id1 >= 0 && id2 >= 0 ) || ( id3 != id4 && id3 >= 0 && id4 >= 0 ) ) continue;
+
+ //referenced track
+ //at this point we either have id1 = id2 (id3 = id4) or only one of the ids pair is -1
+ // id1>=0, id2>=0, id1=id2 : tracklet has associated track
+ // id1>=0, id2 = -1 : 1st layer cluster has associated track
+ // id1=-1, id2>=0 : 2nd layer cluster has associated track
+ // id1=-1, id2=-1 : tracklet has no associated track
+ //
+ Int_t bUsedInGlobal(-1);
+ if ( id1 != -1 ) bUsedInGlobal = globalBits.TestBitNumber(id1) ? id1 : -1;
+ else if ( id2 != -1) bUsedInGlobal = globalBits.TestBitNumber(id2) ? id2 : -1;
+ Int_t bUsedInPureITS(-1);
+ if ( id3 != -1 ) bUsedInPureITS = pureITSBits.TestBitNumber(id3) ? id3 : -1;
+ else if ( id4 != -1) bUsedInPureITS = pureITSBits.TestBitNumber(id4) ? id4 : -1;
+ //
+ AliESDtrack* tr_global = bUsedInGlobal >= 0 ? esd->GetTrack ( bUsedInGlobal ) : 0;
+ AliESDtrack* tr_itssa = bUsedInPureITS >= 0 ? esd->GetTrack ( bUsedInPureITS ) : 0;
+ //
+ // has associated pure ITS track been associated to a previous tracklet?
//*******************************************************************************************************
if (trackType == kTrackletsITSTPC) {
- // count tracklets towards global+complementary tracks
- if ( (tr1 && !tr1->TestBit(kSecBit)) && // reject as secondary
- (tr1 && tr1->TestBit(kRejBit)) ) { // count tracklet as bad quality track
- if(!bUsedInGlobal){
- ++trackletsITSTPC_complementary;
- if(id1>0) globalBits[id1] = kTRUE; // mark global track linked to this tracklet as "associated"
- }
- }
- else if(id1<0) {
- ++trackletsITSTPC_complementary; // if no associated track, count the tracklet
- }
+ //*******************************************************************************************************
+ // count tracklets towards global+complimentary tracks
+ if ( ( tr_global && !tr_global->TestBit ( kSecBit ) ) && ( tr_global && tr_global->TestBit ( kRejBit ) ) ) { // count tracklet as bad quality track
+ globalBits.SetBitNumber( bUsedInGlobal ); // mark global track linked to this tracklet as used
+ ++trackletsITSTPC_complementary;
+ }
+
+ if ( bUsedInGlobal < 0 ) ++trackletsITSTPC_complementary; //no associated track, just count the tracklet
} else {
- // count tracklets towards ITS_SA_pure tracks
- if ( (tr3 && !tr3->TestBit(kSecBit)) && // reject as secondary
- (tr3 && tr3->TestBit(kRejBit)) ) { // count tracklet as bad quality track
- if(!bUsedInPureITS) {
- ++trackletsITSSA_complementary;
- if(id3>0) pureITSBits[id3] = kTRUE; // mark global track linked to this tracklet as "associated"
- }
- }
- else if(id3<0) {
- ++trackletsITSSA_complementary; // if no associated track, count the tracklet
- }
+ //*******************************************************************************************************
+ // count tracklets towards ITS_SA_pure tracks
+ if ( ( tr_itssa && !tr_itssa->TestBit ( kSecBit ) ) && ( tr_itssa && tr_itssa->TestBit ( kRejBit ) ) ) { // count tracklet as bad quality track
+ pureITSBits.SetBitNumber( bUsedInPureITS ); // mark ITS pure SA track linked to this tracklet as used
+ ++trackletsITSSA_complementary;
+ }
+
+ if ( bUsedInPureITS < 0 ) ++trackletsITSSA_complementary; //no associated track, just count the tracklet
}
}
return multiplicityEstimate;
}
+
+//____________________________________________________________________
+void AliESDtrackCuts::SetRequireStandardTOFmatchCuts(){
+
+ // setting the TOF cuts flags (kTOFout = TOF matching distance) to true, to include the selection on the standard TOF matching
+
+ SetRequireTOFout(kTRUE);
+ SetFlagCutTOFdistance(kTRUE);
+ SetCutTOFdistance(3.);
+
+}
+