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