dee33e4499e08b1fee943650b870576d96e23601
[u/mrichter/AliRoot.git] / ZDC / AliGenZDC.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.3  2000/10/02 21:28:20  fca
19 Removal of useless dependecies via forward declarations
20
21 Revision 1.2  2000/07/11 11:12:34  fca
22 Some syntax corrections for non standard HP aCC
23
24 Revision 1.1  2000/07/10 13:58:01  fca
25 New version of ZDC from E.Scomparin & C.Oppedisano
26
27 Revision 1.7  2000/01/19 17:17:40  fca
28
29 Revision 1.6  1999/09/29 09:24:35  fca
30 Introduction of the Copyright and cvs Log
31
32 */
33 #include <assert.h>
34
35 #include <TRandom.h>
36 #include <TLorentzVector.h>
37 #include <TVector3.h>
38 #include "TDatabasePDG.h"
39
40 #include "AliGenZDC.h"
41 #include "AliConst.h"
42 #include "AliPDG.h"
43 #include "AliRun.h"
44  
45 ClassImp(AliGenZDC)
46  
47 //_____________________________________________________________________________
48 AliGenZDC::AliGenZDC()
49    :AliGenerator()
50 {
51   //
52   // Default constructor
53   //
54   fIpart = 0;
55 }
56
57 //_____________________________________________________________________________
58 AliGenZDC::AliGenZDC(Int_t npart)
59    :AliGenerator(npart)
60 {
61   //
62   // Standard constructor
63   //
64   fName = "AliGenZDC";
65   fTitle = "Generation of Test Particles for ZDCs";
66   fIpart = kNeutron;
67   fCosx  = 0.;
68   fCosy  = 0.;
69   fCosz  = 1.;
70   fPseudoRapidity = 0.;
71   fFermiflag = 1;
72   // LHC values for beam divergence and crossing angle
73   fBeamDiv = 0.000032;
74   fBeamCrossAngle = 0.0001;
75   fBeamCrossPlane = 2;
76 }
77
78 //_____________________________________________________________________________
79 void AliGenZDC::Init()
80 {
81   printf("              Initializing AliGenZDC\n");
82   printf("      Fermi flag = %d, Beam Divergence = %f, Crossing Angle "
83          "= %f, Crossing Plane = %d\n\n", fFermiflag, fBeamDiv, fBeamCrossAngle,
84          fBeamCrossPlane);
85   //Initialize Fermi momentum distributions for Pb-Pb
86   FermiTwoGaussian(207.,82.,fPp,fProbintp,fProbintn);
87 }  
88   
89 //_____________________________________________________________________________
90 void AliGenZDC::Generate()
91 {
92   //
93   // Generate one trigger (n or p)
94   //
95   Int_t i;
96
97   Double_t mass, pLab[3], balp0, balp[3], ddp[3], dddp0, dddp[3];
98   Float_t ptot = fPMin;
99   Int_t nt;
100   
101   if(fPseudoRapidity==0.){
102     pLab[0] = ptot*fCosx;
103     pLab[1] = ptot*fCosy;
104     pLab[2] = ptot*fCosz;
105   }
106   else{
107     Float_t scang = 2*TMath::ATan(TMath::Exp(-(fPseudoRapidity)));
108     pLab[0] = -ptot*TMath::Sin(scang);
109     pLab[1] = 0.;
110     pLab[2] = ptot*TMath::Cos(scang);
111   }
112   for(i=0; i<=2; i++){
113      fP[i] = pLab[i];
114   }
115   
116   // Beam divergence and crossing angle
117   if(fBeamDiv!=0.) {BeamDivCross(0,fBeamDiv,fBeamCrossAngle,fBeamCrossPlane,pLab);}
118   if(fBeamCrossAngle!=0.) {BeamDivCross(1,fBeamDiv,fBeamCrossAngle,fBeamCrossPlane,pLab);}
119   
120   // If required apply the Fermi momentum
121   if(fFermiflag==1){
122     if((fIpart==kProton) || (fIpart==kNeutron)){
123       ExtractFermi(fIpart,fPp,fProbintp,fProbintn,ddp);
124     }
125     mass=gAlice->PDGDB()->GetParticle(fIpart)->Mass();
126 //  printf(" pLABx = %f  pLABy = %f  pLABz = %f \n",pLab[0],pLab[1],pLab[2]); 
127     for(i=0; i<=2; i++){
128        balp[i] = -pLab[i];
129     }
130     balp0 = TMath::Sqrt(pLab[0]*pLab[0]+pLab[1]*pLab[1]+pLab[2]*pLab[2]+mass*mass);
131     for(i=0; i<=2; i++){
132        dddp[i] = ddp[i];
133     }
134     dddp0 = TMath::Sqrt(dddp[0]*dddp[0]+dddp[1]*dddp[1]+dddp[2]*dddp[2]+mass*mass);
135     
136     TVector3 b(balp[0]/balp0, balp[1]/balp0, balp[2]/balp0);
137     TLorentzVector pFermi(dddp[0], dddp[1], dddp[2], dddp0);
138
139 //    printf(" pmu -> pLABx = %f  pLABy = %f  pLABz = %f  E = %f\n",
140 //           balp[0],balp[1],balp[2],balp0); 
141 //    printf(" Beta -> bx = %f  by = %f  bz = %f\n", b[0], b[1], b[2]);  
142 //    printf(" pFermi -> px = %f, py = %f, pz = %f\n", pFermi[0], pFermi[1], pFermi[2]);
143     
144     pFermi.Boost(b);
145
146 //    printf(" Boosted momentum -> px = %f, py = %f, pz = %f\n",
147 //           pFermi[0], pFermi[1], pFermi[2]);
148     for(i=0; i<=2; i++){
149        fBoostP[i] = pFermi[i];
150     }
151
152   }
153     
154   Float_t polar[3] = {0,0,0};
155   fBoostP[2]=-fBoostP[2];
156   gAlice->SetTrack(fTrackIt,-1,fIpart,fBoostP,fOrigin.GetArray(),polar,0,
157                    "Primary",nt);
158 }
159
160 //_____________________________________________________________________________
161 void AliGenZDC::FermiTwoGaussian(Double_t A, Float_t Z, Double_t* fPp, Double_t*
162                 fProbintp, Double_t* fProbintn)
163 {
164 //
165 // Momenta distributions according to the "double-gaussian"
166 // distribution (Ilinov) - equal for protons and neutrons
167 //
168 //   printf("           Initialization of Fermi momenta distribution\n");
169    fProbintp[0] = 0;
170    fProbintn[0] = 0;
171    Double_t sig1 = 0.113;
172    Double_t sig2 = 0.250;
173    Double_t alfa = 0.18*(TMath::Power((A/12.),(Float_t)1/3));
174    Double_t xk = (2*k2PI)/((1.+alfa)*(TMath::Power(k2PI,1.5)));
175    
176    for(Int_t i=1; i<=200; i++){
177       Double_t p = i*0.005;
178       fPp[i] = p;
179 //      printf(" fPp[%d] = %f\n",i,fPp[i]);
180       Double_t e1 = (p*p)/(2.*sig1*sig1);
181       Double_t e2 = (p*p)/(2.*sig2*sig2);
182       Double_t f1 = TMath::Exp(-(e1));
183       Double_t f2 = TMath::Exp(-(e2));
184       Double_t probp = xk*p*p*(f1/(TMath::Power(sig1,3.))+
185                       alfa*f2/(TMath::Power(sig2,3.)))*0.005;
186 //      printf("        probp = %f\n",probp);
187       fProbintp[i] = fProbintp[i-1] + probp;
188       fProbintn[i] = fProbintp[i];
189 //      printf(" fProbintp[%d] = %f, fProbintp[%d] = %f\n",i,fProbintp[i],i,fProbintn[i]);
190    }
191
192 //_____________________________________________________________________________
193 void AliGenZDC::ExtractFermi(Int_t id, Double_t* fPp, Double_t* fProbintp,
194                 Double_t* fProbintn, Double_t* ddp)
195 {
196 //
197 // Compute Fermi momentum for spectator nucleons
198 //
199   Int_t i;
200   Float_t xx = gRandom->Rndm();
201   assert ( id==kProton || id==kNeutron );
202   if(id==kProton){
203     for(i=0; i<=200; i++){
204        if((xx>=fProbintp[i-1]) && (xx<fProbintp[i])) break;
205        }
206   }
207   else {
208     for(i=0; i<=200; i++){
209        if((xx>=fProbintn[i-1]) && (xx<fProbintn[i])) break;
210        }
211    }
212          Float_t pext = fPp[i]+0.001;
213          Float_t phi = k2PI*(gRandom->Rndm());
214          Float_t cost = (1.-2.*(gRandom->Rndm()));
215          Float_t tet = TMath::ACos(cost);
216          ddp[0] = pext*TMath::Sin(tet)*TMath::Cos(phi);
217          ddp[1] = pext*TMath::Sin(tet)*TMath::Sin(phi);
218          ddp[2] = pext*cost;
219 }
220
221 //_____________________________________________________________________________
222 void AliGenZDC::BeamDivCross(Int_t icross, Float_t fBeamDiv, Float_t fBeamCrossAngle, 
223                 Int_t fBeamCrossPlane, Double_t* pLab)
224 {
225   Double_t tetpart, fipart, tetdiv=0, fidiv=0, angleSum[2], tetsum, fisum, dplab[3];
226   Double_t rvec;
227
228   Int_t i;
229   
230   Double_t pmq = 0.;
231   for(i=0; i<=2; i++){
232      dplab[i] = pLab[i];
233      pmq = pmq+pLab[i]*pLab[i];
234   }
235   Double_t pmod = TMath::Sqrt(pmq);
236 //  printf("    pmod = %f\n",pmod);
237
238 //  printf("    icross = %d, fBeamDiv = %f\n",icross,fBeamDiv);
239   if(icross==0){
240     rvec = gRandom->Gaus(0.0,1.0);
241     tetdiv = fBeamDiv * TMath::Abs(rvec);
242     fidiv = (gRandom->Rndm())*k2PI;
243   }
244   else if(icross==1){
245     if(fBeamCrossPlane==0.){
246       tetdiv = 0.;
247       fidiv = 0.;
248     }
249     else if(fBeamCrossPlane==1.){
250       tetdiv = fBeamCrossAngle;
251       fidiv = 0.;
252     }
253     else if(fBeamCrossPlane==2.){
254       tetdiv = fBeamCrossAngle;
255       fidiv = k2PI/4.;
256     }
257   }
258 //  printf("    tetdiv = %f, fidiv = %f\n",tetdiv,fidiv);
259   tetpart = TMath::ATan(TMath::Sqrt(dplab[0]*dplab[0]+dplab[1]*dplab[1])/dplab[2]);
260   if(dplab[1]!=0. || dplab[0]!=0.){
261     fipart = TMath::ATan2(dplab[1],dplab[0]);
262   }
263   else{
264     fipart = 0.;
265   }
266   if(fipart<0.) {fipart = fipart+k2PI;}
267 //  printf("    tetpart = %f, fipart = %f\n",tetpart,fipart);
268   tetdiv = tetdiv*kRaddeg;
269   fidiv = fidiv*kRaddeg;
270   tetpart = tetpart*kRaddeg;
271   fipart = fipart*kRaddeg;
272   AddAngle(tetpart,fipart,tetdiv,fidiv,angleSum);
273   tetsum = angleSum[0];
274   fisum  = angleSum[1];
275 //  printf("    tetsum = %f, fisum = %f\n",tetsum,fisum);
276   tetsum = tetsum*kDegrad;
277   fisum = fisum*kDegrad;
278   pLab[0] = pmod*TMath::Sin(tetsum)*TMath::Cos(fisum);
279   pLab[1] = pmod*TMath::Sin(tetsum)*TMath::Sin(fisum);
280   pLab[2] = pmod*TMath::Cos(tetsum);
281 //  printf("    pLab[0] = %f pLab[1] = %f pLab[2] = %f \n\n",
282 //         pLab[0],pLab[1],pLab[2]);
283   for(i=0; i<=2; i++){
284      fDivP[i] = pLab[i];
285   }
286 }
287   
288 //_____________________________________________________________________________
289 void  AliGenZDC::AddAngle(Double_t theta1, Double_t phi1, Double_t theta2,
290                Double_t phi2, Double_t* angleSum)
291 {
292   Double_t temp, conv, cx, cy, cz, ct1, st1, ct2, st2, cp1, sp1, cp2, sp2;
293   Double_t rtetsum, tetsum, fisum;
294   
295   temp = -1.;
296   conv = 180./TMath::ACos(temp);
297   
298   ct1 = TMath::Cos(theta1/conv);
299   st1 = TMath::Sin(theta1/conv);
300   cp1 = TMath::Cos(phi1/conv);
301   sp1 = TMath::Sin(phi1/conv);
302   ct2 = TMath::Cos(theta2/conv);
303   st2 = TMath::Sin(theta2/conv);
304   cp2 = TMath::Cos(phi2/conv);
305   sp2 = TMath::Sin(phi2/conv);
306   cx = ct1*cp1*st2*cp2+st1*cp1*ct2-sp1*st2*sp2;
307   cy = ct1*sp1*st2*cp2+st1*sp1*ct2+cp1*st2*sp2;
308   cz = ct1*ct2-st1*st2*cp2;
309   
310   rtetsum = TMath::ACos(cz);
311   tetsum = conv*rtetsum;
312   if(tetsum==0. || tetsum==180.){
313     fisum = 0.;
314     return;
315   }
316   temp = cx/TMath::Sin(rtetsum);
317   if(temp>1.) temp=1.;
318   if(temp<-1.) temp=-1.;
319   fisum = conv*TMath::ACos(temp);
320   if(cy<0) {fisum = 360.-fisum;}
321 //  printf("    AddAngle -> tetsum = %f, fisum = %f\n",tetsum, fisum); 
322   angleSum[0] = tetsum;
323   angleSum[1] = fisum;
324 }  
325