#include <TDirectory.h>
#include <TH2F.h>
#include <TF1.h>
+#include <TBits.h>
//____________________________________________________________________
ClassImp(AliESDtrackCuts)
"n crossed rows / n findable clusters",
"missing ITS points",
"#Chi^{2} TPC constrained vs. global",
- "TOF Distance cut"
+ "require TOF out",
+ "TOF Distance cut",
+ "min length in active volume TPC"
};
AliESDtrackCuts* AliESDtrackCuts::fgMultEstTrackCuts[AliESDtrackCuts::kNMultEstTrackCuts] = { 0, 0, 0, 0 };
fCutMinRatioCrossedRowsOverFindableClustersTPC(0),
f1CutMinNClustersTPCPtDep(0x0),
fCutMaxPtDepNClustersTPC(0),
+ fCutMinLengthActiveVolumeTPC(0),
fCutMaxChi2PerClusterTPC(0),
fCutMaxChi2PerClusterITS(0),
fCutMaxChi2TPCConstrainedVsGlobal(0),
fEtaMax(0),
fRapMin(0),
fRapMax(0),
+ fCutRequireTOFout(kFALSE),
fFlagCutTOFdistance(kFALSE),
fCutTOFdistance(3.),
fHistogramsOn(0),
fCutMinRatioCrossedRowsOverFindableClustersTPC(0),
f1CutMinNClustersTPCPtDep(0x0),
fCutMaxPtDepNClustersTPC(0),
+ fCutMinLengthActiveVolumeTPC(0),
fCutMaxChi2PerClusterTPC(0),
fCutMaxChi2PerClusterITS(0),
fCutMaxChi2TPCConstrainedVsGlobal(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)
{
//
target.f1CutMinNClustersTPCPtDep = (TFormula*) f1CutMinNClustersTPCPtDep->Clone("f1CutMinNClustersTPCPtDep");
}
target.fCutMaxPtDepNClustersTPC = fCutMaxPtDepNClustersTPC;
-
+ target.fCutMinLengthActiveVolumeTPC = fCutMinLengthActiveVolumeTPC;
+
target.fCutMaxChi2PerClusterTPC = fCutMaxChi2PerClusterTPC;
target.fCutMaxChi2PerClusterITS = fCutMaxChi2PerClusterITS;
target.fCutMaxChi2TPCConstrainedVsGlobal = fCutMaxChi2TPCConstrainedVsGlobal;
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.fFlagCutTOFdistance = fFlagCutTOFdistance;
target.fCutTOFdistance = fCutTOFdistance;
+ target.fCutRequireTOFout = fCutRequireTOFout;
target.fHistogramsOn = fHistogramsOn;
//esdTrackCuts->SetEtaRange(-0.8,+0.8);
esdTrackCuts->SetMaxChi2PerClusterITS(36);
- // to be added after validation: esdTrackCuts->SetFlagCutTOFdistance(kTRUE);
return esdTrackCuts;
}
esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
esdTrackCuts->SetMaxChi2PerClusterITS(36);
- // to be added after validation: esdTrackCuts->SetFlagCutTOFdistance(kTRUE);
return esdTrackCuts;
}
esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
esdTrackCuts->SetMaxChi2PerClusterITS(36);
- // to be added after validation: esdTrackCuts->SetFlagCutTOFdistance(kTRUE);
return esdTrackCuts;
}
else {
nClustersTPC = esdTrack->GetTPCclusters(0);
}
-
+
//Pt dependent NClusters Cut
if(f1CutMinNClustersTPCPtDep) {
if(esdTrack->Pt()<fCutMaxPtDepNClustersTPC)
- fCutMinNClusterTPC = f1CutMinNClustersTPCPtDep->Eval(esdTrack->Pt());
+ fCutMinNClusterTPC = (Int_t)(f1CutMinNClustersTPCPtDep->Eval(esdTrack->Pt()));
else
- fCutMinNClusterTPC = f1CutMinNClustersTPCPtDep->Eval(fCutMaxPtDepNClustersTPC);
+ fCutMinNClusterTPC = (Int_t)(f1CutMinNClustersTPCPtDep->Eval(fCutMaxPtDepNClustersTPC));
}
Float_t nCrossedRowsTPC = esdTrack->GetTPCCrossedRows();
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.;
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(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;}
cut = kTRUE;
}
}
- }
- // TOF signal Dz cut
- Float_t dxTOF = esdTrack->GetTOFsignalDx();
- Float_t dzTOF = esdTrack->GetTOFsignalDz();
- if (fFlagCutTOFdistance){
- 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!");
- }
- }
+ // 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;
+ }
+ }
+ }
- 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[40] = kTRUE;
- cut = kTRUE;
- }
- }
+
}
-
+
//########################################################################
// filling histograms
if (fHistogramsOn) {
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.);
+
+}
+