]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PYTHIA6/AliGenPythia.cxx
Method SetTriggerParticle added.
[u/mrichter/AliRoot.git] / PYTHIA6 / AliGenPythia.cxx
index 3406499d1098e1e9031c77964c8520d3a98ff44a..9d4b0b114ea57883c3162de3b8c4a746d4ddd7e4 100644 (file)
 #include <TPDGCode.h>
 #include <TSystem.h>
 #include <TTree.h>
-
 #include "AliConst.h"
 #include "AliDecayerPythia.h"
 #include "AliGenPythia.h"
+#include "AliHeader.h"
 #include "AliGenPythiaEventHeader.h"
 #include "AliPythia.h"
 #include "AliPythiaRndm.h"
@@ -41,6 +41,7 @@
 #include "AliStack.h"
 #include "AliRunLoader.h"
 #include "AliMC.h"
+#include "pyquenCommon.h"
 
 ClassImp(AliGenPythia)
 
@@ -51,6 +52,12 @@ AliGenPythia::AliGenPythia()
   fParticles = 0;
   fPythia    = 0;
   fHeader = 0;
+  fReadFromFile = 0;
+  fEventTime = 0.;
+  fInteractionRate = 0.;
+  fTimeWindow = 0.;
+  fEventsTime = 0;
+  fCurSubEvent = 0;
   fDecayer   = new AliDecayerPythia();
   SetEventListRange();
   SetJetPhiRange();
@@ -58,10 +65,13 @@ AliGenPythia::AliGenPythia()
   SetJetEtRange();
   SetGammaPhiRange();
   SetGammaEtaRange();
+  SetTriggerParticle();
   SetPtKick();
   SetQuench();
-  
+  SetHadronisation();  
   fSetNuclei = kFALSE;
+  fNewMIS    = kFALSE;
+  fHFoff     = kFALSE;
   if (!AliPythiaRndm::GetPythiaRandom()) 
     AliPythiaRndm::SetPythiaRandom(GetRandom());
 }
@@ -76,6 +86,12 @@ AliGenPythia::AliGenPythia(Int_t npart)
     fName = "Pythia";
     fTitle= "Particle Generator using PYTHIA";
     fXsection  = 0.;
+    fReadFromFile = 0;
+    fEventTime = 0.;
+    fInteractionRate = 0.;
+    fTimeWindow = 0.;
+    fEventsTime = 0;
+    fCurSubEvent = 0;
     SetProcess();
     SetStrucFunc();
     SetForceDecay();
@@ -96,8 +112,10 @@ AliGenPythia::AliGenPythia(Int_t npart)
     SetJetEtRange();
     SetGammaPhiRange();
     SetGammaEtaRange();
+    SetTriggerParticle();
     SetJetReconstructionMode();
     SetQuench();
+    SetHadronisation();
     SetPtKick();
     // Options determining what to keep in the stack (Heavy flavour generation)
     fStackFillOpt = kFlavorSelection; // Keep particle with selected flavor
@@ -109,6 +127,8 @@ AliGenPythia::AliGenPythia(Int_t npart)
     // Pycel
     SetPycellParameters();
     fSetNuclei = kFALSE;
+    fNewMIS    = kFALSE;
+    fHFoff     = kFALSE;
 }
 
 AliGenPythia::AliGenPythia(const AliGenPythia & Pythia)
