/************************************************************************** * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * * * Author: The ALICE Off-line Project. * * Contributors are mentioned in the code where appropriate. * * * * Permission to use, copy, modify and distribute this software and its * * documentation strictly for non-commercial purposes is hereby granted * * without fee, provided that the above copyright notice appears in all * * copies and that both the copyright notice and this permission notice * * appear in the supporting documentation. The authors make no claims * * about the suitability of this software for any purpose. It is * * provided "as is" without express or implied warranty. * **************************************************************************/ //----------------------------------------------------------------- // Implementation of the ESD track class // ESD = Event Summary Data // This is the class to deal with during the phisics analysis of data // Origin: Iouri Belikov, CERN // e-mail: Jouri.Belikov@cern.ch //----------------------------------------------------------------- #include #include #include "AliESDVertex.h" #include "AliESDtrack.h" #include "AliKalmanTrack.h" #include "AliLog.h" #include "AliTrackPointArray.h" ClassImp(AliESDtrack) void SetPIDValues(Float_t * dest, const Double_t * src, Int_t n) { // This function copies "n" PID weights from "scr" to "dest" // and normalizes their sum to 1 thus producing conditional probabilities. // The negative weights are set to 0. // In case all the weights are non-positive they are replaced by // uniform probabilities if (n<=0) return; Float_t uniform = 1./(Float_t)n; Float_t sum = 0; for (Int_t i=0; i=0) { sum+=src[i]; dest[i] = src[i]; } else { dest[i] = 0; } if(sum>0) for (Int_t i=0; iPhi()*180./TMath::Pi(); if (alpha<0) alpha+= 360.; if (alpha>360) alpha -= 360.; Int_t sector = (Int_t)(alpha/20.); alpha = 10. + 20.*sector; alpha /= 180; alpha *= TMath::Pi(); // Covariance matrix: no errors, the parameters are exact for (i=0; i<15; i++) covar[i]=0.; // Get the vertex of origin and the momentum TVector3 ver(part->Vx(),part->Vy(),part->Vz()); TVector3 mom(part->Px(),part->Py(),part->Pz()); // Rotate to the local coordinate system (TPC sector) ver.RotateZ(-alpha); mom.RotateZ(-alpha); // X of the referense plane xref = ver.X(); Int_t pdgCode = part->GetPdgCode(); Double_t charge = TDatabasePDG::Instance()->GetParticle(pdgCode)->Charge(); param[0] = ver.Y(); param[1] = ver.Z(); param[2] = TMath::Sin(mom.Phi()); param[3] = mom.Pz()/mom.Pt(); param[4] = TMath::Sign(1/mom.Pt(),charge); // Set AliExternalTrackParam Set(xref, alpha, param, covar); // Set the PID Int_t indexPID = 99; switch (TMath::Abs(pdgCode)) { case 11: // electron indexPID = 0; break; case 13: // muon indexPID = 1; break; case 211: // pion indexPID = 2; break; case 321: // kaon indexPID = 3; break; case 2212: // proton indexPID = 4; break; default: break; } // If the particle is not e,mu,pi,K or p the PID probabilities are set to 0 if (indexPID < AliPID::kSPECIES) { fR[indexPID]=1.; fITSr[indexPID]=1.; fTPCr[indexPID]=1.; fTRDr[indexPID]=1.; fTOFr[indexPID]=1.; fHMPIDr[indexPID]=1.; } // AliESD track label SetLabel(part->GetUniqueID()); } //_______________________________________________________________________ AliESDtrack::~AliESDtrack(){ // // This is destructor according Coding Conventrions // //printf("Delete track\n"); delete fIp; delete fOp; delete fCp; delete fFriendTrack; } void AliESDtrack::AddCalibObject(TObject * object){ // // add calib object to the list // if (!fFriendTrack) fFriendTrack = new AliESDfriendTrack; fFriendTrack->AddCalibObject(object); } TObject * AliESDtrack::GetCalibObject(Int_t index){ // // return calib objct at given position // if (!fFriendTrack) return 0; return fFriendTrack->GetCalibObject(index); } //_______________________________________________________________________ void AliESDtrack::MakeMiniESDtrack(){ // Resets everything except // fFlags: Reconstruction status flags // fLabel: Track label // fID: Unique ID of the track // fD: Impact parameter in XY-plane // fZ: Impact parameter in Z // fR[AliPID::kSPECIES]: combined "detector response probability" // Running track parameters in the base class (AliExternalTrackParam) fTrackLength = 0; for (Int_t i=0;imax) {k=i; max=fR[i];} } if (k==0) { // dE/dx "crossing points" in the TPC Double_t p=GetP(); if ((p>0.38)&&(p<0.48)) if (fR[0]0.75)&&(p<0.85)) if (fR[0]GetLabel(); if (t->IsStartedTimeIntegral()) { SetStatus(kTIME); Double_t times[10];t->GetIntegratedTimes(times); SetIntegratedTimes(times); SetIntegratedLength(t->GetIntegratedLength()); } Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance()); switch (flags) { case kITSin: case kITSout: case kITSrefit: fITSncls=t->GetNumberOfClusters(); index=fFriendTrack->GetITSindices(); for (Int_t i=0;iGetClusterIndex(i); if (i> 28; SETBIT(fITSClusterMap,l); } } fITSchi2=t->GetChi2(); fITSsignal=t->GetPIDsignal(); fITSLabel = t->GetLabel(); break; case kTPCin: case kTPCrefit: fTPCLabel = t->GetLabel(); if (!fIp) fIp=new AliExternalTrackParam(*t); else fIp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance()); case kTPCout: index=fFriendTrack->GetTPCindices(); if (flags & kTPCout){ if (!fOp) fOp=new AliExternalTrackParam(*t); else fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance()); } fTPCncls=t->GetNumberOfClusters(); fTPCchi2=t->GetChi2(); {//prevrow must be declared in separate namespace, otherwise compiler cries: //"jump to case label crosses initialization of `Int_t prevrow'" Int_t prevrow = -1; // for (Int_t i=0;iGetClusterIndex(i); Int_t idx = index[i]; if (idx<0) continue; // Piotr's Cluster Map for HBT // ### please change accordingly if cluster array is changing // to "New TPC Tracking" style (with gaps in array) Int_t sect = (idx&0xff000000)>>24; Int_t row = (idx&0x00ff0000)>>16; if (sect > 18) row +=63; //if it is outer sector, add number of inner sectors fTPCClusterMap.SetBitNumber(row,kTRUE); //Fill the gap between previous row and this row with 0 bits //In case ### pleas change it as well - just set bit 0 in case there //is no associated clusters for current "i" if (prevrow < 0) { prevrow = row;//if previous bit was not assigned yet == this is the first one } else { //we don't know the order (inner to outer or reverse) //just to be save in case it is going to change Int_t n = 0, m = 0; if (prevrow < row) { n = prevrow; m = row; } else { n = row; m = prevrow; } for (Int_t j = n+1; j < m; j++) { fTPCClusterMap.SetBitNumber(j,kFALSE); } prevrow = row; } // End Of Piotr's Cluster Map for HBT } } fTPCsignal=t->GetPIDsignal(); break; case kTRDout: case kTRDin: case kTRDrefit: index=fFriendTrack->GetTRDindices(); fTRDLabel = t->GetLabel(); fTRDncls=t->GetNumberOfClusters(); fTRDchi2=t->GetChi2(); for (Int_t i=0;iGetClusterIndex(i); fTRDsignal=t->GetPIDsignal(); break; case kTRDbackup: if (!fOp) fOp=new AliExternalTrackParam(*t); else fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance()); fTRDncls0 = t->GetNumberOfClusters(); break; case kTOFin: break; case kTOFout: break; case kTRDStop: break; default: AliError("Wrong flag !"); return kFALSE; } return rc; } //_______________________________________________________________________ void AliESDtrack::GetExternalParameters(Double_t &x, Double_t p[5]) const { //--------------------------------------------------------------------- // This function returns external representation of the track parameters //--------------------------------------------------------------------- x=GetX(); for (Int_t i=0; i<5; i++) p[i]=GetParameter()[i]; } //_______________________________________________________________________ void AliESDtrack::GetExternalCovariance(Double_t cov[15]) const { //--------------------------------------------------------------------- // This function returns external representation of the cov. matrix //--------------------------------------------------------------------- for (Int_t i=0; i<15; i++) cov[i]=AliExternalTrackParam::GetCovariance()[i]; } //_______________________________________________________________________ Bool_t AliESDtrack::GetConstrainedExternalParameters (Double_t &alpha, Double_t &x, Double_t p[5]) const { //--------------------------------------------------------------------- // This function returns the constrained external track parameters //--------------------------------------------------------------------- if (!fCp) return kFALSE; alpha=fCp->GetAlpha(); x=fCp->GetX(); for (Int_t i=0; i<5; i++) p[i]=fCp->GetParameter()[i]; return kTRUE; } //_______________________________________________________________________ Bool_t AliESDtrack::GetConstrainedExternalCovariance(Double_t c[15]) const { //--------------------------------------------------------------------- // This function returns the constrained external cov. matrix //--------------------------------------------------------------------- if (!fCp) return kFALSE; for (Int_t i=0; i<15; i++) c[i]=fCp->GetCovariance()[i]; return kTRUE; } Bool_t AliESDtrack::GetInnerExternalParameters (Double_t &alpha, Double_t &x, Double_t p[5]) const { //--------------------------------------------------------------------- // This function returns external representation of the track parameters // at the inner layer of TPC //--------------------------------------------------------------------- if (!fIp) return kFALSE; alpha=fIp->GetAlpha(); x=fIp->GetX(); for (Int_t i=0; i<5; i++) p[i]=fIp->GetParameter()[i]; return kTRUE; } Bool_t AliESDtrack::GetInnerExternalCovariance(Double_t cov[15]) const { //--------------------------------------------------------------------- // This function returns external representation of the cov. matrix // at the inner layer of TPC //--------------------------------------------------------------------- if (!fIp) return kFALSE; for (Int_t i=0; i<15; i++) cov[i]=fIp->GetCovariance()[i]; return kTRUE; } Bool_t AliESDtrack::GetOuterExternalParameters (Double_t &alpha, Double_t &x, Double_t p[5]) const { //--------------------------------------------------------------------- // This function returns external representation of the track parameters // at the inner layer of TRD //--------------------------------------------------------------------- if (!fOp) return kFALSE; alpha=fOp->GetAlpha(); x=fOp->GetX(); for (Int_t i=0; i<5; i++) p[i]=fOp->GetParameter()[i]; return kTRUE; } Bool_t AliESDtrack::GetOuterExternalCovariance(Double_t cov[15]) const { //--------------------------------------------------------------------- // This function returns external representation of the cov. matrix // at the inner layer of TRD //--------------------------------------------------------------------- if (!fOp) return kFALSE; for (Int_t i=0; i<15; i++) cov[i]=fOp->GetCovariance()[i]; return kTRUE; } Int_t AliESDtrack::GetNcls(Int_t idet) const { // Get number of clusters by subdetector index // Int_t ncls = 0; switch(idet){ case 0: ncls = fITSncls; break; case 1: ncls = fTPCncls; break; case 2: ncls = fTRDncls; break; case 3: if (fTOFindex != 0) ncls = 1; break; default: break; } return ncls; } Int_t AliESDtrack::GetClusters(Int_t idet, Int_t *idx) const { // Get cluster index array by subdetector index // Int_t ncls = 0; switch(idet){ case 0: ncls = GetITSclusters(idx); break; case 1: ncls = GetTPCclusters(idx); break; case 2: ncls = GetTRDclusters(idx); break; case 3: if (fTOFindex != 0) { idx[0] = GetTOFcluster(); ncls = 1; } break; default: break; } return ncls; } //_______________________________________________________________________ void AliESDtrack::GetIntegratedTimes(Double_t *times) const { // Returns the array with integrated times for each particle hypothesis for (Int_t i=0; iGetITSindices(); for (Int_t i=0; iGetTPCindices(); for (Int_t i=0; iGetTPCindices(); for (Int_t i=row0;i<=row1;i++){ Int_t idx = index[i]; if (idx!=-1) good++; // track outside of dead zone if (idx>0) found++; } Float_t density=0.5; if (good>(row1-row0)*0.5) density = Float_t(found)/Float_t(good); return density; } //_______________________________________________________________________ void AliESDtrack::SetTPCpid(const Double_t *p) { // Sets values for the probability of each particle type (in TPC) SetPIDValues(fTPCr,p,AliPID::kSPECIES); SetStatus(AliESDtrack::kTPCpid); } //_______________________________________________________________________ void AliESDtrack::GetTPCpid(Double_t *p) const { // Gets the probability of each particle type (in TPC) for (Int_t i=0; iGetTRDindices(); for (Int_t i=0; iGetXv()*cs + vtx->GetYv()*sn; Double_t yv=-vtx->GetXv()*sn + vtx->GetYv()*cs, zv=vtx->GetZv(); x-=xv; y-=yv; //Estimate the impact parameter neglecting the track curvature Double_t d=TMath::Abs(x*snp - y*TMath::Sqrt(1.- snp*snp)); if (d > maxd) return kFALSE; //Propagate to the DCA Double_t crv=kB2C*b*GetParameter()[4]; if (TMath::Abs(b) < kAlmost0Field) crv=0.; Double_t tgfv=-(crv*x - snp)/(crv*y + TMath::Sqrt(1.-snp*snp)); sn=tgfv/TMath::Sqrt(1.+ tgfv*tgfv); if (TMath::Abs(tgfv)>0.) cs = sn/tgfv; else cs=1.; x = xv*cs + yv*sn; yv=-xv*sn + yv*cs; xv=x; if (!Propagate(alpha+TMath::ASin(sn),xv,b)) return kFALSE; fD = GetParameter()[0] - yv; fZ = GetParameter()[1] - zv; Double_t cov[6]; vtx->GetCovMatrix(cov); //***** Improvements by A.Dainese alpha=GetAlpha(); sn=TMath::Sin(alpha); cs=TMath::Cos(alpha); Double_t s2ylocvtx = cov[0]*sn*sn + cov[2]*cs*cs - 2.*cov[1]*cs*sn; fCdd = GetCovariance()[0] + s2ylocvtx; // neglecting correlations fCdz = GetCovariance()[1]; // between (x,y) and z fCzz = GetCovariance()[2] + cov[5]; // in vertex's covariance matrix //***** {//Try to constrain Double_t p[2]={yv,zv}, c[3]={cov[2],0.,cov[5]}; Double_t chi2=GetPredictedChi2(p,c); if (chi2>77.) return kFALSE; AliExternalTrackParam tmp(*this); if (!tmp.Update(p,c)) return kFALSE; fCchi2=chi2; if (!fCp) fCp=new AliExternalTrackParam(); new (fCp) AliExternalTrackParam(tmp); } return kTRUE; } //_______________________________________________________________________ void AliESDtrack::Print(Option_t *) const { // Prints info on the track printf("ESD track info\n") ; Double_t p[AliPID::kSPECIESN] ; Int_t index = 0 ; if( IsOn(kITSpid) ){ printf("From ITS: ") ; GetITSpid(p) ; for(index = 0 ; index < AliPID::kSPECIES; index++) printf("%f, ", p[index]) ; printf("\n signal = %f\n", GetITSsignal()) ; } if( IsOn(kTPCpid) ){ printf("From TPC: ") ; GetTPCpid(p) ; for(index = 0 ; index < AliPID::kSPECIES; index++) printf("%f, ", p[index]) ; printf("\n signal = %f\n", GetTPCsignal()) ; } if( IsOn(kTRDpid) ){ printf("From TRD: ") ; GetTRDpid(p) ; for(index = 0 ; index < AliPID::kSPECIES; index++) printf("%f, ", p[index]) ; printf("\n signal = %f\n", GetTRDsignal()) ; } if( IsOn(kTOFpid) ){ printf("From TOF: ") ; GetTOFpid(p) ; for(index = 0 ; index < AliPID::kSPECIES; index++) printf("%f, ", p[index]) ; printf("\n signal = %f\n", GetTOFsignal()) ; } if( IsOn(kHMPIDpid) ){ printf("From HMPID: ") ; GetHMPIDpid(p) ; for(index = 0 ; index < AliPID::kSPECIES; index++) printf("%f, ", p[index]) ; printf("\n signal = %f\n", GetHMPIDsignal()) ; } } Bool_t AliESDtrack::PropagateTo(Double_t xToGo, Double_t b, Double_t mass, Double_t maxStep, Bool_t rotateTo, Double_t maxSnp){ //---------------------------------------------------------------- // // MI's function // // Propagates this track to the plane X=xk (cm) // in the magnetic field "b" (kG), // the correction for the material is included // // mass - mass used in propagation - used for energy loss correction // maxStep - maximal step for propagation //---------------------------------------------------------------- const Double_t kEpsilon = 0.00001; Double_t xpos = GetX(); Double_t dir = (xpos kEpsilon){ Double_t step = dir*TMath::Min(TMath::Abs(xToGo-xpos), maxStep); Double_t x = xpos+step; Double_t xyz0[3],xyz1[3],param[7]; GetXYZ(xyz0); //starting global position if (!GetXYZAt(x,b,xyz1)) return kFALSE; // no prolongation xyz1[2]+=kEpsilon; // waiting for bug correction in geo AliKalmanTrack::MeanMaterialBudget(xyz0,xyz1,param); if (TMath::Abs(GetSnpAt(x,b)) >= maxSnp) return kFALSE; if (!AliExternalTrackParam::PropagateTo(x,b)) return kFALSE; Double_t rho=param[0],x0=param[1],distance=param[4]; Double_t d=distance*rho/x0; if (!CorrectForMaterial(d,x0,mass)) return kFALSE; if (rotateTo){ if (TMath::Abs(GetSnp()) >= maxSnp) return kFALSE; GetXYZ(xyz0); // global position Double_t alphan = TMath::ATan2(xyz0[1], xyz0[0]); // Double_t ca=TMath::Cos(alphan-GetAlpha()), sa=TMath::Sin(alphan-GetAlpha()); Double_t sf=GetSnp(), cf=TMath::Sqrt(1.- sf*sf); Double_t sinNew = sf*ca - cf*sa; if (TMath::Abs(sinNew) >= maxSnp) return kFALSE; if (!Rotate(alphan)) return kFALSE; } xpos = GetX(); } return kTRUE; }