#include <TArrayI.h>\r
#include <TRandom.h>\r
#include <TParticle.h>\r
+#include <TFile.h>\r
\r
#include "AliAnalysisTaskESDfilter.h"\r
#include "AliAnalysisManager.h"\r
#include "AliAnalysisFilter.h"\r
#include "AliESDMuonTrack.h"\r
#include "AliESDVertex.h"\r
+#include "AliCentrality.h"\r
#include "AliESDv0.h"\r
#include "AliESDkink.h"\r
#include "AliESDcascade.h"\r
#include "AliESDCaloCells.h"\r
#include "AliMultiplicity.h"\r
#include "AliLog.h"\r
-\r
+#include "AliTrackerBase.h"\r
+#include "AliESDtrackCuts.h"\r
+#include "AliPID.h"\r
+ \r
ClassImp(AliAnalysisTaskESDfilter)\r
\r
////////////////////////////////////////////////////////////////////////\r
fKinkFilter(0x0),\r
fV0Filter(0x0),\r
fCascadeFilter(0x0),\r
+ fTPCOnlyFilterMask(0),\r
fHighPthreshold(0),\r
fPtshape(0x0),\r
- fEnableFillAOD(kTRUE)\r
+ fEnableFillAOD(kTRUE),\r
+ fTimeZeroType(AliESDpid::kTOF_T0)\r
{\r
// Default constructor\r
}\r
fKinkFilter(0x0),\r
fV0Filter(0x0),\r
fCascadeFilter(0x0),\r
+ fTPCOnlyFilterMask(0),\r
fHighPthreshold(0),\r
fPtshape(0x0),\r
- fEnableFillAOD(kTRUE)\r
+ fEnableFillAOD(kTRUE),\r
+ fTimeZeroType(AliESDpid::kTOF_T0)\r
{\r
// Constructor\r
}\r
AliESD* old = esd->GetAliESDOld();\r
\r
// Fetch Stack for debuggging if available \r
- AliStack *pStack = 0;\r
AliMCEventHandler *mcH = 0;\r
if(MCEvent()){\r
- pStack = MCEvent()->Stack();\r
mcH = (AliMCEventHandler*) ((AliAnalysisManager::GetAnalysisManager())->GetMCtruthEventHandler()); \r
}\r
// set arrays and pointers\r
\r
header->SetRunNumber(esd->GetRunNumber());\r
header->SetOfflineTrigger(fInputHandler->IsEventSelected()); // propagate the decision of the physics selection\r
+ TTree* tree = fInputHandler->GetTree();\r
+ if (tree) {\r
+ TFile* file = tree->GetCurrentFile();\r
+ if (file) header->SetESDFileName(file->GetName());\r
+ }\r
+ \r
if (old) {\r
header->SetBunchCrossNumber(0);\r
header->SetOrbitNumber(0);\r
header->SetPeriodNumber(0);\r
header->SetEventType(0);\r
header->SetMuonMagFieldScale(-999.);\r
- header->SetCentrality(-999.); \r
+ header->SetCentrality(0); \r
} else {\r
header->SetBunchCrossNumber(esd->GetBunchCrossNumber());\r
header->SetOrbitNumber(esd->GetOrbitNumber());\r
header->SetPeriodNumber(esd->GetPeriodNumber());\r
header->SetEventType(esd->GetEventType());\r
- header->SetCentrality(-999.); // FIXME\r
+\r
+ header->SetEventNumberESDFile(esd->GetHeader()->GetEventNumberInFile());\r
+ if(esd->GetCentrality()){\r
+ header->SetCentrality(new AliCentrality(*(esd->GetCentrality())));\r
+ }\r
+ else{\r
+ header->SetCentrality(0);\r
+ }\r
}\r
+ \r
// Trigger\r
header->SetFiredTriggerClasses(esd->GetFiredTriggerClasses());\r
header->SetTriggerMask(esd->GetTriggerMask()); \r
header->SetTriggerCluster(esd->GetTriggerCluster());\r
- \r
+ header->SetL0TriggerInputs(esd->GetHeader()->GetL0TriggerInputs()); \r
+ header->SetL1TriggerInputs(esd->GetHeader()->GetL1TriggerInputs()); \r
+ header->SetL2TriggerInputs(esd->GetHeader()->GetL2TriggerInputs()); \r
\r
header->SetMagneticField(esd->GetMagneticField());\r
header->SetMuonMagFieldScale(esd->GetCurrentDip()/6000.);\r
//\r
//\r
Int_t nV0s = esd->GetNumberOfV0s();\r
- Int_t nCascades = esd->GetNumberOfCascades();\r
- Int_t nKinks = esd->GetNumberOfKinks();\r
+ Int_t nCascades = 0; // esd->GetNumberOfCascades();\r
+ Int_t nKinks = 0; // esd->GetNumberOfKinks();\r
Int_t nVertices = nV0s + nCascades /*V0 wihtin cascade already counted*/+ nKinks + 1 /* = prim. vtx*/;\r
Int_t nPileSPDVertices=1+esd->GetNumberOfPileupVerticesSPD(); // also SPD main vertex\r
Int_t nPileTrkVertices=esd->GetNumberOfPileupVerticesTracks();\r
\r
AliAODTrack *aodTrack = 0x0;\r
AliAODPid *detpid = 0x0;\r
- Double_t timezero = 0; //TO BE FIXED\r
+ // Double_t timezero = 0; //not needed anymore \r
AliAODVertex *vV0FromCascade = 0x0;\r
AliAODv0 *aodV0 = 0x0;\r
AliAODcascade *aodCascade = 0x0;\r
TRefArray *aodV0Refs = NULL;\r
if (nV0s > 0) aodV0Refs = new TRefArray(nV0s);\r
\r
- \r
-\r
-\r
-\r
// Array to take into account the tracks already added to the AOD\r
Bool_t * usedTrack = NULL;\r
if (nTracks>0) {\r
\r
// Create vertices starting from the most complex objects\r
Double_t chi2 = 0.;\r
+\r
+\r
+ //setting best TOF PID\r
+ AliESDInputHandler* handler = dynamic_cast<AliESDInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());\r
+ \r
+ AliESDpid *esdPid = 0;\r
+ if (handler) esdPid = handler->GetESDpid();\r
+\r
+ Bool_t isPidOwner = kFALSE;\r
+ if(!esdPid){ //in case of no Tender attached \r
+ esdPid = new AliESDpid;\r
+ isPidOwner = kTRUE;\r
+ }\r
+ \r
+ if(!esd->GetTOFHeader()){ //protection in case the pass2 LHC10b,c,d have been processed without tender. \r
+ Float_t *t0spread= new Float_t[10];\r
+ Float_t intrinsicTOFres=100; //ps ok for LHC10b,c,d pass2!! \r
+ for (Int_t i=0; i<10; i++) t0spread[i] = (TMath::Sqrt(esd->GetSigma2DiamondZ()))/0.03; //0.03 to convert from cm to ps\r
+ esdPid->GetTOFResponse().SetT0resolution(t0spread);\r
+ esdPid->GetTOFResponse().SetTimeResolution(intrinsicTOFres);\r
+ \r
+ esdPid->SetTOFResponse(esd, (AliESDpid::EStartTimeType_t)fTimeZeroType);\r
\r
+ delete[] t0spread;\r
+ t0spread=0x0;\r
+ }\r
+ \r
+ if(esd->GetTOFHeader() && isPidOwner) esdPid->SetTOFResponse(esd, (AliESDpid::EStartTimeType_t)fTimeZeroType); //in case of AOD production strating form LHC10e without Tender. \r
+\r
+\r
// Cascades (Modified by A.Maire - February 2009)\r
for (Int_t nCascade = 0; nCascade < nCascades; ++nCascade) {\r
\r
if (esdCascadeBach->GetSign() > 0) nPosTracks++;\r
aodTrack->ConvertAliPIDtoAODPID();\r
aodTrack->SetFlags(esdCascadeBach->GetStatus());\r
- SetAODPID(esdCascadeBach,aodTrack,detpid,timezero,esd->GetMagneticField());\r
+ SetAODPID(esdCascadeBach,aodTrack,detpid,esd->GetMagneticField(), esdPid);\r
}\r
else {\r
aodTrack = dynamic_cast<AliAODTrack*>( aodTrackRefs->At(idxBachFromCascade) );\r
if (esdCascadePos->GetSign() > 0) nPosTracks++;\r
aodTrack->ConvertAliPIDtoAODPID();\r
aodTrack->SetFlags(esdCascadePos->GetStatus());\r
- SetAODPID(esdCascadePos,aodTrack,detpid,timezero,esd->GetMagneticField());\r
+ SetAODPID(esdCascadePos,aodTrack,detpid,esd->GetMagneticField(), esdPid);\r
}\r
else {\r
aodTrack = dynamic_cast<AliAODTrack*>(aodTrackRefs->At(idxPosFromV0Dghter));\r
if (esdCascadeNeg->GetSign() > 0) nPosTracks++;\r
aodTrack->ConvertAliPIDtoAODPID();\r
aodTrack->SetFlags(esdCascadeNeg->GetStatus());\r
- SetAODPID(esdCascadeNeg,aodTrack,detpid,timezero,esd->GetMagneticField());\r
+ SetAODPID(esdCascadeNeg,aodTrack,detpid,esd->GetMagneticField(),esdPid);\r
}\r
else {\r
aodTrack = dynamic_cast<AliAODTrack*>(aodTrackRefs->At(idxNegFromV0Dghter));\r
if (esdV0Pos->GetSign() > 0) nPosTracks++;\r
aodTrack->ConvertAliPIDtoAODPID();\r
aodTrack->SetFlags(esdV0Pos->GetStatus());\r
- SetAODPID(esdV0Pos,aodTrack,detpid,timezero,esd->GetMagneticField());\r
+ SetAODPID(esdV0Pos,aodTrack,detpid,esd->GetMagneticField(),esdPid);\r
}\r
else {\r
aodTrack = dynamic_cast<AliAODTrack*>(aodTrackRefs->At(posFromV0));\r
if (esdV0Neg->GetSign() > 0) nPosTracks++;\r
aodTrack->ConvertAliPIDtoAODPID();\r
aodTrack->SetFlags(esdV0Neg->GetStatus());\r
- SetAODPID(esdV0Neg,aodTrack,detpid,timezero,esd->GetMagneticField());\r
+ SetAODPID(esdV0Neg,aodTrack,detpid,esd->GetMagneticField(),esdPid);\r
}\r
else {\r
aodTrack = dynamic_cast<AliAODTrack*>(aodTrackRefs->At(negFromV0));\r
mother->ConvertAliPIDtoAODPID();\r
primary->AddDaughter(mother);\r
mother->ConvertAliPIDtoAODPID();\r
- SetAODPID(esdTrackM,mother,detpid,timezero,esd->GetMagneticField());\r
+ SetAODPID(esdTrackM,mother,detpid,esd->GetMagneticField(),esdPid);\r
}\r
else {\r
// cerr << "Error: event " << esd->GetEventNumberInFile() << " kink " << TMath::Abs(ikink)-1\r
daughter->ConvertAliPIDtoAODPID();\r
vkink->AddDaughter(daughter);\r
daughter->ConvertAliPIDtoAODPID();\r
- SetAODPID(esdTrackD,daughter,detpid,timezero,esd->GetMagneticField());\r
+ SetAODPID(esdTrackD,daughter,detpid,esd->GetMagneticField(),esdPid);\r
}\r
else {\r
// cerr << "Error: event " << esd->GetEventNumberInFile() << " kink " << TMath::Abs(ikink)-1\r
for (Int_t nTrack = 0; nTrack < nTracks; ++nTrack) {\r
\r
\r
- if (usedTrack[nTrack]) continue;\r
-\r
+ if (usedTrack[nTrack]){\r
+ continue;\r
+ }\r
AliESDtrack *esdTrack = esd->GetTrack(nTrack);\r
UInt_t selectInfo = 0;\r
//\r
if (esdTrack->GetSign() > 0) nPosTracks++;\r
aodTrack->SetFlags(esdTrack->GetStatus());\r
aodTrack->ConvertAliPIDtoAODPID();\r
- SetAODPID(esdTrack,aodTrack,detpid,timezero,esd->GetMagneticField());\r
+ SetAODPID(esdTrack,aodTrack,detpid,esd->GetMagneticField(),esdPid);\r
} // end of loop on tracks\r
\r
// Update number of AOD tracks in header at the end of track loop (M.G.)\r
header->SetRefMultiplicityNeg(jTracks - nPosTracks);\r
if (fDebug > 0) \r
printf(" NAODTRACKS=%d NPOS=%d NNEG=%d\n", jTracks, nPosTracks, jTracks - nPosTracks);\r
+\r
+\r
// Do not shrink the array of tracks - other filters may add to it (M.G)\r
// tracks.Expand(jTracks); // remove 'empty slots' due to unwritten tracks\r
- \r
+ \r
+ if(fTPCOnlyFilterMask){\r
+ // Loop over the tracks and extract and mask out all aod tracks that pass the selections for AODt racks\r
+ for(int it = 0;it < jTracks;++it){\r
+ AliAODTrack *tr = (AliAODTrack*)tracks.At(it);\r
+ if(!tr)continue;\r
+ UInt_t map = tr->GetFilterMap();\r
+ if(map&fTPCOnlyFilterMask){\r
+ // we only reset the track select ionfo, no deletion...\r
+ tr->SetFilterMap(map&~fTPCOnlyFilterMask);\r
+ }\r
+ }\r
+ // Loop over the ESD trcks and pick out the tracks passing TPC only cuts\r
+ \r
+ \r
+ const AliESDVertex *vtxSPD = esd->GetPrimaryVertexSPD();\r
+ for (Int_t nTrack = 0; nTrack < nTracks; ++nTrack) {\r
+ AliESDtrack* esdTrack = esd->GetTrack(nTrack); //carefull do not modify it othwise need to work with a copy \r
+ \r
+ UInt_t selectInfo = 0;\r
+ //\r
+ // Track selection\r
+ if (fTrackFilter) {\r
+ selectInfo = fTrackFilter->IsSelected(esdTrack);\r
+ }\r
+ selectInfo &= fTPCOnlyFilterMask;\r
+ if (!selectInfo)continue;\r
+\r
+ // create a tpc only tracl\r
+ AliESDtrack *track = AliESDtrackCuts::GetTPCOnlyTrack(esd,esdTrack->GetID());\r
+ if(!track) continue;\r
+\r
+\r
+\r
+ if(track->Pt()>0.){\r
+ // only constrain tracks above threshold\r
+ AliExternalTrackParam exParam;\r
+ // take the B-feild from the ESD, no 3D fieldMap available at this point\r
+ Bool_t relate = false;\r
+ relate = track->RelateToVertex(vtxSPD,esd->GetMagneticField(),kVeryBig,&exParam);\r
+ if(!relate){\r
+ delete track;\r
+ continue;\r
+ }\r
+ track->Set(exParam.GetX(),exParam.GetAlpha(),exParam.GetParameter(),exParam.GetCovariance());\r
+ }\r
+\r
+ track->GetPxPyPz(p);\r
+ track->GetXYZ(pos);\r
+ track->GetCovarianceXYZPxPyPz(covTr);\r
+ track->GetESDpid(pid);\r
+ if(mcH)mcH->SelectParticle(esdTrack->GetLabel());\r
+ aodTrack = new(tracks[jTracks++]) AliAODTrack((track->GetID()+1)*-1,\r
+ track->GetLabel(),\r
+ p,\r
+ kTRUE,\r
+ pos,\r
+ kFALSE,\r
+ covTr, \r
+ (Short_t)track->GetSign(),\r
+ track->GetITSClusterMap(), \r
+ pid,\r
+ primary,\r
+ kTRUE, // check if this is right\r
+ vtx->UsesTrack(track->GetID()),\r
+ AliAODTrack::kPrimary, \r
+ selectInfo);\r
+ aodTrack->SetTPCClusterMap(track->GetTPCClusterMap());\r
+ aodTrack->SetTPCSharedMap (track->GetTPCSharedMap());\r
+ aodTrack->SetChi2perNDF(Chi2perNDF(track));\r
+ aodTrack->SetFlags(track->GetStatus());\r
+ delete track;\r
+ } // end of loop on tracks\r
+ \r
+ }//end if(fTPCOnlyFilterMask\r
+ \r
// Access to the AOD container of PMD clusters\r
TClonesArray &pmdClusters = *(AODEvent()->GetPmdClusters());\r
Int_t jPmdClusters=0;\r
delete aodV0Refs;\r
delete aodV0VtxRefs;\r
delete aodTrackRefs;\r
-\r
+ if (isPidOwner) delete esdPid;\r
return;\r
}\r
\r
\r
-void AliAnalysisTaskESDfilter::SetAODPID(AliESDtrack *esdtrack, AliAODTrack *aodtrack, AliAODPid *detpid, Double_t timezero, Double_t bfield)\r
+void AliAnalysisTaskESDfilter::SetAODPID(AliESDtrack *esdtrack, AliAODTrack *aodtrack, AliAODPid *detpid, Double_t bfield, AliESDpid *esdpid)\r
{\r
//\r
// Setter for the raw PID detector signals\r
if (pidSave) {\r
if(!aodtrack->GetDetPid()){// prevent memory leak when calling SetAODPID twice for the same track\r
detpid = new AliAODPid();\r
- SetDetectorRawSignals(detpid,esdtrack,timezero, bfield);\r
+ SetDetectorRawSignals(detpid,esdtrack, bfield, esdpid);\r
aodtrack->SetDetPID(detpid);\r
}\r
}\r
}\r
\r
-void AliAnalysisTaskESDfilter::SetDetectorRawSignals(AliAODPid *aodpid, AliESDtrack *track, Double_t timezero, Double_t bfield)\r
+void AliAnalysisTaskESDfilter::SetDetectorRawSignals(AliAODPid *aodpid, AliESDtrack *track, Double_t bfield, AliESDpid *esdpid)\r
{\r
//\r
//assignment of the detector signals (AliXXXesdPID inspired)\r
\r
aodpid->SetITSsignal(track->GetITSsignal());\r
aodpid->SetTPCsignal(track->GetTPCsignal());\r
+ aodpid->SetTPCsignalN(track->GetTPCsignalN());\r
\r
//n TRD planes = 6\r
Int_t nslices = track->GetNumberOfTRDslices()*6;\r
}\r
\r
aodpid->SetTRDsignal(track->GetNumberOfTRDslices()*6,trdslices);\r
+\r
+ //TOF PID \r
Double_t times[AliAODPid::kSPECIES]; track->GetIntegratedTimes(times);\r
aodpid->SetIntegratedTimes(times);\r
+ Float_t tzeroTrack = esdpid->GetTOFResponse().GetStartTime(track->P());\r
+ aodpid->SetTOFsignal(track->GetTOFsignal()-tzeroTrack);\r
\r
- aodpid->SetTOFsignal(track->GetTOFsignal()-timezero); // to be fixed\r
+ Double_t tofRes[5];\r
+ for (Int_t iMass=0; iMass<5; iMass++){\r
+ tofRes[iMass]=(Double_t)esdpid->GetTOFResponse().GetExpectedSigma(track->P(), times[iMass], AliPID::ParticleMass(iMass));\r
+ }\r
+ aodpid->SetTOFpidResolution(tofRes);\r
+ \r
aodpid->SetHMPIDsignal(track->GetHMPIDsignal());\r
\r
//Extrapolate track to EMCAL surface for AOD-level track-cluster matching\r