Pythia takes care of vertex smearing. Correct conversion from Pythia units (mm) to
[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.17  2000/06/09 20:34:07  morsch
19 All coding rule violations except RS3 corrected
20
21 Revision 1.16  2000/05/15 15:04:20  morsch
22 The full event is written for fNtrack = -1
23 Coding rule violations corrected.
24
25 Revision 1.15  2000/04/26 10:14:24  morsch
26 Particles array has one entry more than pythia particle list. Upper bound of
27 particle loop changed to np-1 (R. Guernane, AM)
28
29 Revision 1.14  2000/04/05 08:36:13  morsch
30 Check status code of particles in Pythia event
31 to avoid double counting as partonic state and final state particle.
32
33 Revision 1.13  1999/11/09 07:38:48  fca
34 Changes for compatibility with version 2.23 of ROOT
35
36 Revision 1.12  1999/11/03 17:43:20  fca
37 New version from G.Martinez & A.Morsch
38
39 Revision 1.11  1999/09/29 09:24:14  fca
40 Introduction of the Copyright and cvs Log
41 */
42
43 #include "AliGenPythia.h"
44 #include "AliRun.h"
45 #include "AliPythia.h"
46 #include <TParticle.h>
47
48  ClassImp(AliGenPythia)
49
50 AliGenPythia::AliGenPythia()
51                  :AliGenerator()
52 {
53 // Constructor
54 }
55
56 AliGenPythia::AliGenPythia(Int_t npart)
57                  :AliGenerator(npart)
58 {
59 // default charm production at 5. 5 TeV
60 // semimuonic decay
61 // structure function GRVHO
62 //
63     fXsection  = 0.;
64     fParentSelect.Set(5);
65     fChildSelect.Set(5);
66     for (Int_t i=0; i<5; i++) fParentSelect[i]=fChildSelect[i]=0;
67     SetProcess();
68     SetStrucFunc();
69     SetForceDecay();
70     SetPtHard();
71     SetEnergyCMS();
72 }
73
74 AliGenPythia::AliGenPythia(const AliGenPythia & Pythia)
75 {
76 // copy constructor
77 }
78
79 AliGenPythia::~AliGenPythia()
80 {
81 // Destructor
82 }
83
84 void AliGenPythia::Init()
85 {
86 // Initialisation
87     SetMC(new AliPythia());
88     fPythia=(AliPythia*) fgMCEvGen;
89 //
90     fParentWeight=1./Float_t(fNpart);
91 //
92 //  Forward Paramters to the AliPythia object
93     fPythia->DefineParticles();
94     fPythia->SetCKIN(3,fPtHardMin);
95     fPythia->SetCKIN(4,fPtHardMax);    
96     fPythia->ProcInit(fProcess,fEnergyCMS,fStrucFunc);
97     fPythia->ForceDecay(fForceDecay);
98     fPythia->Lulist(0);
99     fPythia->Pystat(2);
100 //  Parent and Children Selection
101     switch (fProcess) 
102     {
103     case charm:
104
105         fParentSelect[0]=411;
106         fParentSelect[1]=421;
107         fParentSelect[2]=431;
108         fParentSelect[3]=4122;  
109         break;
110     case charm_unforced:
111
112         fParentSelect[0]=411;
113         fParentSelect[1]=421;
114         fParentSelect[2]=431;
115         fParentSelect[3]=4122;  
116         break;
117     case beauty:
118         fParentSelect[0]=511;
119         fParentSelect[1]=521;
120         fParentSelect[2]=531;
121         fParentSelect[3]=5122;  
122         break;
123     case beauty_unforced:
124         fParentSelect[0]=511;
125         fParentSelect[1]=521;
126         fParentSelect[2]=531;
127         fParentSelect[3]=5122;  
128         break;
129     case jpsi_chi:
130     case jpsi:
131         fParentSelect[0]=443;
132         break;
133     case mb:
134         break;
135     }
136
137     switch (fForceDecay) 
138     {
139     case semielectronic:
140     case dielectron:
141     case b_jpsi_dielectron:
142     case b_psip_dielectron:
143         fChildSelect[0]=11;     
144         break;
145     case semimuonic:
146     case dimuon:
147     case b_jpsi_dimuon:
148     case b_psip_dimuon:
149     case pitomu:
150     case katomu:
151         fChildSelect[0]=13;
152         break;
153     case all:
154     case nodecay:
155         break;
156     }
157 }
158
159 void AliGenPythia::Generate()
160 {
161 // Generate one event
162
163     Float_t polar[3] =   {0,0,0};
164     Float_t origin[3]=   {0,0,0};
165     Float_t originP[3]= {0,0,0};
166     Float_t origin0[3]=  {0,0,0};
167     Float_t p[3], pP[4];
168 //    Float_t random[6];
169     static TClonesArray *particles;
170 //  converts from mm/c to s
171     const Float_t kconv=0.001/2.999792458e8;
172     
173     
174 //
175     Int_t nt=0;
176     Int_t ntP=0;
177     Int_t jev=0;
178     Int_t j, kf;
179
180     if(!particles) particles=new TClonesArray("TParticle",1000);
181     
182     fTrials=0;
183     for (j=0;j<3;j++) origin0[j]=fOrigin[j];
184     if(fVertexSmear==perEvent) {
185         fPythia->SetMSTP(151,1);
186         for (j=0;j<3;j++) {
187             fPythia->SetPARP(151+j, fOsigma[j]/10.);
188         }
189     } else if (fVertexSmear==perTrack) {
190         fPythia->SetMSTP(151,0);
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]=origin0[0]+ichild->Vx()*10.;
263                                     origin[1]=origin0[1]+ichild->Vy()*10.;
264                                     origin[2]=origin0[2]+ichild->Vz()*10.;              
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