]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PYTHIA6/AliGenPythia.cxx
90f714450ce72c695c8cebeea3e119829da9cd64
[u/mrichter/AliRoot.git] / PYTHIA6 / 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 /* $Id$ */
17
18 //
19 // Generator using the TPythia interface (via AliPythia)
20 // to generate pp collisions.
21 // Using SetNuclei() also nuclear modifications to the structure functions
22 // can be taken into account. This makes, of course, only sense for the
23 // generation of the products of hard processes (heavy flavor, jets ...)
24 //
25 // andreas.morsch@cern.ch
26 //
27
28 #include <TDatabasePDG.h>
29 #include <TParticle.h>
30 #include <TPDGCode.h>
31 #include <TSystem.h>
32 #include <TTree.h>
33 #include "AliConst.h"
34 #include "AliDecayerPythia.h"
35 #include "AliGenPythia.h"
36 #include "AliHeader.h"
37 #include "AliGenPythiaEventHeader.h"
38 #include "AliPythia.h"
39 #include "AliPythiaRndm.h"
40 #include "AliRun.h"
41 #include "AliStack.h"
42 #include "AliRunLoader.h"
43 #include "AliMC.h"
44 #include "pyquenCommon.h"
45
46 ClassImp(AliGenPythia)
47
48 AliGenPythia::AliGenPythia()
49                  :AliGenMC()
50 {
51 // Default Constructor
52   fParticles = 0;
53   fPythia    = 0;
54   fHeader = 0;
55   fReadFromFile = 0;
56   fEventTime = 0.;
57   fInteractionRate = 0.;
58   fTimeWindow = 0.;
59   fEventsTime = 0;
60   fCurSubEvent = 0;
61   fDecayer   = new AliDecayerPythia();
62   SetEventListRange();
63   SetJetPhiRange();
64   SetJetEtaRange();
65   SetJetEtRange();
66   SetGammaPhiRange();
67   SetGammaEtaRange();
68   SetPtKick();
69   SetQuench();
70   SetHadronisation();  
71   fSetNuclei = kFALSE;
72   if (!AliPythiaRndm::GetPythiaRandom()) 
73     AliPythiaRndm::SetPythiaRandom(GetRandom());
74 }
75
76 AliGenPythia::AliGenPythia(Int_t npart)
77                  :AliGenMC(npart)
78 {
79 // default charm production at 5. 5 TeV
80 // semimuonic decay
81 // structure function GRVHO
82 //
83     fName = "Pythia";
84     fTitle= "Particle Generator using PYTHIA";
85     fXsection  = 0.;
86     fReadFromFile = 0;
87     fEventTime = 0.;
88     fInteractionRate = 0.;
89     fTimeWindow = 0.;
90     fEventsTime = 0;
91     fCurSubEvent = 0;
92     SetProcess();
93     SetStrucFunc();
94     SetForceDecay();
95     SetPtHard();
96     SetYHard();
97     SetEnergyCMS();
98     fDecayer = new AliDecayerPythia();
99     // Set random number generator 
100     if (!AliPythiaRndm::GetPythiaRandom()) 
101       AliPythiaRndm::SetPythiaRandom(GetRandom());
102     fFlavorSelect   = 0;
103     // Produced particles  
104     fParticles = new TClonesArray("TParticle",1000);
105     fHeader = 0;
106     SetEventListRange();
107     SetJetPhiRange();
108     SetJetEtaRange();
109     SetJetEtRange();
110     SetGammaPhiRange();
111     SetGammaEtaRange();
112     SetJetReconstructionMode();
113     SetQuench();
114     SetHadronisation();
115     SetPtKick();
116     // Options determining what to keep in the stack (Heavy flavour generation)
117     fStackFillOpt = kFlavorSelection; // Keep particle with selected flavor
118     fFeedDownOpt = kTRUE;             // allow feed down from higher family
119     // Fragmentation on/off
120     fFragmentation = kTRUE;
121     // Default counting mode
122     fCountMode = kCountAll;
123     // Pycel
124     SetPycellParameters();
125     fSetNuclei = kFALSE;
126 }
127
128 AliGenPythia::AliGenPythia(const AliGenPythia & Pythia)
129     :AliGenMC(Pythia)
130 {
131 // copy constructor
132     Pythia.Copy(*this);
133 }
134
135 AliGenPythia::~AliGenPythia()
136 {
137 // Destructor
138   if(fEventsTime) delete fEventsTime;
139 }
140
141 void AliGenPythia::SetInteractionRate(Float_t rate,Float_t timewindow)
142 {
143 // Generate pileup using user specified rate
144     fInteractionRate = rate;
145     fTimeWindow = timewindow;
146     GeneratePileup();
147 }
148
149 void AliGenPythia::GeneratePileup()
150 {
151 // Generate sub events time for pileup
152     fEventsTime = 0;
153     if(fInteractionRate == 0.) {
154       Warning("GeneratePileup","Zero interaction specified. Skipping pileup generation.\n");
155       return;
156     }
157
158     Int_t npart = NumberParticles();
159     if(npart < 0) {
160       Warning("GeneratePileup","Negative number of particles. Skipping pileup generation.\n");
161       return;
162     }
163
164     if(fEventsTime) delete fEventsTime;
165     fEventsTime = new TArrayF(npart);
166     TArrayF &array = *fEventsTime;
167     for(Int_t ipart = 0; ipart < npart; ipart++)
168       array[ipart] = 0.;
169
170     Float_t eventtime = 0.;
171     while(1)
172       {
173         eventtime += (AliPythiaRndm::GetPythiaRandom())->Exp(1./fInteractionRate);
174         if(eventtime > fTimeWindow) break;
175         array.Set(array.GetSize()+1);
176         array[array.GetSize()-1] = eventtime;
177       }
178
179     eventtime = 0.;
180     while(1)
181       {
182         eventtime -= (AliPythiaRndm::GetPythiaRandom())->Exp(1./fInteractionRate);
183         if(TMath::Abs(eventtime) > fTimeWindow) break;
184         array.Set(array.GetSize()+1);
185         array[array.GetSize()-1] = eventtime;
186       }
187
188     SetNumberParticles(fEventsTime->GetSize());
189 }
190
191 void AliGenPythia::SetPycellParameters(Float_t etamax, Int_t neta, Int_t nphi,
192                                        Float_t thresh, Float_t etseed, Float_t minet, Float_t r)
193 {
194 // Set pycell parameters
195     fPycellEtaMax    =  etamax;
196     fPycellNEta      =  neta;
197     fPycellNPhi      =  nphi;
198     fPycellThreshold =  thresh;
199     fPycellEtSeed    =  etseed;
200     fPycellMinEtJet  =  minet;
201     fPycellMaxRadius =  r;
202 }
203
204
205
206 void AliGenPythia::SetEventListRange(Int_t eventFirst, Int_t eventLast)
207 {
208   // Set a range of event numbers, for which a table
209   // of generated particle will be printed
210   fDebugEventFirst = eventFirst;
211   fDebugEventLast  = eventLast;
212   if (fDebugEventLast==-1) fDebugEventLast=fDebugEventFirst;
213 }
214
215 void AliGenPythia::Init()
216 {
217 // Initialisation
218     
219     SetMC(AliPythia::Instance());
220     fPythia=(AliPythia*) fMCEvGen;
221     
222 //
223     fParentWeight=1./Float_t(fNpart);
224 //
225 //  Forward Paramters to the AliPythia object
226     fDecayer->SetForceDecay(fForceDecay);    
227     fDecayer->Init();
228
229
230     fPythia->SetCKIN(3,fPtHardMin);
231     fPythia->SetCKIN(4,fPtHardMax);
232     fPythia->SetCKIN(7,fYHardMin);
233     fPythia->SetCKIN(8,fYHardMax);
234     
235     if (fAProjectile > 0 && fATarget > 0) fPythia->SetNuclei(fAProjectile, fATarget);  
236     // Fragmentation?
237     if (fFragmentation) {
238       fPythia->SetMSTP(111,1);
239     } else {
240       fPythia->SetMSTP(111,0);
241     }
242
243
244 //  initial state radiation   
245     fPythia->SetMSTP(61,fGinit);
246 //  final state radiation
247     fPythia->SetMSTP(71,fGfinal);
248 //  pt - kick
249     if (fPtKick > 0.) {
250         fPythia->SetMSTP(91,1);
251         fPythia->SetPARP(91,fPtKick);
252     } else {
253         fPythia->SetMSTP(91,0);
254     }
255
256
257     if (fReadFromFile) {
258         fRL  =  AliRunLoader::Open(fFileName, "Partons");
259         fRL->LoadKinematics();
260         fRL->LoadHeader();
261     } else {
262         fRL = 0x0;
263     }
264     
265     
266  //
267     fPythia->ProcInit(fProcess,fEnergyCMS,fStrucFunc);
268
269 //  Parent and Children Selection
270     switch (fProcess) 
271     {
272     case kPyCharm:
273     case kPyCharmUnforced:
274     case kPyCharmPbPbMNR:
275     case kPyCharmppMNR:
276     case kPyCharmpPbMNR:
277         fParentSelect[0] =   411;
278         fParentSelect[1] =   421;
279         fParentSelect[2] =   431;
280         fParentSelect[3] =  4122;
281         fFlavorSelect    =  4;  
282         break;
283     case kPyD0PbPbMNR:
284     case kPyD0pPbMNR:
285     case kPyD0ppMNR:
286         fParentSelect[0] =   421;
287         fFlavorSelect    =   4; 
288         break;
289     case kPyDPlusPbPbMNR:
290     case kPyDPluspPbMNR:
291     case kPyDPlusppMNR:
292         fParentSelect[0] =   411;
293         fFlavorSelect    =   4; 
294         break;
295     case kPyBeauty:
296     case kPyBeautyPbPbMNR:
297     case kPyBeautypPbMNR:
298     case kPyBeautyppMNR:
299         fParentSelect[0]=  511;
300         fParentSelect[1]=  521;
301         fParentSelect[2]=  531;
302         fParentSelect[3]= 5122;
303         fParentSelect[4]= 5132;
304         fParentSelect[5]= 5232;
305         fParentSelect[6]= 5332;
306         fFlavorSelect   = 5;    
307         break;
308     case kPyBeautyUnforced:
309         fParentSelect[0] =  511;
310         fParentSelect[1] =  521;
311         fParentSelect[2] =  531;
312         fParentSelect[3] = 5122;
313         fParentSelect[4] = 5132;
314         fParentSelect[5] = 5232;
315         fParentSelect[6] = 5332;
316         fFlavorSelect    = 5;   
317         break;
318     case kPyJpsiChi:
319     case kPyJpsi:
320         fParentSelect[0] = 443;
321         break;
322     case kPyMb:
323     case kPyMbNonDiffr:
324     case kPyJets:
325     case kPyDirectGamma:
326         break;
327     case kPyW:
328         break;
329     }
330 //
331 //
332 //  JetFinder for Trigger
333 //
334 //  Configure detector (EMCAL like)
335 //
336         fPythia->SetPARU(51, fPycellEtaMax);
337         fPythia->SetMSTU(51, fPycellNEta);
338         fPythia->SetMSTU(52, fPycellNPhi);
339 //
340 //  Configure Jet Finder
341 //  
342         fPythia->SetPARU(58,  fPycellThreshold);
343         fPythia->SetPARU(52,  fPycellEtSeed);
344         fPythia->SetPARU(53,  fPycellMinEtJet);
345         fPythia->SetPARU(54,  fPycellMaxRadius);
346         fPythia->SetMSTU(54,  2);
347 //
348 //  This counts the total number of calls to Pyevnt() per run.
349     fTrialsRun = 0;
350     fQ         = 0.;
351     fX1        = 0.;
352     fX2        = 0.;    
353     fNev       = 0 ;
354 //    
355 //
356 //
357     AliGenMC::Init();
358 //
359 //
360 //  
361     if (fSetNuclei) {
362         fDyBoost = 0;
363         Warning("Init","SetNuclei used. Use SetProjectile + SetTarget instead. fDyBoost has been reset to 0\n");
364     }
365
366     if (fQuench) {
367         fPythia->InitQuenching(0., 0.1, 0.6e6, 0);
368     }
369     
370 }
371
372 void AliGenPythia::Generate()
373 {
374 // Generate one event
375     
376     fDecayer->ForceDecay();
377
378     Float_t polar[3]   =   {0,0,0};
379     Float_t origin[3]  =   {0,0,0};
380     Float_t p[4];
381 //  converts from mm/c to s
382     const Float_t kconv=0.001/2.999792458e8;
383 //
384     Int_t nt=0;
385     Int_t jev=0;
386     Int_t j, kf;
387     fTrials=0;
388     fEventTime = 0.;
389     
390     
391
392     //  Set collision vertex position 
393     if (fVertexSmear == kPerEvent) Vertex();
394     
395 //  event loop    
396     while(1)
397     {
398 //
399 // Produce event
400 //
401 //
402 // Switch hadronisation off
403 //
404         fPythia->SetMSTJ(1, 0);
405 //
406 // Either produce new event or read partons from file
407 //      
408         if (!fReadFromFile) {
409             fPythia->Pyevnt();
410             fNpartons = fPythia->GetN();
411         } else {
412             printf("Loading Event %d\n",AliRunLoader::GetRunLoader()->GetEventNumber());
413             fRL->GetEvent(AliRunLoader::GetRunLoader()->GetEventNumber());
414             fPythia->SetN(0);
415             LoadEvent(fRL->Stack(), 0 , 1);
416             fPythia->Pyedit(21);
417         }
418         
419 //
420 //  Run quenching routine 
421 //
422         if (fQuench == 1) {
423             fPythia->Quench();
424         } else if (fQuench == 2){
425             fPythia->Pyquen(208., 0, 0.);
426         }
427 //
428 // Switch hadronisation on
429 //
430         fPythia->SetMSTJ(1, 1);
431 //
432 // .. and perform hadronisation
433 //      printf("Calling hadronisation %d\n", fPythia->GetN());
434         fPythia->Pyexec();      
435         fTrials++;
436         fPythia->ImportParticles(fParticles,"All");
437         Boost();
438 //
439 //
440 //
441         Int_t i;
442         
443
444         Int_t np = fParticles->GetEntriesFast();
445         
446         if (np == 0) continue;
447 //
448         
449 //
450         Int_t* pParent   = new Int_t[np];
451         Int_t* pSelected = new Int_t[np];
452         Int_t* trackIt   = new Int_t[np];
453         for (i = 0; i < np; i++) {
454             pParent[i]   = -1;
455             pSelected[i] =  0;
456             trackIt[i]   =  0;
457         }
458
459         Int_t nc = 0;        // Total n. of selected particles
460         Int_t nParents = 0;  // Selected parents
461         Int_t nTkbles = 0;   // Trackable particles
462         if (fProcess != kPyMb && fProcess != kPyJets && 
463             fProcess != kPyDirectGamma &&
464             fProcess != kPyMbNonDiffr  &&
465             fProcess != kPyW) {
466             
467             for (i = 0; i < np; i++) {
468                 TParticle* iparticle = (TParticle *) fParticles->At(i);
469                 Int_t ks = iparticle->GetStatusCode();
470                 kf = CheckPDGCode(iparticle->GetPdgCode());
471 // No initial state partons
472                 if (ks==21) continue;
473 //
474 // Heavy Flavor Selection
475 //
476                 // quark ?
477                 kf = TMath::Abs(kf);
478                 Int_t kfl = kf;
479                 // Resonance
480
481                 if (kfl > 100000) kfl %= 100000;
482                 if (kfl > 10000)  kfl %= 10000;
483                 // meson ?
484                 if  (kfl > 10) kfl/=100;
485                 // baryon
486                 if (kfl > 10) kfl/=10;
487                 Int_t ipa = iparticle->GetFirstMother()-1;
488                 Int_t kfMo = 0;
489 //
490 // Establish mother daughter relation between heavy quarks and mesons
491 //
492                 if (kf >= fFlavorSelect && kf <= 6) {
493                     Int_t idau = iparticle->GetFirstDaughter() - 1;
494                     if (idau > -1) {
495                         TParticle* daughter = (TParticle *) fParticles->At(idau);
496                         Int_t pdgD = daughter->GetPdgCode();
497                         if (pdgD == 91 || pdgD == 92) {
498                             Int_t jmin = daughter->GetFirstDaughter() - 1;
499                             Int_t jmax = daughter->GetLastDaughter()  - 1;                          
500                             for (Int_t j = jmin; j <= jmax; j++)
501                                 ((TParticle *) fParticles->At(j))->SetFirstMother(i+1);
502                         } // is string or cluster
503                     } // has daughter
504                 } // heavy quark
505                 
506
507                 if (ipa > -1) {
508                     TParticle *  mother = (TParticle *) fParticles->At(ipa);
509                     kfMo = TMath::Abs(mother->GetPdgCode());
510                 }
511                 
512                 // What to keep in Stack?
513                 Bool_t flavorOK = kFALSE;
514                 Bool_t selectOK = kFALSE;
515                 if (fFeedDownOpt) {
516                     if (kfl >= fFlavorSelect) flavorOK = kTRUE;
517                 } else {
518                     if (kfl > fFlavorSelect) {
519                         nc = -1;
520                         break;
521                     }
522                     if (kfl == fFlavorSelect) flavorOK = kTRUE;
523                 }
524                 switch (fStackFillOpt) {
525                 case kFlavorSelection:
526                     selectOK = kTRUE;
527                     break;
528                 case kParentSelection:
529                     if (ParentSelected(kf) || kf <= 10) selectOK = kTRUE;
530                     break;
531                 }
532                 if (flavorOK && selectOK) { 
533 //
534 // Heavy flavor hadron or quark
535 //
536 // Kinematic seletion on final state heavy flavor mesons
537                     if (ParentSelected(kf) && !KinematicSelection(iparticle, 0)) 
538                     {
539                         continue;
540                     }
541                     pSelected[i] = 1;
542                     if (ParentSelected(kf)) ++nParents; // Update parent count
543 //                  printf("\n particle (HF)  %d %d %d", i, pSelected[i], kf);
544                 } else {
545 // Kinematic seletion on decay products
546                     if (fCutOnChild && ParentSelected(kfMo) && ChildSelected(kf) 
547                         && !KinematicSelection(iparticle, 1)) 
548                     {
549                         continue;
550                     }
551 //
552 // Decay products 
553 // Select if mother was selected and is not tracked
554
555                     if (pSelected[ipa] && 
556                         !trackIt[ipa]  &&     // mother will be  tracked ?
557                         kfMo !=  5 &&         // mother is b-quark, don't store fragments          
558                         kfMo !=  4 &&         // mother is c-quark, don't store fragments 
559                         kf   != 92)           // don't store string
560                     {
561 //
562 // Semi-stable or de-selected: diselect decay products:
563 // 
564 //
565                         if (pSelected[i] == -1 ||  fDecayer->GetLifetime(kf) > fMaxLifeTime)
566                         {
567                             Int_t ipF = iparticle->GetFirstDaughter();
568                             Int_t ipL = iparticle->GetLastDaughter();   
569                             if (ipF > 0) for (j = ipF-1; j < ipL; j++) pSelected[j] = -1;
570                         }
571 //                      printf("\n particle (decay)  %d %d %d", i, pSelected[i], kf);
572                         pSelected[i] = (pSelected[i] == -1) ? 0 : 1;
573                     }
574                 }
575                 if (pSelected[i] == -1) pSelected[i] = 0;
576                 if (!pSelected[i]) continue;
577                 // Count quarks only if you did not include fragmentation
578                 if (fFragmentation && kf <= 10) continue;
579
580                 nc++;
581 // Decision on tracking
582                 trackIt[i] = 0;
583 //
584 // Track final state particle
585                 if (ks == 1) trackIt[i] = 1;
586 // Track semi-stable particles
587                 if ((ks == 1) || (fDecayer->GetLifetime(kf) > fMaxLifeTime))  trackIt[i] = 1;
588 // Track particles selected by process if undecayed. 
589                 if (fForceDecay == kNoDecay) {
590                     if (ParentSelected(kf)) trackIt[i] = 1;
591                 } else {
592                     if (ParentSelected(kf)) trackIt[i] = 0;
593                 }
594                 if (trackIt[i] == 1) ++nTkbles; // Update trackable counter
595 //
596 //
597
598             } // particle selection loop
599             if (nc > 0) {
600                 for (i = 0; i<np; i++) {
601                     if (!pSelected[i]) continue;
602                     TParticle *  iparticle = (TParticle *) fParticles->At(i);
603                     kf = CheckPDGCode(iparticle->GetPdgCode());
604                     Int_t ks = iparticle->GetStatusCode();  
605                     p[0] = iparticle->Px();
606                     p[1] = iparticle->Py();
607                     p[2] = iparticle->Pz();
608                     p[3] = iparticle->Energy();
609                     
610                     origin[0] = fVertex[0]+iparticle->Vx()/10; // [cm]
611                     origin[1] = fVertex[1]+iparticle->Vy()/10; // [cm]
612                     origin[2] = fVertex[2]+iparticle->Vz()/10; // [cm]
613                     
614                     Float_t tof   = kconv*iparticle->T();
615                     Int_t ipa     = iparticle->GetFirstMother()-1;
616                     Int_t iparent = (ipa > -1) ? pParent[ipa] : -1;
617  
618                     PushTrack(fTrackIt*trackIt[i], iparent, kf, 
619                               p[0], p[1], p[2], p[3], 
620                               origin[0], origin[1], origin[2], tof, 
621                               polar[0], polar[1], polar[2],
622                               kPPrimary, nt, 1., ks);
623                     pParent[i] = nt;
624                     KeepTrack(nt); 
625                 } //  PushTrack loop
626             }
627         } else {
628             nc = GenerateMB();
629         } // mb ?
630         
631         GetSubEventTime();
632
633         if (pParent)   delete[] pParent;
634         if (pSelected) delete[] pSelected;
635         if (trackIt)   delete[] trackIt;
636
637         if (nc > 0) {
638           switch (fCountMode) {
639           case kCountAll:
640             // printf(" Count all \n");
641             jev += nc;
642             break;
643           case kCountParents:
644             // printf(" Count parents \n");
645             jev += nParents;
646             break;
647           case kCountTrackables:
648             // printf(" Count trackable \n");
649             jev += nTkbles;
650             break;
651           }
652             if (jev >= fNpart || fNpart == -1) {
653                 fKineBias=Float_t(fNpart)/Float_t(fTrials);
654                 printf("\n Trials: %i %i %i\n",fTrials, fNpart, jev);
655
656                 fQ  += fPythia->GetVINT(51);
657                 fX1 += fPythia->GetVINT(41);
658                 fX2 += fPythia->GetVINT(42);
659                 fTrialsRun += fTrials;
660                 fNev++;
661                 MakeHeader();
662                 break;
663             }
664         }
665     } // event loop
666     SetHighWaterMark(nt);
667 //  adjust weight due to kinematic selection
668 //    AdjustWeights();
669 //  get cross-section
670     fXsection=fPythia->GetPARI(1);
671 }
672
673 Int_t  AliGenPythia::GenerateMB()
674 {
675 //
676 // Min Bias selection and other global selections
677 //
678     Int_t i, kf, nt, iparent;
679     Int_t nc = 0;
680     Float_t p[4];
681     Float_t polar[3]   =   {0,0,0};
682     Float_t origin[3]  =   {0,0,0};
683 //  converts from mm/c to s
684     const Float_t kconv=0.001/2.999792458e8;
685     
686
687     
688     Int_t np = (fHadronisation) ? fParticles->GetEntriesFast() : fNpartons;
689
690
691     Int_t* pParent = new Int_t[np];
692     for (i=0; i< np; i++) pParent[i] = -1;
693     if (fProcess == kPyJets || fProcess == kPyDirectGamma) {
694         TParticle* jet1 = (TParticle *) fParticles->At(6);
695         TParticle* jet2 = (TParticle *) fParticles->At(7);
696         if (!CheckTrigger(jet1, jet2)) return 0;
697     }
698     
699     for (i = 0; i < np; i++) {
700         Int_t trackIt = 0;
701         TParticle *  iparticle = (TParticle *) fParticles->At(i);
702         kf = CheckPDGCode(iparticle->GetPdgCode());
703         Int_t ks = iparticle->GetStatusCode();
704         Int_t km = iparticle->GetFirstMother();
705         if ((ks == 1  && kf!=0 && KinematicSelection(iparticle, 0)) ||
706             (ks != 1) ||
707             (fProcess == kPyJets && ks == 21 && km == 0 && i>1)) {
708             nc++;
709             if (ks == 1) trackIt = 1;
710             Int_t ipa = iparticle->GetFirstMother()-1;
711             
712             iparent = (ipa > -1) ? pParent[ipa] : -1;
713             
714 //
715 // store track information
716             p[0] = iparticle->Px();
717             p[1] = iparticle->Py();
718             p[2] = iparticle->Pz();
719             p[3] = iparticle->Energy();
720
721             
722             origin[0] = fVertex[0]+iparticle->Vx()/10; // [cm]
723             origin[1] = fVertex[1]+iparticle->Vy()/10; // [cm]
724             origin[2] = fVertex[2]+iparticle->Vz()/10; // [cm]
725             
726             Float_t tof = fEventTime + kconv * iparticle->T();
727
728             PushTrack(fTrackIt*trackIt, iparent, kf, 
729                       p[0], p[1], p[2], p[3], 
730                       origin[0], origin[1], origin[2], tof, 
731                       polar[0], polar[1], polar[2],
732                       kPPrimary, nt, 1., ks);
733             //
734             // Special Treatment to store color-flow
735             //
736             if (ks == 3 || ks == 13 || ks == 14) {
737                 TParticle* particle = 0;
738                 if (fStack) {
739                     particle = fStack->Particle(nt);
740                 } else {
741                     particle = gAlice->Stack()->Particle(nt);
742                 }
743                 particle->SetFirstDaughter(fPythia->GetK(2, i));
744                 particle->SetLastDaughter(fPythia->GetK(3, i));         
745             }
746             
747             KeepTrack(nt);
748             pParent[i] = nt;
749             SetHighWaterMark(nt);
750             
751         } // select particle
752     } // particle loop 
753
754     if (pParent) delete[] pParent;
755     
756     printf("\n I've put %i particles on the stack \n",nc);
757     return 1;
758 }
759
760
761 void AliGenPythia::FinishRun()
762 {
763 // Print x-section summary
764     fPythia->Pystat(1);
765
766     if (fNev > 0.) {
767         fQ  /= fNev;
768         fX1 /= fNev;
769         fX2 /= fNev;    
770     }
771     
772     printf("\nTotal number of Pyevnt() calls %d\n", fTrialsRun);
773     printf("\nMean Q, x1, x2: %f %f %f\n", fQ, fX1, fX2);
774 }
775
776 void AliGenPythia::AdjustWeights()
777 {
778 // Adjust the weights after generation of all events
779 //
780     if (gAlice) {
781         TParticle *part;
782         Int_t ntrack=gAlice->GetMCApp()->GetNtrack();
783         for (Int_t i=0; i<ntrack; i++) {
784             part= gAlice->GetMCApp()->Particle(i);
785             part->SetWeight(part->GetWeight()*fKineBias);
786         }
787     }
788 }
789     
790 void AliGenPythia::SetNuclei(Int_t a1, Int_t a2)
791 {
792 // Treat protons as inside nuclei with mass numbers a1 and a2  
793
794     fAProjectile = a1;
795     fATarget     = a2;
796     fSetNuclei   = kTRUE;
797 }
798
799
800 void AliGenPythia::MakeHeader()
801 {
802   if (gAlice) {
803     if (gAlice->GetEvNumber()>=fDebugEventFirst &&
804         gAlice->GetEvNumber()<=fDebugEventLast) fPythia->Pylist(2);
805   }
806
807 // Builds the event header, to be called after each event
808     if (fHeader) delete fHeader;
809     fHeader = new AliGenPythiaEventHeader("Pythia");
810 //
811 // Event type  
812     ((AliGenPythiaEventHeader*) fHeader)->SetProcessType(fPythia->GetMSTI(1));
813 //
814 // Number of trials
815     ((AliGenPythiaEventHeader*) fHeader)->SetTrials(fTrials);
816 //
817 // Event Vertex 
818     fHeader->SetPrimaryVertex(fVertex);
819 //
820 // Jets that have triggered
821
822     if (fProcess == kPyJets)
823     {
824         Int_t ntrig, njet;
825         Float_t jets[4][10];
826         GetJets(njet, ntrig, jets);
827
828         
829         for (Int_t i = 0; i < ntrig; i++) {
830             ((AliGenPythiaEventHeader*) fHeader)->AddJet(jets[0][i], jets[1][i], jets[2][i], 
831                                                         jets[3][i]);
832         }
833     }
834 //
835 // Copy relevant information from external header, if present.
836 //
837     Float_t uqJet[4];
838     
839     if (fRL) {
840         AliGenPythiaEventHeader* exHeader = (AliGenPythiaEventHeader*) (fRL->GetHeader()->GenEventHeader());
841         for (Int_t i = 0; i < exHeader->NTriggerJets(); i++)
842         {
843             printf("Adding Jet %d %d \n", i,  exHeader->NTriggerJets());
844             
845             
846             exHeader->TriggerJet(i, uqJet);
847             ((AliGenPythiaEventHeader*) fHeader)->AddUQJet(uqJet[0], uqJet[1], uqJet[2], uqJet[3]);
848         }
849     }
850 //
851 // Store quenching parameters
852 //
853     if (fQuench){
854         Double_t z[4];
855         Double_t xp, yp;
856         if (fQuench == 1) {
857             // Pythia::Quench()
858             fPythia->GetQuenchingParameters(xp, yp, z);
859         } else {
860             // Pyquen
861             Double_t r1 = PARIMP.rb1;
862             Double_t r2 = PARIMP.rb2;
863             Double_t b  = PARIMP.b1;
864             Double_t r   = 0.5 * TMath::Sqrt(2. * (r1 * r1 + r2 * r2) - b * b);
865             Double_t phi = PARIMP.psib1;
866             xp = r * TMath::Cos(phi);
867             yp = r * TMath::Sin(phi);
868             
869         }
870             ((AliGenPythiaEventHeader*) fHeader)->SetXYJet(xp, yp);
871             ((AliGenPythiaEventHeader*) fHeader)->SetZQuench(z);
872         }
873     
874 //
875 //  Pass header to RunLoader
876 //
877     AliRunLoader::GetRunLoader()->GetHeader()->SetGenEventHeader(fHeader);   
878 }
879         
880
881 Bool_t AliGenPythia::CheckTrigger(TParticle* jet1, TParticle* jet2)
882 {
883 // Check the kinematic trigger condition
884 //
885     Double_t eta[2];
886     eta[0] = jet1->Eta();
887     eta[1] = jet2->Eta();
888     Double_t phi[2];
889     phi[0] = jet1->Phi();
890     phi[1] = jet2->Phi();
891     Int_t    pdg[2]; 
892     pdg[0] = jet1->GetPdgCode();
893     pdg[1] = jet2->GetPdgCode();    
894     Bool_t   triggered = kFALSE;
895
896     if (fProcess == kPyJets) {
897         Int_t njets = 0;
898         Int_t ntrig = 0;
899         Float_t jets[4][10];
900 //
901 // Use Pythia clustering on parton level to determine jet axis
902 //
903         GetJets(njets, ntrig, jets);
904         
905         if (ntrig) triggered = kTRUE;
906 //
907     } else {
908         Int_t ij = 0;
909         Int_t ig = 1;
910         if (pdg[0] == kGamma) {
911             ij = 1;
912             ig = 0;
913         }
914         //Check eta range first...
915         if ((eta[ij] < fEtaMaxJet   && eta[ij] > fEtaMinJet) &&
916             (eta[ig] < fEtaMaxGamma && eta[ig] > fEtaMinGamma))
917         {
918             //Eta is okay, now check phi range
919             if ((phi[ij] < fPhiMaxJet   && phi[ij] > fPhiMinJet) &&
920                 (phi[ig] < fPhiMaxGamma && phi[ig] > fPhiMinGamma))
921             {
922                 triggered = kTRUE;
923             }
924         }
925     }
926     return triggered;
927 }
928           
929 AliGenPythia& AliGenPythia::operator=(const  AliGenPythia& rhs)
930 {
931 // Assignment operator
932     rhs.Copy(*this);
933     return *this;
934 }
935
936 void  AliGenPythia::LoadEvent(AliStack* stack, Int_t flag, Int_t reHadr)
937 {
938 //
939 // Load event into Pythia Common Block
940 //
941
942     Int_t npart = stack -> GetNprimary();
943     Int_t n0 = 0;
944     
945     if (!flag) {
946         (fPythia->GetPyjets())->N = npart;
947     } else {
948         n0 = (fPythia->GetPyjets())->N;
949         (fPythia->GetPyjets())->N = n0 + npart;
950     }
951     
952     
953     for (Int_t part = 0; part < npart; part++) {
954         TParticle *MPart = stack->Particle(part);
955         
956         Int_t kf     =  MPart->GetPdgCode();
957         Int_t ks     =  MPart->GetStatusCode();
958         Int_t idf    =  MPart->GetFirstDaughter();
959         Int_t idl    =  MPart->GetLastDaughter();
960         
961         if (reHadr) {
962             if (ks == 11 || ks == 12) {
963                 ks  -= 10;
964                 idf  = -1;
965                 idl  = -1;
966             }
967         }
968         
969         Float_t px = MPart->Px();
970         Float_t py = MPart->Py();
971         Float_t pz = MPart->Pz();
972         Float_t e  = MPart->Energy();
973         Float_t m  = MPart->GetCalcMass();
974         
975         
976         (fPythia->GetPyjets())->P[0][part+n0] = px;
977         (fPythia->GetPyjets())->P[1][part+n0] = py;
978         (fPythia->GetPyjets())->P[2][part+n0] = pz;
979         (fPythia->GetPyjets())->P[3][part+n0] = e;
980         (fPythia->GetPyjets())->P[4][part+n0] = m;
981         
982         (fPythia->GetPyjets())->K[1][part+n0] = kf;
983         (fPythia->GetPyjets())->K[0][part+n0] = ks;
984         (fPythia->GetPyjets())->K[3][part+n0] = idf + 1;
985         (fPythia->GetPyjets())->K[4][part+n0] = idl + 1;
986         (fPythia->GetPyjets())->K[2][part+n0] = MPart->GetFirstMother() + 1;
987     }
988 }
989
990
991 void AliGenPythia::RecJetsUA1(Int_t& njets, Float_t jets [4][50])
992 {
993 //
994 //  Calls the Pythia jet finding algorithm to find jets in the current event
995 //
996 //
997 //
998 //  Save jets
999     Int_t n     = fPythia->GetN();
1000
1001 //
1002 //  Run Jet Finder
1003     fPythia->Pycell(njets);
1004     Int_t i;
1005     for (i = 0; i < njets; i++) {
1006         Float_t px    = (fPythia->GetPyjets())->P[0][n+i];
1007         Float_t py    = (fPythia->GetPyjets())->P[1][n+i];
1008         Float_t pz    = (fPythia->GetPyjets())->P[2][n+i];
1009         Float_t e     = (fPythia->GetPyjets())->P[3][n+i];
1010
1011         jets[0][i] = px;
1012         jets[1][i] = py;
1013         jets[2][i] = pz;
1014         jets[3][i] = e;
1015     }
1016 }
1017
1018
1019
1020 void  AliGenPythia::GetJets(Int_t& nJets, Int_t& nJetsTrig, Float_t jets[4][10])
1021 {
1022 //
1023 //  Calls the Pythia clustering algorithm to find jets in the current event
1024 //
1025     Int_t n     = fPythia->GetN();
1026     nJets       = 0;
1027     nJetsTrig   = 0;
1028     if (fJetReconstruction == kCluster) {
1029 //
1030 //  Configure cluster algorithm
1031 //    
1032         fPythia->SetPARU(43, 2.);
1033         fPythia->SetMSTU(41, 1);
1034 //
1035 //  Call cluster algorithm
1036 //    
1037         fPythia->Pyclus(nJets);
1038 //
1039 //  Loading jets from common block
1040 //
1041     } else {
1042
1043 //
1044 //  Run Jet Finder
1045         fPythia->Pycell(nJets);
1046     }
1047
1048     Int_t i;
1049     for (i = 0; i < nJets; i++) {
1050         Float_t px    = (fPythia->GetPyjets())->P[0][n+i];
1051         Float_t py    = (fPythia->GetPyjets())->P[1][n+i];
1052         Float_t pz    = (fPythia->GetPyjets())->P[2][n+i];
1053         Float_t e     = (fPythia->GetPyjets())->P[3][n+i];
1054         Float_t pt    = TMath::Sqrt(px * px + py * py);
1055         Float_t phi   = TMath::Pi() + TMath::ATan2(-py, -px);  
1056         Float_t theta = TMath::ATan2(pt,pz);
1057         Float_t et    = e * TMath::Sin(theta);
1058         Float_t eta   = -TMath::Log(TMath::Tan(theta / 2.));
1059         if (
1060             eta > fEtaMinJet && eta < fEtaMaxJet && 
1061             phi > fPhiMinJet && phi < fPhiMaxJet &&
1062             et  > fEtMinJet  && et  < fEtMaxJet     
1063             ) 
1064         {
1065             jets[0][nJetsTrig] = px;
1066             jets[1][nJetsTrig] = py;
1067             jets[2][nJetsTrig] = pz;
1068             jets[3][nJetsTrig] = e;
1069             nJetsTrig++;
1070 //          printf("\n........-Jet #%d: %10.3f %10.3f %10.3f %10.3f \n", i, pt, et, eta, phi * kRaddeg);
1071         } else {
1072 //          printf("\n........-Jet #%d: %10.3f %10.3f %10.3f %10.3f \n", i, pt, et, eta, phi * kRaddeg);
1073         }
1074     }
1075 }
1076
1077 void AliGenPythia::GetSubEventTime()
1078 {
1079   // Calculates time of the next subevent
1080   fEventTime = 0.;
1081   if (fEventsTime) {
1082     TArrayF &array = *fEventsTime;
1083     fEventTime = array[fCurSubEvent++];
1084   }
1085   //  printf(" Event time: %d %f %p",fCurSubEvent,fEventTime,fEventsTime);
1086   return;
1087 }
1088
1089 #ifdef never
1090 void AliGenPythia::Streamer(TBuffer &R__b)
1091 {
1092    // Stream an object of class AliGenPythia.
1093
1094    if (R__b.IsReading()) {
1095       Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1096       AliGenerator::Streamer(R__b);
1097       R__b >> (Int_t&)fProcess;
1098       R__b >> (Int_t&)fStrucFunc;
1099       R__b >> (Int_t&)fForceDecay;
1100       R__b >> fEnergyCMS;
1101       R__b >> fKineBias;
1102       R__b >> fTrials;
1103       fParentSelect.Streamer(R__b);
1104       fChildSelect.Streamer(R__b);
1105       R__b >> fXsection;
1106 //      (AliPythia::Instance())->Streamer(R__b);
1107       R__b >> fPtHardMin;
1108       R__b >> fPtHardMax;
1109 //      if (fDecayer) fDecayer->Streamer(R__b);
1110    } else {
1111       R__b.WriteVersion(AliGenPythia::IsA());
1112       AliGenerator::Streamer(R__b);
1113       R__b << (Int_t)fProcess;
1114       R__b << (Int_t)fStrucFunc;
1115       R__b << (Int_t)fForceDecay;
1116       R__b << fEnergyCMS;
1117       R__b << fKineBias;
1118       R__b << fTrials;
1119       fParentSelect.Streamer(R__b);
1120       fChildSelect.Streamer(R__b);
1121       R__b << fXsection;
1122 //      R__b << fPythia;
1123       R__b << fPtHardMin;
1124       R__b << fPtHardMax;
1125       //     fDecayer->Streamer(R__b);
1126    }
1127 }
1128 #endif
1129
1130
1131