@@ -121,6 +141,57 @@ AliGenPythia::AliGenPythia(const AliGenPythia & Pythia)
 AliGenPythia::~AliGenPythia()
 {
 // Destructor
+  if(fEventsTime) delete fEventsTime;
+}
+
+void AliGenPythia::SetInteractionRate(Float_t rate,Float_t timewindow)
+{
+// Generate pileup using user specified rate
+    fInteractionRate = rate;
+    fTimeWindow = timewindow;
+    GeneratePileup();
+}
+
+void AliGenPythia::GeneratePileup()
+{
+// Generate sub events time for pileup
+    fEventsTime = 0;
+    if(fInteractionRate == 0.) {
+      Warning("GeneratePileup","Zero interaction specified. Skipping pileup generation.\n");
+      return;
+    }
+
+    Int_t npart = NumberParticles();
+    if(npart < 0) {
+      Warning("GeneratePileup","Negative number of particles. Skipping pileup generation.\n");
+      return;
+    }
+
+    if(fEventsTime) delete fEventsTime;
+    fEventsTime = new TArrayF(npart);
+    TArrayF &array = *fEventsTime;
+    for(Int_t ipart = 0; ipart < npart; ipart++)
+      array[ipart] = 0.;
+
+    Float_t eventtime = 0.;
+    while(1)
+      {
+       eventtime += (AliPythiaRndm::GetPythiaRandom())->Exp(1./fInteractionRate);
+       if(eventtime > fTimeWindow) break;
+       array.Set(array.GetSize()+1);
+       array[array.GetSize()-1] = eventtime;
+      }
+
+    eventtime = 0.;
+    while(1)
+      {
+       eventtime -= (AliPythiaRndm::GetPythiaRandom())->Exp(1./fInteractionRate);
+       if(TMath::Abs(eventtime) > fTimeWindow) break;
+       array.Set(array.GetSize()+1);
+       array[array.GetSize()-1] = eventtime;
+      }
+
+    SetNumberParticles(fEventsTime->GetSize());
 }
 
 void AliGenPythia::SetPycellParameters(Float_t etamax, Int_t neta, Int_t nphi,
@@ -188,13 +259,30 @@ void AliGenPythia::Init()
        fPythia->SetMSTP(91,0);
     }
 
- //   fPythia->SetMSTJ(1,2);
+
+    if (fReadFromFile) {
+       fRL  =  AliRunLoader::Open(fFileName, "Partons");
+       fRL->LoadKinematics();
+       fRL->LoadHeader();
+    } else {
+       fRL = 0x0;
+    }
+// Switch off Heavy Flavors on request  
+    if (fHFoff) {
+       fPythia->SetMSTP(58, 3);
+       fPythia->SetMSTJ(45, 3);        
+       for (Int_t i = 156; i <= 160; i++) fPythia->SetMDME(i, 1, 0);
+    }
  //
     fPythia->ProcInit(fProcess,fEnergyCMS,fStrucFunc);
 
 //  Parent and Children Selection
     switch (fProcess) 
     {
+    case kPyOldUEQ2ordered:
+    case kPyOldUEQ2ordered2:
+    case kPyOldPopcorn:
+      break;
     case kPyCharm:
     case kPyCharmUnforced:
     case kPyCharmPbPbMNR:
@@ -212,6 +300,12 @@ void AliGenPythia::Init()
        fParentSelect[0] =   421;
        fFlavorSelect    =   4; 
        break;
+    case kPyDPlusPbPbMNR:
+    case kPyDPluspPbMNR:
+    case kPyDPlusppMNR:
+       fParentSelect[0] =   411;
+       fFlavorSelect    =   4; 
+       break;
     case kPyBeauty:
     case kPyBeautyPbPbMNR:
     case kPyBeautypPbMNR:
@@ -244,6 +338,9 @@ void AliGenPythia::Init()
     case kPyJets:
     case kPyDirectGamma:
        break;
+    case kPyW:
+    case kPyZ:
+        break;
     }
 //
 //
@@ -280,6 +377,11 @@ void AliGenPythia::Init()
        fDyBoost = 0;
        Warning("Init","SetNuclei used. Use SetProjectile + SetTarget instead. fDyBoost has been reset to 0\n");
     }
+
+    if (fQuench) {
+       fPythia->InitQuenching(0., 0.1, 0.6e6, 0);
+    }
+    
 }
 
 void AliGenPythia::Generate()
@@ -298,6 +400,8 @@ void AliGenPythia::Generate()
     Int_t jev=0;
     Int_t j, kf;
     fTrials=0;
+    fEventTime = 0.;
+    
     
 
     //  Set collision vertex position 
