]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PYTHIA6/AliGenPythia.cxx
Updates for multiple interactions.
[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 <TClonesArray.h>
29 #include <TDatabasePDG.h>
30 #include <TParticle.h>
31 #include <TPDGCode.h>
32 #include <TObjArray.h>
33 #include <TSystem.h>
34 #include <TTree.h>
35 #include "AliConst.h"
36 #include "AliDecayerPythia.h"
37 #include "AliGenPythia.h"
38 #include "AliFastGlauber.h"
39 #include "AliHeader.h"
40 #include "AliGenPythiaEventHeader.h"
41 #include "AliPythia.h"
42 #include "AliPythiaRndm.h"
43 #include "AliRun.h"
44 #include "AliStack.h"
45 #include "AliRunLoader.h"
46 #include "AliMC.h"
47 #include "PyquenCommon.h"
48
49 ClassImp(AliGenPythia)
50
51
52 AliGenPythia::AliGenPythia():
53     AliGenMC(),
54     fProcess(kPyCharm),          
55     fItune(-1),
56     fStrucFunc(kCTEQ5L), 
57     fKineBias(0.),
58     fTrials(0),
59     fTrialsRun(0),
60     fQ(0.),
61     fX1(0.),
62     fX2(0.),
63     fEventTime(0.),
64     fInteractionRate(0.),
65     fTimeWindow(0.),
66     fCurSubEvent(0),
67     fEventsTime(0),
68     fNev(0),
69     fFlavorSelect(0),
70     fXsection(0.),
71     fPythia(0),
72     fPtHardMin(0.),
73     fPtHardMax(1.e4),
74     fYHardMin(-1.e10),
75     fYHardMax(1.e10),
76     fGinit(1),
77     fGfinal(1),
78     fHadronisation(1),
79     fNpartons(0),
80     fReadFromFile(0),
81     fQuench(0),
82     fQhat(0.),
83     fLength(0.),
84     fImpact(0.),
85     fPtKick(1.),
86     fFullEvent(kTRUE),
87     fDecayer(new AliDecayerPythia()),
88     fDebugEventFirst(-1),
89     fDebugEventLast(-1),
90     fEtMinJet(0.),      
91     fEtMaxJet(1.e4),      
92     fEtaMinJet(-20.),     
93     fEtaMaxJet(20.),     
94     fPhiMinJet(0.),     
95     fPhiMaxJet(2.* TMath::Pi()),     
96     fJetReconstruction(kCell),
97     fEtaMinGamma(-20.),      
98     fEtaMaxGamma(20.),      
99     fPhiMinGamma(0.),      
100     fPhiMaxGamma(2. * TMath::Pi()),      
101     fPycellEtaMax(2.),     
102     fPycellNEta(274),       
103     fPycellNPhi(432),       
104     fPycellThreshold(0.),  
105     fPycellEtSeed(4.),     
106     fPycellMinEtJet(10.),  
107     fPycellMaxRadius(1.), 
108     fStackFillOpt(kFlavorSelection),   
109     fFeedDownOpt(kTRUE),    
110     fFragmentation(kTRUE),
111     fSetNuclei(kFALSE),
112     fNewMIS(kFALSE),   
113     fHFoff(kFALSE),    
114     fNucPdf(0),
115     fTriggerParticle(0),
116     fTriggerEta(0.9),     
117     fTriggerMultiplicity(0),
118     fTriggerMultiplicityEta(0),
119     fTriggerMultiplicityPtMin(0),
120     fCountMode(kCountAll),      
121     fHeader(0),  
122     fRL(0),      
123     fFileName(0),
124     fFragPhotonInCalo(kFALSE),
125     fPi0InCalo(kFALSE) ,
126     fPhotonInCalo(kFALSE),
127     fEleInEMCAL(kFALSE),
128     fCheckEMCAL(kFALSE),
129     fCheckPHOS(kFALSE),
130     fCheckPHOSeta(kFALSE),
131     fFragPhotonOrPi0MinPt(0), 
132     fPhotonMinPt(0), 
133     fElectronMinPt(0), 
134     fPHOSMinPhi(219.),
135     fPHOSMaxPhi(321.),
136     fPHOSEta(0.13),
137     fEMCALMinPhi(79.),
138     fEMCALMaxPhi(191.),
139     fEMCALEta(0.71)
140
141 {
142 // Default Constructor
143   fEnergyCMS = 5500.;
144   if (!AliPythiaRndm::GetPythiaRandom()) 
145       AliPythiaRndm::SetPythiaRandom(GetRandom());
146 }
147
148 AliGenPythia::AliGenPythia(Int_t npart)
149     :AliGenMC(npart),
150      fProcess(kPyCharm),          
151      fItune(-1),
152      fStrucFunc(kCTEQ5L), 
153      fKineBias(0.),
154      fTrials(0),
155      fTrialsRun(0),
156      fQ(0.),
157      fX1(0.),
158      fX2(0.),
159      fEventTime(0.),
160      fInteractionRate(0.),
161      fTimeWindow(0.),
162      fCurSubEvent(0),
163      fEventsTime(0),
164      fNev(0),
165      fFlavorSelect(0),
166      fXsection(0.),
167      fPythia(0),
168      fPtHardMin(0.),
169      fPtHardMax(1.e4),
170      fYHardMin(-1.e10),
171      fYHardMax(1.e10),
172      fGinit(kTRUE),
173      fGfinal(kTRUE),
174      fHadronisation(kTRUE),
175      fNpartons(0),
176      fReadFromFile(kFALSE),
177      fQuench(kFALSE),
178      fQhat(0.),
179      fLength(0.),
180      fImpact(0.),
181      fPtKick(1.),
182      fFullEvent(kTRUE),
183      fDecayer(new AliDecayerPythia()),
184      fDebugEventFirst(-1),
185      fDebugEventLast(-1),
186      fEtMinJet(0.),      
187      fEtMaxJet(1.e4),      
188      fEtaMinJet(-20.),     
189      fEtaMaxJet(20.),     
190      fPhiMinJet(0.),     
191      fPhiMaxJet(2.* TMath::Pi()),     
192      fJetReconstruction(kCell),
193      fEtaMinGamma(-20.),      
194      fEtaMaxGamma(20.),      
195      fPhiMinGamma(0.),      
196      fPhiMaxGamma(2. * TMath::Pi()),      
197      fPycellEtaMax(2.),     
198      fPycellNEta(274),       
199      fPycellNPhi(432),       
200      fPycellThreshold(0.),  
201      fPycellEtSeed(4.),     
202      fPycellMinEtJet(10.),  
203      fPycellMaxRadius(1.), 
204      fStackFillOpt(kFlavorSelection),   
205      fFeedDownOpt(kTRUE),    
206      fFragmentation(kTRUE),
207      fSetNuclei(kFALSE),
208      fNewMIS(kFALSE),   
209      fHFoff(kFALSE),    
210      fNucPdf(0),
211      fTriggerParticle(0),
212      fTriggerEta(0.9),     
213      fTriggerMultiplicity(0),
214      fTriggerMultiplicityEta(0),
215      fTriggerMultiplicityPtMin(0),
216      fCountMode(kCountAll),      
217      fHeader(0),  
218      fRL(0),      
219      fFileName(0),
220      fFragPhotonInCalo(kFALSE),
221      fPi0InCalo(kFALSE) ,
222      fPhotonInCalo(kFALSE),
223      fEleInEMCAL(kFALSE),
224      fCheckEMCAL(kFALSE),
225      fCheckPHOS(kFALSE),
226      fCheckPHOSeta(kFALSE),
227      fFragPhotonOrPi0MinPt(0),
228      fPhotonMinPt(0),
229      fElectronMinPt(0),
230      fPHOSMinPhi(219.),
231      fPHOSMaxPhi(321.),
232      fPHOSEta(0.13),
233      fEMCALMinPhi(79.),
234      fEMCALMaxPhi(191.),
235      fEMCALEta(0.71)
236 {
237 // default charm production at 5. 5 TeV
238 // semimuonic decay
239 // structure function GRVHO
240 //
241     fEnergyCMS = 5500.;
242     fName = "Pythia";
243     fTitle= "Particle Generator using PYTHIA";
244     SetForceDecay();
245     // Set random number generator 
246     if (!AliPythiaRndm::GetPythiaRandom()) 
247       AliPythiaRndm::SetPythiaRandom(GetRandom());
248  }
249
250 AliGenPythia::~AliGenPythia()
251 {
252 // Destructor
253   if(fEventsTime) delete fEventsTime;
254 }
255
256 void AliGenPythia::SetInteractionRate(Float_t rate,Float_t timewindow)
257 {
258 // Generate pileup using user specified rate
259     fInteractionRate = rate;
260     fTimeWindow = timewindow;
261     GeneratePileup();
262 }
263
264 void AliGenPythia::GeneratePileup()
265 {
266 // Generate sub events time for pileup
267     fEventsTime = 0;
268     if(fInteractionRate == 0.) {
269       Warning("GeneratePileup","Zero interaction specified. Skipping pileup generation.\n");
270       return;
271     }
272
273     Int_t npart = NumberParticles();
274     if(npart < 0) {
275       Warning("GeneratePileup","Negative number of particles. Skipping pileup generation.\n");
276       return;
277     }
278
279     if(fEventsTime) delete fEventsTime;
280     fEventsTime = new TArrayF(npart);
281     TArrayF &array = *fEventsTime;
282     for(Int_t ipart = 0; ipart < npart; ipart++)
283       array[ipart] = 0.;
284
285     Float_t eventtime = 0.;
286     while(1)
287       {
288         eventtime += (AliPythiaRndm::GetPythiaRandom())->Exp(1./fInteractionRate);
289         if(eventtime > fTimeWindow) break;
290         array.Set(array.GetSize()+1);
291         array[array.GetSize()-1] = eventtime;
292       }
293
294     eventtime = 0.;
295     while(1)
296       {
297         eventtime -= (AliPythiaRndm::GetPythiaRandom())->Exp(1./fInteractionRate);
298         if(TMath::Abs(eventtime) > fTimeWindow) break;
299         array.Set(array.GetSize()+1);
300         array[array.GetSize()-1] = eventtime;
301       }
302
303     SetNumberParticles(fEventsTime->GetSize());
304 }
305
306 void AliGenPythia::SetPycellParameters(Float_t etamax, Int_t neta, Int_t nphi,
307                                        Float_t thresh, Float_t etseed, Float_t minet, Float_t r)
308 {
309 // Set pycell parameters
310     fPycellEtaMax    =  etamax;
311     fPycellNEta      =  neta;
312     fPycellNPhi      =  nphi;
313     fPycellThreshold =  thresh;
314     fPycellEtSeed    =  etseed;
315     fPycellMinEtJet  =  minet;
316     fPycellMaxRadius =  r;
317 }
318
319
320
321 void AliGenPythia::SetEventListRange(Int_t eventFirst, Int_t eventLast)
322 {
323   // Set a range of event numbers, for which a table
324   // of generated particle will be printed
325   fDebugEventFirst = eventFirst;
326   fDebugEventLast  = eventLast;
327   if (fDebugEventLast==-1) fDebugEventLast=fDebugEventFirst;
328 }
329
330 void AliGenPythia::Init()
331 {
332 // Initialisation
333     
334     SetMC(AliPythia::Instance());
335     fPythia=(AliPythia*) fMCEvGen;
336     
337 //
338     fParentWeight=1./Float_t(fNpart);
339 //
340
341
342     fPythia->SetCKIN(3,fPtHardMin);
343     fPythia->SetCKIN(4,fPtHardMax);
344     fPythia->SetCKIN(7,fYHardMin);
345     fPythia->SetCKIN(8,fYHardMax);
346     
347     if (fAProjectile > 0 && fATarget > 0) fPythia->SetNuclei(fAProjectile, fATarget, fNucPdf);  
348     // Fragmentation?
349     if (fFragmentation) {
350       fPythia->SetMSTP(111,1);
351     } else {
352       fPythia->SetMSTP(111,0);
353     }
354
355
356 //  initial state radiation   
357     fPythia->SetMSTP(61,fGinit);
358 //  final state radiation
359     fPythia->SetMSTP(71,fGfinal);
360 //  pt - kick
361     if (fPtKick > 0.) {
362         fPythia->SetMSTP(91,1);
363         fPythia->SetPARP(91,fPtKick);   
364         fPythia->SetPARP(93, 4. * fPtKick);
365     } else {
366         fPythia->SetMSTP(91,0);
367     }
368
369
370     if (fReadFromFile) {
371         fRL  =  AliRunLoader::Open(fFileName, "Partons");
372         fRL->LoadKinematics();
373         fRL->LoadHeader();
374     } else {
375         fRL = 0x0;
376     }
377  //
378     fPythia->ProcInit(fProcess,fEnergyCMS,fStrucFunc, fItune);
379     //  Forward Paramters to the AliPythia object
380     fDecayer->SetForceDecay(fForceDecay);    
381 // Switch off Heavy Flavors on request  
382     if (fHFoff) {
383         // Maximum number of quark flavours used in pdf 
384         fPythia->SetMSTP(58, 3);
385         // Maximum number of flavors that can be used in showers
386         fPythia->SetMSTJ(45, 3);        
387         // Switch off g->QQbar splitting in decay table
388         ((AliDecayerPythia*) fDecayer)->HeavyFlavourOff();
389     }
390
391     fDecayer->Init();
392
393
394 //  Parent and Children Selection
395     switch (fProcess) 
396     {
397     case kPyOldUEQ2ordered:
398     case kPyOldUEQ2ordered2:
399     case kPyOldPopcorn:
400       break;
401     case kPyCharm:
402     case kPyCharmUnforced:
403     case kPyCharmPbPbMNR:
404     case kPyCharmpPbMNR:
405     case kPyCharmppMNR:
406     case kPyCharmppMNRwmi:
407         fParentSelect[0] =   411;
408         fParentSelect[1] =   421;
409         fParentSelect[2] =   431;
410         fParentSelect[3] =  4122;
411         fParentSelect[4] =  4232;
412         fParentSelect[5] =  4132;
413         fParentSelect[6] =  4332;
414         fFlavorSelect    =  4;  
415         break;
416     case kPyD0PbPbMNR:
417     case kPyD0pPbMNR:
418     case kPyD0ppMNR:
419         fParentSelect[0] =   421;
420         fFlavorSelect    =   4; 
421         break;
422     case kPyDPlusPbPbMNR:
423     case kPyDPluspPbMNR:
424     case kPyDPlusppMNR:
425         fParentSelect[0] =   411;
426         fFlavorSelect    =   4; 
427         break;
428     case kPyDPlusStrangePbPbMNR:
429     case kPyDPlusStrangepPbMNR:
430     case kPyDPlusStrangeppMNR:
431         fParentSelect[0] =   431;
432         fFlavorSelect    =   4; 
433         break;
434     case kPyBeauty:
435     case kPyBeautyJets:
436     case kPyBeautyPbPbMNR:
437     case kPyBeautypPbMNR:
438     case kPyBeautyppMNR:
439     case kPyBeautyppMNRwmi:
440         fParentSelect[0]=  511;
441         fParentSelect[1]=  521;
442         fParentSelect[2]=  531;
443         fParentSelect[3]= 5122;
444         fParentSelect[4]= 5132;
445         fParentSelect[5]= 5232;
446         fParentSelect[6]= 5332;
447         fFlavorSelect   = 5;    
448         break;
449     case kPyBeautyUnforced:
450         fParentSelect[0] =  511;
451         fParentSelect[1] =  521;
452         fParentSelect[2] =  531;
453         fParentSelect[3] = 5122;
454         fParentSelect[4] = 5132;
455         fParentSelect[5] = 5232;
456         fParentSelect[6] = 5332;
457         fFlavorSelect    = 5;   
458         break;
459     case kPyJpsiChi:
460     case kPyJpsi:
461         fParentSelect[0] = 443;
462         break;
463     case kPyMbDefault:
464     case kPyMbAtlasTuneMC09:
465     case kPyMb:
466     case kPyMbWithDirectPhoton:
467     case kPyMbNonDiffr:
468     case kPyMbMSEL1:
469     case kPyJets:
470     case kPyDirectGamma:
471     case kPyLhwgMb:     
472         break;
473     case kPyW:
474     case kPyZ:
475         break;
476     }
477 //
478 //
479 //  JetFinder for Trigger
480 //
481 //  Configure detector (EMCAL like)
482 //
483     fPythia->SetPARU(51, fPycellEtaMax);
484     fPythia->SetMSTU(51, fPycellNEta);
485     fPythia->SetMSTU(52, fPycellNPhi);
486 //
487 //  Configure Jet Finder
488 //  
489     fPythia->SetPARU(58,  fPycellThreshold);
490     fPythia->SetPARU(52,  fPycellEtSeed);
491     fPythia->SetPARU(53,  fPycellMinEtJet);
492     fPythia->SetPARU(54,  fPycellMaxRadius);
493     fPythia->SetMSTU(54,  2);
494 //
495 //  This counts the total number of calls to Pyevnt() per run.
496     fTrialsRun = 0;
497     fQ         = 0.;
498     fX1        = 0.;
499     fX2        = 0.;    
500     fNev       = 0 ;
501 //    
502 //
503 //
504     AliGenMC::Init();
505 //
506 //
507 //  
508     if (fSetNuclei) {
509         fDyBoost = 0;
510         Warning("Init","SetNuclei used. Use SetProjectile + SetTarget instead. fDyBoost has been reset to 0\n");
511     }
512     
513     fPythia->SetPARJ(200, 0.0);
514     fPythia->SetPARJ(199, 0.0);
515     fPythia->SetPARJ(198, 0.0);
516     fPythia->SetPARJ(197, 0.0);
517
518     if (fQuench == 1) {
519         fPythia->InitQuenching(0., 0.1, 0.6e6, 0);
520     }
521
522     if (fQuench == 3) {
523         // Nestor's change of the splittings
524         fPythia->SetPARJ(200, 0.8);
525         fPythia->SetMSTJ(41, 1);  // QCD radiation only
526         fPythia->SetMSTJ(42, 2);  // angular ordering
527         fPythia->SetMSTJ(44, 2);  // option to run alpha_s
528         fPythia->SetMSTJ(47, 0);  // No correction back to hard scattering element
529         fPythia->SetMSTJ(50, 0);  // No coherence in first branching
530         fPythia->SetPARJ(82, 1.); // Cut off for parton showers
531     } else if (fQuench == 4) {
532         // Armesto-Cunqueiro-Salgado change of the splittings.
533         AliFastGlauber* glauber = AliFastGlauber::Instance();
534         glauber->Init(2);
535         //read and store transverse almonds corresponding to differnt
536         //impact parameters.
537         glauber->SetCentralityClass(0.,0.1);
538         fPythia->SetPARJ(200, 1.);
539         fPythia->SetPARJ(198, fQhat);
540         fPythia->SetPARJ(199, fLength);
541         fPythia->SetMSTJ(42, 2);  // angular ordering
542         fPythia->SetMSTJ(44, 2);  // option to run alpha_s
543         fPythia->SetPARJ(82, 1.); // Cut off for parton showers
544     }
545 }
546
547 void AliGenPythia::Generate()
548 {
549 // Generate one event
550     if (!fPythia) fPythia=(AliPythia*) fMCEvGen;
551     fDecayer->ForceDecay();
552
553     Float_t polar[3]   =   {0,0,0};
554     Float_t origin[3]  =   {0,0,0};
555     Float_t p[4];
556 //  converts from mm/c to s
557     const Float_t kconv=0.001/2.999792458e8;
558 //
559     Int_t nt=0;
560     Int_t jev=0;
561     Int_t j, kf;
562     fTrials=0;
563     fEventTime = 0.;
564     
565     
566
567     //  Set collision vertex position 
568     if (fVertexSmear == kPerEvent) Vertex();
569     
570 //  event loop    
571     while(1)
572     {
573 //
574 // Produce event
575 //
576 //
577 // Switch hadronisation off
578 //
579         fPythia->SetMSTJ(1, 0);
580
581         if (fQuench ==4){
582             Double_t bimp;
583             // Quenching comes through medium-modified splitting functions.
584             AliFastGlauber::Instance()->GetRandomBHard(bimp);
585             fPythia->SetPARJ(197, bimp);
586             fImpact = bimp;
587             fPythia->Qpygin0();
588         } 
589 //
590 // Either produce new event or read partons from file
591 //      
592         if (!fReadFromFile) {
593             if (!fNewMIS) {
594                 fPythia->Pyevnt();
595             } else {
596                 fPythia->Pyevnw();
597             }
598             fNpartons = fPythia->GetN();
599         } else {
600             printf("Loading Event %d\n",AliRunLoader::Instance()->GetEventNumber());
601             fRL->GetEvent(AliRunLoader::Instance()->GetEventNumber());
602             fPythia->SetN(0);
603             LoadEvent(fRL->Stack(), 0 , 1);
604             fPythia->Pyedit(21);
605         }
606         
607 //
608 //  Run quenching routine 
609 //
610         if (fQuench == 1) {
611             fPythia->Quench();
612         } else if (fQuench == 2){
613             fPythia->Pyquen(208., 0, 0.);
614         } else if (fQuench == 3) {
615             // Quenching is via multiplicative correction of the splittings
616         }
617         
618 //
619 // Switch hadronisation on
620 //
621         if (fHadronisation) {
622             fPythia->SetMSTJ(1, 1);
623 //
624 // .. and perform hadronisation
625 //      printf("Calling hadronisation %d\n", fPythia->GetN());
626             fPythia->Pyexec();  
627         }
628         fTrials++;
629         fPythia->ImportParticles(&fParticles,"All");
630         if (TMath::Abs(fDyBoost) > 1.e-4) Boost();
631 //
632 //
633 //
634         Int_t i;
635         
636         fNprimaries = 0;
637         Int_t np = fParticles.GetEntriesFast();
638         
639         if (np == 0) continue;
640 //
641         
642 //
643         Int_t* pParent   = new Int_t[np];
644         Int_t* pSelected = new Int_t[np];
645         Int_t* trackIt   = new Int_t[np];
646         for (i = 0; i < np; i++) {
647             pParent[i]   = -1;
648             pSelected[i] =  0;
649             trackIt[i]   =  0;
650         }
651
652         Int_t nc = 0;        // Total n. of selected particles
653         Int_t nParents = 0;  // Selected parents
654         Int_t nTkbles = 0;   // Trackable particles
655         if (fProcess != kPyMbDefault && 
656             fProcess != kPyMb && 
657             fProcess != kPyMbAtlasTuneMC09 && 
658             fProcess != kPyMbWithDirectPhoton && 
659             fProcess != kPyJets && 
660             fProcess != kPyDirectGamma &&
661             fProcess != kPyMbNonDiffr  &&
662             fProcess != kPyMbMSEL1     &&
663             fProcess != kPyW && 
664             fProcess != kPyZ &&
665             fProcess != kPyCharmppMNRwmi && 
666             fProcess != kPyBeautyppMNRwmi &&
667             fProcess != kPyBeautyJets) {
668             
669             for (i = 0; i < np; i++) {
670                 TParticle* iparticle = (TParticle *) fParticles.At(i);
671                 Int_t ks = iparticle->GetStatusCode();
672                 kf = CheckPDGCode(iparticle->GetPdgCode());
673 // No initial state partons
674                 if (ks==21) continue;
675 //
676 // Heavy Flavor Selection
677 //
678                 // quark ?
679                 kf = TMath::Abs(kf);
680                 Int_t kfl = kf;
681                 // Resonance
682
683                 if (kfl > 100000) kfl %= 100000;
684                 if (kfl > 10000)  kfl %= 10000;
685                 // meson ?
686                 if  (kfl > 10) kfl/=100;
687                 // baryon
688                 if (kfl > 10) kfl/=10;
689                 Int_t ipa = iparticle->GetFirstMother()-1;
690                 Int_t kfMo = 0;
691 //
692 // Establish mother daughter relation between heavy quarks and mesons
693 //
694                 if (kf >= fFlavorSelect && kf <= 6) {
695                     Int_t idau = iparticle->GetFirstDaughter() - 1;
696                     if (idau > -1) {
697                         TParticle* daughter = (TParticle *) fParticles.At(idau);
698                         Int_t pdgD = daughter->GetPdgCode();
699                         if (pdgD == 91 || pdgD == 92) {
700                             Int_t jmin = daughter->GetFirstDaughter() - 1;
701                             Int_t jmax = daughter->GetLastDaughter()  - 1;                          
702                             for (Int_t jp = jmin; jp <= jmax; jp++)
703                                 ((TParticle *) fParticles.At(jp))->SetFirstMother(i+1);
704                         } // is string or cluster
705                     } // has daughter
706                 } // heavy quark
707                 
708
709                 if (ipa > -1) {
710                     TParticle *  mother = (TParticle *) fParticles.At(ipa);
711                     kfMo = TMath::Abs(mother->GetPdgCode());
712                 }
713                 
714                 // What to keep in Stack?
715                 Bool_t flavorOK = kFALSE;
716                 Bool_t selectOK = kFALSE;
717                 if (fFeedDownOpt) {
718                     if (kfl >= fFlavorSelect) flavorOK = kTRUE;
719                 } else {
720                     if (kfl > fFlavorSelect) {
721                         nc = -1;
722                         break;
723                     }
724                     if (kfl == fFlavorSelect) flavorOK = kTRUE;
725                 }
726                 switch (fStackFillOpt) {
727                 case kFlavorSelection:
728                     selectOK = kTRUE;
729                     break;
730                 case kParentSelection:
731                     if (ParentSelected(kf) || kf <= 10) selectOK = kTRUE;
732                     break;
733                 }
734                 if (flavorOK && selectOK) { 
735 //
736 // Heavy flavor hadron or quark
737 //
738 // Kinematic seletion on final state heavy flavor mesons
739                     if (ParentSelected(kf) && !KinematicSelection(iparticle, 0)) 
740                     {
741                         continue;
742                     }
743                     pSelected[i] = 1;
744                     if (ParentSelected(kf)) ++nParents; // Update parent count
745 //                  printf("\n particle (HF)  %d %d %d", i, pSelected[i], kf);
746                 } else {
747 // Kinematic seletion on decay products
748                     if (fCutOnChild && ParentSelected(kfMo) && ChildSelected(kf) 
749                         && !KinematicSelection(iparticle, 1)) 
750                     {
751                         continue;
752                     }
753 //
754 // Decay products 
755 // Select if mother was selected and is not tracked
756
757                     if (pSelected[ipa] && 
758                         !trackIt[ipa]  &&     // mother will be  tracked ?
759                         kfMo !=  5 &&         // mother is b-quark, don't store fragments          
760                         kfMo !=  4 &&         // mother is c-quark, don't store fragments 
761                         kf   != 92)           // don't store string
762                     {
763 //
764 // Semi-stable or de-selected: diselect decay products:
765 // 
766 //
767                         if (pSelected[i] == -1 ||  fDecayer->GetLifetime(kf) > fMaxLifeTime)
768                         {
769                             Int_t ipF = iparticle->GetFirstDaughter();
770                             Int_t ipL = iparticle->GetLastDaughter();   
771                             if (ipF > 0) for (j = ipF-1; j < ipL; j++) pSelected[j] = -1;
772                         }
773 //                      printf("\n particle (decay)  %d %d %d", i, pSelected[i], kf);
774                         pSelected[i] = (pSelected[i] == -1) ? 0 : 1;
775                     }
776                 }
777                 if (pSelected[i] == -1) pSelected[i] = 0;
778                 if (!pSelected[i]) continue;
779                 // Count quarks only if you did not include fragmentation
780                 if (fFragmentation && kf <= 10) continue;
781
782                 nc++;
783 // Decision on tracking
784                 trackIt[i] = 0;
785 //
786 // Track final state particle
787                 if (ks == 1) trackIt[i] = 1;
788 // Track semi-stable particles
789                 if ((ks == 1) || (fDecayer->GetLifetime(kf) > fMaxLifeTime))  trackIt[i] = 1;
790 // Track particles selected by process if undecayed. 
791                 if (fForceDecay == kNoDecay) {
792                     if (ParentSelected(kf)) trackIt[i] = 1;
793                 } else {
794                     if (ParentSelected(kf)) trackIt[i] = 0;
795                 }
796                 if (trackIt[i] == 1) ++nTkbles; // Update trackable counter
797 //
798 //
799
800             } // particle selection loop
801             if (nc > 0) {
802                 for (i = 0; i<np; i++) {
803                     if (!pSelected[i]) continue;
804                     TParticle *  iparticle = (TParticle *) fParticles.At(i);
805                     kf = CheckPDGCode(iparticle->GetPdgCode());
806                     Int_t ks = iparticle->GetStatusCode();  
807                     p[0] = iparticle->Px();
808                     p[1] = iparticle->Py();
809                     p[2] = iparticle->Pz();
810                     p[3] = iparticle->Energy();
811                     
812                     origin[0] = fVertex[0]+iparticle->Vx()/10; // [cm]
813                     origin[1] = fVertex[1]+iparticle->Vy()/10; // [cm]
814                     origin[2] = fVertex[2]+iparticle->Vz()/10; // [cm]
815                     
816                     Float_t tof   = kconv*iparticle->T();
817                     Int_t ipa     = iparticle->GetFirstMother()-1;
818                     Int_t iparent = (ipa > -1) ? pParent[ipa] : -1;
819  
820                     PushTrack(fTrackIt*trackIt[i], iparent, kf, 
821                               p[0], p[1], p[2], p[3], 
822                               origin[0], origin[1], origin[2], tof, 
823                               polar[0], polar[1], polar[2],
824                               kPPrimary, nt, 1., ks);
825                     pParent[i] = nt;
826                     KeepTrack(nt);
827                     fNprimaries++;
828                 } //  PushTrack loop
829             }
830         } else {
831             nc = GenerateMB();
832         } // mb ?
833         
834         GetSubEventTime();
835
836         delete[] pParent;
837         delete[] pSelected;
838         delete[] trackIt;
839
840         if (nc > 0) {
841           switch (fCountMode) {
842           case kCountAll:
843             // printf(" Count all \n");
844             jev += nc;
845             break;
846           case kCountParents:
847             // printf(" Count parents \n");
848             jev += nParents;
849             break;
850           case kCountTrackables:
851             // printf(" Count trackable \n");
852             jev += nTkbles;
853             break;
854           }
855             if (jev >= fNpart || fNpart == -1) {
856                 fKineBias=Float_t(fNpart)/Float_t(fTrials);
857                 
858                 fQ  += fPythia->GetVINT(51);
859                 fX1 += fPythia->GetVINT(41);
860                 fX2 += fPythia->GetVINT(42);
861                 fTrialsRun += fTrials;
862                 fNev++;
863                 MakeHeader();
864                 break;
865             }
866         }
867     } // event loop
868     SetHighWaterMark(nt);
869 //  adjust weight due to kinematic selection
870 //    AdjustWeights();
871 //  get cross-section
872     fXsection=fPythia->GetPARI(1);
873 }
874
875 Int_t  AliGenPythia::GenerateMB()
876 {
877 //
878 // Min Bias selection and other global selections
879 //
880     Int_t i, kf, nt, iparent;
881     Int_t nc = 0;
882     Float_t p[4];
883     Float_t polar[3]   =   {0,0,0};
884     Float_t origin[3]  =   {0,0,0};
885 //  converts from mm/c to s
886     const Float_t kconv=0.001/2.999792458e8;
887     
888
889     
890     Int_t np = (fHadronisation) ? fParticles.GetEntriesFast() : fNpartons;
891
892
893
894     Int_t* pParent = new Int_t[np];
895     for (i=0; i< np; i++) pParent[i] = -1;
896      if (fProcess == kPyJets || fProcess == kPyDirectGamma || fProcess == kPyBeautyJets || fProcess == kPyBeautyppMNRwmi) {
897         TParticle* jet1 = (TParticle *) fParticles.At(6);
898         TParticle* jet2 = (TParticle *) fParticles.At(7);
899         if (!CheckTrigger(jet1, jet2)) {
900           delete [] pParent;
901           return 0;
902         }
903     }
904
905     // Select jets with fragmentation photon or pi0 going to PHOS or EMCAL
906     if (fProcess == kPyJets && (fFragPhotonInCalo || fPi0InCalo) ) {
907
908       Bool_t ok = kFALSE;
909
910       Int_t pdg  = 0; 
911       if (fFragPhotonInCalo) pdg = 22   ; // Photon
912       else if (fPi0InCalo)   pdg = 111 ;    // Pi0
913
914       for (i=0; i< np; i++) {
915         TParticle* iparticle = (TParticle *) fParticles.At(i);
916         if(iparticle->GetStatusCode()==1 && iparticle->GetPdgCode()==pdg && 
917            iparticle->Pt() > fFragPhotonOrPi0MinPt){
918           Int_t imother = iparticle->GetFirstMother() - 1;
919           TParticle* pmother = (TParticle *) fParticles.At(imother);
920           if(pdg == 111 || 
921              (pdg == 22 && pmother->GetStatusCode() != 11)) //No photon from hadron decay
922             {
923               Float_t phi = iparticle->Phi()*180./TMath::Pi(); //Convert to degrees
924               Float_t eta =TMath::Abs(iparticle->Eta()); //in calos etamin=-etamax        
925               if((fCheckEMCAL && IsInEMCAL(phi,eta)) ||
926                  (fCheckPHOS    && IsInPHOS(phi,eta)) )
927                 ok =kTRUE;
928             }
929         }
930       }
931       if(!ok)
932         return 0;
933     }
934
935     // Select beauty jets with electron in EMCAL
936     if (fProcess == kPyBeautyJets && fEleInEMCAL) {
937
938       Bool_t ok = kFALSE;
939
940       Int_t pdg  = 11; //electron
941
942       Float_t pt  = 0.;
943       Float_t eta = 0.;
944       Float_t phi = 0.;
945       for (i=0; i< np; i++) {
946         TParticle* iparticle = (TParticle *) fParticles.At(i);
947         if(iparticle->GetStatusCode()==1 && TMath::Abs(iparticle->GetPdgCode())==pdg && 
948            iparticle->Pt() > fElectronMinPt){
949           pt = iparticle->Pt();
950           phi = iparticle->Phi()*180./TMath::Pi(); //Convert to degrees
951           eta =TMath::Abs(iparticle->Eta()); //in calos etamin=-etamax    
952           if(IsInEMCAL(phi,eta))
953             ok =kTRUE;
954         }
955       }
956       if(!ok)
957         return 0;
958       AliDebug(5,Form("Found an electron jet (pt,eta,phi) = (%f,%f,%f)",pt,eta,phi));
959     }
960     // Check for minimum multiplicity
961     if (fTriggerMultiplicity > 0) {
962       Int_t multiplicity = 0;
963       for (i = 0; i < np; i++) {
964         TParticle *  iparticle = (TParticle *) fParticles.At(i);
965         
966         Int_t statusCode = iparticle->GetStatusCode();
967         
968         // Initial state particle
969         if (statusCode != 1)
970           continue;
971         // eta cut
972         if (fTriggerMultiplicityEta > 0 && TMath::Abs(iparticle->Eta()) > fTriggerMultiplicityEta)
973           continue;
974         // pt cut
975         if (iparticle->Pt() < fTriggerMultiplicityPtMin) 
976             continue;
977
978         TParticlePDG* pdgPart = iparticle->GetPDG();
979         if (pdgPart && pdgPart->Charge() == 0)
980           continue;
981         
982         ++multiplicity;
983       }
984
985       if (multiplicity < fTriggerMultiplicity) {
986         delete [] pParent;
987         return 0;
988       }
989       Printf("Triggered on event with multiplicity of %d >= %d", multiplicity, fTriggerMultiplicity);
990     }    
991     
992      // Select events with a photon  pt > min pt going to PHOS eta acceptance or exactly PHOS eta phi
993     if ((fProcess == kPyJets || fProcess == kPyDirectGamma) && fPhotonInCalo && (fCheckPHOSeta || fCheckPHOS)){
994
995       Bool_t okd = kFALSE;
996
997       Int_t pdg  = 22; 
998       Int_t iphcand = -1;
999       for (i=0; i< np; i++) {
1000          TParticle* iparticle = (TParticle *) fParticles.At(i);
1001          Float_t phi = iparticle->Phi()*180./TMath::Pi(); //Convert to degrees
1002          Float_t eta =TMath::Abs(iparticle->Eta());//in calos etamin=-etamax 
1003          
1004          if(iparticle->GetStatusCode() == 1 
1005             && iparticle->GetPdgCode() == pdg   
1006             && iparticle->Pt() > fPhotonMinPt    
1007             && eta < fPHOSEta){                 
1008             
1009             // first check if the photon is in PHOS phi
1010             if(IsInPHOS(phi,eta)){ 
1011                 okd = kTRUE;
1012                 break;
1013             } 
1014             if(fCheckPHOSeta) iphcand = i; // candiate photon to rotate in phi
1015              
1016          }
1017       }
1018       
1019       if(!okd && iphcand != -1) // execute rotation in phi 
1020           RotatePhi(iphcand,okd);
1021       
1022       if(!okd)
1023         return 0;
1024     }
1025     
1026     if (fTriggerParticle) {
1027         Bool_t triggered = kFALSE;
1028         for (i = 0; i < np; i++) {
1029             TParticle *  iparticle = (TParticle *) fParticles.At(i);
1030             kf = CheckPDGCode(iparticle->GetPdgCode());
1031             if (kf != fTriggerParticle) continue;
1032             if (iparticle->Pt() == 0.) continue;
1033             if (TMath::Abs(iparticle->Eta()) > fTriggerEta) continue;
1034             triggered = kTRUE;
1035             break;
1036         }
1037         if (!triggered) {
1038           delete [] pParent;
1039           return 0;
1040         }
1041     }
1042         
1043
1044     // Check if there is a ccbar or bbbar pair with at least one of the two
1045     // in fYMin < y < fYMax
1046
1047     if (fProcess == kPyCharmppMNRwmi || fProcess == kPyBeautyppMNRwmi || fProcess == kPyBeautyJets) {
1048       TParticle *partCheck;
1049       TParticle *mother;
1050       Bool_t  theQ=kFALSE,theQbar=kFALSE,inYcut=kFALSE;
1051       Bool_t  theChild=kFALSE;
1052       Float_t y;  
1053       Int_t   pdg,mpdg,mpdgUpperFamily;
1054       for(i=0; i<np; i++) {
1055         partCheck = (TParticle*)fParticles.At(i);
1056         pdg = partCheck->GetPdgCode();  
1057         if(TMath::Abs(pdg) == fFlavorSelect) { // quark  
1058           if(pdg>0) { theQ=kTRUE; } else { theQbar=kTRUE; }
1059           y = 0.5*TMath::Log((partCheck->Energy()+partCheck->Pz()+1.e-13)/
1060                              (partCheck->Energy()-partCheck->Pz()+1.e-13));
1061           if(y>fYMin && y<fYMax) inYcut=kTRUE;
1062         }
1063         if(fCutOnChild && TMath::Abs(pdg) == fPdgCodeParticleforAcceptanceCut) {
1064           Int_t mi = partCheck->GetFirstMother() - 1;
1065           if(mi<0) continue;
1066           mother = (TParticle*)fParticles.At(mi);
1067           mpdg=TMath::Abs(mother->GetPdgCode());
1068           mpdgUpperFamily=(mpdg>1000 ? mpdg+1000 : mpdg+100); // keep e from c from b
1069           if ( ParentSelected(mpdg) || 
1070               (fFlavorSelect==5 && ParentSelected(mpdgUpperFamily))) {
1071             if (KinematicSelection(partCheck,1)) {
1072               theChild=kTRUE;
1073             }
1074           }
1075         }
1076       }
1077       if (!theQ || !theQbar || !inYcut) { // one of the c/b conditions not satisfied
1078         delete[] pParent;
1079         return 0;
1080       }
1081       if (fCutOnChild && !theChild) { // one of the child conditions not satisfied
1082         delete[] pParent;
1083         return 0;       
1084       }
1085
1086     }
1087
1088     //Introducing child cuts in case kPyW, kPyZ, kPyMb, and kPyMbNonDiff
1089     if ( (fProcess == kPyW ||
1090           fProcess == kPyZ ||
1091           fProcess == kPyMbDefault ||
1092           fProcess == kPyMb ||
1093           fProcess == kPyMbAtlasTuneMC09 ||
1094           fProcess == kPyMbWithDirectPhoton ||
1095           fProcess == kPyMbNonDiffr)  
1096          && (fCutOnChild == 1) ) {
1097       if ( !CheckKinematicsOnChild() ) {
1098         delete[] pParent;
1099         return 0;
1100       }
1101     }
1102   
1103
1104     for (i = 0; i < np; i++) {
1105         Int_t trackIt = 0;
1106         TParticle *  iparticle = (TParticle *) fParticles.At(i);
1107         kf = CheckPDGCode(iparticle->GetPdgCode());
1108         Int_t ks = iparticle->GetStatusCode();
1109         Int_t km = iparticle->GetFirstMother();
1110         if ((ks == 1  && kf!=0 && KinematicSelection(iparticle, 0)) ||
1111             (ks != 1) ||
1112             ((fProcess == kPyJets || fProcess == kPyBeautyJets) && ks == 21 && km == 0 && i>1)) {
1113             nc++;
1114             if (ks == 1) trackIt = 1;
1115             Int_t ipa = iparticle->GetFirstMother()-1;
1116             
1117             iparent = (ipa > -1) ? pParent[ipa] : -1;
1118             
1119 //
1120 // store track information
1121             p[0] = iparticle->Px();
1122             p[1] = iparticle->Py();
1123             p[2] = iparticle->Pz();
1124             p[3] = iparticle->Energy();
1125
1126             
1127             origin[0] = fVertex[0]+iparticle->Vx()/10; // [cm]
1128             origin[1] = fVertex[1]+iparticle->Vy()/10; // [cm]
1129             origin[2] = fVertex[2]+iparticle->Vz()/10; // [cm]
1130             
1131             Float_t tof = fEventTime + kconv * iparticle->T();
1132
1133             PushTrack(fTrackIt*trackIt, iparent, kf, 
1134                       p[0], p[1], p[2], p[3], 
1135                       origin[0], origin[1], origin[2], tof, 
1136                       polar[0], polar[1], polar[2],
1137                       kPPrimary, nt, 1., ks);
1138             fNprimaries++;
1139             KeepTrack(nt);
1140             pParent[i] = nt;
1141             SetHighWaterMark(nt);
1142             
1143         } // select particle
1144     } // particle loop 
1145
1146     delete[] pParent;
1147     
1148     return 1;
1149 }
1150
1151
1152 void AliGenPythia::FinishRun()
1153 {
1154 // Print x-section summary
1155     fPythia->Pystat(1);
1156
1157     if (fNev > 0.) {
1158         fQ  /= fNev;
1159         fX1 /= fNev;
1160         fX2 /= fNev;    
1161     }
1162     
1163     printf("\nTotal number of Pyevnt() calls %d\n", fTrialsRun);
1164     printf("\nMean Q, x1, x2: %f %f %f\n", fQ, fX1, fX2);
1165 }
1166
1167 void AliGenPythia::AdjustWeights() const
1168 {
1169 // Adjust the weights after generation of all events
1170 //
1171     if (gAlice) {
1172         TParticle *part;
1173         Int_t ntrack=gAlice->GetMCApp()->GetNtrack();
1174         for (Int_t i=0; i<ntrack; i++) {
1175             part= gAlice->GetMCApp()->Particle(i);
1176             part->SetWeight(part->GetWeight()*fKineBias);
1177         }
1178     }
1179 }
1180     
1181 void AliGenPythia::SetNuclei(Int_t a1, Int_t a2, Int_t pdfset)
1182 {
1183 // Treat protons as inside nuclei with mass numbers a1 and a2  
1184
1185     fAProjectile = a1;
1186     fATarget     = a2;
1187     fNucPdf      = pdfset;  // 0 EKS98 1 EPS08
1188     fSetNuclei   = kTRUE;
1189 }
1190
1191
1192 void AliGenPythia::MakeHeader()
1193 {
1194 //
1195 // Make header for the simulated event
1196 // 
1197   if (gAlice) {
1198     if (gAlice->GetEvNumber()>=fDebugEventFirst &&
1199         gAlice->GetEvNumber()<=fDebugEventLast) fPythia->Pylist(2);
1200   }
1201
1202 // Builds the event header, to be called after each event
1203     if (fHeader) delete fHeader;
1204     fHeader = new AliGenPythiaEventHeader("Pythia");
1205 //
1206 // Event type  
1207     ((AliGenPythiaEventHeader*) fHeader)->SetProcessType(fPythia->GetMSTI(1));
1208 //
1209 // Number of trials
1210     ((AliGenPythiaEventHeader*) fHeader)->SetTrials(fTrials);
1211 //
1212 // Event Vertex 
1213     fHeader->SetPrimaryVertex(fVertex);
1214     fHeader->SetInteractionTime(fEventTime);
1215 //
1216 // Number of primaries
1217     fHeader->SetNProduced(fNprimaries);
1218 //
1219 // Jets that have triggered
1220
1221     //Need to store jets for b-jet studies too!
1222     if (fProcess == kPyJets || fProcess == kPyDirectGamma || fProcess == kPyBeautyJets || fProcess == kPyBeautyppMNRwmi)
1223     {
1224         Int_t ntrig, njet;
1225         Float_t jets[4][10];
1226         GetJets(njet, ntrig, jets);
1227
1228         
1229         for (Int_t i = 0; i < ntrig; i++) {
1230             ((AliGenPythiaEventHeader*) fHeader)->AddJet(jets[0][i], jets[1][i], jets[2][i], 
1231                                                         jets[3][i]);
1232         }
1233     }
1234 //
1235 // Copy relevant information from external header, if present.
1236 //
1237     Float_t uqJet[4];
1238     
1239     if (fRL) {
1240         AliGenPythiaEventHeader* exHeader = (AliGenPythiaEventHeader*) (fRL->GetHeader()->GenEventHeader());
1241         for (Int_t i = 0; i < exHeader->NTriggerJets(); i++)
1242         {
1243             printf("Adding Jet %d %d \n", i,  exHeader->NTriggerJets());
1244             
1245             
1246             exHeader->TriggerJet(i, uqJet);
1247             ((AliGenPythiaEventHeader*) fHeader)->AddUQJet(uqJet[0], uqJet[1], uqJet[2], uqJet[3]);
1248         }
1249     }
1250 //
1251 // Store quenching parameters
1252 //
1253     if (fQuench){
1254         Double_t z[4];
1255         Double_t xp, yp;
1256         if (fQuench == 1) {
1257             // Pythia::Quench()
1258             fPythia->GetQuenchingParameters(xp, yp, z);
1259         } else if (fQuench == 2){
1260             // Pyquen
1261             Double_t r1 = PARIMP.rb1;
1262             Double_t r2 = PARIMP.rb2;
1263             Double_t b  = PARIMP.b1;
1264             Double_t r   = 0.5 * TMath::Sqrt(2. * (r1 * r1 + r2 * r2) - b * b);
1265             Double_t phi = PARIMP.psib1;
1266             xp = r * TMath::Cos(phi);
1267             yp = r * TMath::Sin(phi);
1268             
1269         } else if (fQuench == 4) {
1270             // QPythia
1271             Double_t xy[2];
1272             Double_t i0i1[2];
1273             AliFastGlauber::Instance()->GetSavedXY(xy);
1274             AliFastGlauber::Instance()->GetSavedI0I1(i0i1);
1275             xp = xy[0];
1276             yp = xy[1];
1277             ((AliGenPythiaEventHeader*) fHeader)->SetImpactParameter(fImpact);
1278         }
1279         
1280             ((AliGenPythiaEventHeader*) fHeader)->SetXYJet(xp, yp);
1281             ((AliGenPythiaEventHeader*) fHeader)->SetZQuench(z);
1282     }
1283 //
1284 // Store pt^hard 
1285     ((AliGenPythiaEventHeader*) fHeader)->SetPtHard(fPythia->GetVINT(47));
1286 //
1287 //  Pass header
1288 //
1289     AddHeader(fHeader);
1290     fHeader = 0x0;
1291 }
1292
1293 Bool_t AliGenPythia::CheckTrigger(TParticle* jet1, TParticle* jet2)
1294 {
1295 // Check the kinematic trigger condition
1296 //
1297     Double_t eta[2];
1298     eta[0] = jet1->Eta();
1299     eta[1] = jet2->Eta();
1300     Double_t phi[2];
1301     phi[0] = jet1->Phi();
1302     phi[1] = jet2->Phi();
1303     Int_t    pdg[2]; 
1304     pdg[0] = jet1->GetPdgCode();
1305     pdg[1] = jet2->GetPdgCode();    
1306     Bool_t   triggered = kFALSE;
1307
1308     if (fProcess == kPyJets || fProcess == kPyBeautyJets || fProcess ==  kPyBeautyppMNRwmi) {
1309         Int_t njets = 0;
1310         Int_t ntrig = 0;
1311         Float_t jets[4][10];
1312 //
1313 // Use Pythia clustering on parton level to determine jet axis
1314 //
1315         GetJets(njets, ntrig, jets);
1316         
1317         if (ntrig || fEtMinJet == 0.) triggered = kTRUE;
1318 //
1319     } else {
1320         Int_t ij = 0;
1321         Int_t ig = 1;
1322         if (pdg[0] == kGamma) {
1323             ij = 1;
1324             ig = 0;
1325         }
1326         //Check eta range first...
1327         if ((eta[ij] < fEtaMaxJet   && eta[ij] > fEtaMinJet) &&
1328             (eta[ig] < fEtaMaxGamma && eta[ig] > fEtaMinGamma))
1329         {
1330             //Eta is okay, now check phi range
1331             if ((phi[ij] < fPhiMaxJet   && phi[ij] > fPhiMinJet) &&
1332                 (phi[ig] < fPhiMaxGamma && phi[ig] > fPhiMinGamma))
1333             {
1334                 triggered = kTRUE;
1335             }
1336         }
1337     }
1338     return triggered;
1339 }
1340
1341
1342
1343 Bool_t AliGenPythia::CheckKinematicsOnChild(){
1344 //
1345 //Checking Kinematics on Child (status code 1, particle code ?, kin cuts
1346 //
1347     Bool_t checking = kFALSE;
1348     Int_t j, kcode, ks, km;
1349     Int_t nPartAcc = 0; //number of particles in the acceptance range
1350     Int_t numberOfAcceptedParticles = 1;
1351     if (fNumberOfAcceptedParticles != 0) { numberOfAcceptedParticles = fNumberOfAcceptedParticles; }
1352     Int_t npart = fParticles.GetEntriesFast();
1353     
1354     for (j = 0; j<npart; j++) {
1355         TParticle *  jparticle = (TParticle *) fParticles.At(j);
1356         kcode = TMath::Abs( CheckPDGCode(jparticle->GetPdgCode()) );
1357         ks = jparticle->GetStatusCode();
1358         km = jparticle->GetFirstMother(); 
1359         
1360         if( (ks == 1)  &&  (kcode == fPdgCodeParticleforAcceptanceCut)  &&  (KinematicSelection(jparticle,1)) ){
1361             nPartAcc++;
1362         }
1363         if( numberOfAcceptedParticles <= nPartAcc){
1364           checking = kTRUE;
1365           break;
1366         }
1367     }
1368
1369     return checking;
1370 }
1371
1372 void  AliGenPythia::LoadEvent(AliStack* stack, Int_t flag, Int_t reHadr)
1373 {
1374   //
1375   // Load event into Pythia Common Block
1376   //
1377   
1378   Int_t npart = stack -> GetNprimary();
1379   Int_t n0 = 0;
1380   
1381   if (!flag) {
1382     (fPythia->GetPyjets())->N = npart;
1383   } else {
1384     n0 = (fPythia->GetPyjets())->N;
1385     (fPythia->GetPyjets())->N = n0 + npart;
1386   }
1387   
1388   
1389   for (Int_t part = 0; part < npart; part++) {
1390     TParticle *mPart = stack->Particle(part);
1391     
1392     Int_t kf     =  mPart->GetPdgCode();
1393     Int_t ks     =  mPart->GetStatusCode();
1394     Int_t idf    =  mPart->GetFirstDaughter();
1395     Int_t idl    =  mPart->GetLastDaughter();
1396     
1397     if (reHadr) {
1398             if (ks == 11 || ks == 12) {
1399         ks  -= 10;
1400         idf  = -1;
1401         idl  = -1;
1402             }
1403     }
1404     
1405     Float_t px = mPart->Px();
1406     Float_t py = mPart->Py();
1407     Float_t pz = mPart->Pz();
1408     Float_t e  = mPart->Energy();
1409     Float_t m  = mPart->GetCalcMass();
1410     
1411     
1412     (fPythia->GetPyjets())->P[0][part+n0] = px;
1413     (fPythia->GetPyjets())->P[1][part+n0] = py;
1414     (fPythia->GetPyjets())->P[2][part+n0] = pz;
1415     (fPythia->GetPyjets())->P[3][part+n0] = e;
1416     (fPythia->GetPyjets())->P[4][part+n0] = m;
1417     
1418     (fPythia->GetPyjets())->K[1][part+n0] = kf;
1419     (fPythia->GetPyjets())->K[0][part+n0] = ks;
1420     (fPythia->GetPyjets())->K[3][part+n0] = idf + 1;
1421     (fPythia->GetPyjets())->K[4][part+n0] = idl + 1;
1422     (fPythia->GetPyjets())->K[2][part+n0] = mPart->GetFirstMother() + 1;
1423   }
1424 }
1425
1426 void  AliGenPythia::LoadEvent(TObjArray* stack, Int_t flag, Int_t reHadr)
1427 {
1428   //
1429   // Load event into Pythia Common Block
1430   //
1431   
1432   Int_t npart = stack -> GetEntries();
1433   Int_t n0 = 0;
1434   
1435   if (!flag) {
1436     (fPythia->GetPyjets())->N = npart;
1437   } else {
1438     n0 = (fPythia->GetPyjets())->N;
1439     (fPythia->GetPyjets())->N = n0 + npart;
1440   }
1441   
1442   
1443   for (Int_t part = 0; part < npart; part++) {
1444     TParticle *mPart = dynamic_cast<TParticle *>(stack->At(part));
1445     Int_t kf     =  mPart->GetPdgCode();
1446     Int_t ks     =  mPart->GetStatusCode();
1447     Int_t idf    =  mPart->GetFirstDaughter();
1448     Int_t idl    =  mPart->GetLastDaughter();
1449     
1450     if (reHadr) {
1451             if (ks == 11 || ks == 12) {
1452         ks  -= 10;
1453         idf  = -1;
1454         idl  = -1;
1455             }
1456     }
1457     
1458     Float_t px = mPart->Px();
1459     Float_t py = mPart->Py();
1460     Float_t pz = mPart->Pz();
1461     Float_t e  = mPart->Energy();
1462     Float_t m  = mPart->GetCalcMass();
1463     
1464     
1465     (fPythia->GetPyjets())->P[0][part+n0] = px;
1466     (fPythia->GetPyjets())->P[1][part+n0] = py;
1467     (fPythia->GetPyjets())->P[2][part+n0] = pz;
1468     (fPythia->GetPyjets())->P[3][part+n0] = e;
1469     (fPythia->GetPyjets())->P[4][part+n0] = m;
1470     
1471     (fPythia->GetPyjets())->K[1][part+n0] = kf;
1472     (fPythia->GetPyjets())->K[0][part+n0] = ks;
1473     (fPythia->GetPyjets())->K[3][part+n0] = idf + 1;
1474     (fPythia->GetPyjets())->K[4][part+n0] = idl + 1;
1475     (fPythia->GetPyjets())->K[2][part+n0] = mPart->GetFirstMother() + 1;
1476   }
1477 }
1478
1479
1480 void AliGenPythia::RecJetsUA1(Int_t& njets, Float_t jets [4][50])
1481 {
1482 //
1483 //  Calls the Pythia jet finding algorithm to find jets in the current event
1484 //
1485 //
1486 //
1487 //  Save jets
1488     Int_t n     = fPythia->GetN();
1489
1490 //
1491 //  Run Jet Finder
1492     fPythia->Pycell(njets);
1493     Int_t i;
1494     for (i = 0; i < njets; i++) {
1495         Float_t px    = (fPythia->GetPyjets())->P[0][n+i];
1496         Float_t py    = (fPythia->GetPyjets())->P[1][n+i];
1497         Float_t pz    = (fPythia->GetPyjets())->P[2][n+i];
1498         Float_t e     = (fPythia->GetPyjets())->P[3][n+i];
1499
1500         jets[0][i] = px;
1501         jets[1][i] = py;
1502         jets[2][i] = pz;
1503         jets[3][i] = e;
1504     }
1505 }
1506
1507
1508
1509 void  AliGenPythia::GetJets(Int_t& nJets, Int_t& nJetsTrig, Float_t jets[4][10])
1510 {
1511 //
1512 //  Calls the Pythia clustering algorithm to find jets in the current event
1513 //
1514     Int_t n     = fPythia->GetN();
1515     nJets       = 0;
1516     nJetsTrig   = 0;
1517     if (fJetReconstruction == kCluster) {
1518 //
1519 //  Configure cluster algorithm
1520 //    
1521         fPythia->SetPARU(43, 2.);
1522         fPythia->SetMSTU(41, 1);
1523 //
1524 //  Call cluster algorithm
1525 //    
1526         fPythia->Pyclus(nJets);
1527 //
1528 //  Loading jets from common block
1529 //
1530     } else {
1531
1532 //
1533 //  Run Jet Finder
1534         fPythia->Pycell(nJets);
1535     }
1536
1537     Int_t i;
1538     for (i = 0; i < nJets; i++) {
1539         Float_t px    = (fPythia->GetPyjets())->P[0][n+i];
1540         Float_t py    = (fPythia->GetPyjets())->P[1][n+i];
1541         Float_t pz    = (fPythia->GetPyjets())->P[2][n+i];
1542         Float_t e     = (fPythia->GetPyjets())->P[3][n+i];
1543         Float_t pt    = TMath::Sqrt(px * px + py * py);
1544         Float_t phi   = TMath::Pi() + TMath::ATan2(-py, -px);  
1545         Float_t theta = TMath::ATan2(pt,pz);
1546         Float_t et    = e * TMath::Sin(theta);
1547         Float_t eta   = -TMath::Log(TMath::Tan(theta / 2.));
1548         if (
1549             eta > fEtaMinJet && eta < fEtaMaxJet && 
1550             phi > fPhiMinJet && phi < fPhiMaxJet &&
1551             et  > fEtMinJet  && et  < fEtMaxJet     
1552             ) 
1553         {
1554             jets[0][nJetsTrig] = px;
1555             jets[1][nJetsTrig] = py;
1556             jets[2][nJetsTrig] = pz;
1557             jets[3][nJetsTrig] = e;
1558             nJetsTrig++;
1559 //          printf("\n........-Jet #%d: %10.3f %10.3f %10.3f %10.3f \n", i, pt, et, eta, phi * kRaddeg);
1560         } else {
1561 //          printf("\n........-Jet #%d: %10.3f %10.3f %10.3f %10.3f \n", i, pt, et, eta, phi * kRaddeg);
1562         }
1563     }
1564 }
1565
1566 void AliGenPythia::GetSubEventTime()
1567 {
1568   // Calculates time of the next subevent
1569   fEventTime = 0.;
1570   if (fEventsTime) {
1571     TArrayF &array = *fEventsTime;
1572     fEventTime = array[fCurSubEvent++];
1573   }
1574   //  printf(" Event time: %d %f %p",fCurSubEvent,fEventTime,fEventsTime);
1575   return;
1576 }
1577
1578 Bool_t AliGenPythia::IsInEMCAL(Float_t phi, Float_t eta)
1579 {
1580   // Is particle in EMCAL acceptance? 
1581   // phi in degrees, etamin=-etamax
1582   if(phi > fEMCALMinPhi  && phi < fEMCALMaxPhi && 
1583      eta < fEMCALEta  ) 
1584     return kTRUE;
1585   else 
1586     return kFALSE;
1587 }
1588
1589 Bool_t AliGenPythia::IsInPHOS(Float_t phi, Float_t eta)
1590 {
1591   // Is particle in PHOS acceptance? 
1592   // Acceptance slightly larger considered.
1593   // phi in degrees, etamin=-etamax
1594   if(phi > fPHOSMinPhi  && phi < fPHOSMaxPhi && 
1595      eta < fPHOSEta  ) 
1596     return kTRUE;
1597   else 
1598     return kFALSE;
1599 }
1600
1601 void AliGenPythia::RotatePhi(Int_t iphcand, Bool_t& okdd)
1602 {
1603   //calculate the new position random between fPHOSMinPhi and fPHOSMaxPhi 
1604   Double_t phiPHOSmin = TMath::Pi()*fPHOSMinPhi/180;
1605   Double_t phiPHOSmax = TMath::Pi()*fPHOSMaxPhi/180;
1606   Double_t phiPHOS = gRandom->Uniform(phiPHOSmin,phiPHOSmax);
1607   
1608   //calculate deltaphi
1609   TParticle* ph = (TParticle *) fParticles.At(iphcand);
1610   Double_t phphi = ph->Phi();
1611   Double_t deltaphi = phiPHOS - phphi;
1612
1613   
1614   
1615   //loop for all particles and produce the phi rotation
1616   Int_t np = (fHadronisation) ? fParticles.GetEntriesFast() : fNpartons;
1617   Double_t oldphi, newphi;
1618   Double_t newVx, newVy, R, Vz, time; 
1619   Double_t newPx, newPy, pt, Pz, e;
1620   for(Int_t i=0; i< np; i++) {
1621       TParticle* iparticle = (TParticle *) fParticles.At(i);
1622       oldphi = iparticle->Phi();
1623       newphi = oldphi + deltaphi;
1624       if(newphi < 0) newphi = 2*TMath::Pi() + newphi; // correct angle 
1625       if(newphi > 2*TMath::Pi()) newphi = newphi - 2*TMath::Pi(); // correct angle
1626       
1627       R = iparticle->R();
1628       newVx = R*TMath::Cos(newphi);
1629       newVy = R*TMath::Sin(newphi);
1630       Vz = iparticle->Vz(); // don't transform
1631       time = iparticle->T(); // don't transform
1632       
1633       pt = iparticle->Pt();
1634       newPx = pt*TMath::Cos(newphi);
1635       newPy = pt*TMath::Sin(newphi);
1636       Pz = iparticle->Pz(); // don't transform
1637       e = iparticle->Energy(); // don't transform
1638       
1639       // apply rotation 
1640       iparticle->SetProductionVertex(newVx, newVy, Vz, time);
1641       iparticle->SetMomentum(newPx, newPy, Pz, e);
1642       
1643   } //end particle loop 
1644   
1645    // now let's check that we put correctly the candidate photon in PHOS
1646    Float_t phi = ph->Phi()*180./TMath::Pi(); //Convert to degrees
1647    Float_t eta =TMath::Abs(ph->Eta());//in calos etamin=-etamax 
1648    if(IsInPHOS(phi,eta)) 
1649       okdd = kTRUE;
1650 }
1651
1652
1653 #ifdef never
1654 void AliGenPythia::Streamer(TBuffer &R__b)
1655 {
1656    // Stream an object of class AliGenPythia.
1657
1658    if (R__b.IsReading()) {
1659       Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1660       AliGenerator::Streamer(R__b);
1661       R__b >> (Int_t&)fProcess;
1662       R__b >> (Int_t&)fStrucFunc;
1663       R__b >> (Int_t&)fForceDecay;
1664       R__b >> fEnergyCMS;
1665       R__b >> fKineBias;
1666       R__b >> fTrials;
1667       fParentSelect.Streamer(R__b);
1668       fChildSelect.Streamer(R__b);
1669       R__b >> fXsection;
1670 //      (AliPythia::Instance())->Streamer(R__b);
1671       R__b >> fPtHardMin;
1672       R__b >> fPtHardMax;
1673 //      if (fDecayer) fDecayer->Streamer(R__b);
1674    } else {
1675       R__b.WriteVersion(AliGenPythia::IsA());
1676       AliGenerator::Streamer(R__b);
1677       R__b << (Int_t)fProcess;
1678       R__b << (Int_t)fStrucFunc;
1679       R__b << (Int_t)fForceDecay;
1680       R__b << fEnergyCMS;
1681       R__b << fKineBias;
1682       R__b << fTrials;
1683       fParentSelect.Streamer(R__b);
1684       fChildSelect.Streamer(R__b);
1685       R__b << fXsection;
1686 //      R__b << fPythia;
1687       R__b << fPtHardMin;
1688       R__b << fPtHardMax;
1689       //     fDecayer->Streamer(R__b);
1690    }
1691 }
1692 #endif
1693
1694
1695