7 #include "AliGenGeVSim.h"
11 ClassImp(AliGenGeVSim);
13 //////////////////////////////////////////////////////////////////////////////////
15 AliGenGeVSim::AliGenGeVSim() : AliGenerator(-1) {
21 for (Int_t i=0; i<4; i++)
25 //////////////////////////////////////////////////////////////////////////////////
27 AliGenGeVSim::AliGenGeVSim(Int_t model, Float_t psi) : AliGenerator(-1) {
29 // checking consistancy
31 if (model < 1 || model > 5)
32 Error("AliGenGeVSim","Model Id ( %d ) out of range [1..4]", model);
34 if (psi < 0 || psi > TMath::Pi() )
35 Error ("AliGenGeVSim", "Reaction plane angle ( %d )out of space [0..2 x Pi]", psi);
44 fPartTypes = new TObjArray();
49 //////////////////////////////////////////////////////////////////////////////////
51 AliGenGeVSim::~AliGenGeVSim() {
53 if (fPartTypes != NULL) delete fPartTypes;
57 //////////////////////////////////////////////////////////////////////////////////
59 Bool_t AliGenGeVSim::CheckPtYPhi(Float_t pt, Float_t y, Float_t phi) {
61 if ( TestBit(kPtRange) && ( pt < fPtMin || pt > fPtMax )) return kFALSE;
62 if ( TestBit(kPhiRange) && ( phi < fPhiMin || phi > fPhiMax )) return kFALSE;
63 if ( TestBit(kYRange) && ( y < fYMin || y > fYMax )) return kFALSE;
65 if ( TestBit(kThetaRange) ) {
66 Float_t theta = TMath::ACos( TMath::TanH(y) );
67 if ( theta < fThetaMin || theta > fThetaMax ) return kFALSE;
73 //////////////////////////////////////////////////////////////////////////////////
75 Bool_t AliGenGeVSim::CheckP(Float_t p[3]) {
77 if ( !TestBit(kMomentumRange) ) return kTRUE;
79 Float_t P = TMath::Sqrt(p[0]*p[0] + p[1]*p[1] + p[2]*p[2]);
80 if ( P < fPMin || P > fPMax) return kFALSE;
85 //////////////////////////////////////////////////////////////////////////////////
87 void AliGenGeVSim::InitFormula() {
90 // Deconvoluted Pt Y formula
92 // ptForm: pt -> x , mass -> [0] , temperature -> [1]
93 // y Form: y -> x , sigmaY -> [0]
95 const char* ptForm = " x * exp( -sqrt([0]*[0] + x*x) / [1] )";
96 const char* yForm = " exp ( - x*x / (2 * [0]*[0] ) )";
98 fPtFormula = new TF1("gevsimPt", ptForm, 0, 3);
99 fYFormula = new TF1("gevsimRapidity", yForm, -3, 3);
101 fPtFormula->SetParNames("Mass", "Temperature");
102 fPtFormula->SetParameters(1., 1.);
104 fYFormula->SetParName(0, "Sigma Y");
105 fYFormula->SetParameter(0, 1.);
108 fPtFormula->SetNpx(100);
109 fYFormula->SetNpx(100);
115 // mass -> [0] , temperature -> [1] , expansion velocity -> [2]
118 const char *formE = " ( sqrt([0]*[0] + x*x) * cosh(y) ) ";
119 const char *formG = " ( 1 / sqrt( 1 - [2]*[2] ) ) ";
120 const char *formYp = "( [2] * sqrt( ([0]*[0]+x*x)*cosh(y)*cosh(y) - [0]*[0] ) / ( [1] * sqrt(1-[2]*[2])) ) ";
122 const char* formula[3] = {
123 " x * %s * exp( -%s / [1]) ",
124 " (x * %s) / ( exp( %s / [1]) - 1 ) ",
125 " x * %s * exp (- %s * %s / [1] ) * ( (sinh(%s)/%s) + ([1]/(%s * %s)) * ( sinh(%s)/%s - cosh(%s) ) ) "
128 const char* paramNames[3] = {"Mass", "Temperature", "ExpVel"};
132 sprintf(buffer, formula[0], formE, formE);
133 fPtYFormula[0] = new TF2("gevsimPtY_2", buffer, 0, 4, -3, 3);
135 sprintf(buffer, formula[1], formE, formE);
136 fPtYFormula[1] = new TF2("gevsimPtY_3", buffer, 0, 4, -3, 3);
138 sprintf(buffer, formula[2], formE, formG, formE, formYp, formYp, formG, formE, formYp, formYp, formYp);
139 fPtYFormula[2] = new TF2("gevsimPtY_4", buffer, 0, 4, -3, 3);
144 // setting names & initialisation
147 for (i=0; i<3; i++) {
149 fPtYFormula[i]->SetNpx(100); // 40 MeV
150 fPtYFormula[i]->SetNpy(100); //
152 for (j=0; j<3; j++) {
154 if ( i != 2 && j == 2 ) continue; // ExpVel
155 fPtYFormula[i]->SetParName(j, paramNames[j]);
156 fPtYFormula[i]->SetParameter(j, 0.5);
163 // Psi -> [0] , Direct Flow -> [1] , Ellipticla Flow -> [2]
165 const char* phiForm = " 1 + 2*[1]*cos(x-[0]) + 2*[2]*cos(2*(x-[0])) ";
166 fPhiFormula = new TF1("gevsimPhi", phiForm, 0, 2*TMath::Pi());
168 fPhiFormula->SetParNames("Reaction Plane", "Direct Flow", "Elliptical Flow");
169 fPhiFormula->SetParameters(0., 0.1, 0.1);
171 fPhiFormula->SetNpx(360);
175 //////////////////////////////////////////////////////////////////////////////////
177 void AliGenGeVSim::AddParticleType(AliGeVSimParticle *part) {
179 if (fPartTypes == NULL)
180 fPartTypes = new TObjArray();
182 fPartTypes->Add(part);
186 //////////////////////////////////////////////////////////////////////////////////
188 Float_t AliGenGeVSim::FindScaler(Int_t paramId, Int_t pdg) {
191 static const char* params[] = {"Temp", "SigmaY", "ExpVel", "V1", "V2", "Mult"};
192 static const char* ending[] = {"", "Rndm"};
194 static const char* patt1 = "gevsim%s%s";
195 static const char* patt2 = "gevsim%d%s%s";
202 // Scaler evoluation: i - global/local, j - determ/random
206 for (i=0; i<2; i++) {
207 for (j=0; j<2; j++) {
211 if (i == 0) sprintf(buffer, patt1, params[paramId], ending[j]);
212 else sprintf(buffer, patt2, pdg, params[paramId], ending[j]);
214 form = (TF1 *)gROOT->GetFunction(buffer);
217 if (j == 0) scaler *= form->Eval(gAlice->GetEvNumber());
219 form->SetParameter(0, gAlice->GetEvNumber());
220 scaler *= form->GetRandom();
229 //////////////////////////////////////////////////////////////////////////////////
231 void AliGenGeVSim::Init() {
233 // init custom formula
239 fPtYFormula[customId] = 0;
240 fPtYFormula[customId] = (TF2 *)gROOT->GetFunction("gevsimPtY");
242 if (fPtYFormula[customId] == 0)
243 Error("Init", "No custom Formula 'gevsimPtY' found");
246 fPtYFormula[customId]->SetNpx(100);
247 fPtYFormula[customId]->SetNpy(100);
251 //////////////////////////////////////////////////////////////////////////////////
253 void AliGenGeVSim::Generate() {
258 PDG_t pdg; // particle type
259 Float_t mass; // particle mass
260 Float_t orgin[3] = {0,0,0}; // particle orgin [cm]
261 Float_t polar[3] = {0,0,0}; // polarisation
262 Float_t p[3] = {0,0,0}; // particle momentum
263 Float_t time = 0; // time of creation
264 Double_t pt, y, phi; // particle momentum in {pt, y, phi}
269 TFormula *model = NULL;
271 const Int_t parent = -1;
274 TLorentzVector *v = new TLorentzVector(0,0,0,0);
280 orgin[0] = fVertex[0];
281 orgin[1] = fVertex[1];
282 orgin[2] = fVertex[2];
286 cout << orgin[i] << "\t";
290 // Particle params database
292 TDatabasePDG *db = TDatabasePDG::Instance();
294 AliGeVSimParticle *partType;
296 Int_t nType, nParticle, nParam;
300 // Reaction Plane Determination
305 form = (TF1 *)gROOT->GetFunction("gevsimPsi");
306 if (form != 0) fPsi = form->Eval(gAlice->GetEvNumber());
309 form = (TF1 *)gROOT->GetFunction("gevsimPsiRndm");
310 if (form != 0) fPsi = form->GetRandom();
312 fPhiFormula->SetParameter(0, fPsi);
314 // setting selected model
317 form = (TF1 *)gROOT->GetFunction("gevsimModel");
318 if (form != 0) fModel = (Int_t)form->Eval(gAlice->GetEvNumber());
320 if (fModel == 1) model = fPtFormula;
321 if (fModel > 1) model = fPtYFormula[fModel-2];
324 // loop over particle types
326 for (nType = 0; nType < fPartTypes->GetEntries(); nType++) {
328 partType = (AliGeVSimParticle *)fPartTypes->At(nType);
330 pdg = (PDG_t)partType->GetPdgCode();
331 type = db->GetParticle(pdg);
334 cout << "Particle type: " << pdg << "\tMass: " << mass << "\t" << model << endl;
336 model->SetParameter("Mass", mass);
339 // Evaluation of parameters - loop over parameters
341 for (nParam =0; nParam < nParams; nParam++) {
343 paramScaler = FindScaler(nParam, pdg);
346 model->SetParameter("Temperature", paramScaler * partType->GetTemperature());
347 cout << "temperature Set to: " << (paramScaler * partType->GetTemperature()) << endl;
350 if (nParam == 1 && fModel == 1)
351 fYFormula->SetParameter("Sigma Y", paramScaler * partType->GetSigmaY());
353 if (nParam == 2 && fModel == 4) {
355 Double_t totalExpVal;
356 //if ( (partType->GetExpansionVelocity() == 0.) && (paramScaler != 1.0)) {
357 // Warning("generate","Scaler = 0.0 setting scaler = 1.0");
358 // partType->SetExpansionVelocity(1.0);
361 totalExpVal = paramScaler * partType->GetExpansionVelocity();
363 if (totalExpVal == 0.0) totalExpVal = 0.0001;
364 if (totalExpVal == 1.0) totalExpVal = 9.9999;
366 cout << "Expansion: " << paramScaler << " " << totalExpVal << endl;
367 model->SetParameter("ExpVel", totalExpVal);
372 if (nParam == 3) fPhiFormula->SetParameter(1, paramScaler * partType->GetDirectFlow());
373 if (nParam == 4) fPhiFormula->SetParameter(2, paramScaler * partType->GetEllipticalFlow());
377 if (nParam == 5) multiplicity = (Int_t) ( paramScaler * partType->GetMultiplicity() );
381 // loop over particles
385 while (nParticle < multiplicity) {
389 // fModel dependent momentum distribution
392 pt = fPtFormula->GetRandom();
393 y = fYFormula->GetRandom();
397 ((TF2*)model)->GetRandom2(pt, y);
401 phi = fPhiFormula->GetRandom();
405 if ( !CheckPtYPhi(pt, y, phi) ) continue;
407 // coordinate transformation
409 v->SetPtEtaPhiM(pt, y, phi, mass);
415 // momentum range test
417 if ( !CheckP(p) ) continue;
419 // putting particle on the stack
421 SetTrack(fTrackIt, parent, pdg, p, orgin, polar, time, kPPrimary, id, 1);
427 //////////////////////////////////////////////////////////////////////////////////