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 Revision 1.11 2000/10/20 13:22:26 morsch
19 - skip particle type 92 (string)
20 - Charmed and beauty baryions (5122, 4122) are considered as stable consistent with
23 Revision 1.10 2000/10/17 15:10:20 morsch
24 Write first all the parent particles to the stack and then the final state particles.
26 Revision 1.9 2000/10/17 13:38:59 morsch
27 Protection against division by zero in EvaluateCrossSection() and KinematicSelection(..) (FCA)
29 Revision 1.8 2000/10/17 12:46:31 morsch
30 Protect EvaluateCrossSections() against division by zero.
32 Revision 1.7 2000/10/02 21:28:06 fca
33 Removal of useless dependecies via forward declarations
35 Revision 1.6 2000/09/11 13:23:37 morsch
36 Write last seed to file (fortran lun 50) and reed back from same lun using calls to
37 luget_hijing and luset_hijing.
39 Revision 1.5 2000/09/07 16:55:40 morsch
40 fHijing->Initialize(); after change of parameters. (Dmitri Yurevitch Peressounko)
42 Revision 1.4 2000/07/11 18:24:56 fca
43 Coding convention corrections + few minor bug fixes
45 Revision 1.3 2000/06/30 12:08:36 morsch
46 In member data: char* replaced by TString, Init takes care of resizing the strings to
47 8 characters required by Hijing.
49 Revision 1.2 2000/06/15 14:15:05 morsch
50 Add possibility for heavy flavor selection: charm and beauty.
52 Revision 1.1 2000/06/09 20:47:27 morsch
53 AliGenerator interface class to HIJING using THijing (test version)
57 #include "AliGenHijing.h"
58 #include "AliGenHijingEventHeader.h"
63 #include <TParticle.h>
66 ClassImp(AliGenHijing)
68 AliGenHijing::AliGenHijing()
74 AliGenHijing::AliGenHijing(Int_t npart)
77 // Default PbPb collisions at 5. 5 TeV
80 SetImpactParameterRange();
93 AliGenHijing::AliGenHijing(const AliGenHijing & Hijing)
99 AliGenHijing::~AliGenHijing()
104 void AliGenHijing::Init()
109 fProjectile.Resize(8);
111 SetMC(new THijing(fEnergyCMS, fFrame, fProjectile, fTarget,
112 fAProjectile, fZProjectile, fATarget, fZTarget,
113 fMinImpactParam, fMaxImpactParam));
115 fHijing=(THijing*) fgMCEvGen;
117 fHijing->SetIHPR2(3, fTrigger);
118 fHijing->SetIHPR2(4, fQuench);
119 fHijing->SetIHPR2(6, fShadowing);
120 fHijing->SetIHPR2(12, fDecaysOff);
121 fHijing->SetIHPR2(21, fKeep);
122 fHijing->Rluset(50,0);
123 fHijing->Initialize();
127 if (fEvaluate) EvaluateCrossSections();
130 void AliGenHijing::Generate()
132 // Generate one event
134 Float_t polar[3] = {0,0,0};
135 Float_t origin[3]= {0,0,0};
136 Float_t origin0[3]= {0,0,0};
137 Float_t p[3], random[6];
140 static TClonesArray *particles;
141 // converts from mm/c to s
142 const Float_t kconv=0.001/2.999792458e8;
146 Int_t j, kf, ks, imo;
149 if(!particles) particles=new TClonesArray("TParticle",10000);
152 for (j=0;j<3;j++) origin0[j]=fOrigin[j];
153 if(fVertexSmear==kPerEvent) {
156 origin0[j]+=fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
157 TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
158 // fHijing->SetMSTP(151,0);
160 } else if (fVertexSmear==kPerTrack) {
161 // fHijing->SetMSTP(151,0);
163 // fHijing->SetPARP(151+j, fOsigma[j]*10.);
169 fHijing->GenerateEvent();
171 fHijing->ImportParticles(particles,"All");
172 Int_t np = particles->GetEntriesFast();
173 printf("\n **************************************************%d\n",np);
175 if (np == 0 ) continue;
177 Int_t * newPos = new Int_t[np];
179 for (i = 0; i<np; i++) *(newPos+i)=i;
181 // First write parent particles
184 for (i = 0; i<np; i++) {
185 TParticle * iparticle = (TParticle *) particles->At(i);
186 // Is this a parent particle ?
187 if (Stable(iparticle)) continue;
189 Bool_t hasMother = (iparticle->GetFirstMother() >=0);
190 Bool_t selected = kTRUE;
191 Bool_t hasSelectedDaughters = kFALSE;
194 kf = iparticle->GetPdgCode();
195 ks = iparticle->GetStatusCode();
196 if (kf == 92) continue;
198 if (!fSelectAll) selected = KinematicSelection(iparticle)&&SelectFlavor(kf);
199 hasSelectedDaughters = DaughtersSelection(iparticle, particles);
201 // Put particle on the stack if it is either selected or it is the mother of at least one seleted particle
203 if (selected || hasSelectedDaughters) {
205 p[0]=iparticle->Px();
206 p[1]=iparticle->Py();
207 p[2]=iparticle->Pz();
208 origin[0]=origin0[0]+iparticle->Vx()/10;
209 origin[1]=origin0[1]+iparticle->Vy()/10;
210 origin[2]=origin0[2]+iparticle->Vz()/10;
211 tof=kconv*iparticle->T();
214 imo=iparticle->GetFirstMother();
215 TParticle* mother= (TParticle *) particles->At(imo);
216 imo = (mother->GetPdgCode() != 92) ? imo=*(newPos+imo) : -1;
218 // Put particle on the stack ...
219 // printf("\n set track mother: %d %d %d %d %d %d ",i,imo, kf, nt+1, selected, hasSelectedDaughters);
221 gAlice->SetTrack(0,imo,kf,p,origin,polar,
223 // ... and keep it there
224 gAlice->KeepTrack(nt);
228 } // particle loop parents
230 // Now write the final state particles
233 for (i = 0; i<np; i++) {
234 TParticle * iparticle = (TParticle *) particles->At(i);
235 // Is this a final state particle ?
236 if (!Stable(iparticle)) continue;
238 Bool_t hasMother = (iparticle->GetFirstMother() >=0);
239 Bool_t selected = kTRUE;
240 kf = iparticle->GetPdgCode();
241 if (!fSelectAll) selected = KinematicSelection(iparticle)&&SelectFlavor(kf);
243 // Put particle on the stack if selected
247 ks = iparticle->GetStatusCode();
248 p[0]=iparticle->Px();
249 p[1]=iparticle->Py();
250 p[2]=iparticle->Pz();
251 origin[0]=origin0[0]+iparticle->Vx()/10;
252 origin[1]=origin0[1]+iparticle->Vy()/10;
253 origin[2]=origin0[2]+iparticle->Vz()/10;
254 tof=kconv*iparticle->T();
258 imo=iparticle->GetFirstMother();
259 TParticle* mother= (TParticle *) particles->At(imo);
260 imo = (mother->GetPdgCode() != 92) ? imo=*(newPos+imo) : -1;
262 // Put particle on the stack
263 gAlice->SetTrack(fTrackIt,imo,kf,p,origin,polar,
266 // printf("\n set track final: %d %d %d",imo, kf, nt);
267 gAlice->KeepTrack(nt);
270 } // particle loop final state
274 printf("\n I've put %i particles on the stack \n",nc);
277 if (jev >= fNpart || fNpart == -1) {
278 fKineBias=Float_t(fNpart)/Float_t(fTrials);
279 printf("\n Trials: %i %i %i\n",fTrials, fNpart, jev);
284 fHijing->Rluget(50,-1);
287 Bool_t AliGenHijing::KinematicSelection(TParticle *particle)
289 // Perform kinematic selection
290 Double_t px=particle->Px();
291 Double_t py=particle->Py();
292 Double_t pz=particle->Pz();
293 Double_t e=particle->Energy();
296 // transverse momentum cut
297 Double_t pt=TMath::Sqrt(px*px+py*py);
298 if (pt > fPtMax || pt < fPtMin)
300 // printf("\n failed pt cut %f %f %f \n",pt,fPtMin,fPtMax);
305 Double_t p=TMath::Sqrt(px*px+py*py+pz*pz);
306 if (p > fPMax || p < fPMin)
308 // printf("\n failed p cut %f %f %f \n",p,fPMin,fPMax);
314 Double_t theta = Double_t(TMath::ATan2(Double_t(pt),Double_t(pz)));
315 if (theta > fThetaMax || theta < fThetaMin)
318 // printf("\n failed theta cut %f %f %f \n",theta,fThetaMin,fThetaMax);
326 else if (e<=-pz) y = -99;
327 else y = 0.5*TMath::Log((e+pz)/(e-pz));
328 if (y > fYMax || y < fYMin)
330 // printf("\n failed y cut %f %f %f \n",y,fYMin,fYMax);
336 Double_t phi=Double_t(TMath::ATan2(Double_t(py),Double_t(px)));
337 if (phi > fPhiMax || phi < fPhiMin)
339 // printf("\n failed phi cut %f %f %f \n",phi,fPhiMin,fPhiMax);
346 void AliGenHijing::KeepFullEvent()
351 void AliGenHijing::EvaluateCrossSections()
353 // Glauber Calculation of geometrical x-section
355 Float_t xTot=0.; // barn
356 Float_t xTotHard=0.; // barn
357 Float_t xPart=0.; // barn
358 Float_t xPartHard=0.; // barn
359 Float_t sigmaHard=0.1; // mbarn
361 Float_t bMax=fHijing->GetHIPR1(34)+fHijing->GetHIPR1(35);
362 const Float_t kdib=0.2;
363 Int_t kMax=Int_t((bMax-bMin)/kdib)+1;
366 printf("\n Projectile Radius (fm): %f \n",fHijing->GetHIPR1(34));
367 printf("\n Target Radius (fm): %f \n",fHijing->GetHIPR1(35));
371 for (i=0; i<kMax; i++)
373 Float_t xb=bMin+i*kdib;
375 ov=fHijing->Profile(xb);
376 Float_t gb = 2.*0.01*fHijing->GetHIPR1(40)*kdib*xb*(1.-TMath::Exp(-fHijing->GetHINT1(12)*ov));
377 Float_t gbh = 2.*0.01*fHijing->GetHIPR1(40)*kdib*xb*sigmaHard*ov;
380 if (xb > fMinImpactParam && xb < fMaxImpactParam)
386 if(oldvalue) if ((xTot-oldvalue)/oldvalue<0.0001) break;
388 printf("\n Total cross section (barn): %d %f %f \n",i, xb, xTot);
389 printf("\n Hard cross section (barn): %d %f %f \n\n",i, xb, xTotHard);
391 printf("\n Total cross section (barn): %f \n",xTot);
392 printf("\n Hard cross section (barn): %f \n \n",xTotHard);
393 printf("\n Partial cross section (barn): %f %f \n",xPart, xPart/xTot*100.);
394 printf("\n Partial hard cross section (barn): %f %f \n",xPartHard, xPartHard/xTotHard*100.);
397 Bool_t AliGenHijing::DaughtersSelection(TParticle* iparticle, TClonesArray* particles)
400 // Looks recursively if one of the daughters has been selected
402 // printf("\n Consider daughters %d:",iparticle->GetPdgCode());
406 Bool_t hasDaughters= (iparticle->GetFirstDaughter() >=0);
407 Bool_t selected=kFALSE;
409 imin=iparticle->GetFirstDaughter();
410 imax=iparticle->GetLastDaughter();
411 for (i=imin; i<= imax; i++){
412 TParticle * jparticle = (TParticle *) particles->At(i);
413 Int_t ip=jparticle->GetPdgCode();
414 if (KinematicSelection(jparticle)&&SelectFlavor(ip)) {
415 selected=kTRUE; break;
417 if (DaughtersSelection(jparticle, particles)) {selected=kTRUE; break; }
427 Bool_t AliGenHijing::SelectFlavor(Int_t pid)
429 // Select flavor of particle
431 // 4: charm and beauty
433 if (fFlavor == 0) return kTRUE;
435 Int_t ifl=TMath::Abs(pid/100);
436 if (ifl > 10) ifl/=10;
437 return (fFlavor == ifl);
440 Bool_t AliGenHijing::Stable(TParticle* particle)
442 Int_t kf = TMath::Abs(particle->GetPdgCode());
444 if ( (particle->GetFirstDaughter() < 0 ) || (kf == 1000*fFlavor+122))
453 void AliGenHijing::MakeHeader()
455 // Builds the event header, to be called after each event
456 AliGenHijingEventHeader* header = new AliGenHijingEventHeader("Hijing");
457 // header->SetDate(date);
458 // header->SetRunNumber(run);
459 // header->SetEventNumber(event);
460 header->SetNProduced(fHijing->GetNATT());
461 header->SetImpactParameter(fHijing->GetHINT1(19));
462 header->SetTotalEnergy(fHijing->GetEATT());
463 header->SetHardScatters(fHijing->GetJATT());
464 header->SetParticipants(fHijing->GetNP(), fHijing->GetNT());
465 header->SetCollisions(fHijing->GetN0(),
471 AliGenHijing& AliGenHijing::operator=(const AliGenHijing& rhs)
473 // Assignment operator