All coding rule violations except RS3 corrected
[u/mrichter/AliRoot.git] / EVGEN / AliGenPythia.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.16  2000/05/15 15:04:20  morsch
19 The full event is written for fNtrack = -1
20 Coding rule violations corrected.
21
22 Revision 1.15  2000/04/26 10:14:24  morsch
23 Particles array has one entry more than pythia particle list. Upper bound of
24 particle loop changed to np-1 (R. Guernane, AM)
25
26 Revision 1.14  2000/04/05 08:36:13  morsch
27 Check status code of particles in Pythia event
28 to avoid double counting as partonic state and final state particle.
29
30 Revision 1.13  1999/11/09 07:38:48  fca
31 Changes for compatibility with version 2.23 of ROOT
32
33 Revision 1.12  1999/11/03 17:43:20  fca
34 New version from G.Martinez & A.Morsch
35
36 Revision 1.11  1999/09/29 09:24:14  fca
37 Introduction of the Copyright and cvs Log
38 */
39
40 #include "AliGenPythia.h"
41 #include "AliRun.h"
42 #include "AliPythia.h"
43 #include <TParticle.h>
44
45  ClassImp(AliGenPythia)
46
47 AliGenPythia::AliGenPythia()
48                  :AliGenerator()
49 {
50 // Constructor
51 }
52
53 AliGenPythia::AliGenPythia(Int_t npart)
54                  :AliGenerator(npart)
55 {
56 // default charm production at 5. 5 TeV
57 // semimuonic decay
58 // structure function GRVHO
59 //
60     fXsection  = 0.;
61     fParentSelect.Set(5);
62     fChildSelect.Set(5);
63     for (Int_t i=0; i<5; i++) fParentSelect[i]=fChildSelect[i]=0;
64     SetProcess();
65     SetStrucFunc();
66     SetForceDecay();
67     SetPtHard();
68     SetEnergyCMS();
69 }
70
71 AliGenPythia::AliGenPythia(const AliGenPythia & Pythia)
72 {
73 // copy constructor
74 }
75
76 AliGenPythia::~AliGenPythia()
77 {
78 // Destructor
79 }
80
81 void AliGenPythia::Init()
82 {
83 // Initialisation
84     SetMC(new AliPythia());
85     fPythia=(AliPythia*) fgMCEvGen;
86 //
87     fParentWeight=1./Float_t(fNpart);
88 //
89 //  Forward Paramters to the AliPythia object
90     fPythia->DefineParticles();
91     fPythia->SetCKIN(3,fPtHardMin);
92     fPythia->SetCKIN(4,fPtHardMax);    
93     fPythia->ProcInit(fProcess,fEnergyCMS,fStrucFunc);
94     fPythia->ForceDecay(fForceDecay);
95     fPythia->Lulist(0);
96     fPythia->Pystat(2);
97 //  Parent and Children Selection
98     switch (fProcess) 
99     {
100     case charm:
101
102         fParentSelect[0]=411;
103         fParentSelect[1]=421;
104         fParentSelect[2]=431;
105         fParentSelect[3]=4122;  
106         break;
107     case charm_unforced:
108
109         fParentSelect[0]=411;
110         fParentSelect[1]=421;
111         fParentSelect[2]=431;
112         fParentSelect[3]=4122;  
113         break;
114     case beauty:
115         fParentSelect[0]=511;
116         fParentSelect[1]=521;
117         fParentSelect[2]=531;
118         fParentSelect[3]=5122;  
119         break;
120     case beauty_unforced:
121         fParentSelect[0]=511;
122         fParentSelect[1]=521;
123         fParentSelect[2]=531;
124         fParentSelect[3]=5122;  
125         break;
126     case jpsi_chi:
127     case jpsi:
128         fParentSelect[0]=443;
129         break;
130     case mb:
131         break;
132     }
133
134     switch (fForceDecay) 
135     {
136     case semielectronic:
137     case dielectron:
138     case b_jpsi_dielectron:
139     case b_psip_dielectron:
140         fChildSelect[0]=11;     
141         break;
142     case semimuonic:
143     case dimuon:
144     case b_jpsi_dimuon:
145     case b_psip_dimuon:
146     case pitomu:
147     case katomu:
148         fChildSelect[0]=13;
149         break;
150     case all:
151     case nodecay:
152         break;
153     }
154 }
155
156 void AliGenPythia::Generate()
157 {
158 // Generate one event
159
160     Float_t polar[3] =   {0,0,0};
161     Float_t origin[3]=   {0,0,0};
162     Float_t originP[3]= {0,0,0};
163     Float_t origin0[3]=  {0,0,0};
164     Float_t p[3], pP[4], random[6];
165     static TClonesArray *particles;
166 //  converts from mm/c to s
167     const Float_t kconv=0.001/2.999792458e8;
168     
169     
170 //
171     Int_t nt=0;
172     Int_t ntP=0;
173     Int_t jev=0;
174     Int_t j, kf;
175
176     if(!particles) particles=new TClonesArray("TParticle",1000);
177     
178     fTrials=0;
179     for (j=0;j<3;j++) origin0[j]=fOrigin[j];
180     if(fVertexSmear==perEvent) {
181         gMC->Rndm(random,6);
182         for (j=0;j<3;j++) {
183             origin0[j]+=fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
184                 TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
185             fPythia->SetMSTP(151,0);
186         }
187     } else if (fVertexSmear==perTrack) {
188         fPythia->SetMSTP(151,0);
189         for (j=0;j<3;j++) {
190             fPythia->SetPARP(151+j, fOsigma[j]*10.);
191         }
192     }
193     while(1)
194     {
195         fPythia->Pyevnt();
196 //      fPythia->Lulist(1);
197         fTrials++;
198         fPythia->ImportParticles(particles,"All");
199         Int_t np = particles->GetEntriesFast();
200         printf("\n **************************************************%d\n",np);
201         Int_t nc=0;
202         if (np == 0 ) continue;
203         if (fProcess != mb) {
204             for (Int_t i = 0; i<np-1; i++) {
205                 TParticle *  iparticle = (TParticle *) particles->At(i);
206                 Int_t ks = iparticle->GetStatusCode();
207                 kf = CheckPDGCode(iparticle->GetPdgCode());
208                 if (ks==21) continue;
209
210                 fChildWeight=(fPythia->GetBraPart(kf))*fParentWeight;     
211 //
212 // Parent
213                 if (ParentSelected(TMath::Abs(kf))) {
214                     if (KinematicSelection(iparticle)) {
215                         if (nc==0) {
216 //
217 // Store information concerning the hard scattering process
218 //
219                             Float_t massP  = fPythia->GetPARI(13);
220                             Float_t   ptP  = fPythia->GetPARI(17);
221                             Float_t    yP  = fPythia->GetPARI(37);
222                             Float_t  xmtP  = sqrt(ptP*ptP+massP*massP);
223                             Float_t    ty  = Float_t(TMath::TanH(yP));
224                             pP[0] = ptP;
225                             pP[1] = 0;
226                             pP[2] = xmtP*ty/sqrt(1.-ty*ty);
227                             pP[3] = massP;
228                             gAlice->SetTrack(0,-1,-1,
229                                              pP,originP,polar,
230                                              0,"Hard Scat.",ntP,fParentWeight);
231                             gAlice->KeepTrack(ntP);
232                         }
233                         nc++;
234 //
235 // store parent track information
236                         p[0]=iparticle->Px();
237                         p[1]=iparticle->Py();
238                         p[2]=iparticle->Pz();
239                         origin[0]=origin0[0]+iparticle->Vx()/10;
240                         origin[1]=origin0[1]+iparticle->Vy()/10;
241                         origin[2]=origin0[2]+iparticle->Vz()/10;
242
243                         Int_t ifch=iparticle->GetFirstDaughter();
244                         Int_t ilch=iparticle->GetLastDaughter();        
245                         if (ifch !=0 && ilch !=0) {
246                             gAlice->SetTrack(0,ntP,kf,
247                                              p,origin,polar,
248                                              0,"Primary",nt,fParentWeight);
249                             gAlice->KeepTrack(nt);
250                             Int_t iparent = nt;
251 //
252 // Children         
253
254                             for (j=ifch; j<=ilch; j++)
255                             {
256                                 TParticle *  ichild = 
257                                     (TParticle *) particles->At(j-1);
258                                 kf = CheckPDGCode(ichild->GetPdgCode());
259 //
260 // 
261                                 if (ChildSelected(TMath::Abs(kf))) {
262                                     origin[0]=ichild->Vx();
263                                     origin[1]=ichild->Vy();
264                                     origin[2]=ichild->Vz();             
265                                     p[0]=ichild->Px();
266                                     p[1]=ichild->Py();
267                                     p[2]=ichild->Pz();
268                                     Float_t tof=kconv*ichild->T();
269                                     gAlice->SetTrack(fTrackIt, iparent, kf,
270                                                      p,origin,polar,
271                                                      tof,"Decay",nt,fChildWeight);
272                                     gAlice->KeepTrack(nt);
273                                 } // select child
274                             } // child loop
275                         }
276                     } // kinematic selection
277                 } // select particle
278             } // particle loop
279         } else {
280             for (Int_t i = 0; i<np-1; i++) {
281                 TParticle *  iparticle = (TParticle *) particles->At(i);
282                 kf = CheckPDGCode(iparticle->GetPdgCode());
283                 Int_t ks = iparticle->GetStatusCode();
284
285                 if (ks==1 && kf!=0 && KinematicSelection(iparticle)) {
286                         nc++;
287 //
288 // store track information
289                         p[0]=iparticle->Px();
290                         p[1]=iparticle->Py();
291                         p[2]=iparticle->Pz();
292                         origin[0]=origin0[0]+iparticle->Vx()/10;
293                         origin[1]=origin0[1]+iparticle->Vy()/10;
294                         origin[2]=origin0[2]+iparticle->Vz()/10;
295                         Float_t tof=kconv*iparticle->T();
296                         gAlice->SetTrack(fTrackIt,-1,kf,p,origin,polar,
297                                          tof,"Primary",nt);
298                         gAlice->KeepTrack(nt);
299                 } // select particle
300             } // particle loop 
301             printf("\n I've put %i particles on the stack \n",nc);
302         } // mb ?
303         if (nc > 0) {
304             jev+=nc;
305             if (jev >= fNpart || fNpart == -1) {
306                 fKineBias=Float_t(fNpart)/Float_t(fTrials);
307                 printf("\n Trials: %i %i %i\n",fTrials, fNpart, jev);
308                 break;
309             }
310         }
311     } // event loop
312 //  adjust weight due to kinematic selection
313     AdjustWeights();
314 //  get cross-section
315     fXsection=fPythia->GetPARI(1);
316 }
317
318 Bool_t AliGenPythia::ParentSelected(Int_t ip)
319 {
320 // True if particle is in list of parent particles to be selected
321     for (Int_t i=0; i<5; i++)
322     {
323         if (fParentSelect[i]==ip) return kTRUE;
324     }
325     return kFALSE;
326 }
327
328 Bool_t AliGenPythia::ChildSelected(Int_t ip)
329 {
330 // True if particle is in list of decay products to be selected
331     for (Int_t i=0; i<5; i++)
332     {
333         if (fChildSelect[i]==ip) return kTRUE;
334     }
335     return kFALSE;
336 }
337
338 Bool_t AliGenPythia::KinematicSelection(TParticle *particle)
339 {
340 // Perform kinematic selection
341     Float_t px=particle->Px();
342     Float_t py=particle->Py();
343     Float_t pz=particle->Pz();
344     Float_t  e=particle->Energy();
345
346 //
347 //  transverse momentum cut    
348     Float_t pt=TMath::Sqrt(px*px+py*py);
349     if (pt > fPtMax || pt < fPtMin) 
350     {
351 //      printf("\n failed pt cut %f %f %f \n",pt,fPtMin,fPtMax);
352         return kFALSE;
353     }
354 //
355 // momentum cut
356     Float_t p=TMath::Sqrt(px*px+py*py+pz*pz);
357     if (p > fPMax || p < fPMin) 
358     {
359 //      printf("\n failed p cut %f %f %f \n",p,fPMin,fPMax);
360         return kFALSE;
361     }
362     
363 //
364 // theta cut
365     Float_t  theta = Float_t(TMath::ATan2(Double_t(pt),Double_t(pz)));
366     if (theta > fThetaMax || theta < fThetaMin) 
367     {
368 //      printf("\n failed theta cut %f %f %f \n",theta,fThetaMin,fThetaMax);
369         return kFALSE;
370     }
371
372 //
373 // rapidity cut
374     Float_t y = 0.5*TMath::Log((e+pz)/(e-pz));
375     if (y > fYMax || y < fYMin)
376     {
377 //      printf("\n failed y cut %f %f %f \n",y,fYMin,fYMax);
378         return kFALSE;
379     }
380
381 //
382 // phi cut
383     Float_t phi=Float_t(TMath::ATan2(Double_t(py),Double_t(px)));
384     if (phi > fPhiMax || phi < fPhiMin)
385     {
386 //      printf("\n failed phi cut %f %f %f \n",phi,fPhiMin,fPhiMax);
387         return kFALSE;
388     }
389
390     return kTRUE;
391 }
392 void AliGenPythia::AdjustWeights()
393 {
394 // Adjust the weights after generation of all events
395 //
396     TClonesArray *partArray = gAlice->Particles();
397     TParticle *part;
398     Int_t ntrack=gAlice->GetNtrack();
399     for (Int_t i=0; i<ntrack; i++) {
400         part= (TParticle*) partArray->UncheckedAt(i);
401         part->SetWeight(part->GetWeight()*fKineBias);
402     }
403 }
404
405 Int_t AliGenPythia::CheckPDGCode(Int_t pdgcode)
406 {
407 //
408 //  If the particle is in a diffractive state, then take action accordingly
409   switch (pdgcode) {
410   case 110:
411     //rho_diff0 -- difficult to translate, return rho0
412     return 113;
413   case 210:
414     //pi_diffr+ -- change to pi+
415     return 211;
416   case 220:
417     //omega_di0 -- change to omega0
418     return 223;
419   case 330:
420     //phi_diff0 -- return phi0
421     return 333;
422   case 440:
423     //J/psi_di0 -- return J/psi
424     return 443;
425   case 2110:
426     //n_diffr -- return neutron
427     return 2112;
428   case 2210:
429     //p_diffr+ -- return proton
430     return 2212;
431   }
432   //non diffractive state -- return code unchanged
433   return pdgcode;
434 }
435                   
436 AliGenPythia& AliGenPythia::operator=(const  AliGenPythia& rhs)
437 {
438 // Assignment operator
439     return *this;
440 }
441
442
443
444
445
446
447