* provided "as is" without express or implied warranty. *
**************************************************************************/
+/* $Id$ */
+
/*
* author: M.Kalisky@gsi.de
* 08/Dec/2010
*
* Description: This class allows with purely kinematical cuts
* to select clean samples of electrons, pions and protons from the
- * V0 online finder ESD V0 candidates for PID and dectero resonse
+ * V0 online finder ESD V0 candidates for PID and dectector resonse
* studies.
*/
#include "AliESDv0.h"
#include "AliESDtrack.h"
#include "AliESDEvent.h"
+#include "AliVEvent.h"
#include "AliLog.h"
#include "AliKFParticle.h"
#include "AliVTrack.h"
//____________________________________________________________________
AliESDv0KineCuts::AliESDv0KineCuts() :
- fV0(0x0)
- , fEvent(0x0)
+ fEvent(0x0)
, fPrimaryVertex(0x0)
+ , fType(0)
+ , fMode(0)
+ , fTPCNcls(1)
+ , fTPCrefit(kTRUE)
+ , fTPCchi2perCls(4.0)
+ , fTPCclsRatio(0.6)
+ , fNoKinks(kTRUE)
+ , fGcutChi2NDF(10)
+ , fGcutInvMass(0.05)
+ , fK0cutChi2NDF(10)
+ , fLcutChi2NDF(10)
{
//
// Default constructor
//
+ // default single track cuts
+ fTPCNcls = 1; // minimal number of the TPC clusters
+ fTPCrefit = kTRUE; // TPC refit
+ fTPCchi2perCls = 4.0; // chi2 per TPC cluster
+ fTPCclsRatio = 0.6; // minimal foun/findable TPC cluster ratio
+ fNoKinks = kTRUE; // kinks - no [kTRUE] or do not care [kFalse]
+
+
+ // default gamma cuts values
+ fGcutChi2NDF = 10; // Chi2NF cut value for the AliKFparticle gamma
+ fGcutCosPoint[0] = 0; // cos of the pointing angle [min, max]
+ fGcutCosPoint[1] = 0.02; // cos of the pointing angle [min, max]
+ fGcutDCA[0] = 0.; // DCA between the daughter tracks [min, max]
+ fGcutDCA[1] = 0.25; // DCA between the daughter tracks [min, max]
+ fGcutVertexR[0] = 3.; // radius of the conversion point [min, max]
+ fGcutVertexR[1] = 90.; // radius of the conversion point [min, max]
+ fGcutPsiPair[0] = 0.; // value of the psi pair cut [min, max]
+ fGcutPsiPair[1] = 0.05; // value of the psi pair cut [min, max]
+ fGcutInvMass = 0.05; // upper value on the gamma invariant mass
+ // default K0 cuts
+ fK0cutChi2NDF = 10; // Chi2NF cut value for the AliKFparticle K0
+ fK0cutCosPoint[0] = 0.; // cos of the pointing angle [min, max]
+ fK0cutCosPoint[1] = 0.02; // cos of the pointing angle [min, max]
+ fK0cutDCA[0] = 0.; // DCA between the daughter tracks [min, max]
+ fK0cutDCA[1] = 0.2; // DCA between the daughter tracks [min, max]
+ fK0cutVertexR[0] = 2.0; // radius of the decay point [min, max]
+ fK0cutVertexR[1] = 30.0; // radius of the decay point [min, max]
+ fK0cutInvMass[0] = 0.486; // invariant mass window
+ fK0cutInvMass[1] = 0.508; // invariant mass window
+ // Lambda & anti-Lambda cut values
+ fLcutChi2NDF = 10; // Chi2NF cut value for the AliKFparticle K0
+ fLcutCosPoint[0] = 0.; // cos of the pointing angle [min, max]
+ fLcutCosPoint[1] = 0.02; // cos of the pointing angle [min, max]
+ fLcutDCA[0] = 0.; // DCA between the daughter tracks [min, max]
+ fLcutDCA[1] = 0.2; // DCA between the daughter tracks [min, max]
+ fLcutVertexR[0] = 2.0; // radius of the decay point [min, max]
+ fLcutVertexR[1] = 40.0; // radius of the decay point [min, max]
+ fLcutInvMass[0] = 1.11; // invariant mass window
+ fLcutInvMass[1] = 1.12; // invariant mass window
+
}
//____________________________________________________________________
AliESDv0KineCuts::~AliESDv0KineCuts(){
// Destructor
//
- if (fV0) delete fV0;
}
//____________________________________________________________________
AliESDv0KineCuts::AliESDv0KineCuts(const AliESDv0KineCuts &ref):
TObject(ref)
- , fV0(0x0)
, fEvent(0x0)
, fPrimaryVertex(0x0)
+ , fType(0)
+ , fMode(0)
+ , fTPCNcls(1)
+ , fTPCrefit(kTRUE)
+ , fTPCchi2perCls(4.0)
+ , fTPCclsRatio(0.6)
+ , fNoKinks(kTRUE)
+ , fGcutChi2NDF(10)
+ , fGcutInvMass(0.05)
+ , fK0cutChi2NDF(10)
+ , fLcutChi2NDF(10)
{
//
// Copy operator
TObject::Copy(ref);
AliESDv0KineCuts &target = dynamic_cast<AliESDv0KineCuts &>(ref);
- if(fV0)
- target.fV0 = dynamic_cast<AliESDv0 *>(fV0->Clone());
- else
- target.fV0 = NULL;
+
+ // default single track cuts
+ target.fTPCNcls = fTPCNcls;
+ target.fTPCrefit = fTPCrefit;
+ target.fTPCchi2perCls = fTPCchi2perCls;
+ target.fTPCclsRatio = fTPCclsRatio;
+ target.fNoKinks = fNoKinks;
+
+
+ // default gamma cuts values
+ target.fGcutChi2NDF = fGcutChi2NDF;
+ memcpy(target.fGcutCosPoint, fGcutCosPoint, sizeof(Float_t) * 2);
+ memcpy(target.fGcutDCA, fGcutDCA, sizeof(Float_t) * 2);
+ memcpy(target.fGcutVertexR, fGcutVertexR, sizeof(Float_t) * 2);
+ memcpy(target.fGcutPsiPair, fGcutPsiPair, sizeof(Float_t) * 2);
+ target.fGcutInvMass = fGcutInvMass;
+ // default K0 cuts
+ target.fK0cutChi2NDF = fK0cutChi2NDF;
+ memcpy(target.fK0cutCosPoint, fK0cutCosPoint, sizeof(Float_t) * 2);
+ memcpy(target.fK0cutDCA, fK0cutDCA, sizeof(Float_t) * 2);
+ memcpy(target.fK0cutVertexR, fK0cutVertexR, sizeof(Float_t) * 2);
+ memcpy(target.fK0cutInvMass, fK0cutInvMass, sizeof(Float_t) * 2);
+ // Lambda & anti-Lambda cut values
+ target.fLcutChi2NDF = fLcutChi2NDF;
+ memcpy(target.fLcutCosPoint, fLcutCosPoint, sizeof(Float_t) * 2);
+ memcpy(target.fLcutDCA, fLcutDCA, sizeof(Float_t) * 2);
+ memcpy(target.fLcutVertexR, fLcutVertexR, sizeof(Float_t) * 2);
+ memcpy(target.fLcutInvMass, fLcutInvMass, sizeof(Float_t) * 2);
}
//____________________________________________________________________
//
// Make a preselection (exclusive) of the V0 cadidates based on
// Armenteros plot
+ // the armenteros cut values are currently fixed and user is not able to set them via
+ // set funcions. The reason is that these cuts are optimized and furneter changes should
+ // not be necessary. To prove otherwise please study in detail before changing the values
//
Float_t ap[2] = {-1., -1.};
// Gamma cuts
const Double_t cutAlphaG = 0.35;
- const Double_t cutAlphaG2[2] = {0.6, 0.8};
const Double_t cutQTG = 0.05;
+ const Double_t cutAlphaG2[2] = {0.6, 0.8};
const Double_t cutQTG2 = 0.04;
// K0 cuts
const Float_t cutAPL[3] = {0.107, -0.69, 0.5}; // parameters fir curved QT cut
+ if(kPurity == fMode){
// Check for Gamma candidates
- if(qt < cutQTG){
- if( (TMath::Abs(alpha) < cutAlphaG) ) return kGamma;
+ if(qt < cutQTG){
+ if( (TMath::Abs(alpha) < cutAlphaG) ) return kGamma;
+ }
+ // additional region - should help high pT gammas
+ if(qt < cutQTG2){
+ if( (TMath::Abs(alpha) > cutAlphaG2[0]) && (TMath::Abs(alpha) < cutAlphaG2[1]) ) return kGamma;
+ }
}
- // additional region - should help high pT gammas
- if(qt < cutQTG2){
- if( (TMath::Abs(alpha) > cutAlphaG2[0]) && (TMath::Abs(alpha) < cutAlphaG2[1]) ) return kGamma;
+ if(kEffGamma == fMode){
+ if(qt < cutQTG) return kGamma;
}
Float_t iMass = v0->GetEffMass(0, 0);
- // Cut values
- const Double_t cutMass = 0.05; // old [0.05]
- const Double_t cutChi2NDF = 40.; // old [7.]
- const Double_t cutCosPoint[2] = {0., 0.02}; // old [0., 0.03]
- const Double_t cutDCA[2] = {0., 0.25}; // old [0., 0.25]
- const Double_t cutProdVtxR[2] = {8., 90.}; // old [6., 9999]
- const Double_t cutPsiPair[2] = {0., 0.05}; // old [0. 0.05]
- const Double_t cutOAngle[2] = {0, 0.1}; // old [0., 0.1]
-
// cos pointing angle
Double_t cosPoint = v0->GetV0CosineOfPointingAngle();
cosPoint = TMath::ACos(cosPoint);
r2 = TMath::Sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
}
- // Opening angle
- Double_t oAngle = OpenAngle(v0);
-
// psi pair
Double_t psiPair = PsiPair(v0);
// apply the cuts
- if(iMass > cutMass) return kFALSE;
+ if(iMass > fGcutInvMass) return kFALSE;
- if(chi2ndf > cutChi2NDF) return kFALSE;
+ if(chi2ndf > fGcutChi2NDF) return kFALSE;
- if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE;
+ if(cosPoint < fGcutCosPoint[0] || cosPoint > fGcutCosPoint[1]) return kFALSE;
- if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE;
+ if(dca < fGcutDCA[0] || dca > fGcutDCA[1]) return kFALSE;
- if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE;
+ if(r < fGcutVertexR[0] || r > fGcutVertexR[1]) return kFALSE;
- if(psiPair < cutPsiPair[0] || psiPair > cutPsiPair[1]) return kFALSE;
-
- if(oAngle < cutOAngle[0] || oAngle > cutOAngle[1]) return kFALSE;
+ if(psiPair < fGcutPsiPair[0] || psiPair > fGcutPsiPair[1]) return kFALSE;
// all cuts passed
Float_t iMass = v0->GetEffMass(2, 2);
- const Double_t cutMass[2] = {0.486, 0.508}; // ORG [0.485, 0.51]
- const Double_t cutChi2NDF = 40.; // ORG [7.]
- const Double_t cutCosPoint[2] = {0., 0.02}; // ORG [0., 0.03]
- const Double_t cutDCA[2] = {0., 0.2}; // ORG [0., 0.1]
- const Double_t cutProdVtxR[2] = {2.0, 30.}; // ORG [0., 8.1]
-
// cos pointing angle
Double_t cosPoint = v0->GetV0CosineOfPointingAngle();
cosPoint = TMath::ACos(cosPoint);
//
// apply the cuts
//
- if(iMass < cutMass[0] || iMass > cutMass[1]) return kFALSE;
+ if(iMass < fK0cutInvMass[0] || iMass > fK0cutInvMass[1]) return kFALSE;
- if(chi2ndf > cutChi2NDF) return kFALSE;
+ if(chi2ndf > fK0cutChi2NDF) return kFALSE;
- if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE;
+ if(cosPoint < fK0cutCosPoint[0] || cosPoint > fK0cutCosPoint[1]) return kFALSE;
- if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE;
+ if(dca < fK0cutDCA[0] || dca > fK0cutDCA[1]) return kFALSE;
- if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE;
+ if(r < fK0cutVertexR[0] || r > fK0cutVertexR[1]) return kFALSE;
// all cuts passed
pdgV0 = 310;
iMass = (type == 0) ? v0->GetEffMass(2, 4) : v0->GetEffMass(4, 2);
}
- // Cuts
- const Double_t cutMass[2] = {1.11, 1.12}; // ORG [1.11, 1.12]
- const Double_t cutChi2NDF = 40.; // ORG [5.]
- const Double_t cutCosPoint[2] = {0., 0.02}; // ORG [0., 0.03]
- const Double_t cutDCA[2] = {0., 0.2}; // ORG [0., 0.2]
- const Double_t cutProdVtxR[2] = {2., 40.}; // ORG [0., 24.]
-
// cos pointing angle
Double_t cosPoint = v0->GetV0CosineOfPointingAngle();
cosPoint = TMath::ACos(cosPoint);
// apply the cuts
//
- if(iMass < cutMass[0] || iMass > cutMass[1]) return kFALSE;
+ if(iMass < fLcutInvMass[0] || iMass > fLcutInvMass[1]) return kFALSE;
- if(chi2ndf > cutChi2NDF) return kFALSE;
+ if(chi2ndf > fLcutChi2NDF) return kFALSE;
- if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE;
+ if(cosPoint < fLcutCosPoint[0] || cosPoint > fLcutCosPoint[1]) return kFALSE;
- if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE;
+ if(dca < fLcutDCA[0] || dca > fLcutDCA[1]) return kFALSE;
- if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE;
+ if(r < fLcutVertexR[0] || r > fLcutVertexR[1]) return kFALSE;
// all cuts passed
return correct;
}
-//____________________________________________________________________
-void AliESDv0KineCuts::SetEvent(AliESDEvent* const event){
- //
- // direct setter of ESD event
- //
- if(!event){
- AliErrorClass("Invalid input event pointer");
- return;
- }
- fEvent = event;
-}
-//____________________________________________________________________
-void AliESDv0KineCuts::SetEvent(AliVEvent* const event){
- //
- // Set the current working ESD event
- //
- if(!event){
- AliErrorClass("Invalid input event pointer");
- return;
- }
-
- SetEvent(dynamic_cast<AliESDEvent*>(event));
-}
-//________________________________________________________________
-Double_t AliESDv0KineCuts::OpenAngle(AliESDv0 *v0) const {
- //
- // Opening angle between two daughter tracks
- //
- Double_t mn[3] = {0,0,0};
- Double_t mp[3] = {0,0,0};
-
-
- v0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter;
- v0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter;
-
-
- Double_t openAngle = TMath::ACos((mp[0]*mn[0] + mp[1]*mn[1] + mp[2]*mn[2])/(TMath::Sqrt(mp[0]*mp[0] + mp[1]*mp[1] + mp[2]*mp[2])*TMath::Sqrt(mn[0]*mn[0] + mn[1]*mn[1] + mn[2]*mn[2])));
-
- return TMath::Abs(openAngle);
-}
//________________________________________________________________
Double_t AliESDv0KineCuts::PsiPair(AliESDv0* const v0) {
//
return m;
}
+//____________________________________________________________________
+void AliESDv0KineCuts::SetEvent(AliESDEvent* const event){
+ //
+ // direct setter of ESD event
+ //
+ fEvent = event;
+ if(!fEvent){
+ AliErrorClass("Invalid input event pointer");
+ return;
+ }
+
+}
+//____________________________________________________________________
+void AliESDv0KineCuts::SetEvent(AliVEvent* const event){
+ //
+ // direct setter of ESD event
+ //
+ if(event)
+ fEvent = static_cast<AliESDEvent*>(event);
+ if(!fEvent){
+ AliErrorClass("Invalid input event pointer");
+ return;
+ }
+
+}
+//________________________________________________________________
+void AliESDv0KineCuts::SetPrimaryVertex(AliKFVertex* const v){
+ //
+ // set the primary vertex of the event
+ //
+ fPrimaryVertex = v;
+ if(!fPrimaryVertex){
+ AliErrorClass("Failed to initialize the primary vertex");
+ return;
+ }
+}
+//___________________________________________________________________
+void AliESDv0KineCuts::SetMode(Int_t mode, Int_t type){
+ //
+ // this function allows the user to select (prior running the 'ProcessV0' function)
+ // to select different approaches to V0 selection - the 'mode'
+ // - and -
+ // different systems (pp, PbPb) - 'type'
+ //
+ // To see the cut values for different modes please refer to the
+ // function SetCuts()
+ //
+ // Important notice: based on the parameters particular sets of cuts will
+ // be activated for teh V0 selection. If some additional changes to single
+ // cuts are needed please us the SetXXXcut function (see the header file)
+ //
+
+ switch(mode){
+ case kPurity:
+ fMode = kPurity; // used to obtain highest purity possible - the efficiency may be low
+ case kEffGamma:
+ fMode = kEffGamma; // used to obtain highes efficiency possible - the purity may be worse
+ default:
+ AliError("V0 selection mode not recognozed, setting 'kPurity'");
+ fMode = kPurity;
+ }
+
+ switch(type){
+ case kPP:
+ fType = kPP; // cuts optimized for low multiplicity
+ case kPbPb:
+ fType = kPbPb; // cuts optimized for high multiplicity
+ }
+
+ // setup the cut values for selected mode & type
+ SetCuts();
+
+}
+//___________________________________________________________________
+void AliESDv0KineCuts::SetMode(Int_t mode, const char* type){
+ //
+ // overloaded function - please see above
+ //
+
+ Int_t t = -1;
+
+ if(!strcmp("pp", type)) t = kPP;
+ else if(!(strcmp("PbPb", type))) t = kPbPb;
+ else{
+ AliError("data type not recognized, setting 'pp'");
+ t = kPP;
+ }
+
+ SetMode(mode, t);
+
+}
+//___________________________________________________________________
+void AliESDv0KineCuts::SetCuts(){
+ //
+ // this funciton sets the default cut values based on the selected
+ // fMode and fType.
+ // please note that only the cuts that have different values than the default
+ // cuts are updated here
+ //
+
+ // last update: 14/02/2011
+ // as a very preliminary - the only change to default cuts is to apply
+ // less restricting gamma conversion selection in PreselectV0() function
+
+
+
+}