#include <TParticle.h>
#include <TF1.h>
#include <TF3.h>
#include <TDatabasePDG.h>
#include "AliRun.h"
#include "AliLog.h"
#include "AliESDtrack.h"
#include "AliESDVertex.h"
#include "AliGenFunction.h"
#include "AliGenEventHeader.h"
ClassImp(AliGenFunction)
AliGenFunction::AliGenFunction():
AliGenerator(),
fBkG(0.),
fFMomentum(0),
fFPhi(0),
fFTheta(0),
fFPosition(0),
fFPdg(0),
fRefRadius(0),
fZmin(0),
fZmax(0),
fMaxTrial(10000)
{
SetNumberParticles(1);
}
AliGenFunction::AliGenFunction(const AliGenFunction& func):
AliGenerator(),
fBkG(func.fBkG),
fFMomentum(func.fFMomentum),
fFPhi(func.fFPhi),
fFTheta(func.fFTheta),
fFPosition(func.fFPosition),
fFPdg(func.fFPdg),
fRefRadius(func.fRefRadius),
fZmin(func.fZmin),
fZmax(func.fZmax),
fMaxTrial(10000)
{
SetNumberParticles(1);
}
AliGenFunction & AliGenFunction::operator=(const AliGenFunction& func)
{
if(&func == this) return *this;
fBkG = func.fBkG;
fFMomentum = func.fFMomentum;
fFPhi = func.fFPhi;
fFTheta = func.fFTheta;
fFPosition = func.fFPosition;
fFPdg = func.fFPdg;
fRefRadius = func.fRefRadius;
fZmin = func.fZmin;
fZmax = func.fZmax;
fMaxTrial = func.fMaxTrial;
return *this;
}
void AliGenFunction::Generate()
{
Int_t naccepted =0;
for (Int_t ipart=0; ipart<fMaxTrial && naccepted<fNpart; ipart++){
Float_t mom[3];
Float_t posf[3];
Double_t pos[3];
Int_t pdg;
Double_t ptot, pt, phi, theta;
ptot = fFMomentum->GetRandom();
phi = fFPhi->GetRandom();
theta = fFTheta->GetRandom();
pt = ptot*TMath::Sin(theta);
mom[0] = pt*TMath::Cos(phi);
mom[1] = pt*TMath::Sin(phi);
mom[2] = ptot*TMath::Cos(theta);
fFPosition->GetRandom3(pos[0],pos[1],pos[2]);
posf[0]=pos[0];
posf[1]=pos[1];
posf[2]=pos[2];
pdg = TMath::Nint(fFPdg->GetRandom());
if (!IntersectCylinder(fRefRadius,fZmin, fZmax, pdg, posf, mom)) continue;
Float_t polarization[3]= {0,0,0};
Int_t nt;
PushTrack(fTrackIt,-1,pdg,mom, posf, polarization,0,kPPrimary,nt);
naccepted++;
}
AliGenEventHeader* header = new AliGenEventHeader("THn");
gAlice->SetGenEventHeader(header);
return;
}
void AliGenFunction::Init()
{
printf("************ AliGenFunction ****************\n");
printf("************************************************\n");
if (!fFMomentum){
AliFatal("Momentum distribution function not specified");
}
if (!fFPosition){
AliFatal("Position distribution function not specified");
}
if (!fFPdg){
AliFatal("PDG distribution function not specified");
}
if (fZmin==fZmax){
AliFatal("Z range not specified");
}
return;
}
void AliGenFunction::SetFunctions(TF1 * momentum, TF1 *fphi, TF1 *ftheta,TF3 * position, TF1* pdg){
fFMomentum = momentum;
fFPhi = fphi;
fFTheta = ftheta;
fFPosition = position;
fFPdg = pdg;
}
void AliGenFunction::SetCylinder(Double_t refR, Double_t zmin, Double_t zmax){
fRefRadius = refR;
fZmin = zmin;
fZmax = zmax;
}
Bool_t AliGenFunction::IntersectCylinder(Float_t r,Float_t zmin, Float_t zmax,Int_t pdg,
Float_t o[3],Float_t p[3]) const
{
Double_t mass=0;
if (TDatabasePDG::Instance()->GetParticle(pdg)){
mass = TDatabasePDG::Instance()->GetParticle(13)->Mass();
}
Float_t en = TMath::Sqrt(mass*mass+p[0]*p[0]+p[1]*p[1]+p[2]*p[2]);
TParticle part(pdg,0,0,0,0,0,p[0],p[1],p[2],en,o[0],o[1],o[2],0);
AliESDtrack track(&part);
Double_t pos[3]={0.,0.,0.},sigma[3]={0.,0.,0.};
AliESDVertex origin(pos,sigma);
track.RelateToVertex(&origin,fBkG,10000.);
Float_t d0z0[2],covd0z0[3];
track.GetImpactParameters(d0z0,covd0z0);
if(TMath::Abs(d0z0[0])>r) return kFALSE;
if(d0z0[1]>zmax) return kFALSE;
if(d0z0[1]<zmin) return kFALSE;
return kTRUE;
}