]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PYTHIA6/AliGenPythia.cxx
1987ec0cdeab5f255fa5187d8182acef7fa1a686
[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, fHadronisation);
431         
432 //
433 // .. and perform hadronisation
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)) {
697             delete pParent;
698             return 0;
699         }
700     }
701     
702     for (i = 0; i < np; i++) {
703         Int_t trackIt = 0;
704         TParticle *  iparticle = (TParticle *) fParticles->At(i);
705         kf = CheckPDGCode(iparticle->GetPdgCode());
706         Int_t ks = iparticle->GetStatusCode();
707         Int_t km = iparticle->GetFirstMother();
708         if ((ks == 1  && kf!=0 && KinematicSelection(iparticle, 0)) ||
709             (ks != 1) ||
710             (fProcess == kPyJets && ks == 21 && km == 0 && i>1)) {
711             nc++;
712             if (ks == 1) trackIt = 1;
713             Int_t ipa = iparticle->GetFirstMother()-1;
714             
715             iparent = (ipa > -1) ? pParent[ipa] : -1;
716             
717 //
718 // store track information
719             p[0] = iparticle->Px();
720             p[1] = iparticle->Py();
721             p[2] = iparticle->Pz();
722             p[3] = iparticle->Energy();
723
724             
725             origin[0] = fVertex[0]+iparticle->Vx()/10; // [cm]
726             origin[1] = fVertex[1]+iparticle->Vy()/10; // [cm]
727             origin[2] = fVertex[2]+iparticle->Vz()/10; // [cm]
728             
729             Float_t tof = fEventTime + kconv * iparticle->T();
730
731             PushTrack(fTrackIt*trackIt, iparent, kf, 
732                       p[0], p[1], p[2], p[3], 
733                       origin[0], origin[1], origin[2], tof, 
734                       polar[0], polar[1], polar[2],
735                       kPPrimary, nt, 1., ks);
736             //
737             // Special Treatment to store color-flow
738             //
739             if (ks == 3 || ks == 13 || ks == 14) {
740                 TParticle* particle = 0;
741                 if (fStack) {
742                     particle = fStack->Particle(nt);
743                 } else {
744                     particle = gAlice->Stack()->Particle(nt);
745                 }
746                 particle->SetFirstDaughter(fPythia->GetK(2, i));
747                 particle->SetLastDaughter(fPythia->GetK(3, i));         
748             }
749             
750             KeepTrack(nt);
751             pParent[i] = nt;
752             SetHighWaterMark(nt);
753             
754         } // select particle
755     } // particle loop 
756
757     if (pParent) delete[] pParent;
758     
759     printf("\n I've put %i particles on the stack \n",nc);
760     return 1;
761 }
762
763
764 void AliGenPythia::FinishRun()
765 {
766 // Print x-section summary
767     fPythia->Pystat(1);
768
769     if (fNev > 0.) {
770         fQ  /= fNev;
771         fX1 /= fNev;
772         fX2 /= fNev;    
773     }
774     
775     printf("\nTotal number of Pyevnt() calls %d\n", fTrialsRun);
776     printf("\nMean Q, x1, x2: %f %f %f\n", fQ, fX1, fX2);
777 }
778
779 void AliGenPythia::AdjustWeights()
780 {
781 // Adjust the weights after generation of all events
782 //
783     if (gAlice) {
784         TParticle *part;
785         Int_t ntrack=gAlice->GetMCApp()->GetNtrack();
786         for (Int_t i=0; i<ntrack; i++) {
787             part= gAlice->GetMCApp()->Particle(i);
788             part->SetWeight(part->GetWeight()*fKineBias);
789         }
790     }
791 }
792     
793 void AliGenPythia::SetNuclei(Int_t a1, Int_t a2)
794 {
795 // Treat protons as inside nuclei with mass numbers a1 and a2  
796
797     fAProjectile = a1;
798     fATarget     = a2;
799     fSetNuclei   = kTRUE;
800 }
801
802
803 void AliGenPythia::MakeHeader()
804 {
805   if (gAlice) {
806     if (gAlice->GetEvNumber()>=fDebugEventFirst &&
807         gAlice->GetEvNumber()<=fDebugEventLast) fPythia->Pylist(2);
808   }
809
810 // Builds the event header, to be called after each event
811     if (fHeader) delete fHeader;
812     fHeader = new AliGenPythiaEventHeader("Pythia");
813 //
814 // Event type  
815     ((AliGenPythiaEventHeader*) fHeader)->SetProcessType(fPythia->GetMSTI(1));
816 //
817 // Number of trials
818     ((AliGenPythiaEventHeader*) fHeader)->SetTrials(fTrials);
819 //
820 // Event Vertex 
821     fHeader->SetPrimaryVertex(fVertex);
822 //
823 // Jets that have triggered
824
825     if (fProcess == kPyJets)
826     {
827         Int_t ntrig, njet;
828         Float_t jets[4][10];
829         GetJets(njet, ntrig, jets);
830
831         
832         for (Int_t i = 0; i < ntrig; i++) {
833             ((AliGenPythiaEventHeader*) fHeader)->AddJet(jets[0][i], jets[1][i], jets[2][i], 
834                                                         jets[3][i]);
835         }
836     }
837 //
838 // Copy relevant information from external header, if present.
839 //
840     Float_t uqJet[4];
841     
842     if (fRL) {
843         AliGenPythiaEventHeader* exHeader = (AliGenPythiaEventHeader*) (fRL->GetHeader()->GenEventHeader());
844         for (Int_t i = 0; i < exHeader->NTriggerJets(); i++)
845         {
846             printf("Adding Jet %d %d \n", i,  exHeader->NTriggerJets());
847             
848             
849             exHeader->TriggerJet(i, uqJet);
850             ((AliGenPythiaEventHeader*) fHeader)->AddUQJet(uqJet[0], uqJet[1], uqJet[2], uqJet[3]);
851         }
852     }
853 //
854 // Store quenching parameters
855 //
856     if (fQuench){
857         Double_t z[4];
858         Double_t xp, yp;
859         if (fQuench == 1) {
860             // Pythia::Quench()
861             fPythia->GetQuenchingParameters(xp, yp, z);
862         } else {
863             // Pyquen
864             Double_t r1 = PARIMP.rb1;
865             Double_t r2 = PARIMP.rb2;
866             Double_t b  = PARIMP.b1;
867             Double_t r   = 0.5 * TMath::Sqrt(2. * (r1 * r1 + r2 * r2) - b * b);
868             Double_t phi = PARIMP.psib1;
869             xp = r * TMath::Cos(phi);
870             yp = r * TMath::Sin(phi);
871             
872         }
873             ((AliGenPythiaEventHeader*) fHeader)->SetXYJet(xp, yp);
874             ((AliGenPythiaEventHeader*) fHeader)->SetZQuench(z);
875         }
876     
877 //
878 //  Pass header
879 //
880     AddHeader(fHeader);
881 }
882
883 void AliGenPythia::AddHeader(AliGenEventHeader* header)
884 {
885     // Add header to container or runloader
886     if (fContainer) {
887         fContainer->AddHeader(header);
888     } else {
889         AliRunLoader::GetRunLoader()->GetHeader()->SetGenEventHeader(header);   
890     }
891 }
892
893
894 Bool_t AliGenPythia::CheckTrigger(TParticle* jet1, TParticle* jet2)
895 {
896 // Check the kinematic trigger condition
897 //
898     Double_t eta[2];
899     eta[0] = jet1->Eta();
900     eta[1] = jet2->Eta();
901     Double_t phi[2];
902     phi[0] = jet1->Phi();
903     phi[1] = jet2->Phi();
904     Int_t    pdg[2]; 
905     pdg[0] = jet1->GetPdgCode();
906     pdg[1] = jet2->GetPdgCode();    
907     Bool_t   triggered = kFALSE;
908
909     if (fProcess == kPyJets) {
910         Int_t njets = 0;
911         Int_t ntrig = 0;
912         Float_t jets[4][10];
913 //
914 // Use Pythia clustering on parton level to determine jet axis
915 //
916         GetJets(njets, ntrig, jets);
917         
918         if (ntrig) triggered = kTRUE;
919 //
920     } else {
921         Int_t ij = 0;
922         Int_t ig = 1;
923         if (pdg[0] == kGamma) {
924             ij = 1;
925             ig = 0;
926         }
927         //Check eta range first...
928         if ((eta[ij] < fEtaMaxJet   && eta[ij] > fEtaMinJet) &&
929             (eta[ig] < fEtaMaxGamma && eta[ig] > fEtaMinGamma))
930         {
931             //Eta is okay, now check phi range
932             if ((phi[ij] < fPhiMaxJet   && phi[ij] > fPhiMinJet) &&
933                 (phi[ig] < fPhiMaxGamma && phi[ig] > fPhiMinGamma))
934             {
935                 triggered = kTRUE;
936             }
937         }
938     }
939     return triggered;
940 }
941           
942 AliGenPythia& AliGenPythia::operator=(const  AliGenPythia& rhs)
943 {
944 // Assignment operator
945     rhs.Copy(*this);
946     return *this;
947 }
948
949 void  AliGenPythia::LoadEvent(AliStack* stack, Int_t flag, Int_t reHadr)
950 {
951 //
952 // Load event into Pythia Common Block
953 //
954
955     Int_t npart = stack -> GetNprimary();
956     Int_t n0 = 0;
957     
958     if (!flag) {
959         (fPythia->GetPyjets())->N = npart;
960     } else {
961         n0 = (fPythia->GetPyjets())->N;
962         (fPythia->GetPyjets())->N = n0 + npart;
963     }
964     
965     
966     for (Int_t part = 0; part < npart; part++) {
967         TParticle *MPart = stack->Particle(part);
968         
969         Int_t kf     =  MPart->GetPdgCode();
970         Int_t ks     =  MPart->GetStatusCode();
971         Int_t idf    =  MPart->GetFirstDaughter();
972         Int_t idl    =  MPart->GetLastDaughter();
973         
974         if (reHadr) {
975             if (ks == 11 || ks == 12) {
976                 ks  -= 10;
977                 idf  = -1;
978                 idl  = -1;
979             }
980         }
981         
982         Float_t px = MPart->Px();
983         Float_t py = MPart->Py();
984         Float_t pz = MPart->Pz();
985         Float_t e  = MPart->Energy();
986         Float_t m  = MPart->GetCalcMass();
987         
988         
989         (fPythia->GetPyjets())->P[0][part+n0] = px;
990         (fPythia->GetPyjets())->P[1][part+n0] = py;
991         (fPythia->GetPyjets())->P[2][part+n0] = pz;
992         (fPythia->GetPyjets())->P[3][part+n0] = e;
993         (fPythia->GetPyjets())->P[4][part+n0] = m;
994         
995         (fPythia->GetPyjets())->K[1][part+n0] = kf;
996         (fPythia->GetPyjets())->K[0][part+n0] = ks;
997         (fPythia->GetPyjets())->K[3][part+n0] = idf + 1;
998         (fPythia->GetPyjets())->K[4][part+n0] = idl + 1;
999         (fPythia->GetPyjets())->K[2][part+n0] = MPart->GetFirstMother() + 1;
1000     }
1001 }
1002
1003
1004 void AliGenPythia::RecJetsUA1(Int_t& njets, Float_t jets [4][50])
1005 {
1006 //
1007 //  Calls the Pythia jet finding algorithm to find jets in the current event
1008 //
1009 //
1010 //
1011 //  Save jets
1012     Int_t n     = fPythia->GetN();
1013
1014 //
1015 //  Run Jet Finder
1016     fPythia->Pycell(njets);
1017     Int_t i;
1018     for (i = 0; i < njets; i++) {
1019         Float_t px    = (fPythia->GetPyjets())->P[0][n+i];
1020         Float_t py    = (fPythia->GetPyjets())->P[1][n+i];
1021         Float_t pz    = (fPythia->GetPyjets())->P[2][n+i];
1022         Float_t e     = (fPythia->GetPyjets())->P[3][n+i];
1023
1024         jets[0][i] = px;
1025         jets[1][i] = py;
1026         jets[2][i] = pz;
1027         jets[3][i] = e;
1028     }
1029 }
1030
1031
1032
1033 void  AliGenPythia::GetJets(Int_t& nJets, Int_t& nJetsTrig, Float_t jets[4][10])
1034 {
1035 //
1036 //  Calls the Pythia clustering algorithm to find jets in the current event
1037 //
1038     Int_t n     = fPythia->GetN();
1039     nJets       = 0;
1040     nJetsTrig   = 0;
1041     if (fJetReconstruction == kCluster) {
1042 //
1043 //  Configure cluster algorithm
1044 //    
1045         fPythia->SetPARU(43, 2.);
1046         fPythia->SetMSTU(41, 1);
1047 //
1048 //  Call cluster algorithm
1049 //    
1050         fPythia->Pyclus(nJets);
1051 //
1052 //  Loading jets from common block
1053 //
1054     } else {
1055
1056 //
1057 //  Run Jet Finder
1058         fPythia->Pycell(nJets);
1059     }
1060
1061     Int_t i;
1062     for (i = 0; i < nJets; i++) {
1063         Float_t px    = (fPythia->GetPyjets())->P[0][n+i];
1064         Float_t py    = (fPythia->GetPyjets())->P[1][n+i];
1065         Float_t pz    = (fPythia->GetPyjets())->P[2][n+i];
1066         Float_t e     = (fPythia->GetPyjets())->P[3][n+i];
1067         Float_t pt    = TMath::Sqrt(px * px + py * py);
1068         Float_t phi   = TMath::Pi() + TMath::ATan2(-py, -px);  
1069         Float_t theta = TMath::ATan2(pt,pz);
1070         Float_t et    = e * TMath::Sin(theta);
1071         Float_t eta   = -TMath::Log(TMath::Tan(theta / 2.));
1072         if (
1073             eta > fEtaMinJet && eta < fEtaMaxJet && 
1074             phi > fPhiMinJet && phi < fPhiMaxJet &&
1075             et  > fEtMinJet  && et  < fEtMaxJet     
1076             ) 
1077         {
1078             jets[0][nJetsTrig] = px;
1079             jets[1][nJetsTrig] = py;
1080             jets[2][nJetsTrig] = pz;
1081             jets[3][nJetsTrig] = e;
1082             nJetsTrig++;
1083 //          printf("\n........-Jet #%d: %10.3f %10.3f %10.3f %10.3f \n", i, pt, et, eta, phi * kRaddeg);
1084         } else {
1085 //          printf("\n........-Jet #%d: %10.3f %10.3f %10.3f %10.3f \n", i, pt, et, eta, phi * kRaddeg);
1086         }
1087     }
1088 }
1089
1090 void AliGenPythia::GetSubEventTime()
1091 {
1092   // Calculates time of the next subevent
1093   fEventTime = 0.;
1094   if (fEventsTime) {
1095     TArrayF &array = *fEventsTime;
1096     fEventTime = array[fCurSubEvent++];
1097   }
1098   //  printf(" Event time: %d %f %p",fCurSubEvent,fEventTime,fEventsTime);
1099   return;
1100 }
1101
1102 #ifdef never
1103 void AliGenPythia::Streamer(TBuffer &R__b)
1104 {
1105    // Stream an object of class AliGenPythia.
1106
1107    if (R__b.IsReading()) {
1108       Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1109       AliGenerator::Streamer(R__b);
1110       R__b >> (Int_t&)fProcess;
1111       R__b >> (Int_t&)fStrucFunc;
1112       R__b >> (Int_t&)fForceDecay;
1113       R__b >> fEnergyCMS;
1114       R__b >> fKineBias;
1115       R__b >> fTrials;
1116       fParentSelect.Streamer(R__b);
1117       fChildSelect.Streamer(R__b);
1118       R__b >> fXsection;
1119 //      (AliPythia::Instance())->Streamer(R__b);
1120       R__b >> fPtHardMin;
1121       R__b >> fPtHardMax;
1122 //      if (fDecayer) fDecayer->Streamer(R__b);
1123    } else {
1124       R__b.WriteVersion(AliGenPythia::IsA());
1125       AliGenerator::Streamer(R__b);
1126       R__b << (Int_t)fProcess;
1127       R__b << (Int_t)fStrucFunc;
1128       R__b << (Int_t)fForceDecay;
1129       R__b << fEnergyCMS;
1130       R__b << fKineBias;
1131       R__b << fTrials;
1132       fParentSelect.Streamer(R__b);
1133       fChildSelect.Streamer(R__b);
1134       R__b << fXsection;
1135 //      R__b << fPythia;
1136       R__b << fPtHardMin;
1137       R__b << fPtHardMax;
1138       //     fDecayer->Streamer(R__b);
1139    }
1140 }
1141 #endif
1142
1143
1144