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