1 ///////////////////////////////////////////////////////////////////
2 //                                                               //
3 //    Generate the final state of the interaction as the input   //
4 //    to the MonteCarlo                                          //
5 //
6 //Begin_Html
7 /*
8 <img src="gif/AliGeneratorClass.gif">
9 </pre>
10 <br clear=left>
11 <font size=+2 color=red>
12 <p>The responsible person for this module is
13 <a href="mailto:andreas.morsch@cern.ch">Andreas Morsch</a>.
14 </font>
15 <pre>
16 */
17 //End_Html
18 //                                                               //
19 ///////////////////////////////////////////////////////////////////
21 #include "AliSimpleGen.h"
22 #include "AliRun.h"
24 ClassImp(AliGenHIJINGpara)
26 //_____________________________________________________________________________
27 static Double_t ptpi(Double_t *px, Double_t *)
28 {
29   //
30   //     PT-PARAMETERIZATION CDF, PRL 61(88) 1819
31   //     POWER LAW FOR PT > 500 MEV
32   //     MT SCALING BELOW (T=160 MEV)
33   //
34   const Double_t p0 = 1.3;
35   const Double_t xn = 8.28;
36   const Double_t xlim=0.5;
37   const Double_t t=0.160;
38   const Double_t xmpi=0.139;
39   const Double_t b=1.;
40   Double_t y, y1, xmpi2, ynorm, a;
41   Double_t x=*px;
42   //
43   y1=TMath::Power(p0/(p0+xlim),xn);
44   xmpi2=xmpi*xmpi;
45   ynorm=b*(TMath::Exp(-sqrt(xlim*xlim+xmpi2)/t));
46   a=ynorm/y1;
47   if (x > xlim)
48     y=a*TMath::Power(p0/(p0+x),xn);
49   else
50     y=b*TMath::Exp(-sqrt(x*x+xmpi2)/t);
51   return y*x;
52 }
54 //_____________________________________________________________________________
55 static Double_t ptscal(Double_t pt, Int_t np)
56 {
57   //    SCALING EN MASSE PAR RAPPORT A PTPI
58   //     MASS PI,K,ETA,RHO,OMEGA,ETA',PHI
59   const Double_t hm[10] = {.13957,.493,.5488,.769,.7826,.958,1.02,0,0,0};
60   //     VALUE MESON/PI AT 5 GEV
61   const Double_t fmax[10]={1.,0.3,0.55,1.0,1.0,1.0,1.0,0,0,0};
62   np--;
63   Double_t f5=TMath::Power(((sqrt(100.018215)+2.)/(sqrt(100.+hm[np]*hm[np])+2.0)),12.3);
64   Double_t fmax2=f5/fmax[np];
65   // PIONS
66   Double_t ptpion=100.*ptpi(&pt, (Double_t*) 0);
67   Double_t fmtscal=TMath::Power(((sqrt(pt*pt+0.018215)+2.)/
68                                  (sqrt(pt*pt+hm[np]*hm[np])+2.0)),12.3)/ fmax2;
69   return fmtscal*ptpion;
70 }
72 //_____________________________________________________________________________
73 static Double_t ptka( Double_t *px, Double_t *)
74 {
75   //
76   // pt parametrisation for k
77   //
78   return ptscal(*px,2);
79 }
82 //_____________________________________________________________________________
83 static Double_t etapic( Double_t *py, Double_t *)
84 {
85   //
86   // eta parametrisation for pi
87   //
88   const Double_t a1    = 4913.;
89   const Double_t a2    = 1819.;
90   const Double_t eta1  = 0.22;
91   const Double_t eta2  = 3.66;
92   const Double_t deta1 = 1.47;
93   const Double_t deta2 = 1.51;
94   Double_t y=TMath::Abs(*py);
95   //
96   Double_t ex1 = (y-eta1)*(y-eta1)/(2*deta1*deta1);
97   Double_t ex2 = (y-eta2)*(y-eta2)/(2*deta2*deta2);
98   return a1*TMath::Exp(-ex1)+a2*TMath::Exp(-ex2);
99 }
101 //_____________________________________________________________________________
102 static Double_t etakac( Double_t *py, Double_t *)
103 {
104   //
105   // eta parametrisation for ka
106   //
107   const Double_t a1    = 497.6;
108   const Double_t a2    = 215.6;
109   const Double_t eta1  = 0.79;
110   const Double_t eta2  = 4.09;
111   const Double_t deta1 = 1.54;
112   const Double_t deta2 = 1.40;
113   Double_t y=TMath::Abs(*py);
114   //
115   Double_t ex1 = (y-eta1)*(y-eta1)/(2*deta1*deta1);
116   Double_t ex2 = (y-eta2)*(y-eta2)/(2*deta2*deta2);
117   return a1*TMath::Exp(-ex1)+a2*TMath::Exp(-ex2);
118 }
120 //_____________________________________________________________________________
121 AliGenHIJINGpara::AliGenHIJINGpara()
122   :AliGenerator()
123 {
124   //
125   // Default constructor
126   //
127   fPtpi = 0;
128   fPtka = 0;
129   fETApic = 0;
130   fETAkac = 0;
131 }
133 //_____________________________________________________________________________
134 AliGenHIJINGpara::AliGenHIJINGpara(Int_t npart)
135   :AliGenerator(npart)
136 {
137   //
138   // Standard constructor
139   //
140   fName="HIGINGpara";
141   fTitle="HIJING Parametrisation Particle Generator";
142   fPtpi = 0;
143   fPtka = 0;
144   fETApic = 0;
145   fETAkac = 0;
146 }
148 //_____________________________________________________________________________
149 AliGenHIJINGpara::~AliGenHIJINGpara()
150 {
151   //
152   // Standard destructor
153   //
154   delete fPtpi;
155   delete fPtka;
156   delete fETApic;
157   delete fETAkac;
158 }
160 //_____________________________________________________________________________
161 void AliGenHIJINGpara::Init()
162 {
163   //
164   // Initialise the HIJING parametrisation
165   //
166   Float_t etaMin = -TMath::Log(TMath::Tan(TMath::Min((Double_t)fThetaMax/2,TMath::Pi()/2-1.e-10)));
167   Float_t etaMax = -TMath::Log(TMath::Tan(TMath::Max((Double_t)fThetaMin/2,              1.e-10)));
168   fPtpi = new TF1("ptpi",&ptpi,0,20,0);
169   fPtka = new TF1("ptka",&ptka,0,20,0);
170   fETApic = new TF1("etapic",&etapic,etaMin,etaMax,0);
171   fETAkac = new TF1("etakac",&etakac,etaMin,etaMax,0);
172   TF1 *ETApic0 = new TF1("etapic",&etapic,-7,7,0);
173   TF1 *ETAkac0 = new TF1("etakac",&etakac,-7,7,0);
174   Float_t IntETApi  = ETApic0->Integral(-0.5, 0.5);
175   Float_t IntETAka  = ETAkac0->Integral(-0.5, 0.5);
176   Float_t scalePi=7316/(IntETApi/1.5);
177   Float_t scaleKa= 684/(IntETAka/2.0);
179   Float_t IntPt  = (0.877*ETApic0->Integral(0, 15)+
180                     0.123*ETAkac0->Integral(0, 15));
181   Float_t IntPtSel = (0.877*ETApic0->Integral(fPtMin, fPtMax)+
182                       0.123*ETAkac0->Integral(fPtMin, fPtMax));
183   Float_t PtFrac = IntPtSel/IntPt;
186   Float_t IntETASel  = (scalePi*ETApic0->Integral(etaMin, etaMax)+
187                         scaleKa*ETAkac0->Integral(etaMin, etaMax));
188   Float_t PhiFrac = (fPhiMax-fPhiMin)/2/TMath::Pi();
189   fParentWeight = Float_t(fNpart)/IntETASel*PtFrac*PhiFrac;
191   printf("\n The number of particles in the selected kinematic region corresponds to %f percent of a full event\n ", 100.*fParentWeight);
193 }
195 //_____________________________________________________________________________
196 void AliGenHIJINGpara::Generate()
197 {
198   //
199   // Generate one trigger
200   //
202   AliMC* pMC = AliMC::GetMC();
204   const Float_t raKpic=0.14;
205   const Float_t borne=1/(1+raKpic);
206   Float_t polar[3]= {0,0,0};
207   //
208   const Int_t pi0=7;
209   const Int_t piplus=8;
210   const Int_t piminus=9;
211   const Int_t k0l=10;
212   const Int_t k0s=16;
213   const Int_t kplus=11;
214   const Int_t kminus=12;
215   //
216   const Int_t pions[3] = {pi0, piplus, piminus};
217   const Int_t kaons[4] = {k0l, k0s, kplus, kminus};
218   //
219   Float_t origin[3];
220   Float_t pt, pl, ptot;
221   Float_t phi, theta;
222   Float_t p[3];
223   Int_t i, part, nt, j;
224   //
225   TF1 *ptf;
226   TF1 *etaf;
227   //
228   Float_t random[6];
229   //
230   for (j=0;j<3;j++) origin[j]=fOrigin[j];
231   if(fVertexSmear==perEvent) {
232     pMC->Rndm(random,6);
233     for (j=0;j<3;j++) {
234       origin[j]+=fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
235         TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
236     }
237   }
238   for(i=0;i<fNpart;i++) {
239     while(1) {
240       pMC->Rndm(random,3);
241       if(random[0]<borne) {
242         part=pions[Int_t (random[1]*3)];
243         ptf=fPtpi;
244         etaf=fETApic;
245       } else {
246         part=kaons[Int_t (random[1]*4)];
247         ptf=fPtka;
248         etaf=fETAkac;
249       }
250       phi=2*random[2]*TMath::Pi();
251       if(phi<fPhiMin || phi>fPhiMax) continue;
252       theta=2*TMath::ATan(TMath::Exp(-etaf->GetRandom()));
253       if(theta<fThetaMin || theta>fThetaMax) continue;
254       pt=ptf->GetRandom();
255       pl=pt/TMath::Tan(theta);
256       ptot=TMath::Sqrt(pt*pt+pl*pl);
257       if(ptot<fPMin || ptot>fPMax) continue;
258       p[0]=pt*TMath::Cos(phi);
259       p[1]=pt*TMath::Sin(phi);
260       p[2]=pl;
261       if(fVertexSmear==perTrack) {
262         pMC->Rndm(random,6);
263         for (j=0;j<3;j++) {
264           origin[j]=fOrigin[j]+fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
265             TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
266         }
267       }
268       gAlice->SetTrack(1,-1,part,p,origin,polar,0,"Primary",nt,fParentWeight);
269       break;
270     }
271   }
272 }
274 ClassImp(AliGenFixed)
276 //_____________________________________________________________________________
277 AliGenFixed::AliGenFixed()
278   :AliGenerator()
279 {
280   //
281   // Default constructor
282   //
283   fIpart = 0;
284 }
286 //_____________________________________________________________________________
287 AliGenFixed::AliGenFixed(Int_t npart)
288   :AliGenerator(npart)
289 {
290   //
291   // Standard constructor
292   //
293   fName="Fixed";
294   fTitle="Fixed Particle Generator";
295   // Generate Proton by default
296   fIpart=14;
297 }
299 //_____________________________________________________________________________
300 void AliGenFixed::Generate()
301 {
302   //
303   // Generate one trigger
304   //
305   Float_t polar[3]= {0,0,0};
306   Float_t p[3] = {fPMin*TMath::Cos(fPhiMin)*TMath::Sin(fThetaMin),
307                   fPMin*TMath::Sin(fPhiMin)*TMath::Sin(fThetaMin),
308                   fPMin*TMath::Cos(fThetaMin)};
309   Int_t i, nt;
310   //
311   for(i=0;i<fNpart;i++) {
312     gAlice->SetTrack(1,-1,fIpart,p,fOrigin.GetArray(),polar,0,"Primary",nt);
313   }
314 }
316 //_____________________________________________________________________________
317 void AliGenFixed::SetSigma(Float_t, Float_t, Float_t)
318 {
319   //
320   // Set the interaction point sigma
321   //
322   printf("Vertex smearing not implemented for fixed generator\n");
323 }
326 ClassImp(AliGenBox)
328 //_____________________________________________________________________________
329 AliGenBox::AliGenBox()
330     :AliGenerator()
331 {
332   //
333   // Default constructor
334   //
335   fIpart=0;
336 }
338 //_____________________________________________________________________________
339 AliGenBox::AliGenBox(Int_t npart)
340   :AliGenerator(npart)
341 {
342   //
343   // Standard constructor
344   //
345   fName="Box";
346   fTitle="Box particle generator";
347   // Generate Proton by default
348   fIpart=14;
349 }
351 //_____________________________________________________________________________
352 void AliGenBox::Generate()
353 {
354   //
355   // Generate one trigger
356   //
357   AliMC* pMC = AliMC::GetMC();
359   Float_t polar[3]= {0,0,0};
360   //
361   Float_t origin[3];
362   Float_t p[3];
363   Int_t i, j, nt;
364   Float_t pmom, theta, phi;
365   //
366   Float_t random[6];
367   //
368   for (j=0;j<3;j++) origin[j]=fOrigin[j];
369   if(fVertexSmear==perEvent) {
370     pMC->Rndm(random,6);
371     for (j=0;j<3;j++) {
372       origin[j]+=fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
373         TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
374     }
375   }
376   for(i=0;i<fNpart;i++) {
377     pMC->Rndm(random,3);
378     pmom=fPMin+random[0]*(fPMax-fPMin);
379     theta=fThetaMin+random[1]*(fThetaMax-fThetaMin);
380     phi=fPhiMin+random[2]*(fPhiMax-fPhiMin);
381     p[0] = pmom*TMath::Cos(phi)*TMath::Sin(theta);
382     p[1] = pmom*TMath::Sin(phi)*TMath::Sin(theta);
383     p[2] = pmom*TMath::Cos(theta);
384     if(fVertexSmear==perTrack) {
385       pMC->Rndm(random,6);
386       for (j=0;j<3;j++) {
387         origin[j]=fOrigin[j]+fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
388           TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
389       }
390     }
391     gAlice->SetTrack(1,-1,fIpart,p,origin,polar,0,"Primary",nt);
392   }
393 }