]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVGEN/AliGenPythia.cxx
Add possibility if jet kinematic biasing.
[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.45  2001/11/28 08:06:52  morsch
19 Use fMaxLifeTime parameter.
20
21 Revision 1.44  2001/11/27 13:13:07  morsch
22 Maximum lifetime for long-lived particles to be put on the stack is parameter.
23 It can be set via SetMaximumLifetime(..).
24
25 Revision 1.43  2001/10/21 18:35:56  hristov
26 Several pointers were set to zero in the default constructors to avoid memory management problems
27
28 Revision 1.42  2001/10/15 08:21:55  morsch
29 Vertex truncation settings moved to AliGenMC.
30
31 Revision 1.41  2001/10/08 08:45:42  morsch
32 Possibility of vertex cut added.
33
34 Revision 1.40  2001/09/25 11:30:23  morsch
35 Pass event vertex to header.
36
37 Revision 1.39  2001/07/27 17:09:36  morsch
38 Use local SetTrack, KeepTrack and SetHighWaterMark methods
39 to delegate either to local stack or to stack owned by AliRun.
40 (Piotr Skowronski, A.M.)
41
42 Revision 1.38  2001/07/13 10:58:54  morsch
43 - Some coded moved to AliGenMC
44 - Improved handling of secondary vertices.
45
46 Revision 1.37  2001/06/28 11:17:28  morsch
47 SetEventListRange setter added. Events in specified range are listed for
48 debugging. (Yuri Kharlov)
49
50 Revision 1.36  2001/03/30 07:05:49  morsch
51 Final print-out in finish run.
52 Write parton system for jet-production (preliminary solution).
53
54 Revision 1.35  2001/03/09 13:03:40  morsch
55 Process_t and Struc_Func_t moved to AliPythia.h
56
57 Revision 1.34  2001/02/14 15:50:40  hristov
58 The last particle in event marked using SetHighWaterMark
59
60 Revision 1.33  2001/01/30 09:23:12  hristov
61 Streamers removed (R.Brun)
62
63 Revision 1.32  2001/01/26 19:55:51  hristov
64 Major upgrade of AliRoot code
65
66 Revision 1.31  2001/01/17 10:54:31  hristov
67 Better protection against FPE
68
69 Revision 1.30  2000/12/18 08:55:35  morsch
70 Make AliPythia dependent generartors work with new scheme of random number generation
71
72 Revision 1.29  2000/12/04 11:22:03  morsch
73 Init of sRandom as in 1.15
74
75 Revision 1.28  2000/12/02 11:41:39  morsch
76 Use SetRandom() to initialize random number generator in constructor.
77
78 Revision 1.27  2000/11/30 20:29:02  morsch
79 Initialise static variable sRandom in constructor: sRandom = fRandom;
80
81 Revision 1.26  2000/11/30 07:12:50  alibrary
82 Introducing new Rndm and QA classes
83
84 Revision 1.25  2000/10/18 19:11:27  hristov
85 Division by zero fixed
86
87 Revision 1.24  2000/09/18 10:41:35  morsch
88 Add possibility to use nuclear structure functions from PDF library V8.
89
90 Revision 1.23  2000/09/14 14:05:40  morsch
91 dito
92
93 Revision 1.22  2000/09/14 14:02:22  morsch
94 - Correct conversion from mm to cm when passing particle vertex to MC.
95 - Correct handling of fForceDecay == all.
96
97 Revision 1.21  2000/09/12 14:14:55  morsch
98 Call fDecayer->ForceDecay() at the beginning of Generate().
99
100 Revision 1.20  2000/09/06 14:29:33  morsch
101 Use AliPythia for event generation an AliDecayPythia for decays.
102 Correct handling of "nodecay" option
103
104 Revision 1.19  2000/07/11 18:24:56  fca
105 Coding convention corrections + few minor bug fixes
106
107 Revision 1.18  2000/06/30 12:40:34  morsch
108 Pythia takes care of vertex smearing. Correct conversion from Pythia units (mm) to
109 Geant units (cm).
110
111 Revision 1.17  2000/06/09 20:34:07  morsch
112 All coding rule violations except RS3 corrected
113
114 Revision 1.16  2000/05/15 15:04:20  morsch
115 The full event is written for fNtrack = -1
116 Coding rule violations corrected.
117
118 Revision 1.15  2000/04/26 10:14:24  morsch
119 Particles array has one entry more than pythia particle list. Upper bound of
120 particle loop changed to np-1 (R. Guernane, AM)
121
122 Revision 1.14  2000/04/05 08:36:13  morsch
123 Check status code of particles in Pythia event
124 to avoid double counting as partonic state and final state particle.
125
126 Revision 1.13  1999/11/09 07:38:48  fca
127 Changes for compatibility with version 2.23 of ROOT
128
129 Revision 1.12  1999/11/03 17:43:20  fca
130 New version from G.Martinez & A.Morsch
131
132 Revision 1.11  1999/09/29 09:24:14  fca
133 Introduction of the Copyright and cvs Log
134 */
135
136 #include "AliGenPythia.h"
137 #include "AliGenPythiaEventHeader.h"
138 #include "AliDecayerPythia.h"
139 #include "AliRun.h"
140 #include "AliPythia.h"
141 #include "AliPDG.h"
142 #include <TParticle.h>
143 #include <TSystem.h>
144
145  ClassImp(AliGenPythia)
146
147 AliGenPythia::AliGenPythia()
148                  :AliGenMC()
149 {
150 // Default Constructor
151   fParticles = 0;
152   fPythia    = 0;
153   fDecayer   = new AliDecayerPythia();
154   SetEventListRange();
155   SetJetPhiRange();
156   SetJetEtaRange();
157 }
158
159 AliGenPythia::AliGenPythia(Int_t npart)
160                  :AliGenMC(npart)
161 {
162 // default charm production at 5. 5 TeV
163 // semimuonic decay
164 // structure function GRVHO
165 //
166     fXsection  = 0.;
167     fNucA1=0;
168     fNucA2=0;
169     SetProcess();
170     SetStrucFunc();
171     SetForceDecay();
172     SetPtHard();
173     SetEnergyCMS();
174     fDecayer = new AliDecayerPythia();
175     // Set random number generator 
176     sRandom=fRandom;
177     fFlavorSelect   = 0;
178     // Produced particles  
179     fParticles = new TClonesArray("TParticle",1000);
180     fEventVertex.Set(3);
181     SetEventListRange();
182     SetJetPhiRange();
183     SetJetEtaRange();
184 }
185
186 AliGenPythia::AliGenPythia(const AliGenPythia & Pythia)
187 {
188 // copy constructor
189 }
190
191 AliGenPythia::~AliGenPythia()
192 {
193 // Destructor
194 }
195
196 void AliGenPythia::SetEventListRange(Int_t eventFirst, Int_t eventLast)
197 {
198   // Set a range of event numbers, for which a table
199   // of generated particle will be printed
200   fDebugEventFirst = eventFirst;
201   fDebugEventLast  = eventLast;
202   if (fDebugEventLast==-1) fDebugEventLast=fDebugEventFirst;
203 }
204
205 void AliGenPythia::Init()
206 {
207 // Initialisation
208   SetMC(AliPythia::Instance());
209     fPythia=(AliPythia*) fgMCEvGen;
210 //
211     fParentWeight=1./Float_t(fNpart);
212 //
213 //  Forward Paramters to the AliPythia object
214     fDecayer->SetForceDecay(fForceDecay);    
215     fDecayer->Init();
216
217
218     fPythia->SetCKIN(3,fPtHardMin);
219     fPythia->SetCKIN(4,fPtHardMax);    
220     if (fNucA1 > 0 && fNucA2 > 0) fPythia->SetNuclei(fNucA1, fNucA2);  
221     fPythia->ProcInit(fProcess,fEnergyCMS,fStrucFunc);
222
223     //    fPythia->Pylist(0);
224     //    fPythia->Pystat(2);
225 //  Parent and Children Selection
226     switch (fProcess) 
227     {
228     case kPyCharm:
229         fParentSelect[0] =  411;
230         fParentSelect[1] =  421;
231         fParentSelect[2] =  431;
232         fParentSelect[3] = 4122;        
233         fFlavorSelect    = 4;
234         break;
235     case kPyCharmUnforced:
236         fParentSelect[0] =  411;
237         fParentSelect[1] =  421;
238         fParentSelect[2] =  431;
239         fParentSelect[3]=  4122;
240         fFlavorSelect    = 4;   
241         break;
242     case kPyBeauty:
243         fParentSelect[0]=  511;
244         fParentSelect[1]=  521;
245         fParentSelect[2]=  531;
246         fParentSelect[3]= 5122;
247         fParentSelect[4]= 5132;
248         fParentSelect[5]= 5232;
249         fParentSelect[6]= 5332;
250         fFlavorSelect   = 5;    
251         break;
252     case kPyBeautyUnforced:
253         fParentSelect[0] =  511;
254         fParentSelect[1] =  521;
255         fParentSelect[2] =  531;
256         fParentSelect[3] = 5122;
257         fParentSelect[4] = 5132;
258         fParentSelect[5] = 5232;
259         fParentSelect[6] = 5332;
260         fFlavorSelect    = 5;   
261         break;
262     case kPyJpsiChi:
263     case kPyJpsi:
264         fParentSelect[0] = 443;
265         break;
266     case kPyMb:
267     case kPyJets:
268     case kPyDirectGamma:
269         break;
270     }
271     AliGenMC::Init();
272 }
273
274 void AliGenPythia::Generate()
275 {
276 // Generate one event
277     fDecayer->ForceDecay();
278
279     Float_t polar[3]   =   {0,0,0};
280     Float_t origin[3]  =   {0,0,0};
281     Float_t p[3];
282 //  converts from mm/c to s
283     const Float_t kconv=0.001/2.999792458e8;
284 //
285     Int_t nt=0;
286     Int_t jev=0;
287     Int_t j, kf;
288     fTrials=0;
289
290 //  Set collision vertex position 
291     if(fVertexSmear==kPerEvent) {
292         fPythia->SetMSTP(151,1);
293         for (j=0;j<3;j++) {
294             fPythia->SetPARP(151+j, fOsigma[j]*10.);
295         }
296     } else if (fVertexSmear==kPerTrack) {
297         fPythia->SetMSTP(151,0);
298     }
299 //  event loop    
300     while(1)
301     {
302         fPythia->Pyevnt();
303         if (gAlice->GetEvNumber()>=fDebugEventFirst &&
304             gAlice->GetEvNumber()<=fDebugEventLast) fPythia->Pylist(1);
305         fTrials++;
306         
307         fPythia->ImportParticles(fParticles,"All");
308
309 //
310 //
311 //
312         Int_t i;
313         
314         Int_t np = fParticles->GetEntriesFast();
315         if (np == 0 ) continue;
316 // Get event vertex and discard the event if the Z coord. is too big    
317         TParticle *iparticle = (TParticle *) fParticles->At(0);
318         Float_t distz = iparticle->Vz()/10.;
319         if(TMath::Abs(distz)>fCutVertexZ*fOsigma[2]) continue;
320 //
321         fEventVertex[0] = iparticle->Vx()/10.+fOrigin.At(0);
322         fEventVertex[1] = iparticle->Vy()/10.+fOrigin.At(1);
323         fEventVertex[2] = iparticle->Vz()/10.+fOrigin.At(2);
324 //
325         Int_t* pParent   = new Int_t[np];
326         Int_t* pSelected = new Int_t[np];
327         Int_t* trackIt   = new Int_t[np];
328         for (i=0; i< np-1; i++) {
329             pParent[i]   = -1;
330             pSelected[i] =  0;
331         }
332         printf("\n **************************************************%d\n",np);
333         Int_t nc = 0;
334         if (fProcess != kPyMb && fProcess != kPyJets && fProcess != kPyDirectGamma) {
335             for (i = 0; i<np-1; i++) {
336                 iparticle = (TParticle *) fParticles->At(i);
337                 Int_t ks = iparticle->GetStatusCode();
338                 kf = CheckPDGCode(iparticle->GetPdgCode());
339 // No initial state partons
340                 if (ks==21) continue;
341 //
342 // Heavy Flavor Selection
343 //
344                 // quark ?
345                 kf = TMath::Abs(kf);
346                 Int_t kfl = kf;
347                 // meson ?
348                 if  (kfl > 10) kfl/=100;
349                 // baryon
350                 if (kfl > 10) kfl/=10;
351                 if (kfl > 10) kfl/=10;
352
353                 Int_t ipa = iparticle->GetFirstMother()-1;
354                 Int_t kfMo = 0;
355                 
356                 if (ipa > -1) {
357                     TParticle *  mother = (TParticle *) fParticles->At(ipa);
358                     kfMo = TMath::Abs(mother->GetPdgCode());
359                 }
360 //              printf("\n particle (all)  %d %d %d", i, pSelected[i], kf);
361                 if (kfl >= fFlavorSelect) { 
362 //
363 // Heavy flavor hadron or quark
364 //
365 // Kinematic seletion on final state heavy flavor mesons
366                     if (ParentSelected(kf) && !KinematicSelection(iparticle, 0)) 
367                     {
368                         nc = -1;
369                         break;
370                     }
371                     pSelected[i] = 1;
372 //                  printf("\n particle (HF)  %d %d %d", i, pSelected[i], kf);
373                 } else {
374 // Kinematic seletion on decay products
375                     if (fCutOnChild && ParentSelected(kfMo) && ChildSelected(kf) 
376                         && !KinematicSelection(iparticle, 1))
377                     {
378                         nc = -1;
379                         break;
380                     }
381 //
382 // Decay products 
383 // Select if mother was selected and is not tracked
384
385                     if (pSelected[ipa] && 
386                         !trackIt[ipa]  &&     // mother will be  tracked ?
387                         kfMo !=  5 &&         // mother is b-quark, don't store fragments          
388                         kfMo !=  4 &&         // mother is c-quark, don't store fragments 
389                         kf   != 92)           // don't store string
390                     {
391 //
392 // Semi-stable or de-selected: diselect decay products:
393 // 
394 //
395                         if (pSelected[i] == -1 ||  fDecayer->GetLifetime(kf) > fMaxLifeTime)
396                         {
397                             Int_t ipF = iparticle->GetFirstDaughter();
398                             Int_t ipL = iparticle->GetLastDaughter();   
399                             if (ipF > 0) for (j = ipF-1; j < ipL; j++) pSelected[j] = -1;
400                         }
401 //                      printf("\n particle (decay)  %d %d %d", i, pSelected[i], kf);
402                         pSelected[i] = (pSelected[i] == -1) ? 0 : 1;
403                     }
404                 }
405                 if (pSelected[i] == -1) pSelected[i] = 0;
406                 if (!pSelected[i]) continue;
407                 nc++;
408 // Decision on tracking
409                 trackIt[i] = 0;
410 //
411 // Track final state particle
412                 if (ks == 1) trackIt[i] = 1;
413 // Track semi-stable particles
414                 if ((ks ==1) || (fDecayer->GetLifetime(kf) > fMaxLifeTime))  trackIt[i] = 1;
415 // Track particles selected by process if undecayed. 
416                 if (fForceDecay == kNoDecay) {
417                     if (ParentSelected(kf)) trackIt[i] = 1;
418                 } else {
419                     if (ParentSelected(kf)) trackIt[i] = 0;
420                 }
421 //
422 //
423
424             } // particle selection loop
425             if (nc > -1) {
426                 for (i = 0; i<np-1; i++) {
427                     if (!pSelected[i]) continue;
428                     TParticle *  iparticle = (TParticle *) fParticles->At(i);
429                     kf = CheckPDGCode(iparticle->GetPdgCode());
430                     p[0] = iparticle->Px();
431                     p[1] = iparticle->Py();
432                     p[2] = iparticle->Pz();
433                     origin[0] = fOrigin[0]+iparticle->Vx()/10.;
434                     origin[1] = fOrigin[1]+iparticle->Vy()/10.;
435                     origin[2] = fOrigin[2]+iparticle->Vz()/10.;
436                     Float_t tof   = kconv*iparticle->T();
437                     Int_t ipa     = iparticle->GetFirstMother()-1;
438                     Int_t iparent = (ipa > -1) ? pParent[ipa] : -1;
439                     SetTrack(fTrackIt*trackIt[i] ,
440                                      iparent, kf, p, origin, polar, tof, kPPrimary, nt, 1.);
441                     pParent[i] = nt;
442                     KeepTrack(nt); 
443                 } //  SetTrack loop
444             }
445         } else {
446             nc = GenerateMB();
447         } // mb ?
448
449         if (nc > 0) {
450             jev+=nc;
451             if (jev >= fNpart || fNpart == -1) {
452                 fKineBias=Float_t(fNpart)/Float_t(fTrials);
453                 printf("\n Trials: %i %i %i\n",fTrials, fNpart, jev);
454                 break;
455             }
456         }
457     } // event loop
458     SetHighWaterMark(nt);
459 //  adjust weight due to kinematic selection
460     AdjustWeights();
461 //  get cross-section
462     fXsection=fPythia->GetPARI(1);
463 }
464
465 Int_t  AliGenPythia::GenerateMB()
466 {
467     Int_t i, kf, nt, iparent;
468     Int_t nc = 0;
469     Float_t p[3];
470     Float_t polar[3]   =   {0,0,0};
471     Float_t origin[3]  =   {0,0,0};
472 //  converts from mm/c to s
473     const Float_t kconv=0.001/2.999792458e8;
474     
475     Int_t np = fParticles->GetEntriesFast();
476     Int_t* pParent = new Int_t[np];
477     for (i=0; i< np-1; i++) pParent[i] = -1;
478     if (fProcess == kPyJets) {
479         TParticle* jet1 = (TParticle *) fParticles->At(6);
480         TParticle* jet2 = (TParticle *) fParticles->At(7);
481         if (!CheckTrigger(jet1, jet2)) return 0;
482     }
483     
484     for (i = 0; i<np-1; i++) {
485         Int_t trackIt = 0;
486         TParticle *  iparticle = (TParticle *) fParticles->At(i);
487         kf = CheckPDGCode(iparticle->GetPdgCode());
488         Int_t ks = iparticle->GetStatusCode();
489         Int_t km = iparticle->GetFirstMother();
490 //      printf("\n Particle: %d %d %d", i, kf, ks);
491         
492         if ((ks == 1  && kf!=0 && KinematicSelection(iparticle, 0)) ||
493             (ks != 1) ||
494             (fProcess == kPyJets && ks == 21 && km == 0 && i>1)) {
495             nc++;
496             if (ks == 1) trackIt = 1;
497             Int_t ipa = iparticle->GetFirstMother()-1;
498
499             iparent = (ipa > -1) ? pParent[ipa] : -1;
500
501 //
502 // store track information
503             p[0] = iparticle->Px();
504             p[1] = iparticle->Py();
505             p[2] = iparticle->Pz();
506             origin[0] = fOrigin[0]+iparticle->Vx()/10.;
507             origin[1] = fOrigin[1]+iparticle->Vy()/10.;
508             origin[2] = fOrigin[2]+iparticle->Vz()/10.;
509             Float_t tof=kconv*iparticle->T();
510             SetTrack(fTrackIt*trackIt, iparent, kf, p, origin, polar,
511                          tof, kPPrimary, nt);
512             KeepTrack(nt);
513             pParent[i] = nt;
514         } // select particle
515     } // particle loop 
516
517     if (pParent) delete[] pParent;
518     
519     printf("\n I've put %i particles on the stack \n",nc);
520     MakeHeader();
521     return nc;
522 }
523
524
525 void AliGenPythia::FinishRun()
526 {
527 // Print x-section summary
528     fPythia->Pystat(1);
529 }
530
531 void AliGenPythia::AdjustWeights()
532 {
533 // Adjust the weights after generation of all events
534 //
535     TParticle *part;
536     Int_t ntrack=gAlice->GetNtrack();
537     for (Int_t i=0; i<ntrack; i++) {
538         part= gAlice->Particle(i);
539         part->SetWeight(part->GetWeight()*fKineBias);
540     }
541 }
542     
543 void AliGenPythia::SetNuclei(Int_t a1, Int_t a2)
544 {
545 // Treat protons as inside nuclei with mass numbers a1 and a2  
546     fNucA1 = a1;
547     fNucA2 = a2;
548 }
549
550
551 void AliGenPythia::MakeHeader()
552 {
553 // Builds the event header, to be called after each event
554     AliGenEventHeader* header = new AliGenPythiaEventHeader("Pythia");
555     ((AliGenPythiaEventHeader*) header)->SetProcessType(fPythia->GetMSTI(1));
556     header->SetPrimaryVertex(fEventVertex);
557     gAlice->SetGenEventHeader(header);
558 }
559         
560
561 Bool_t AliGenPythia::CheckTrigger(TParticle* jet1, TParticle* jet2)
562 {
563 // Check the kinematic trigger condition
564 //
565     Double_t eta1      = jet1->Eta();
566     Double_t eta2      = jet2->Eta();
567     Double_t phi1      = jet1->Phi();
568     Double_t phi2      = jet2->Phi();
569     Bool_t   triggered = kFALSE;
570     //Check eta range first...    
571     if ((eta1 < fEtaMaxJet && eta1 > fEtaMinJet) ||
572         (eta2 < fEtaMaxJet && eta2 > fEtaMinJet))
573     {
574         //Eta is okay, now check phi range
575         if ((phi1 < fPhiMaxJet && phi1 > fPhiMinJet) ||
576             (phi2 < fPhiMaxJet && phi2 > fPhiMinJet))
577         {
578             triggered = kTRUE;
579         }
580     }
581     return triggered;
582 }
583           
584 AliGenPythia& AliGenPythia::operator=(const  AliGenPythia& rhs)
585 {
586 // Assignment operator
587     return *this;
588 }
589
590
591
592 #ifdef never
593 void AliGenPythia::Streamer(TBuffer &R__b)
594 {
595    // Stream an object of class AliGenPythia.
596
597    if (R__b.IsReading()) {
598       Version_t R__v = R__b.ReadVersion(); if (R__v) { }
599       AliGenerator::Streamer(R__b);
600       R__b >> (Int_t&)fProcess;
601       R__b >> (Int_t&)fStrucFunc;
602       R__b >> (Int_t&)fForceDecay;
603       R__b >> fEnergyCMS;
604       R__b >> fKineBias;
605       R__b >> fTrials;
606       fParentSelect.Streamer(R__b);
607       fChildSelect.Streamer(R__b);
608       R__b >> fXsection;
609 //      (AliPythia::Instance())->Streamer(R__b);
610       R__b >> fPtHardMin;
611       R__b >> fPtHardMax;
612 //      if (fDecayer) fDecayer->Streamer(R__b);
613    } else {
614       R__b.WriteVersion(AliGenPythia::IsA());
615       AliGenerator::Streamer(R__b);
616       R__b << (Int_t)fProcess;
617       R__b << (Int_t)fStrucFunc;
618       R__b << (Int_t)fForceDecay;
619       R__b << fEnergyCMS;
620       R__b << fKineBias;
621       R__b << fTrials;
622       fParentSelect.Streamer(R__b);
623       fChildSelect.Streamer(R__b);
624       R__b << fXsection;
625 //      R__b << fPythia;
626       R__b << fPtHardMin;
627       R__b << fPtHardMax;
628       //     fDecayer->Streamer(R__b);
629    }
630 }
631 #endif
632