#include "AliTOFT0v1.h"
#include "AliTOFT0maker.h"
#include "AliPID.h"
#include "AliLog.h"
#include "AliESDpid.h"
#include "AliESDEvent.h"
#include "TFile.h"
#include "TH1F.h"
#include "AliTOFcalib.h"
#include "AliTOFRunParams.h"
#include "TRandom.h"
#include "AliTOFHeader.h"
ClassImp(AliTOFT0maker)
AliTOFT0maker::AliTOFT0maker():
TObject(),
fT0TOF(NULL),
fPIDesd(NULL),
fExternalPIDFlag(kFALSE),
fTOFcalib(NULL),
fNoTOFT0(0),
fNmomBins(0),
fTimeResolution(100),
fT0sigma(1000),
fHmapChannel(0),
fKmask(0),
fT0width(150.),
fT0spreadExt(-1.),
fT0fillExt(0),
fTOFT0algorithm(1)
{
fCalculated[0] = 0;
fCalculated[1] = 0;
fCalculated[2] = 0;
fCalculated[3] = 0;
fT0cur[0]=0.;
fT0cur[1]=0.;
if(AliPID::ParticleMass(0) == 0) new AliPID();
fPIDesd = new AliESDpid();
fNmomBins = fPIDesd->GetTOFResponse().GetNmomBins();
SetTOFResponse();
fT0TOF = new AliTOFT0v1(fPIDesd);
}
AliTOFT0maker::AliTOFT0maker(AliESDpid *externalPID, AliTOFcalib *tofCalib):
TObject(),
fT0TOF(NULL),
fPIDesd(externalPID),
fExternalPIDFlag(kTRUE),
fTOFcalib(tofCalib),
fNoTOFT0(0),
fNmomBins(0),
fTimeResolution(100),
fT0sigma(1000),
fHmapChannel(0),
fKmask(0),
fT0width(150.),
fT0spreadExt(-1.),
fT0fillExt(0),
fTOFT0algorithm(1)
{
fCalculated[0] = 0;
fCalculated[1] = 0;
fCalculated[2] = 0;
fCalculated[3] = 0;
fT0cur[0]=0.;
fT0cur[1]=0.;
if(AliPID::ParticleMass(0) == 0) new AliPID();
if(!fPIDesd){
fPIDesd = new AliESDpid();
fExternalPIDFlag = kFALSE;
}
fNmomBins = fPIDesd->GetTOFResponse().GetNmomBins();
SetTOFResponse();
fT0TOF = new AliTOFT0v1(fPIDesd);
}
AliTOFT0maker::~AliTOFT0maker()
{
delete fT0TOF;
if (!fExternalPIDFlag) delete fPIDesd;
}
Double_t* AliTOFT0maker::ComputeT0TOF(AliESDEvent *esd,Double_t t0time,Double_t t0sigma){
Double_t t0tof[6];
if(fKmask) ApplyMask(esd);
Double_t t0fill = 0.;
fPIDesd->GetTOFResponse().ResetT0info();
if (fTOFcalib && esd) {
AliTOFRunParams *runParams = fTOFcalib->GetRunParams();
if (runParams && runParams->GetTimestamp(0) != 0) {
Float_t t0spread = runParams->EvalT0Spread(esd->GetTimeStamp());
if(fT0spreadExt > 0) SetT0FillWidth(fT0spreadExt);
else{
SetT0FillWidth(t0spread);
t0fill = fT0fillExt;
}
}
else{
if(fT0spreadExt > 0) SetT0FillWidth(fT0spreadExt);
t0fill = fT0fillExt;
}
}
else if(esd){
Float_t t0spread = esd->GetSigma2DiamondZ();
if(t0spread > 0) t0spread = TMath::Sqrt(t0spread)/0.0299792458;
if(fT0spreadExt > 0) SetT0FillWidth(fT0spreadExt);
else{
SetT0FillWidth(t0spread);
t0fill = fT0fillExt;
}
}
Float_t thrGood = TMath::Max(Float_t(500.),fT0width*3);
fT0TOF->Init(esd);
AliTOFT0v1* t0maker = fT0TOF;
if (fTOFT0algorithm==2) t0maker->SetOptimization(kTRUE);
t0maker->DefineT0("all",1.5,3.0);
t0tof[0] = t0maker->GetResult(0);
t0tof[1] = t0maker->GetResult(1);
t0tof[2] = t0maker->GetResult(2);
t0tof[3] = t0maker->GetResult(3);
t0tof[4] = t0maker->GetResult(4);
t0tof[5] = t0maker->GetResult(5);
Float_t lT0Current=0.;
fT0sigma=1000;
t0time += t0fill;
Float_t sigmaFill = fT0width;
if(sigmaFill < 20) sigmaFill = 140;
fCalculated[0]=-1000*t0tof[0];
fCalculated[1]=1000*t0tof[1];
fCalculated[2] = t0fill;
fCalculated[3] = t0tof[2];
fCalculated[4]=-1000*t0tof[0];
fCalculated[5]=1000*t0tof[1];
fCalculated[6]=sigmaFill;
fCalculated[7] = t0tof[3];
if(fCalculated[7] > 30) thrGood = 10000000;
fCalculated[8] = t0tof[4];
fCalculated[9] = t0tof[5];
if(fCalculated[1] < sigmaFill && TMath::Abs(fCalculated[0] - t0fill) < thrGood && fCalculated[1] < fTimeResolution*1.2){
fT0sigma=fCalculated[1];
lT0Current=fCalculated[0];
}
else{
fCalculated[4] = t0fill;
fCalculated[5] = sigmaFill;
}
if(fCalculated[1] < 1 || fT0sigma > sigmaFill || fCalculated[1] > fTimeResolution* 1.2){
fT0sigma =1000;
fCalculated[4] = t0fill;
fCalculated[5] = sigmaFill;
}
if(t0sigma < 1000){
if(fT0sigma < 1000){
Double_t w1 = 1./t0sigma/t0sigma;
Double_t w2 = 1./fCalculated[1]/fCalculated[1];
Double_t wtot = w1+w2;
lT0Current = (w1*t0time + w2*fCalculated[0]) / wtot;
fT0sigma = TMath::Sqrt(1./wtot);
}
else{
lT0Current=t0time;
fT0sigma=t0sigma;
}
}
if(fT0sigma < sigmaFill && TMath::Abs(lT0Current - t0fill) < thrGood){
fCalculated[1]=fT0sigma;
fCalculated[0]=lT0Current;
}
if(fT0sigma >= 1000 || fNoTOFT0){
lT0Current = t0fill;
fT0sigma = sigmaFill;
fCalculated[0] = t0fill;
fCalculated[1] = sigmaFill;
}
Float_t *t0values = new Float_t[fNmomBins];
Float_t *t0resolution = new Float_t[fNmomBins];
if(fCalculated[7] < 100){
for(Int_t i=0;i<fNmomBins;i++){
t0maker->DefineT0("all",fPIDesd->GetTOFResponse().GetMinMom(i),fPIDesd->GetTOFResponse().GetMaxMom(i));
t0tof[0] = t0maker->GetResult(0);
t0tof[1] = t0maker->GetResult(1);
t0tof[2] = t0maker->GetResult(2);
t0tof[3] = t0maker->GetResult(3);
Float_t t0bin =-1000*t0tof[0];
Float_t t0binRes =1000*t0tof[1];
if(t0binRes < sigmaFill && t0binRes < fTimeResolution * 1.2 && TMath::Abs(t0bin - t0fill) < thrGood){
if(t0sigma < 1000){
Double_t w1 = 1./t0sigma/t0sigma;
Double_t w2 = 1./t0binRes/t0binRes;
Double_t wtot = w1+w2;
t0bin = (w1*t0time + w2*t0bin) / wtot;
t0binRes = TMath::Sqrt(1./wtot);
}
}
else{
t0bin = t0fill;
t0binRes = sigmaFill;
if(t0sigma < 1000){
t0bin = t0time;
t0binRes= t0sigma;
}
}
t0values[i] = t0bin;
t0resolution[i] = t0binRes;
}
}
else{
for(Int_t i=0;i<fNmomBins;i++){
t0values[i] = lT0Current;
t0resolution[i] = fT0sigma;
}
}
for(Int_t i=0;i<fNmomBins;i++){
fPIDesd->GetTOFResponse().SetT0bin(i,t0values[i]);
fPIDesd->GetTOFResponse().SetT0binRes(i,t0resolution[i]);
}
delete[] t0values;
delete[] t0resolution;
return fCalculated;
}
Double_t *AliTOFT0maker::GetT0p(Float_t p){
Int_t i=fPIDesd->GetTOFResponse().GetMomBin(p);
fT0cur[0] = fPIDesd->GetTOFResponse().GetT0bin(i);
fT0cur[1] = fPIDesd->GetTOFResponse().GetT0binRes(i);
return fT0cur;
}
void AliTOFT0maker::SetTOFResponse(){
fPIDesd->GetTOFResponse().SetTimeResolution(fTimeResolution);
}
Float_t AliTOFT0maker::GetExpectedSigma(Float_t mom, Float_t tof, Float_t mass){
Float_t sigma = fPIDesd->GetTOFResponse().GetExpectedSigma(mom,tof,mass);
return sigma;
}
void AliTOFT0maker::ApplyT0TOF(AliESDEvent *esd){
Int_t ntracks = esd->GetNumberOfTracks();
while (ntracks--) {
AliESDtrack *t=esd->GetTrack(ntracks);
if ((t->GetStatus()&AliESDtrack::kTOFout)==0) continue;
Double_t time=t->GetTOFsignal();
Float_t p = t->GetP();
Double_t *t0=GetT0p(p);
time -= t0[0];
t->SetTOFsignal(time);
}
for(Int_t i=0;i<fNmomBins;i++){
fPIDesd->GetTOFResponse().SetT0bin(i,0.0);
}
}
void AliTOFT0maker::LoadChannelMap(const char *filename){
TFile *f= new TFile(filename);
if(!f){
printf("Cannot open the channel map file (%s)\n",filename);
return;
}
fHmapChannel = (TH1F *) f->Get("hChEnabled");
if(!fHmapChannel){
printf("Cannot laod the channel map histo (from %s)\n",filename);
return;
}
}
void AliTOFT0maker::ApplyMask(AliESDEvent * const esd){
if(!fHmapChannel){
printf("Channel Map is not available\n");
return;
}
Int_t ntracks = esd->GetNumberOfTracks();
while (ntracks--) {
AliESDtrack *t=esd->GetTrack(ntracks);
if ((t->GetStatus()&AliESDtrack::kTOFout)==0) continue;
Int_t chan = t->GetTOFCalChannel();
if(fHmapChannel->GetBinContent(chan) < 0.01){
t->ResetStatus(AliESDtrack::kTOFout);
}
}
}
Float_t
AliTOFT0maker::TuneForMC(AliESDEvent *esd){
Float_t TOFtimeResolutionDefault=80;
Float_t t0 = gRandom->Gaus(0.,fT0width);
Float_t extraSmearing = 0;
if(fTimeResolution > TOFtimeResolutionDefault){
extraSmearing = TMath::Sqrt(fTimeResolution*fTimeResolution - TOFtimeResolutionDefault*TOFtimeResolutionDefault);
}
Int_t ntracks = esd->GetNumberOfTracks();
while (ntracks--) {
AliESDtrack *t=esd->GetTrack(ntracks);
if ((t->GetStatus()&AliESDtrack::kTOFout)==0) continue;
if (fTOFcalib){
if(!fTOFcalib->IsChannelEnabled(t->GetTOFCalChannel())) {
t->ResetStatus(AliESDtrack::kTOFin);
t->ResetStatus(AliESDtrack::kTOFout);
t->ResetStatus(AliESDtrack::kTOFmismatch);
t->ResetStatus(AliESDtrack::kTOFpid);
}
}
Double_t time=t->GetTOFsignal();
time += t0;
if(extraSmearing>0){
Float_t smearing = gRandom->Gaus(0.,extraSmearing);
time += smearing;
}
t->SetTOFsignal(time);
}
return t0;
}
void AliTOFT0maker::WriteInESD(AliESDEvent *esd){
Int_t nMomBins = fPIDesd->GetTOFResponse().GetNmomBins();
Int_t nt0=0;
Float_t *t0 = new Float_t[nMomBins];
Float_t *t0res = new Float_t[nMomBins];
Int_t *multT0 = new Int_t[nMomBins];
for(Int_t i=0;i<nMomBins;i++){
multT0[i]=0;
Bool_t kNewT0=kTRUE;
for(Int_t j=0;j < nt0;j++){
if(TMath::Abs(fPIDesd->GetTOFResponse().GetT0bin(i) - t0[j])<0.1){
kNewT0=kFALSE;
multT0[j]++;
j=nMomBins*10;
}
}
if(kNewT0){
t0[nt0]=fPIDesd->GetTOFResponse().GetT0bin(i);
t0res[nt0]=fPIDesd->GetTOFResponse().GetT0binRes(i);
nt0++;
}
}
Int_t iMultT0=0,nmult=0;
for(Int_t j=0;j < nt0;j++){
if(multT0[j] > nmult){
iMultT0 = j;
nmult = multT0[j];
}
}
Float_t *t0ESD = new Float_t[nMomBins];
Float_t *t0resESD = new Float_t[nMomBins];
Int_t *it0ESD = new Int_t[nMomBins];
Float_t t0Gen,t0ResGen;
t0Gen = t0[iMultT0];
t0ResGen = t0res[iMultT0];
nt0=0;
for(Int_t i=0;i<nMomBins;i++){
if(TMath::Abs(fPIDesd->GetTOFResponse().GetT0bin(i) - t0Gen)>0.1){
t0ESD[nt0]=fPIDesd->GetTOFResponse().GetT0bin(i);
t0resESD[nt0]=fPIDesd->GetTOFResponse().GetT0binRes(i);
it0ESD[nt0]=i;
nt0++;
}
}
AliTOFHeader *tofHeader =
new AliTOFHeader(t0Gen,t0ResGen,nt0,
t0ESD,t0resESD,it0ESD,fTimeResolution,fT0width);
esd->SetTOFHeader(tofHeader);
delete tofHeader;
AliDebug(1,Form("resTOF=%f T0spread=%f t0Gen=%f t0resGen=%f",fTimeResolution,fT0width,t0Gen,t0ResGen));
AliDebug(1,Form("%d ",nt0));
for (Int_t ii=0; ii<nt0; ii++)
AliDebug(1,Form("pBin=%d t0val=%f t0res=%f",it0ESD[ii],t0ESD[ii],t0resESD[ii]));
delete[] t0;
t0 = NULL;
delete[] t0res;
t0res = NULL;
delete[] multT0;
multT0 = NULL;
delete[] t0ESD;
t0ESD = NULL;
delete[] t0resESD;
t0resESD = NULL;
delete[] it0ESD;
it0ESD = NULL;
}