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