LCOV - code coverage report
Current view: top level - PYTHIA6/AliPythia6 - AliGenPythiaPlus.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 801 0.1 %
Date: 2016-06-14 17:26:59 Functions: 1 30 3.3 %

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

Generated by: LCOV version 1.11