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