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