fPythia = 0;
fHeader = 0;
fReadFromFile = 0;
+ fEventTime = 0.;
+ fInteractionRate = 0.;
+ fTimeWindow = 0.;
+ fEventsTime = 0;
+ fCurSubEvent = 0;
fDecayer = new AliDecayerPythia();
SetEventListRange();
SetJetPhiRange();
SetJetEtRange();
SetGammaPhiRange();
SetGammaEtaRange();
+ SetTriggerParticle();
SetPtKick();
SetQuench();
SetHadronisation();
fSetNuclei = kFALSE;
+ fNewMIS = kFALSE;
+ fHFoff = kFALSE;
if (!AliPythiaRndm::GetPythiaRandom())
AliPythiaRndm::SetPythiaRandom(GetRandom());
}
fTitle= "Particle Generator using PYTHIA";
fXsection = 0.;
fReadFromFile = 0;
+ fEventTime = 0.;
+ fInteractionRate = 0.;
+ fTimeWindow = 0.;
+ fEventsTime = 0;
+ fCurSubEvent = 0;
SetProcess();
SetStrucFunc();
SetForceDecay();
SetJetEtRange();
SetGammaPhiRange();
SetGammaEtaRange();
+ SetTriggerParticle();
SetJetReconstructionMode();
SetQuench();
SetHadronisation();
// Pycel
SetPycellParameters();
fSetNuclei = kFALSE;
+ fNewMIS = kFALSE;
+ fHFoff = kFALSE;
}
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,
} 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:
case kPyDirectGamma:
break;
case kPyW:
+ case kPyZ:
break;
}
//
Int_t jev=0;
Int_t j, kf;
fTrials=0;
+ fEventTime = 0.;
+
// Set collision vertex position
// Either produce new event or read partons from file
//
if (!fReadFromFile) {
- fPythia->Pyevnt();
+ if (!fNewMIS) {
+ fPythia->Pyevnt();
+ } else {
+ fPythia->Pyevnw();
+ }
fNpartons = fPythia->GetN();
} else {
printf("Loading Event %d\n",AliRunLoader::GetRunLoader()->GetEventNumber());
if (fProcess != kPyMb && fProcess != kPyJets &&
fProcess != kPyDirectGamma &&
fProcess != kPyMbNonDiffr &&
- fProcess != kPyW) {
+ fProcess != kPyW && fProcess != kPyZ ) {
for (i = 0; i < np; i++) {
TParticle* iparticle = (TParticle *) fParticles->At(i);
kf = TMath::Abs(kf);
Int_t kfl = kf;
// Resonance
+
if (kfl > 100000) kfl %= 100000;
if (kfl > 10000) kfl %= 10000;
// meson ?
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;
} else {
nc = GenerateMB();
} // mb ?
+
+ GetSubEventTime();
if (pParent) delete[] pParent;
if (pSelected) delete[] pSelected;
}
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);
// converts from mm/c to s
const Float_t kconv=0.001/2.999792458e8;
-
-
Int_t np = (fHadronisation) ? fParticles->GetEntriesFast() : fNpartons;
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());
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],
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;
}
{
if (gAlice) {
if (gAlice->GetEvNumber()>=fDebugEventFirst &&
- gAlice->GetEvNumber()<=fDebugEventLast) fPythia->Pylist(1);
+ gAlice->GetEvNumber()<=fDebugEventLast) fPythia->Pylist(2);
}
// Builds the event header, to be called after each event
fHeader->SetPrimaryVertex(fVertex);
//
// Jets that have triggered
+
if (fProcess == kPyJets)
{
Int_t ntrig, njet;
((AliGenPythiaEventHeader*) fHeader)->SetXYJet(xp, yp);
((AliGenPythiaEventHeader*) fHeader)->SetZQuench(z);
}
-
//
-// Pass header to RunLoader
+// Store pt^hard
+ ((AliGenPythiaEventHeader*) fHeader)->SetPtHard(fPythia->GetVINT(47));
+//
+// Pass header
//
- AliRunLoader::GetRunLoader()->GetHeader()->SetGenEventHeader(fHeader);
+ 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)
{
}
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)
{
}
}
+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)