Better control of momentum range in GenBox
[u/mrichter/AliRoot.git] / EVGEN / AliSimpleGen.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /*
17 $Log$
18 Revision 1.7  2000/06/07 16:29:58  fca
19 Adding check for pt range in AliGenBox
20
21 Revision 1.6  1999/11/03 17:43:20  fca
22 New version from G.Martinez & A.Morsch
23
24 Revision 1.5  1999/09/29 09:24:14  fca
25 Introduction of the Copyright and cvs Log
26
27 */
28
29 ///////////////////////////////////////////////////////////////////
30 //                                                               //
31 //    Generate the final state of the interaction as the input   //
32 //    to the MonteCarlo                                          //
33 //
34 //Begin_Html
35 /*
36 <img src="picts/AliGeneratorClass.gif">
37 </pre>
38 <br clear=left>
39 <font size=+2 color=red>
40 <p>The responsible person for this module is
41 <a href="mailto:andreas.morsch@cern.ch">Andreas Morsch</a>.
42 </font>
43 <pre>
44 */
45 //End_Html
46 //                                                               //
47 ///////////////////////////////////////////////////////////////////
48
49 #include "AliSimpleGen.h"
50 #include "AliRun.h"
51 #include "AliConst.h"
52 #include "AliPDG.h"
53 #include "TF1.h"
54
55 ClassImp(AliGenHIJINGpara)
56
57 //_____________________________________________________________________________
58 static Double_t ptpi(Double_t *px, Double_t *)
59 {
60   //
61   //     PT-PARAMETERIZATION CDF, PRL 61(88) 1819
62   //     POWER LAW FOR PT > 500 MEV
63   //     MT SCALING BELOW (T=160 MEV)
64   //
65   const Double_t kp0 = 1.3;
66   const Double_t kxn = 8.28;
67   const Double_t kxlim=0.5;
68   const Double_t kt=0.160;
69   const Double_t kxmpi=0.139;
70   const Double_t kb=1.;
71   Double_t y, y1, xmpi2, ynorm, a;
72   Double_t x=*px;
73   //
74   y1=TMath::Power(kp0/(kp0+kxlim),kxn);
75   xmpi2=kxmpi*kxmpi;
76   ynorm=kb*(TMath::Exp(-sqrt(kxlim*kxlim+xmpi2)/kt));
77   a=ynorm/y1;
78   if (x > kxlim)
79     y=a*TMath::Power(kp0/(kp0+x),kxn);
80   else
81     y=kb*TMath::Exp(-sqrt(x*x+xmpi2)/kt);
82   return y*x;
83 }
84
85 //_____________________________________________________________________________
86 static Double_t ptscal(Double_t pt, Int_t np)
87 {
88     //    SCALING EN MASSE PAR RAPPORT A PTPI
89     //     MASS PI,K,ETA,RHO,OMEGA,ETA',PHI
90     const Double_t khm[10] = {.13957,.493,.5488,.769,.7826,.958,1.02,0,0,0};
91     //     VALUE MESON/PI AT 5 GEV
92     const Double_t kfmax[10]={1.,0.3,0.55,1.0,1.0,1.0,1.0,0,0,0};
93     np--;
94     Double_t f5=TMath::Power(((
95         sqrt(100.018215)+2.)/(sqrt(100.+khm[np]*khm[np])+2.0)),12.3);
96     Double_t fmax2=f5/kfmax[np];
97     // PIONS
98     Double_t ptpion=100.*ptpi(&pt, (Double_t*) 0);
99     Double_t fmtscal=TMath::Power(((
100         sqrt(pt*pt+0.018215)+2.)/ (sqrt(pt*pt+khm[np]*khm[np])+2.0)),12.3)/ 
101         fmax2;
102     return fmtscal*ptpion;
103 }
104
105 //_____________________________________________________________________________
106 static Double_t ptka( Double_t *px, Double_t *)
107 {
108     //
109     // pt parametrisation for k
110     //
111     return ptscal(*px,2);
112 }
113
114
115 //_____________________________________________________________________________
116 static Double_t etapic( Double_t *py, Double_t *)
117 {
118   //
119   // eta parametrisation for pi
120   //
121     const Double_t ka1    = 4913.;
122     const Double_t ka2    = 1819.;
123     const Double_t keta1  = 0.22;
124     const Double_t keta2  = 3.66;
125     const Double_t kdeta1 = 1.47;
126     const Double_t kdeta2 = 1.51;
127     Double_t y=TMath::Abs(*py);
128     //
129     Double_t ex1 = (y-keta1)*(y-keta1)/(2*kdeta1*kdeta1);
130     Double_t ex2 = (y-keta2)*(y-keta2)/(2*kdeta2*kdeta2);
131     return ka1*TMath::Exp(-ex1)+ka2*TMath::Exp(-ex2);
132 }
133
134 //_____________________________________________________________________________
135 static Double_t etakac( Double_t *py, Double_t *)
136 {
137     //
138     // eta parametrisation for ka
139     //
140     const Double_t ka1    = 497.6;
141     const Double_t ka2    = 215.6;
142     const Double_t keta1  = 0.79;
143     const Double_t keta2  = 4.09;
144     const Double_t kdeta1 = 1.54;
145     const Double_t kdeta2 = 1.40;
146     Double_t y=TMath::Abs(*py);
147     //
148     Double_t ex1 = (y-keta1)*(y-keta1)/(2*kdeta1*kdeta1);
149     Double_t ex2 = (y-keta2)*(y-keta2)/(2*kdeta2*kdeta2);
150     return ka1*TMath::Exp(-ex1)+ka2*TMath::Exp(-ex2);
151 }
152
153 //_____________________________________________________________________________
154 AliGenHIJINGpara::AliGenHIJINGpara()
155   :AliGenerator()
156 {
157     //
158     // Default constructor
159     //
160     fPtpi = 0;
161     fPtka = 0;
162     fETApic = 0;
163     fETAkac = 0;
164 }
165
166 //_____________________________________________________________________________
167 AliGenHIJINGpara::AliGenHIJINGpara(Int_t npart)
168   :AliGenerator(npart)
169 {
170   // 
171   // Standard constructor
172   //
173     fName="HIGINGpara";
174     fTitle="HIJING Parametrisation Particle Generator";
175     fPtpi = 0;
176     fPtka = 0;
177     fETApic = 0;
178     fETAkac = 0;
179 }
180
181 //_____________________________________________________________________________
182 AliGenHIJINGpara::~AliGenHIJINGpara()
183 {
184   //
185   // Standard destructor
186   //
187     delete fPtpi;
188     delete fPtka;
189     delete fETApic;
190     delete fETAkac;
191 }
192
193 //_____________________________________________________________________________
194 void AliGenHIJINGpara::Init()
195 {
196   //
197   // Initialise the HIJING parametrisation
198   //
199     Float_t etaMin =-TMath::Log(TMath::Tan(
200         TMath::Min((Double_t)fThetaMax/2,TMath::Pi()/2-1.e-10)));
201     Float_t etaMax = -TMath::Log(TMath::Tan(
202         TMath::Max((Double_t)fThetaMin/2,1.e-10)));
203     fPtpi = new TF1("ptpi",&ptpi,0,20,0);
204     fPtka = new TF1("ptka",&ptka,0,20,0);
205     fETApic = new TF1("etapic",&etapic,etaMin,etaMax,0);
206     fETAkac = new TF1("etakac",&etakac,etaMin,etaMax,0);
207     TF1 *etaPic0 = new TF1("etapic",&etapic,-7,7,0);
208     TF1 *etaKac0 = new TF1("etakac",&etakac,-7,7,0);
209     Float_t intETApi  = etaPic0->Integral(-0.5, 0.5);
210     Float_t intETAka  = etaKac0->Integral(-0.5, 0.5);
211     Float_t scalePi=7316/(intETApi/1.5);
212     Float_t scaleKa= 684/(intETAka/2.0);
213     
214     Float_t intPt  = (0.877*etaPic0->Integral(0, 15)+
215                       0.123*etaKac0->Integral(0, 15));
216     Float_t intPtSel = (0.877*etaPic0->Integral(fPtMin, fPtMax)+
217                         0.123*etaKac0->Integral(fPtMin, fPtMax));
218     Float_t ptFrac = intPtSel/intPt;
219     
220     
221     Float_t intETASel  = (scalePi*etaPic0->Integral(etaMin, etaMax)+
222                           scaleKa*etaKac0->Integral(etaMin, etaMax));
223     Float_t phiFrac = (fPhiMax-fPhiMin)/2/TMath::Pi();
224     fParentWeight = Float_t(fNpart)/intETASel*ptFrac*phiFrac;
225     
226     printf("\n The number of particles in the selected kinematic region corresponds to %f percent of a full event\n ", 100.*fParentWeight);
227     
228 }
229
230 //_____________________________________________________________________________
231 void AliGenHIJINGpara::Generate()
232 {
233   //
234   // Generate one trigger
235   //
236
237   
238     const Float_t kRaKpic=0.14;
239     const Float_t kBorne=1/(1+kRaKpic);
240     Float_t polar[3]= {0,0,0};
241     //
242     const Int_t kPions[3] = {kPi0, kPiPlus, kPiMinus};
243     const Int_t kKaons[4] = {kK0Long, kK0Short, kKPlus, kKMinus};
244     //
245     Float_t origin[3];
246     Float_t pt, pl, ptot;
247     Float_t phi, theta;
248     Float_t p[3];
249     Int_t i, part, nt, j;
250     //
251     TF1 *ptf;
252     TF1 *etaf;
253     //
254     Float_t random[6];
255     //
256     for (j=0;j<3;j++) origin[j]=fOrigin[j];
257     if(fVertexSmear==perEvent) {
258         gMC->Rndm(random,6);
259         for (j=0;j<3;j++) {
260             origin[j]+=fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
261                 TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
262         }
263     }
264     for(i=0;i<fNpart;i++) {
265         while(1) {
266             gMC->Rndm(random,3);
267             if(random[0]<kBorne) {
268                 part=kPions[Int_t (random[1]*3)];
269                 ptf=fPtpi;
270               etaf=fETApic;
271             } else {
272                 part=kKaons[Int_t (random[1]*4)];
273                 ptf=fPtka;
274                 etaf=fETAkac;
275             }
276             phi=fPhiMin+random[2]*(fPhiMax-fPhiMin);
277             theta=2*TMath::ATan(TMath::Exp(-etaf->GetRandom()));
278             if(theta<fThetaMin || theta>fThetaMax) continue;
279             pt=ptf->GetRandom();
280             pl=pt/TMath::Tan(theta);
281             ptot=TMath::Sqrt(pt*pt+pl*pl);
282             if(ptot<fPMin || ptot>fPMax) continue;
283             p[0]=pt*TMath::Cos(phi);
284             p[1]=pt*TMath::Sin(phi);
285             p[2]=pl;
286             if(fVertexSmear==perTrack) {
287                 gMC->Rndm(random,6);
288                 for (j=0;j<3;j++) {
289                     origin[j]=fOrigin[j]+fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
290                         TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
291                 }
292             }
293             gAlice->SetTrack(fTrackIt,-1,part,p,origin,polar,0,"Primary",nt,fParentWeight);
294             break;
295         }
296     }
297 }
298   
299 ClassImp(AliGenFixed)
300
301 //_____________________________________________________________________________
302 AliGenFixed::AliGenFixed()
303   :AliGenerator()
304 {
305   //
306   // Default constructor
307   //
308   fIpart = 0;
309 }
310
311 //_____________________________________________________________________________
312 AliGenFixed::AliGenFixed(Int_t npart)
313   :AliGenerator(npart)
314 {
315   //
316   // Standard constructor
317   //
318   fName="Fixed";
319   fTitle="Fixed Particle Generator";
320   // Generate Proton by default
321   fIpart=kProton;
322 }
323
324 //_____________________________________________________________________________
325 void AliGenFixed::Generate()
326 {
327   //
328   // Generate one trigger
329   //
330   Float_t polar[3]= {0,0,0};
331   Float_t p[3] = {fPMin*TMath::Cos(fPhiMin)*TMath::Sin(fThetaMin),
332                   fPMin*TMath::Sin(fPhiMin)*TMath::Sin(fThetaMin),
333                   fPMin*TMath::Cos(fThetaMin)};
334   Int_t i, nt;
335   //
336   for(i=0;i<fNpart;i++) {
337     gAlice->SetTrack(fTrackIt,-1,fIpart,p,fOrigin.GetArray(),polar,0,"Primary",nt);
338   }
339 }
340   
341 //_____________________________________________________________________________
342 void AliGenFixed::SetSigma(Float_t sx, Float_t sy, Float_t sz)
343 {
344   //
345   // Set the interaction point sigma
346   //
347   printf("Vertex smearing not implemented for fixed generator\n");
348 }
349
350
351 ClassImp(AliGenBox)
352
353 //_____________________________________________________________________________
354 AliGenBox::AliGenBox()
355     :AliGenerator()
356 {
357   //
358   // Default constructor
359   //
360   fIpart=0;
361 }
362
363 //_____________________________________________________________________________
364 AliGenBox::AliGenBox(Int_t npart)
365   :AliGenerator(npart)
366 {
367   //
368   // Standard constructor
369   //
370   fName="Box";
371   fTitle="Box particle generator";
372   // Generate Proton by default
373   fIpart=kProton;
374 }
375
376 //_____________________________________________________________________________
377
378 void AliGenBox::Generate()
379 {
380   //
381   // Generate one trigger
382   //
383   
384     Float_t polar[3]= {0,0,0};
385   //
386     Float_t origin[3];
387     Float_t p[3];
388     Int_t i, j, nt;
389     Double_t pmom, theta, phi, pt;
390     //
391     Float_t random[6];
392   //
393     for (j=0;j<3;j++) origin[j]=fOrigin[j];
394     if(fVertexSmear==perEvent) {
395         gMC->Rndm(random,6);
396         for (j=0;j<3;j++) {
397             origin[j]+=fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
398                 TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
399         }
400     }
401     for(i=0;i<fNpart;i++) {
402         gMC->Rndm(random,3);
403         theta=fThetaMin+random[0]*(fThetaMax-fThetaMin);
404         if(TestBit(kMomentumRange)) {
405             pmom=fPMin+random[1]*(fPMax-fPMin);
406             pt=pmom*TMath::Sin(theta);
407         } else {
408
409             pt=fPtMin+random[1]*(fPtMax-fPtMin);
410             pmom=pt/TMath::Sin(theta);
411         }
412         phi=fPhiMin+random[2]*(fPhiMax-fPhiMin);
413         p[0] = pt*TMath::Cos(phi);
414         p[1] = pt*TMath::Sin(phi);
415         p[2] = pmom*TMath::Cos(theta);
416
417         if(fVertexSmear==perTrack) {
418             gMC->Rndm(random,6);
419             for (j=0;j<3;j++) {
420                 origin[j]=fOrigin[j]+fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
421                     TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
422             }
423         }
424         gAlice->SetTrack(fTrackIt,-1,fIpart,p,origin,polar,0,"Primary",nt);
425     }
426 }
427
428 //_____________________________________________________________________________
429
430 void AliGenBox::Init()
431 {
432   if(TestBit(kPtRange)&&TestBit(kMomentumRange)) 
433     Fatal("Init","You should not set the momentum range and the pt range!\n");
434   if((!TestBit(kPtRange))&&(!TestBit(kMomentumRange))) 
435     Fatal("Init","You should set either the momentum or the pt range!\n");
436 }