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