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