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