@@ -306,40 +410,66 @@ void AliGenPythia::Generate()
 //  event loop    
     while(1)
     {
-       if (fQuench) {
-           fPythia->SetMSTJ(1, 0);
-       }
-       fPythia->Pyevnt();
-
-       if (fQuench) {
-           fPythia->Quench();
-           fPythia->SetMSTJ(1, 1);
-           fPythia->Pyexec();
+//
+// Produce event
+//
+//
+// Switch hadronisation off
+//
+       fPythia->SetMSTJ(1, 0);
+//
+// Either produce new event or read partons from file
+//     
+       if (!fReadFromFile) {
+           if (!fNewMIS) {
+               fPythia->Pyevnt();
+           } else {
+               fPythia->Pyevnw();
+           }
+           fNpartons = fPythia->GetN();
+       } else {
+           printf("Loading Event %d\n",AliRunLoader::GetRunLoader()->GetEventNumber());
+           fRL->GetEvent(AliRunLoader::GetRunLoader()->GetEventNumber());
+           fPythia->SetN(0);
+           LoadEvent(fRL->Stack(), 0 , 1);
+           fPythia->Pyedit(21);
        }
        
-       if (gAlice) {
-           if (gAlice->GetEvNumber()>=fDebugEventFirst &&
-               gAlice->GetEvNumber()<=fDebugEventLast) fPythia->Pylist(1);
+//
+//  Run quenching routine 
+//
+       if (fQuench == 1) {
+           fPythia->Quench();
+       } else if (fQuench == 2){
+           fPythia->Pyquen(208., 0, 0.);
        }
-       
+//
+// Switch hadronisation on
+//
+       fPythia->SetMSTJ(1, 1);
+//
+// .. and perform hadronisation
+//     printf("Calling hadronisation %d\n", fPythia->GetN());
+       fPythia->Pyexec();      
        fTrials++;
        fPythia->ImportParticles(fParticles,"All");
-
        Boost();
 //
 //
 //
        Int_t i;
        
+
        Int_t np = fParticles->GetEntriesFast();
-       if (np == 0 ) continue;
+       
+       if (np == 0) continue;
 //
        
 //
        Int_t* pParent   = new Int_t[np];
        Int_t* pSelected = new Int_t[np];
        Int_t* trackIt   = new Int_t[np];
-       for (i=0; i< np; i++) {
+       for (i = 0; i < np; i++) {
            pParent[i]   = -1;
            pSelected[i] =  0;
            trackIt[i]   =  0;
@@ -350,9 +480,10 @@ void AliGenPythia::Generate()
        Int_t nTkbles = 0;   // Trackable particles
        if (fProcess != kPyMb && fProcess != kPyJets && 
            fProcess != kPyDirectGamma &&
-           fProcess != kPyMbNonDiffr) {
+           fProcess != kPyMbNonDiffr  &&
+           fProcess != kPyW && fProcess != kPyZ ) {
            
-           for (i = 0; i<np; i++) {
+           for (i = 0; i < np; i++) {
                TParticle* iparticle = (TParticle *) fParticles->At(i);
                Int_t ks = iparticle->GetStatusCode();
                kf = CheckPDGCode(iparticle->GetPdgCode());
@@ -364,38 +495,58 @@ void AliGenPythia::Generate()
                // quark ?
                kf = TMath::Abs(kf);
                Int_t kfl = kf;
+               // Resonance
+
+               if (kfl > 100000) kfl %= 100000;
+               if (kfl > 10000)  kfl %= 10000;
                // meson ?
                if  (kfl > 10) kfl/=100;
                // baryon
                if (kfl > 10) kfl/=10;
-               if (kfl > 10) kfl/=10;
-
                Int_t ipa = iparticle->GetFirstMother()-1;
                Int_t kfMo = 0;
+//
+// Establish mother daughter relation between heavy quarks and mesons
+//
+               if (kf >= fFlavorSelect && kf <= 6) {
+                   Int_t idau = iparticle->GetFirstDaughter() - 1;
+                   if (idau > -1) {
+                       TParticle* daughter = (TParticle *) fParticles->At(idau);
+                       Int_t pdgD = daughter->GetPdgCode();
+                       if (pdgD == 91 || pdgD == 92) {
+                           Int_t jmin = daughter->GetFirstDaughter() - 1;
+                           Int_t jmax = daughter->GetLastDaughter()  - 1;                          
+                           for (Int_t j = jmin; j <= jmax; j++)
+                               ((TParticle *) fParticles->At(j))->SetFirstMother(i+1);
+                       } // is string or cluster
+                   } // has daughter
+               } // heavy quark
                
+
                if (ipa > -1) {
                    TParticle *  mother = (TParticle *) fParticles->At(ipa);
                    kfMo = TMath::Abs(mother->GetPdgCode());
                }
+               
                // What to keep in Stack?
                Bool_t flavorOK = kFALSE;
                Bool_t selectOK = kFALSE;
                if (fFeedDownOpt) {
-                 if (kfl >= fFlavorSelect) flavorOK = kTRUE;
+                   if (kfl >= fFlavorSelect) flavorOK = kTRUE;
                } else {
-                 if (kfl > fFlavorSelect) {
-                   nc = -1;
-                   break;
-                 }
-                 if (kfl == fFlavorSelect) flavorOK = kTRUE;
+                   if (kfl > fFlavorSelect) {
+                       nc = -1;
+                       break;
+                   }
+                   if (kfl == fFlavorSelect) flavorOK = kTRUE;
                }
                switch (fStackFillOpt) {
                case kFlavorSelection:
-                 selectOK = kTRUE;
-                 break;
+                   selectOK = kTRUE;
+                   break;
                case kParentSelection:
-                 if (ParentSelected(kf) || kf <= 10) selectOK = kTRUE;
-                 break;
+                   if (ParentSelected(kf) || kf <= 10) selectOK = kTRUE;
+                   break;
                }
                if (flavorOK && selectOK) { 
 //
@@ -404,7 +555,7 @@ void AliGenPythia::Generate()
 // Kinematic seletion on final state heavy flavor mesons
                    if (ParentSelected(kf) && !KinematicSelection(iparticle, 0)) 
                    {
-                     continue;
+                       continue;
                    }
                    pSelected[i] = 1;
                    if (ParentSelected(kf)) ++nParents; // Update parent count
@@ -412,9 +563,9 @@ void AliGenPythia::Generate()
                } else {
 // Kinematic seletion on decay products
                    if (fCutOnChild && ParentSelected(kfMo) && ChildSelected(kf) 
-                       && !KinematicSelection(iparticle, 1))
+                       && !KinematicSelection(iparticle, 1)) 
                    {
-                     continue;
+                       continue;
                    }
 //
 // Decay products 
@@ -444,6 +595,7 @@ void AliGenPythia::Generate()
                if (!pSelected[i]) continue;
                // Count quarks only if you did not include fragmentation
                if (fFragmentation && kf <= 10) continue;
+
                nc++;
 // Decision on tracking
                trackIt[i] = 0;
@@ -494,6 +646,8 @@ void AliGenPythia::Generate()
        } else {
            nc = GenerateMB();
        } // mb ?
+       
+       GetSubEventTime();
 
        if (pParent)   delete[] pParent;
        if (pSelected) delete[] pSelected;
@@ -516,8 +670,6 @@ void AliGenPythia::Generate()
          }
            if (jev >= fNpart || fNpart == -1) {
                fKineBias=Float_t(fNpart)/Float_t(fTrials);
-               printf("\n Trials: %i %i %i\n",fTrials, fNpart, jev);
-
                fQ  += fPythia->GetVINT(51);
                fX1 += fPythia->GetVINT(41);
                fX2 += fPythia->GetVINT(42);
@@ -548,7 +700,9 @@ Int_t  AliGenPythia::GenerateMB()
 //  converts from mm/c to s
     const Float_t kconv=0.001/2.999792458e8;
     
-    Int_t np = fParticles->GetEntriesFast();
+    Int_t np = (fHadronisation) ? fParticles->GetEntriesFast() : fNpartons;
+
+
     Int_t* pParent = new Int_t[np];
     for (i=0; i< np; i++) pParent[i] = -1;
     if (fProcess == kPyJets || fProcess == kPyDirectGamma) {
@@ -557,7 +711,33 @@ Int_t  AliGenPythia::GenerateMB()
        if (!CheckTrigger(jet1, jet2)) return 0;
     }
     
-    for (i = 0; i<np; i++) {
+    if (fTriggerParticle) {
+       Bool_t triggered = kFALSE;
+       for (i = 0; i < np; i++) {
+           TParticle *  iparticle = (TParticle *) fParticles->At(i);
+           kf = CheckPDGCode(iparticle->GetPdgCode());
+           if (TMath::Abs(kf) != fTriggerParticle) continue;
+           if (iparticle->Pt() == 0.) continue;
+           if (TMath::Abs(iparticle->Eta()) > fTriggerEta) continue;
+           triggered = kTRUE;
+           break;
+       }
+       if (!triggered) return 0;
+    }
+    
+
+    //Introducing child cuts in case kPyW, kPyZ, kPyMb, and kPyMbNonDiff
+    if ( (fProcess == kPyW || fProcess == kPyZ || fProcess == kPyMb || fProcess == kPyMbNonDiffr)  
+        && (fCutOnChild == 1) ) {
+      if ( !CheckKinematicsOnChild() ) {
+       if (pParent)   delete[] pParent;
+       return 0;
+      }
+    }
+  
+
+    
+    for (i = 0; i < np; i++) {
        Int_t trackIt = 0;
        TParticle *  iparticle = (TParticle *) fParticles->At(i);
        kf = CheckPDGCode(iparticle->GetPdgCode());
@@ -578,27 +758,42 @@ Int_t  AliGenPythia::GenerateMB()
            p[1] = iparticle->Py();
            p[2] = iparticle->Pz();
            p[3] = iparticle->Energy();
+
            
            origin[0] = fVertex[0]+iparticle->Vx()/10; // [cm]
            origin[1] = fVertex[1]+iparticle->Vy()/10; // [cm]
            origin[2] = fVertex[2]+iparticle->Vz()/10; // [cm]
            
-           Float_t tof=kconv*iparticle->T();
+           Float_t tof = fEventTime + kconv * iparticle->T();
 
            PushTrack(fTrackIt*trackIt, iparent, kf, 
                      p[0], p[1], p[2], p[3], 
                      origin[0], origin[1], origin[2], tof, 
                      polar[0], polar[1], polar[2],
                      kPPrimary, nt, 1., ks);
+           //
+           // Special Treatment to store color-flow
+           //
+           if (ks == 3 || ks == 13 || ks == 14) {
+               TParticle* particle = 0;
+               if (fStack) {
+                   particle = fStack->Particle(nt);
+               } else {
+                   particle = gAlice->Stack()->Particle(nt);
+               }
+               particle->SetFirstDaughter(fPythia->GetK(2, i));
+               particle->SetLastDaughter(fPythia->GetK(3, i));         
+           }
+           
            KeepTrack(nt);
            pParent[i] = nt;
+           SetHighWaterMark(nt);
+           
        } // select particle
     } // particle loop 
 
     if (pParent) delete[] pParent;
-    
-    printf("\n I've put %i particles on the stack \n",nc);
-    return nc;
+    return 1;
 }
 
 
@@ -606,13 +801,15 @@ void AliGenPythia::FinishRun()
 {
 // Print x-section summary
     fPythia->Pystat(1);
-    fQ  /= fNev;
-    fX1 /= fNev;
-    fX2 /= fNev;    
+
+    if (fNev > 0.) {
+       fQ  /= fNev;
+       fX1 /= fNev;
+       fX2 /= fNev;    
+    }
+    
     printf("\nTotal number of Pyevnt() calls %d\n", fTrialsRun);
     printf("\nMean Q, x1, x2: %f %f %f\n", fQ, fX1, fX2);
-    
-
 }
 
 void AliGenPythia::AdjustWeights()
@@ -641,6 +838,11 @@ void AliGenPythia::SetNuclei(Int_t a1, Int_t a2)
 
 void AliGenPythia::MakeHeader()
 {
+  if (gAlice) {
+    if (gAlice->GetEvNumber()>=fDebugEventFirst &&
+       gAlice->GetEvNumber()<=fDebugEventLast) fPythia->Pylist(2);
+  }
+
 // Builds the event header, to be called after each event
     if (fHeader) delete fHeader;
     fHeader = new AliGenPythiaEventHeader("Pythia");
@@ -655,20 +857,77 @@ void AliGenPythia::MakeHeader()
     fHeader->SetPrimaryVertex(fVertex);
 //
 // Jets that have triggered
+
     if (fProcess == kPyJets)
     {
        Int_t ntrig, njet;
        Float_t jets[4][10];
        GetJets(njet, ntrig, jets);
+
        
        for (Int_t i = 0; i < ntrig; i++) {
            ((AliGenPythiaEventHeader*) fHeader)->AddJet(jets[0][i], jets[1][i], jets[2][i], 
                                                        jets[3][i]);
        }
     }
-    if (gAlice) gAlice->SetGenEventHeader(fHeader);
+//
+// Copy relevant information from external header, if present.
+//
+    Float_t uqJet[4];
+    
+    if (fRL) {
+       AliGenPythiaEventHeader* exHeader = (AliGenPythiaEventHeader*) (fRL->GetHeader()->GenEventHeader());
+       for (Int_t i = 0; i < exHeader->NTriggerJets(); i++)
+       {
+           printf("Adding Jet %d %d \n", i,  exHeader->NTriggerJets());
+           
+           
+           exHeader->TriggerJet(i, uqJet);
+           ((AliGenPythiaEventHeader*) fHeader)->AddUQJet(uqJet[0], uqJet[1], uqJet[2], uqJet[3]);
+       }
+    }
+//
+// Store quenching parameters
+//
+    if (fQuench){
+       Double_t z[4];
+       Double_t xp, yp;
+       if (fQuench == 1) {
+           // Pythia::Quench()
+           fPythia->GetQuenchingParameters(xp, yp, z);
+       } else {
+           // Pyquen
+           Double_t r1 = PARIMP.rb1;
+           Double_t r2 = PARIMP.rb2;
+           Double_t b  = PARIMP.b1;
+           Double_t r   = 0.5 * TMath::Sqrt(2. * (r1 * r1 + r2 * r2) - b * b);
+           Double_t phi = PARIMP.psib1;
+           xp = r * TMath::Cos(phi);
+           yp = r * TMath::Sin(phi);
+           
+       }
+           ((AliGenPythiaEventHeader*) fHeader)->SetXYJet(xp, yp);
+           ((AliGenPythiaEventHeader*) fHeader)->SetZQuench(z);
+       }
+//
+// Store pt^hard 
+    ((AliGenPythiaEventHeader*) fHeader)->SetPtHard(fPythia->GetVINT(47));
+//
+//  Pass header
+//
+    AddHeader(fHeader);
 }
-       
+
+void AliGenPythia::AddHeader(AliGenEventHeader* header)
+{
+    // Add header to container or runloader
+    if (fContainer) {
+       fContainer->AddHeader(header);
+    } else {
+       AliRunLoader::GetRunLoader()->GetHeader()->SetGenEventHeader(header);   
+    }
+}
+
 
 Bool_t AliGenPythia::CheckTrigger(TParticle* jet1, TParticle* jet2)
 {
@@ -717,6 +976,36 @@ Bool_t AliGenPythia::CheckTrigger(TParticle* jet1, TParticle* jet2)
     }
     return triggered;
 }
+
+
+//Checking Kinematics on Child (status code 1, particle code ?, kin cuts
+Bool_t AliGenPythia::CheckKinematicsOnChild(){
+
+    Bool_t checking = kFALSE;
+    Int_t j, kcode, ks, km;
+    Int_t nPartAcc = 0; //number of particles in the acceptance range
+    Int_t numberOfAcceptedParticles = 1;
+    if (fNumberOfAcceptedParticles != 0) { numberOfAcceptedParticles = fNumberOfAcceptedParticles; }
+    Int_t npart = fParticles->GetEntriesFast();
+    
+    for (j = 0; j<npart; j++) {
+       TParticle *  jparticle = (TParticle *) fParticles->At(j);
+       kcode = TMath::Abs( CheckPDGCode(jparticle->GetPdgCode()) );
+       ks = jparticle->GetStatusCode();
+       km = jparticle->GetFirstMother(); 
+       
+       if( (ks == 1)  &&  (kcode == fPdgCodeParticleforAcceptanceCut)  &&  (KinematicSelection(jparticle,1)) ){
+           nPartAcc++;
+       }
+       if( numberOfAcceptedParticles <= nPartAcc){
+         checking = kTRUE;
+         break;
+       }
+    }
+
+    return checking;
+}
+
          
 AliGenPythia& AliGenPythia::operator=(const  AliGenPythia& rhs)
 {
@@ -725,20 +1014,39 @@ AliGenPythia& AliGenPythia::operator=(const  AliGenPythia& rhs)
     return *this;
 }
 
-void  AliGenPythia::LoadEvent()
+void  AliGenPythia::LoadEvent(AliStack* stack, Int_t flag, Int_t reHadr)
 {
 //
 // Load event into Pythia Common Block
 //
-    AliRunLoader* rl = AliRunLoader::GetRunLoader();
-    Int_t npart = (rl->Stack())-> GetNprimary();
-   (fPythia->GetPyjets())->N = npart;
 
+    Int_t npart = stack -> GetNprimary();
+    Int_t n0 = 0;
+    
+    if (!flag) {
+       (fPythia->GetPyjets())->N = npart;
+    } else {
+       n0 = (fPythia->GetPyjets())->N;
+       (fPythia->GetPyjets())->N = n0 + npart;
+    }
+    
+    
     for (Int_t part = 0; part < npart; part++) {
-       TParticle *MPart = (rl->Stack())->Particle(part);
-       Int_t kf     = MPart->GetPdgCode();
-       Int_t ks     = MPart->GetStatusCode();
+       TParticle *MPart = stack->Particle(part);
+       
+       Int_t kf     =  MPart->GetPdgCode();
+       Int_t ks     =  MPart->GetStatusCode();
+       Int_t idf    =  MPart->GetFirstDaughter();
+       Int_t idl    =  MPart->GetLastDaughter();
+       
+       if (reHadr) {
+           if (ks == 11 || ks == 12) {
+               ks  -= 10;
+               idf  = -1;
+               idl  = -1;
+           }
+       }
+       
        Float_t px = MPart->Px();
        Float_t py = MPart->Py();
        Float_t pz = MPart->Pz();
@@ -746,17 +1054,21 @@ void  AliGenPythia::LoadEvent()
        Float_t m  = MPart->GetCalcMass();
        
        
-       (fPythia->GetPyjets())->P[0][part] = px;
-       (fPythia->GetPyjets())->P[1][part] = py;
-       (fPythia->GetPyjets())->P[2][part] = pz;
-       (fPythia->GetPyjets())->P[3][part] = e;
-       (fPythia->GetPyjets())->P[4][part] = m;
+       (fPythia->GetPyjets())->P[0][part+n0] = px;
+       (fPythia->GetPyjets())->P[1][part+n0] = py;
+       (fPythia->GetPyjets())->P[2][part+n0] = pz;
+       (fPythia->GetPyjets())->P[3][part+n0] = e;
+       (fPythia->GetPyjets())->P[4][part+n0] = m;
        
-       (fPythia->GetPyjets())->K[1][part] = kf;
-       (fPythia->GetPyjets())->K[0][part] = ks;
+       (fPythia->GetPyjets())->K[1][part+n0] = kf;
+       (fPythia->GetPyjets())->K[0][part+n0] = ks;
+       (fPythia->GetPyjets())->K[3][part+n0] = idf + 1;
+       (fPythia->GetPyjets())->K[4][part+n0] = idl + 1;
+       (fPythia->GetPyjets())->K[2][part+n0] = MPart->GetFirstMother() + 1;
     }
 }
 
+
 void AliGenPythia::RecJetsUA1(Int_t& njets, Float_t jets [4][50])
 {
 //
@@ -825,7 +1137,6 @@ void  AliGenPythia::GetJets(Int_t& nJets, Int_t& nJetsTrig, Float_t jets[4][10])
        Float_t theta = TMath::ATan2(pt,pz);
        Float_t et    = e * TMath::Sin(theta);
        Float_t eta   = -TMath::Log(TMath::Tan(theta / 2.));
-
        if (
            eta > fEtaMinJet && eta < fEtaMaxJet && 
            phi > fPhiMinJet && phi < fPhiMaxJet &&
@@ -837,13 +1148,24 @@ void  AliGenPythia::GetJets(Int_t& nJets, Int_t& nJetsTrig, Float_t jets[4][10])
            jets[2][nJetsTrig] = pz;
            jets[3][nJetsTrig] = e;
            nJetsTrig++;
-           
+//         printf("\n........-Jet #%d: %10.3f %10.3f %10.3f %10.3f \n", i, pt, et, eta, phi * kRaddeg);
        } else {
 //         printf("\n........-Jet #%d: %10.3f %10.3f %10.3f %10.3f \n", i, pt, et, eta, phi * kRaddeg);
        }
     }
 }
 
+void AliGenPythia::GetSubEventTime()
+{
+  // Calculates time of the next subevent
+  fEventTime = 0.;
+  if (fEventsTime) {
+    TArrayF &array = *fEventsTime;
+    fEventTime = array[fCurSubEvent++];
+  }
+  //  printf(" Event time: %d %f %p",fCurSubEvent,fEventTime,fEventsTime);
+  return;
+}
 
 #ifdef never
 void AliGenPythia::Streamer(TBuffer &R__b)
@@ -886,3 +1208,5 @@ void AliGenPythia::Streamer(TBuffer &R__b)
 }
 #endif
 
+
+