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