1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 // Generator using AMPT as an external generator
20 #include "AliGenAmpt.h"
22 #include <TClonesArray.h>
25 #include <TLorentzVector.h>
27 #include <TParticle.h>
29 #include "AliGenHijingEventHeader.h"
30 #define AliGenAmptEventHeader AliGenHijingEventHeader
31 #include "AliAmptRndm.h"
37 AliGenAmpt::AliGenAmpt()
63 fPhiMaxJet(TMath::TwoPi()),
73 fNoHeavyQuarks(kFALSE),
79 fHeader(new AliGenAmptEventHeader("Ampt"))
83 AliAmptRndm::SetAmptRandom(GetRandom());
86 AliGenAmpt::AliGenAmpt(Int_t npart)
112 fPhiMaxJet(2. * TMath::Pi()),
122 fNoHeavyQuarks(kFALSE),
128 fHeader(new AliGenAmptEventHeader("Ampt"))
130 // Default PbPb collisions at 5.5 TeV
134 fTitle= "Particle Generator using AMPT";
135 AliAmptRndm::SetAmptRandom(GetRandom());
138 AliGenAmpt::~AliGenAmpt()
141 if ( fDsigmaDb) delete fDsigmaDb;
142 if ( fDnDb) delete fDnDb;
143 if ( fHeader) delete fHeader;
146 void AliGenAmpt::Init()
152 fProjectile.Resize(8);
154 fAmpt = new TAmpt(fEnergyCMS, fFrame, fProjectile, fTarget,
155 fAProjectile, fZProjectile, fATarget, fZTarget,
156 fMinImpactParam, fMaxImpactParam);
159 fAmpt->SetIHPR2(2, fRadiation);
160 fAmpt->SetIHPR2(3, fTrigger);
161 fAmpt->SetIHPR2(6, fShadowing);
162 fAmpt->SetIHPR2(12, fDecaysOff);
163 fAmpt->SetIHPR2(21, fKeep);
164 fAmpt->SetHIPR1(8, fPtHardMin);
165 fAmpt->SetHIPR1(9, fPtHardMax);
166 fAmpt->SetHIPR1(10, fPtMinJet);
167 fAmpt->SetHIPR1(50, fSimpleJet);
170 // fQuench = 0: no quenching
171 // fQuench = 1: Hijing default
172 // fQuench = 2: new LHC parameters for HIPR1(11) and HIPR1(14)
173 // fQuench = 3: new RHIC parameters for HIPR1(11) and HIPR1(14)
174 // fQuench = 4: new LHC parameters with log(e) dependence
175 // fQuench = 5: new RHIC parameters with log(e) dependence
176 fAmpt->SetIHPR2(50, 0);
178 fAmpt->SetIHPR2(4, 1);
180 fAmpt->SetIHPR2(4, 0);
183 fAmpt->SetHIPR1(14, 1.1);
184 fAmpt->SetHIPR1(11, 3.7);
185 } else if (fQuench == 3) {
186 fAmpt->SetHIPR1(14, 0.20);
187 fAmpt->SetHIPR1(11, 2.5);
188 } else if (fQuench == 4) {
189 fAmpt->SetIHPR2(50, 1);
190 fAmpt->SetHIPR1(14, 4.*0.34);
191 fAmpt->SetHIPR1(11, 3.7);
192 } else if (fQuench == 5) {
193 fAmpt->SetIHPR2(50, 1);
194 fAmpt->SetHIPR1(14, 0.34);
195 fAmpt->SetHIPR1(11, 2.5);
199 if (fNoHeavyQuarks) {
200 fAmpt->SetIHPR2(49, 1);
202 fAmpt->SetIHPR2(49, 0);
206 fAmpt->SetIsoft(fIsoft);
207 fAmpt->SetNtMax(fNtMax);
208 fAmpt->SetIpop(fIpop);
216 EvaluateCrossSections();
219 void AliGenAmpt::Generate()
221 // Generate one event
223 Float_t polar[3] = {0,0,0};
224 Float_t origin[3] = {0,0,0};
225 Float_t origin0[3] = {0,0,0};
229 // converts from mm/c to s
230 const Float_t kconv = 0.001/2.99792458e8;
234 Int_t j, kf, ks, ksp, imo;
238 for (j = 0;j < 3; j++)
239 origin0[j] = fOrigin[j];
241 if(fVertexSmear == kPerEvent) {
243 for (j=0; j < 3; j++)
244 origin0[j] = fVertex[j];
247 Float_t sign = (fRandomPz && (Rndm() < 0.5))? -1. : 1.;
250 // Generate one event
251 Int_t fpemask = gSystem->GetFPEMask();
252 gSystem->SetFPEMask(0);
253 fAmpt->GenerateEvent();
254 gSystem->SetFPEMask(fpemask);
257 fAmpt->ImportParticles(&fParticles,"All");
258 Int_t np = fParticles.GetEntriesFast();
262 if (fTrigger != kNoTrigger) {
270 Int_t* newPos = new Int_t[np];
271 Int_t* pSelected = new Int_t[np];
273 for (Int_t i = 0; i < np; i++) {
279 //TParticle * iparticle = (TParticle *) fParticles.At(0);
280 fVertex[0] = origin0[0];
281 fVertex[1] = origin0[1];
282 fVertex[2] = origin0[2];
284 // First select parent particles
285 for (Int_t i = 0; i < np; i++) {
286 TParticle *iparticle = (TParticle *) fParticles.At(i);
288 // Is this a parent particle ?
289 if (Stable(iparticle)) continue;
290 Bool_t selected = kTRUE;
291 Bool_t hasSelectedDaughters = kFALSE;
292 kf = iparticle->GetPdgCode();
293 ks = iparticle->GetStatusCode();
298 selected = KinematicSelection(iparticle, 0) && SelectFlavor(kf);
299 hasSelectedDaughters = DaughtersSelection(iparticle);
301 // Put particle on the stack if it is either selected or
302 // it is the mother of at least one seleted particle
303 if (selected || hasSelectedDaughters) {
307 } // particle loop parents
309 // Now select the final state particles
310 fProjectileSpecn = 0;
311 fProjectileSpecp = 0;
314 for (Int_t i = 0; i<np; i++) {
315 TParticle *iparticle = (TParticle *) fParticles.At(i);
316 // Is this a final state particle ?
317 if (!Stable(iparticle))
319 Bool_t selected = kTRUE;
320 kf = iparticle->GetPdgCode();
321 ks = iparticle->GetStatusCode();
322 ksp = iparticle->GetUniqueID();
324 // --------------------------------------------------------------------------
325 // Count spectator neutrons and protons
326 if(ksp == 0 || ksp == 1) {
327 if(kf == kNeutron) fProjectileSpecn += 1;
328 if(kf == kProton) fProjectileSpecp += 1;
329 } else if(ksp == 10 || ksp == 11) {
330 if(kf == kNeutron) fTargetSpecn += 1;
331 if(kf == kProton) fTargetSpecp += 1;
333 // --------------------------------------------------------------------------
335 selected = KinematicSelection(iparticle,0)&&SelectFlavor(kf);
336 if (!fSpectators && selected)
337 selected = (ksp != 0 && ksp != 1 && ksp != 10 && ksp != 11);
340 // Put particle on the stack if selected
345 } // particle loop final state
347 //Time of the interactions
349 if (fPileUpTimeWindow > 0.)
350 tInt = fPileUpTimeWindow * (2. * gRandom->Rndm() - 1.);
352 // Write particles to stack
353 for (Int_t i = 0; i<np; i++) {
354 TParticle *iparticle = (TParticle *) fParticles.At(i);
355 Bool_t hasMother = (iparticle->GetFirstMother() >=0);
356 Bool_t hasDaughter = (iparticle->GetFirstDaughter() >=0);
358 kf = iparticle->GetPdgCode();
359 ks = iparticle->GetStatusCode();
360 p[0] = iparticle->Px();
361 p[1] = iparticle->Py();
362 p[2] = iparticle->Pz() * sign;
363 origin[0] = origin0[0]+iparticle->Vx()/10;
364 origin[1] = origin0[1]+iparticle->Vy()/10;
365 origin[2] = origin0[2]+iparticle->Vz()/10;
368 if (TestBit(kVertexRange)) {
369 fEventTime = sign * origin0[2] / 2.99792458e10;
370 tof = kconv * iparticle->T() + fEventTime;
372 tof = kconv * iparticle->T();
374 if (fPileUpTimeWindow > 0.) tof += tInt;
377 TParticle* mother = 0;
379 imo = iparticle->GetFirstMother();
380 mother = (TParticle *) fParticles.At(imo);
381 imo = (mother->GetPdgCode() != 92) ? newPos[imo] : -1;
383 Bool_t tFlag = (fTrackIt && !hasDaughter);
384 PushTrack(tFlag,imo,kf,p,origin,polar,tof,kPNoProcess,nt, 1., ks);
393 AliInfo(Form("\n I've put %i particles on the stack \n",nc));
396 if (jev >= fNpart || fNpart == -1) {
397 fKineBias = Float_t(fNpart)/Float_t(fTrials);
398 AliInfo(Form("\n Trials: %i %i %i\n",fTrials, fNpart, jev));
404 SetHighWaterMark(nt);
407 void AliGenAmpt::EvaluateCrossSections()
409 // Glauber Calculation of geometrical x-section
411 Float_t xTot = 0.; // barn
412 Float_t xTotHard = 0.; // barn
413 Float_t xPart = 0.; // barn
414 Float_t xPartHard = 0.; // barn
415 Float_t sigmaHard = 0.1; // mbarn
417 Float_t bMax = fAmpt->GetHIPR1(34)+fAmpt->GetHIPR1(35);
418 const Float_t kdib = 0.2;
419 Int_t kMax = Int_t((bMax-bMin)/kdib)+1;
421 printf("\n Projectile Radius (fm): %f \n",fAmpt->GetHIPR1(34));
422 printf("\n Target Radius (fm): %f \n",fAmpt->GetHIPR1(35));
425 Float_t oldvalue= 0.;
426 Float_t* b = new Float_t[kMax];
427 Float_t* si1 = new Float_t[kMax];
428 Float_t* si2 = new Float_t[kMax];
429 for (i = 0; i < kMax; i++) {
430 Float_t xb = bMin+i*kdib;
431 Float_t ov=fAmpt->Profile(xb);
432 Float_t gb = 2.*0.01*fAmpt->GetHIPR1(40)*kdib*xb*(1.-TMath::Exp(-fAmpt->GetHINT1(12)*ov));
433 Float_t gbh = 2.*0.01*fAmpt->GetHIPR1(40)*kdib*xb*sigmaHard*ov;
436 printf("profile %f %f %f\n", xb, ov, fAmpt->GetHINT1(12));
438 if (xb > fMinImpactParam && xb < fMaxImpactParam) {
443 if ((oldvalue) && ((xTot-oldvalue)/oldvalue<0.0001))
446 printf("\n Total cross section (barn): %d %f %f \n",i, xb, xTot);
447 printf("\n Hard cross section (barn): %d %f %f \n\n",i, xb, xTotHard);
455 printf("\n Total cross section (barn): %f \n",xTot);
456 printf("\n Hard cross section (barn): %f \n \n",xTotHard);
457 printf("\n Partial cross section (barn): %f %f \n",xPart, xPart/xTot*100.);
458 printf("\n Partial hard cross section (barn): %f %f \n",xPartHard, xPartHard/xTotHard*100.);
460 // Store result as a graph
465 fDsigmaDb = new TGraph(i, b, si1);
467 fDnDb = new TGraph(i, b, si2);
470 Bool_t AliGenAmpt::DaughtersSelection(TParticle* iparticle)
472 // Looks recursively if one of the daughters has been selected
473 //printf("\n Consider daughters %d:",iparticle->GetPdgCode());
476 Bool_t hasDaughters = (iparticle->GetFirstDaughter() >=0);
477 Bool_t selected = kFALSE;
479 imin = iparticle->GetFirstDaughter();
480 imax = iparticle->GetLastDaughter();
481 for (Int_t i = imin; i <= imax; i++){
482 TParticle * jparticle = (TParticle *) fParticles.At(i);
483 Int_t ip = jparticle->GetPdgCode();
484 if (KinematicSelection(jparticle,0)&&SelectFlavor(ip)) {
485 selected=kTRUE; break;
487 if (DaughtersSelection(jparticle)) {selected=kTRUE; break; }
495 Bool_t AliGenAmpt::SelectFlavor(Int_t pid)
497 // Select flavor of particle
499 // 4: charm and beauty
506 Int_t ifl = TMath::Abs(pid/100);
507 if (ifl > 10) ifl/=10;
508 res = (fFlavor == ifl);
511 // This part if gamma writing is inhibited
513 res = res && (pid != kGamma && pid != kPi0);
518 Bool_t AliGenAmpt::Stable(TParticle* particle) const
520 // Return true for a stable particle
522 if (particle->GetFirstDaughter() < 0 )
530 void AliGenAmpt::MakeHeader()
532 // Fills the event header, to be called after each event
534 fHeader->SetNProduced(fNprimaries);
535 fHeader->SetImpactParameter(fAmpt->GetHINT1(19));
536 fHeader->SetTotalEnergy(fAmpt->GetEATT());
537 fHeader->SetHardScatters(fAmpt->GetJATT());
538 fHeader->SetParticipants(fAmpt->GetNP(), fAmpt->GetNT());
539 fHeader->SetCollisions(fAmpt->GetN0(),
543 fHeader->SetSpectators(fProjectileSpecn, fProjectileSpecp,
544 fTargetSpecn,fTargetSpecp);
545 fHeader->SetReactionPlaneAngle(fAmpt->GetHINT1(20));
546 //printf("Impact Parameter %13.3f \n", fAmpt->GetHINT1(19));
548 // 4-momentum vectors of the triggered jets.
549 // Before final state gluon radiation.
550 TLorentzVector* jet1 = new TLorentzVector(fAmpt->GetHINT1(21),
553 fAmpt->GetHINT1(24));
555 TLorentzVector* jet2 = new TLorentzVector(fAmpt->GetHINT1(31),
558 fAmpt->GetHINT1(34));
559 // After final state gluon radiation.
560 TLorentzVector* jet3 = new TLorentzVector(fAmpt->GetHINT1(26),
563 fAmpt->GetHINT1(29));
565 TLorentzVector* jet4 = new TLorentzVector(fAmpt->GetHINT1(36),
568 fAmpt->GetHINT1(39));
569 fHeader->SetJets(jet1, jet2, jet3, jet4);
570 // Bookkeeping for kinematic bias
571 fHeader->SetTrials(fTrials);
573 fHeader->SetPrimaryVertex(fVertex);
574 fHeader->SetInteractionTime(fEventTime);
576 fCollisionGeometry = fHeader;
581 Bool_t AliGenAmpt::CheckTrigger()
583 // Check the kinematic trigger condition
585 Bool_t triggered = kFALSE;
589 TLorentzVector* jet1 = new TLorentzVector(fAmpt->GetHINT1(26),
592 fAmpt->GetHINT1(29));
594 TLorentzVector* jet2 = new TLorentzVector(fAmpt->GetHINT1(36),
597 fAmpt->GetHINT1(39));
598 Double_t eta1 = jet1->Eta();
599 Double_t eta2 = jet2->Eta();
600 Double_t phi1 = jet1->Phi();
601 Double_t phi2 = jet2->Phi();
602 //printf("\n Trigger: %f %f %f %f", fEtaMinJet, fEtaMaxJet, fPhiMinJet, fPhiMaxJet);
603 if ( (eta1 < fEtaMaxJet && eta1 > fEtaMinJet &&
604 phi1 < fPhiMaxJet && phi1 > fPhiMinJet)
606 (eta2 < fEtaMaxJet && eta2 > fEtaMinJet &&
607 phi2 < fPhiMaxJet && phi2 > fPhiMinJet)
610 } else if (fTrigger == 2) {
612 Int_t np = fParticles.GetEntriesFast();
613 for (Int_t i = 0; i < np; i++) {
614 TParticle* part = (TParticle*) fParticles.At(i);
615 Int_t kf = part->GetPdgCode();
616 Int_t ksp = part->GetUniqueID();
617 if (kf == 22 && ksp == 40) {
618 Float_t phi = part->Phi();
619 Float_t eta = part->Eta();
620 if (eta < fEtaMaxJet &&
626 } // check phi,eta within limits