// Origin: Marian Ivanov, CERN, Marian.Ivanov@cern.ch
//-----------------------------------------------------------------
#include "TClonesArray.h"
+#include "TGraphErrors.h"
#include "AliTPCseed.h"
#include "AliTPCReconstructor.h"
#include "AliTPCClusterParam.h"
#include "AliTPCCalROC.h"
#include "AliTPCcalibDB.h"
#include "AliTPCParam.h"
-
+#include "AliMathBase.h"
+#include "AliTPCTransform.h"
+#include "AliSplineFit.h"
+#include "AliCDBManager.h"
+#include "AliTPCcalibDButil.h"
ClassImp(AliTPCseed)
//-----------------------------------------------------------------
// This funtion calculates dE/dX within the "low" and "up" cuts.
//-----------------------------------------------------------------
+ // CookdEdxAnalytical(Double_t low, Double_t up, Int_t type, Int_t i1, Int_t i2, Int_t returnVal)
AliTPCParam *param = AliTPCcalibDB::Instance()->GetParameters();
+
Int_t row0 = param->GetNRowLow();
Int_t row1 = row0+param->GetNRowUp1();
Int_t row2 = row1+param->GetNRowUp2();
+ const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
+ Int_t useTot = 0;
+ if (recoParam) useTot = (recoParam->GetUseTotCharge())? 0:1;
//
//
//
- fDEDX[0] = CookdEdxNorm(low,up,0 ,i1 ,i2, kTRUE,kFALSE,2,0);
- fDEDX[1] = CookdEdxNorm(low,up,0 ,0 ,row0,kTRUE,kFALSE,2,0);
- fDEDX[2] = CookdEdxNorm(low,up,0 ,row0,row1,kTRUE,kFALSE,2,0);
- fDEDX[3] = CookdEdxNorm(low,up,0 ,row1,row2,kTRUE,kFALSE,2,0);
+ fDEDX[0] = CookdEdxAnalytical(low,up,useTot ,i1 ,i2, 0);
+ fDEDX[1] = CookdEdxAnalytical(low,up,useTot ,0 ,row0, 0);
+ fDEDX[2] = CookdEdxAnalytical(low,up,useTot ,row0,row1, 0);
+ fDEDX[3] = CookdEdxAnalytical(low,up,useTot ,row1,row2, 0);
//
- fSDEDX[0] = CookdEdxNorm(low,up,0 ,i1 ,i2, kTRUE,kFALSE,2,1);
- fSDEDX[1] = CookdEdxNorm(low,up,0 ,0 ,row0,kTRUE,kFALSE,2,1);
- fSDEDX[2] = CookdEdxNorm(low,up,0 ,row0,row1,kTRUE,kFALSE,2,1);
- fSDEDX[3] = CookdEdxNorm(low,up,0 ,row1,row2,kTRUE,kFALSE,2,1);
+ fSDEDX[0] = CookdEdxAnalytical(low,up,useTot ,i1 ,i2, 1);
+ fSDEDX[1] = CookdEdxAnalytical(low,up,useTot ,0 ,row0, 1);
+ fSDEDX[2] = CookdEdxAnalytical(low,up,useTot ,row0,row1, 1);
+ fSDEDX[3] = CookdEdxAnalytical(low,up,useTot ,row1,row2, 1);
//
- fNCDEDX[0] = TMath::Nint(CookdEdxNorm(low,up,0 ,i1 ,i2, kTRUE,kFALSE,2,2));
- fNCDEDX[1] = TMath::Nint(CookdEdxNorm(low,up,0 ,0 ,row0,kTRUE,kFALSE,2,2));
- fNCDEDX[2] = TMath::Nint(CookdEdxNorm(low,up,0 ,row0,row1,kTRUE,kFALSE,2,2));
- fNCDEDX[3] = TMath::Nint(CookdEdxNorm(low,up,0 ,row1,row2,kTRUE,kFALSE,2,2));
+ fNCDEDX[0] = TMath::Nint(CookdEdxAnalytical(low,up,useTot ,i1 ,i2, 2));
+ fNCDEDX[1] = TMath::Nint(CookdEdxAnalytical(low,up,useTot ,0 ,row0, 2));
+ fNCDEDX[2] = TMath::Nint(CookdEdxAnalytical(low,up,useTot ,row0,row1, 2));
+ fNCDEDX[3] = TMath::Nint(CookdEdxAnalytical(low,up,useTot ,row1,row2, 2));
SetdEdx(fDEDX[0]);
return fDEDX[0];
// SetdEdx(dedx);
// return dedx;
}
-Double_t AliTPCseed::Bethe(Double_t bg){
- //
- // This is the Bethe-Bloch function normalised to 1 at the minimum
- //
- Double_t bg2=bg*bg;
- Double_t bethe;
- if (bg<3.5e1)
- bethe=(1.+ bg2)/bg2*(log(5940*bg2) - bg2/(1.+ bg2));
- else // Density effect ( approximately :)
- bethe=1.15*(1.+ bg2)/bg2*(log(3.5*5940*bg) - bg2/(1.+ bg2));
- return bethe/11.091;
-}
void AliTPCseed::CookPID()
{
Double_t mass=AliPID::ParticleMass(j);
Double_t mom=GetP();
Double_t dedx=fdEdx/fMIP;
- Double_t bethe=Bethe(mom/mass);
+ Double_t bethe=AliMathBase::BetheBlochAleph(mom/mass);
Double_t sigma=fRes*bethe;
if (sigma>0.001){
if (TMath::Abs(dedx-bethe) > fRange*sigma) {
-Float_t AliTPCseed::CookdEdxNorm(Double_t low, Double_t up, Int_t type, Int_t i1, Int_t i2, Bool_t shapeNorm,Bool_t posNorm, Int_t padNorm, Int_t returnVal){
+Float_t AliTPCseed::CookdEdxNorm(Double_t low, Double_t up, Int_t type, Int_t i1, Int_t i2, Bool_t shapeNorm,Int_t posNorm, Int_t padNorm, Int_t returnVal){
//
// calculates dedx using the cluster
}
}
- if (posNorm){
+ if (posNorm>0){
//
// Do position normalization - relative distance to
// center of pad- time bin
// cluster->GetTimeBin(), cluster->GetZ(),
// cluster->GetSigmaY2(),cluster->GetSigmaZ2(),
// cluster->GetMax(),cluster->GetQ());
+ // scaled response function
+ Float_t yres0 = parcl->GetRMS0(0,ipad,0,0)/param->GetPadPitchWidth(cluster->GetDetector());
+ Float_t zres0 = parcl->GetRMS0(1,ipad,0,0)/param->GetZWidth();
+ //
+
AliTPCTrackerPoint * point = GetTrackPoint(irow);
Float_t ty = TMath::Abs(point->GetAngleY());
Float_t tz = TMath::Abs(point->GetAngleZ()*TMath::Sqrt(1+ty*ty));
if (type==1) corrPos =
parcl->QmaxCorrection(cluster->GetDetector(), cluster->GetRow(),cluster->GetPad(),
- TMath::Nint(cluster->GetTimeBin()),ty,tz,0.5,0.2,1.6);
+ cluster->GetTimeBin(),ty,tz,yres0,zres0,0.4);
if (type==0) corrPos =
parcl->QtotCorrection(cluster->GetDetector(), cluster->GetRow(),cluster->GetPad(),
- TMath::Nint(cluster->GetTimeBin()),ty,tz,0.5,0.2,cluster->GetQ(),2.5,1.6);
+ cluster->GetTimeBin(),ty,tz,yres0,zres0,cluster->GetQ(),2.5,0.4);
+ if (posNorm==3){
+ Float_t dr = (250.-TMath::Abs(cluster->GetZ()))/250.;
+ Double_t signtgl = (cluster->GetZ()*point->GetAngleZ()>0)? 1:-1;
+ Double_t p2 = TMath::Abs(TMath::Sin(TMath::ATan(ty)));
+ Float_t corrHis = parcl->QnormHis(ipad,type,dr,p2,TMath::Abs(point->GetAngleZ())*signtgl);
+ if (corrHis>0) corrPos*=corrHis;
+ }
+
}
if (padNorm==1){
//taken from OCDB
- if (type==0 && parcl->fQpadTnorm) corrPadType = (*parcl->fQpadTnorm)[ipad];
- if (type==1 && parcl->fQpadTnorm) corrPadType = (*parcl->fQpadMnorm)[ipad];
+ if (type==0 && parcl->QpadTnorm()) corrPadType = (*parcl->QpadTnorm())[ipad];
+ if (type==1 && parcl->QpadMnorm()) corrPadType = (*parcl->QpadMnorm())[ipad];
}
if (padNorm==2){
}
Float_t mean =suma/sumn;
Float_t rms =TMath::Sqrt(TMath::Abs(suma2/sumn-mean*mean));
+ //
+ // do time-dependent correction for pressure and temperature variations
+ UInt_t runNumber = 1;
+ Float_t corrTimeGain = 1;
+ AliTPCTransform * trans = AliTPCcalibDB::Instance()->GetTransform();
+ const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
+ if (trans && recoParam->GetUseGainCorrectionTime()>0) {
+ runNumber = trans->GetCurrentRunNumber();
+ //AliTPCcalibDB::Instance()->SetRun(runNumber);
+ TObjArray * timeGainSplines = AliTPCcalibDB::Instance()->GetTimeGainSplinesRun(runNumber);
+ if (timeGainSplines) {
+ UInt_t time = trans->GetCurrentTimeStamp();
+ AliSplineFit * fitMIP = (AliSplineFit *) timeGainSplines->At(0);
+ AliSplineFit * fitFPcosmic = (AliSplineFit *) timeGainSplines->At(1);
+ if (fitMIP) {
+ corrTimeGain = AliTPCcalibDButil::EvalGraphConst(fitMIP, time);/*fitMIP->Eval(time);*/
+ } else {
+ if (fitFPcosmic) corrTimeGain = AliTPCcalibDButil::EvalGraphConst(fitFPcosmic, time);/*fitFPcosmic->Eval(time);*/
+ }
+ }
+ }
+ mean /= corrTimeGain;
+ rms /= corrTimeGain;
+ //
if (returnVal==1) return rms;
if (returnVal==2) return ncl;
return mean;
}
-
-Double_t AliTPCseed::BetheMass(Double_t mass){
+Float_t AliTPCseed::CookdEdxAnalytical(Double_t low, Double_t up, Int_t type, Int_t i1, Int_t i2, Int_t returnVal, Int_t rowThres){
+
//
- // return bethe-bloch
+ // calculates dedx using the cluster
+ // low - up specify trunc mean range - default form 0-0.7
+ // type - 1 - max charge or 0- total charge in cluster
+ // //2- max no corr 3- total+ correction
+ // i1-i2 - the pad-row range used for calculation
+ //
+ // posNorm - usage of pos normalization
+ // returnVal - 0 return mean
+ // - 1 return RMS
+ // - 2 return number of clusters
+ //
+ // rowThres - number of rows before and after given pad row to check for clusters below threshold
+ //
+ // normalization parametrization taken from AliTPCClusterParam
//
- Float_t bg= P()/mass;
- const Double_t kp1=0.76176e-1;
- const Double_t kp2=10.632;
- const Double_t kp3=0.13279e-4;
- const Double_t kp4=1.8631;
- const Double_t kp5=1.9479;
+ AliTPCClusterParam * parcl = AliTPCcalibDB::Instance()->GetClusterParam();
+ AliTPCParam * param = AliTPCcalibDB::Instance()->GetParameters();
+ if (!parcl) return 0;
+ if (!param) return 0;
+ Int_t row0 = param->GetNRowLow();
+ Int_t row1 = row0+param->GetNRowUp1();
- Double_t dbg = (Double_t) bg;
+ Float_t amp[160];
+ Int_t indexes[160];
+ Int_t ncl=0;
+ Int_t nclBelowThr = 0; // counts number of clusters below threshold
+ //
+ //
+ Float_t gainGG = 1; // gas gain factor -always enabled
+ Float_t gainPad = 1; // gain map - used always
+ Float_t corrPos = 1; // local position correction - if posNorm enabled
+ //
+ //
+ //
+ if (AliTPCcalibDB::Instance()->GetParameters()){
+ gainGG= AliTPCcalibDB::Instance()->GetParameters()->GetGasGain()/20000; //relative gas gain
+ }
+ //
+ // extract time-dependent correction for pressure and temperature variations
+ //
+ UInt_t runNumber = 1;
+ Float_t corrTimeGain = 1;
+ TObjArray * timeGainSplines = 0x0;
+ TGraphErrors * grPadEqual = 0x0;
+ //
+ AliTPCTransform * trans = AliTPCcalibDB::Instance()->GetTransform();
+ const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
+ //
+ if (recoParam->GetNeighborRowsDedx() == 0) rowThres = 0;
+ //
+ if (trans) {
+ runNumber = trans->GetCurrentRunNumber();
+ //AliTPCcalibDB::Instance()->SetRun(runNumber);
+ timeGainSplines = AliTPCcalibDB::Instance()->GetTimeGainSplinesRun(runNumber);
+ if (timeGainSplines && recoParam->GetUseGainCorrectionTime()>0) {
+ UInt_t time = trans->GetCurrentTimeStamp();
+ AliSplineFit * fitMIP = (AliSplineFit *) timeGainSplines->At(0);
+ AliSplineFit * fitFPcosmic = (AliSplineFit *) timeGainSplines->At(1);
+ if (fitMIP) {
+ corrTimeGain = AliTPCcalibDButil::EvalGraphConst(fitMIP, time); /*fitMIP->Eval(time);*/
+ } else {
+ if (fitFPcosmic) corrTimeGain = AliTPCcalibDButil::EvalGraphConst(fitFPcosmic, time); /*fitFPcosmic->Eval(time); */
+ }
+ //
+ if (type==1) grPadEqual = (TGraphErrors * ) timeGainSplines->FindObject("TGRAPHERRORS_MEANQMAX_PADREGIONGAIN_BEAM_ALL");
+ if (type==0) grPadEqual = (TGraphErrors * ) timeGainSplines->FindObject("TGRAPHERRORS_MEANQTOT_PADREGIONGAIN_BEAM_ALL");
+ }
+ }
+
+ const Float_t kClusterShapeCut = 1.5; // IMPPRTANT TO DO: move value to AliTPCRecoParam
+ const Float_t ktany = TMath::Tan(TMath::DegToRad()*10);
+ const Float_t kedgey =3.;
+ //
+ //
+ for (Int_t irow=i1; irow<i2; irow++){
+ AliTPCclusterMI* cluster = GetClusterPointer(irow);
+ if (!cluster && irow > 1 && irow < 157) {
+ Bool_t isClBefore = kFALSE;
+ Bool_t isClAfter = kFALSE;
+ for(Int_t ithres = 1; ithres <= rowThres; ithres++) {
+ AliTPCclusterMI * clusterBefore = GetClusterPointer(irow - ithres);
+ if (clusterBefore) isClBefore = kTRUE;
+ AliTPCclusterMI * clusterAfter = GetClusterPointer(irow + ithres);
+ if (clusterAfter) isClAfter = kTRUE;
+ }
+ if (isClBefore && isClAfter) nclBelowThr++;
+ }
+ if (!cluster) continue;
+ //
+ //
+ if (TMath::Abs(cluster->GetY())>cluster->GetX()*ktany-kedgey) continue; // edge cluster
+ //
+ AliTPCTrackerPoint * point = GetTrackPoint(irow);
+ if (point==0) continue;
+ Float_t rsigmay = TMath::Sqrt(point->GetSigmaY());
+ if (rsigmay > kClusterShapeCut) continue;
+ //
+ if (cluster->IsUsed(11)) continue; // remove shared clusters for PbPb
+ //
+ Float_t charge= (type%2)? cluster->GetMax():cluster->GetQ();
+ Int_t ipad= 0;
+ if (irow>=row0) ipad=1;
+ if (irow>=row1) ipad=2;
+ //
+ //
+ //
+ AliTPCCalPad * gainMap = AliTPCcalibDB::Instance()->GetDedxGainFactor();
+ if (gainMap) {
+ //
+ // Get gainPad - pad by pad calibration
+ //
+ Float_t factor = 1;
+ AliTPCCalROC * roc = gainMap->GetCalROC(cluster->GetDetector());
+ if (irow < row0) { // IROC
+ factor = roc->GetValue(irow, TMath::Nint(cluster->GetPad()));
+ } else { // OROC
+ factor = roc->GetValue(irow - row0, TMath::Nint(cluster->GetPad()));
+ }
+ if (factor>0.3) gainPad=factor;
+ }
+ //
+ // Do position normalization - relative distance to
+ // center of pad- time bin
+
+ Float_t ty = TMath::Abs(point->GetAngleY());
+ Float_t tz = TMath::Abs(point->GetAngleZ()*TMath::Sqrt(1+ty*ty));
+ Float_t yres0 = parcl->GetRMS0(0,ipad,0,0)/param->GetPadPitchWidth(cluster->GetDetector());
+ Float_t zres0 = parcl->GetRMS0(1,ipad,0,0)/param->GetZWidth();
+
+ yres0 *=parcl->GetQnormCorr(ipad, type,0);
+ zres0 *=parcl->GetQnormCorr(ipad, type,1);
+ Float_t effLength=parcl->GetQnormCorr(ipad, type,4)*0.5;
+ Float_t effDiff =(parcl->GetQnormCorr(ipad, type,2)+parcl->GetQnormCorr(ipad, type,3))*0.5;
+ //
+ if (type==1) {
+ corrPos = parcl->GetQnormCorr(ipad, type,5)*
+ parcl->QmaxCorrection(cluster->GetDetector(), cluster->GetRow(),cluster->GetPad(),
+ cluster->GetTimeBin(),ty,tz,yres0,zres0,effLength,effDiff);
+ Float_t drm = 0.5-TMath::Abs(cluster->GetZ()/250.);
+ corrPos*=(1+parcl->GetQnormCorr(ipad, type+2,0)*drm);
+ corrPos*=(1+parcl->GetQnormCorr(ipad, type+2,1)*ty*ty);
+ corrPos*=(1+parcl->GetQnormCorr(ipad, type+2,2)*tz*tz);
+ //
+ }
+ if (type==0) {
+ corrPos = parcl->GetQnormCorr(ipad, type,5)*
+ parcl->QtotCorrection(cluster->GetDetector(), cluster->GetRow(),cluster->GetPad(),
+ cluster->GetTimeBin(),ty,tz,yres0,zres0,cluster->GetQ(),2.5,effLength,effDiff);
+
+ Float_t drm = 0.5-TMath::Abs(cluster->GetZ()/250.);
+ corrPos*=(1+parcl->GetQnormCorr(ipad, type+2,0)*drm);
+ corrPos*=(1+parcl->GetQnormCorr(ipad, type+2,1)*ty*ty);
+ corrPos*=(1+parcl->GetQnormCorr(ipad, type+2,2)*tz*tz);
+ //
+ }
+ //
+ // pad region equalization outside of cluster param
+ //
+ Float_t gainEqualPadRegion = 1;
+ if (grPadEqual) gainEqualPadRegion = grPadEqual->Eval(ipad);
+ //
+ amp[ncl]=charge;
+ amp[ncl]/=gainGG;
+ amp[ncl]/=gainPad;
+ amp[ncl]/=corrPos;
+ amp[ncl]/=gainEqualPadRegion;
+ //
+ ncl++;
+ }
- Double_t beta = dbg/TMath::Sqrt(1.+dbg*dbg);
+ if (type>3) return ncl;
+ TMath::Sort(ncl,amp, indexes, kFALSE);
+ //
+ if (ncl<10) return 0;
+ //
+ Double_t * ampWithBelow = new Double_t[ncl + nclBelowThr];
+ for(Int_t iCl = 0; iCl < ncl + nclBelowThr; iCl++) {
+ if (iCl < nclBelowThr) {
+ ampWithBelow[iCl] = amp[indexes[0]];
+ } else {
+ ampWithBelow[iCl] = amp[indexes[iCl - nclBelowThr]];
+ }
+ }
+ //printf("DEBUG: %i shit %f", nclBelowThr, amp[indexes[0]]);
+ //
+ Float_t suma=0;
+ Float_t suma2=0;
+ Float_t sumn=0;
+ Int_t icl0=TMath::Nint((ncl + nclBelowThr)*low);
+ Int_t icl1=TMath::Nint((ncl + nclBelowThr)*up);
+ for (Int_t icl=icl0; icl<icl1;icl++){
+ suma+=ampWithBelow[icl];
+ suma2+=ampWithBelow[icl]*ampWithBelow[icl];
+ sumn++;
+ }
+ delete [] ampWithBelow;
+ Float_t mean =suma/sumn;
+ Float_t rms =TMath::Sqrt(TMath::Abs(suma2/sumn-mean*mean));
+ //
+ mean /= corrTimeGain;
+ rms /= corrTimeGain;
+ //
+ if (returnVal==1) return rms;
+ if (returnVal==2) return ncl;
+ return mean;
+}
- Double_t aa = TMath::Power(beta,kp4);
- Double_t bb = TMath::Power(1./dbg,kp5);
- bb=TMath::Log(kp3+bb);
-
- return ((Float_t)((kp2-aa-bb)*kp1/aa));
-}
Float_t AliTPCseed::CookShape(Int_t type){
//
if (parin) (*parin)=paramIn;
if (parout) (*parout)=paramOut;
+ delete track;
return ncl;
}