]> git.uio.no Git - u/mrichter/AliRoot.git/blame - EVGEN/AliGenHijing.cxx
New version of FMD code (A.Maevskaia)
[u/mrichter/AliRoot.git] / EVGEN / AliGenHijing.cxx
CommitLineData
110410f9 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/*
17$Log$
a99cf51f 18Revision 1.24 2001/07/20 09:34:56 morsch
19Count the number of spectator neutrons and protons and add information
20to the event header. (Chiara Oppedisano)
21
b46f2676 22Revision 1.23 2001/07/13 17:30:22 morsch
23Derive from AliGenMC.
24
55d6adcf 25Revision 1.22 2001/06/11 13:09:23 morsch
26- Store cross-Section and number of binary collisions as a function of impact parameter
27- Pass AliGenHijingEventHeader to gAlice.
28
21ce2e6f 29Revision 1.21 2001/02/28 17:35:24 morsch
30Consider elastic interactions (ks = 1 and ks = 11) as spectator (Chiara Oppedisano)
31
cf6bac7b 32Revision 1.20 2001/02/14 15:50:40 hristov
33The last particle in event marked using SetHighWaterMark
34
28adac24 35Revision 1.19 2000/12/21 16:24:06 morsch
36Coding convention clean-up
37
675e9664 38Revision 1.18 2000/12/06 17:46:30 morsch
39Avoid random numbers 1 and 0.
40
7498b3ad 41Revision 1.17 2000/12/04 11:22:03 morsch
42Init of sRandom as in 1.15
43
097ec7c1 44Revision 1.16 2000/12/02 11:41:39 morsch
45Use SetRandom() to initialize random number generator in constructor.
46
1ed25e11 47Revision 1.15 2000/11/30 20:29:02 morsch
48Initialise static variable sRandom in constructor: sRandom = fRandom;
49
ad1df918 50Revision 1.14 2000/11/30 07:12:50 alibrary
51Introducing new Rndm and QA classes
52
65fb704d 53Revision 1.13 2000/11/09 17:40:27 morsch
54Possibility to select/unselect spectator protons and neutrons.
55Method SetSpectators(Int_t spect) added. (FCA, Ch. Oppedisano)
56
2705454f 57Revision 1.12 2000/10/20 13:38:38 morsch
58Debug printouts commented.
59
1df2195f 60Revision 1.11 2000/10/20 13:22:26 morsch
61- skip particle type 92 (string)
62- Charmed and beauty baryions (5122, 4122) are considered as stable consistent with
63 mesons.
64
608708ba 65Revision 1.10 2000/10/17 15:10:20 morsch
66Write first all the parent particles to the stack and then the final state particles.
67
e06552ba 68Revision 1.9 2000/10/17 13:38:59 morsch
69Protection against division by zero in EvaluateCrossSection() and KinematicSelection(..) (FCA)
70
c007646a 71Revision 1.8 2000/10/17 12:46:31 morsch
72Protect EvaluateCrossSections() against division by zero.
73
73bc6a56 74Revision 1.7 2000/10/02 21:28:06 fca
75Removal of useless dependecies via forward declarations
76
94de3818 77Revision 1.6 2000/09/11 13:23:37 morsch
78Write last seed to file (fortran lun 50) and reed back from same lun using calls to
79luget_hijing and luset_hijing.
80
b78ff279 81Revision 1.5 2000/09/07 16:55:40 morsch
82fHijing->Initialize(); after change of parameters. (Dmitri Yurevitch Peressounko)
83
ba244bac 84Revision 1.4 2000/07/11 18:24:56 fca
85Coding convention corrections + few minor bug fixes
86
aee8290b 87Revision 1.3 2000/06/30 12:08:36 morsch
88In member data: char* replaced by TString, Init takes care of resizing the strings to
898 characters required by Hijing.
90
3b8bd63f 91Revision 1.2 2000/06/15 14:15:05 morsch
92Add possibility for heavy flavor selection: charm and beauty.
93
eb342d2d 94Revision 1.1 2000/06/09 20:47:27 morsch
95AliGenerator interface class to HIJING using THijing (test version)
96
110410f9 97*/
98
675e9664 99
100
101// Generator using HIJING as an external generator
102// The main HIJING options are accessable for the user through this interface.
103// Uses the THijing implementation of TGenerator.
104//
105// andreas.morsch@cern.ch
106
110410f9 107#include "AliGenHijing.h"
3b8bd63f 108#include "AliGenHijingEventHeader.h"
110410f9 109#include "AliRun.h"
b46f2676 110#include "AliPDG.h"
110410f9 111
112#include <TArrayI.h>
113#include <TParticle.h>
114#include <THijing.h>
21ce2e6f 115#include <TGraph.h>
110410f9 116
ad1df918 117
110410f9 118 ClassImp(AliGenHijing)
119
120AliGenHijing::AliGenHijing()
55d6adcf 121 :AliGenMC()
110410f9 122{
123// Constructor
124}
125
126AliGenHijing::AliGenHijing(Int_t npart)
55d6adcf 127 :AliGenMC(npart)
110410f9 128{
129// Default PbPb collisions at 5. 5 TeV
130//
131 SetEnergyCMS();
132 SetImpactParameterRange();
133 SetTarget();
134 SetProjectile();
21ce2e6f 135 fKeep = 0;
136 fQuench = 1;
137 fShadowing = 1;
138 fTrigger = 0;
139 fDecaysOff = 1;
140 fEvaluate = 0;
141 fSelectAll = 0;
142 fFlavor = 0;
143 fSpectators = 1;
144 fDsigmaDb = 0;
145 fDnDb = 0;
ad1df918 146//
1ed25e11 147// Set random number generator
097ec7c1 148 sRandom = fRandom;
110410f9 149}
150
151AliGenHijing::AliGenHijing(const AliGenHijing & Hijing)
152{
153// copy constructor
154}
155
156
157AliGenHijing::~AliGenHijing()
158{
159// Destructor
21ce2e6f 160 if ( fDsigmaDb) delete fDsigmaDb;
161 if ( fDnDb) delete fDnDb;
110410f9 162}
163
164void AliGenHijing::Init()
165{
166// Initialisation
3b8bd63f 167 fFrame.Resize(8);
168 fTarget.Resize(8);
169 fProjectile.Resize(8);
170
110410f9 171 SetMC(new THijing(fEnergyCMS, fFrame, fProjectile, fTarget,
172 fAProjectile, fZProjectile, fATarget, fZTarget,
173 fMinImpactParam, fMaxImpactParam));
174
175 fHijing=(THijing*) fgMCEvGen;
ba244bac 176
110410f9 177 fHijing->SetIHPR2(3, fTrigger);
178 fHijing->SetIHPR2(4, fQuench);
179 fHijing->SetIHPR2(6, fShadowing);
180 fHijing->SetIHPR2(12, fDecaysOff);
181 fHijing->SetIHPR2(21, fKeep);
ba244bac 182 fHijing->Initialize();
b78ff279 183
184
110410f9 185//
186 if (fEvaluate) EvaluateCrossSections();
ad1df918 187//
188//
189// Initialize random generator
110410f9 190}
191
192void AliGenHijing::Generate()
193{
194// Generate one event
195
21ce2e6f 196 Float_t polar[3] = {0,0,0};
197 Float_t origin[3] = {0,0,0};
198 Float_t origin0[3] = {0,0,0};
28adac24 199 Float_t p[3], random[6];
200 Float_t tof;
110410f9 201
28adac24 202 static TClonesArray *particles;
110410f9 203// converts from mm/c to s
21ce2e6f 204 const Float_t kconv = 0.001/2.999792458e8;
110410f9 205//
21ce2e6f 206 Int_t nt = 0;
207 Int_t jev = 0;
28adac24 208 Int_t j, kf, ks, imo;
21ce2e6f 209 kf = 0;
eb342d2d 210
21ce2e6f 211 if(!particles) particles = new TClonesArray("TParticle",10000);
110410f9 212
21ce2e6f 213 fTrials = 0;
214 for (j = 0;j < 3; j++) origin0[j] = fOrigin[j];
215 if(fVertexSmear == kPerEvent) {
65fb704d 216 Rndm(random,6);
21ce2e6f 217 for (j=0; j < 3; j++) {
218 origin0[j] += fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
110410f9 219 TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
110410f9 220 }
21ce2e6f 221 } else if (fVertexSmear == kPerTrack) {
28adac24 222// fHijing->SetMSTP(151,0);
21ce2e6f 223 for (j = 0; j < 3; j++) {
28adac24 224// fHijing->SetPARP(151+j, fOsigma[j]*10.);
21ce2e6f 225 }
28adac24 226 }
227 while(1)
21ce2e6f 228 {
229// Generate one event
b46f2676 230// --------------------------------------------------------------------------
231 fSpecn = 0;
232 fSpecp = 0;
233// --------------------------------------------------------------------------
28adac24 234 fHijing->GenerateEvent();
235 fTrials++;
236 fHijing->ImportParticles(particles,"All");
237 Int_t np = particles->GetEntriesFast();
238 printf("\n **************************************************%d\n",np);
21ce2e6f 239 Int_t nc = 0;
28adac24 240 if (np == 0 ) continue;
241 Int_t i;
242 Int_t * newPos = new Int_t[np];
243
21ce2e6f 244 for (i = 0; i < np; i++) *(newPos+i) = i;
e06552ba 245//
246// First write parent particles
247//
248
21ce2e6f 249 for (i = 0; i < np; i++) {
250 TParticle * iparticle = (TParticle *) particles->At(i);
e06552ba 251// Is this a parent particle ?
28adac24 252 if (Stable(iparticle)) continue;
e06552ba 253//
28adac24 254 Bool_t hasMother = (iparticle->GetFirstMother() >=0);
255 Bool_t selected = kTRUE;
256 Bool_t hasSelectedDaughters = kFALSE;
e06552ba 257
258
28adac24 259 kf = iparticle->GetPdgCode();
260 ks = iparticle->GetStatusCode();
261 if (kf == 92) continue;
608708ba 262
55d6adcf 263 if (!fSelectAll) selected = KinematicSelection(iparticle, 0)&&SelectFlavor(kf);
28adac24 264 hasSelectedDaughters = DaughtersSelection(iparticle, particles);
110410f9 265//
266// Put particle on the stack if it is either selected or it is the mother of at least one seleted particle
267//
28adac24 268 if (selected || hasSelectedDaughters) {
21ce2e6f 269 nc++;
270 p[0] = iparticle->Px();
271 p[1] = iparticle->Py();
272 p[2] = iparticle->Pz();
273 origin[0] = origin0[0]+iparticle->Vx()/10;
274 origin[1] = origin0[1]+iparticle->Vy()/10;
275 origin[2] = origin0[2]+iparticle->Vz()/10;
276 tof = kconv*iparticle->T();
277 imo = -1;
278 if (hasMother) {
279 imo = iparticle->GetFirstMother();
280 TParticle* mother = (TParticle *) particles->At(imo);
281 imo = (mother->GetPdgCode() != 92) ? imo =* (newPos+imo) : -1;
282 }
e06552ba 283// Put particle on the stack ...
1df2195f 284// printf("\n set track mother: %d %d %d %d %d %d ",i,imo, kf, nt+1, selected, hasSelectedDaughters);
21ce2e6f 285
a99cf51f 286 SetTrack(0,imo,kf,p,origin,polar, tof,kPPrimary,nt);
e06552ba 287// ... and keep it there
a99cf51f 288 KeepTrack(nt);
e06552ba 289//
21ce2e6f 290 *(newPos+i)=nt;
28adac24 291 } // selected
292 } // particle loop parents
e06552ba 293//
294// Now write the final state particles
295//
296
28adac24 297 for (i = 0; i<np; i++) {
298 TParticle * iparticle = (TParticle *) particles->At(i);
e06552ba 299// Is this a final state particle ?
28adac24 300 if (!Stable(iparticle)) continue;
b46f2676 301
28adac24 302 Bool_t hasMother = (iparticle->GetFirstMother() >=0);
303 Bool_t selected = kTRUE;
304 kf = iparticle->GetPdgCode();
305 ks = iparticle->GetStatusCode();
b46f2676 306// --------------------------------------------------------------------------
307// Count spectator neutrons and protons
308 if(ks == 0 || ks == 1 || ks == 10 || ks == 11){
309 if(kf == kNeutron) fSpecn += 1;
310 if(kf == kProton) fSpecp += 1;
311 }
312// --------------------------------------------------------------------------
313//
28adac24 314 if (!fSelectAll) {
55d6adcf 315 selected = KinematicSelection(iparticle,0)&&SelectFlavor(kf);
21ce2e6f 316 if (!fSpectators && selected) selected = (ks != 0 && ks != 1 && ks != 10
317 && ks != 11);
28adac24 318 }
e06552ba 319//
320// Put particle on the stack if selected
321//
28adac24 322 if (selected) {
21ce2e6f 323 nc++;
324 p[0] = iparticle->Px();
325 p[1] = iparticle->Py();
326 p[2] = iparticle->Pz();
327 origin[0] = origin0[0]+iparticle->Vx()/10;
328 origin[1] = origin0[1]+iparticle->Vy()/10;
329 origin[2] = origin0[2]+iparticle->Vz()/10;
330 tof = kconv*iparticle->T();
331 imo = -1;
332
333 if (hasMother) {
334 imo = iparticle->GetFirstMother();
335 TParticle* mother = (TParticle *) particles->At(imo);
336 imo = (mother->GetPdgCode() != 92) ? imo=*(newPos+imo) : -1;
337 }
e06552ba 338// Put particle on the stack
a99cf51f 339 SetTrack(fTrackIt,imo,kf,p,origin,polar,
21ce2e6f 340 tof,kPNoProcess,nt);
a99cf51f 341 KeepTrack(nt);
21ce2e6f 342 *(newPos+i)=nt;
28adac24 343 } // selected
344 } // particle loop final state
e06552ba 345
28adac24 346 delete newPos;
347
348 printf("\n I've put %i particles on the stack \n",nc);
349 if (nc > 0) {
21ce2e6f 350 jev += nc;
351 if (jev >= fNpart || fNpart == -1) {
352 fKineBias = Float_t(fNpart)/Float_t(fTrials);
353 printf("\n Trials: %i %i %i\n",fTrials, fNpart, jev);
354 break;
355 }
28adac24 356 }
21ce2e6f 357 } // event loop
358 MakeHeader();
359
a99cf51f 360 SetHighWaterMark(nt);
110410f9 361}
362
110410f9 363void AliGenHijing::KeepFullEvent()
364{
365 fKeep=1;
366}
367
368void AliGenHijing::EvaluateCrossSections()
369{
370// Glauber Calculation of geometrical x-section
371//
21ce2e6f 372 Float_t xTot = 0.; // barn
373 Float_t xTotHard = 0.; // barn
374 Float_t xPart = 0.; // barn
375 Float_t xPartHard = 0.; // barn
376 Float_t sigmaHard = 0.1; // mbarn
377 Float_t bMin = 0.;
378 Float_t bMax = fHijing->GetHIPR1(34)+fHijing->GetHIPR1(35);
379 const Float_t kdib = 0.2;
380 Int_t kMax = Int_t((bMax-bMin)/kdib)+1;
110410f9 381
382
383 printf("\n Projectile Radius (fm): %f \n",fHijing->GetHIPR1(34));
384 printf("\n Target Radius (fm): %f \n",fHijing->GetHIPR1(35));
385 Int_t i;
21ce2e6f 386 Float_t oldvalue= 0.;
387
388 Float_t* b = new Float_t[kMax];
389 Float_t* si1 = new Float_t[kMax];
390 Float_t* si2 = new Float_t[kMax];
110410f9 391
21ce2e6f 392 for (i = 0; i < kMax; i++)
110410f9 393 {
21ce2e6f 394 Float_t xb = bMin+i*kdib;
110410f9 395 Float_t ov;
396 ov=fHijing->Profile(xb);
21ce2e6f 397 Float_t gb = 2.*0.01*fHijing->GetHIPR1(40)*kdib*xb*(1.-TMath::Exp(-fHijing->GetHINT1(12)*ov));
398 Float_t gbh = 2.*0.01*fHijing->GetHIPR1(40)*kdib*xb*sigmaHard*ov;
110410f9 399 xTot+=gb;
21ce2e6f 400 xTotHard += gbh;
110410f9 401 if (xb > fMinImpactParam && xb < fMaxImpactParam)
402 {
21ce2e6f 403 xPart += gb;
404 xPartHard += gbh;
110410f9 405 }
406
c007646a 407 if(oldvalue) if ((xTot-oldvalue)/oldvalue<0.0001) break;
21ce2e6f 408 oldvalue = xTot;
110410f9 409 printf("\n Total cross section (barn): %d %f %f \n",i, xb, xTot);
410 printf("\n Hard cross section (barn): %d %f %f \n\n",i, xb, xTotHard);
21ce2e6f 411 if (i>0) {
412 si1[i] = gb/kdib;
413 si2[i] = gbh/gb;
414 b[i] = xb;
415 }
110410f9 416 }
21ce2e6f 417
110410f9 418 printf("\n Total cross section (barn): %f \n",xTot);
419 printf("\n Hard cross section (barn): %f \n \n",xTotHard);
420 printf("\n Partial cross section (barn): %f %f \n",xPart, xPart/xTot*100.);
421 printf("\n Partial hard cross section (barn): %f %f \n",xPartHard, xPartHard/xTotHard*100.);
21ce2e6f 422
423// Store result as a graph
424 b[0] = 0;
425 si1[0] = 0;
426 si2[0]=si2[1];
427
428 fDsigmaDb = new TGraph(i, b, si1);
429 fDnDb = new TGraph(i, b, si2);
110410f9 430}
431
432Bool_t AliGenHijing::DaughtersSelection(TParticle* iparticle, TClonesArray* particles)
433{
434//
435// Looks recursively if one of the daughters has been selected
436//
437// printf("\n Consider daughters %d:",iparticle->GetPdgCode());
21ce2e6f 438 Int_t imin = -1;
439 Int_t imax = -1;
110410f9 440 Int_t i;
21ce2e6f 441 Bool_t hasDaughters = (iparticle->GetFirstDaughter() >=0);
442 Bool_t selected = kFALSE;
110410f9 443 if (hasDaughters) {
21ce2e6f 444 imin = iparticle->GetFirstDaughter();
445 imax = iparticle->GetLastDaughter();
446 for (i = imin; i <= imax; i++){
447 TParticle * jparticle = (TParticle *) particles->At(i);
448 Int_t ip = jparticle->GetPdgCode();
55d6adcf 449 if (KinematicSelection(jparticle,0)&&SelectFlavor(ip)) {
608708ba 450 selected=kTRUE; break;
451 }
110410f9 452 if (DaughtersSelection(jparticle, particles)) {selected=kTRUE; break; }
453 }
454 } else {
455 return kFALSE;
456 }
110410f9 457 return selected;
458}
459
460
eb342d2d 461Bool_t AliGenHijing::SelectFlavor(Int_t pid)
462{
463// Select flavor of particle
464// 0: all
465// 4: charm and beauty
466// 5: beauty
467 if (fFlavor == 0) return kTRUE;
468
21ce2e6f 469 Int_t ifl = TMath::Abs(pid/100);
eb342d2d 470 if (ifl > 10) ifl/=10;
608708ba 471 return (fFlavor == ifl);
472}
eb342d2d 473
608708ba 474Bool_t AliGenHijing::Stable(TParticle* particle)
475{
675e9664 476// Return true for a stable particle
477//
608708ba 478 Int_t kf = TMath::Abs(particle->GetPdgCode());
479
480 if ( (particle->GetFirstDaughter() < 0 ) || (kf == 1000*fFlavor+122))
608708ba 481 {
482 return kTRUE;
483 } else {
484 return kFALSE;
485 }
eb342d2d 486}
110410f9 487
3b8bd63f 488void AliGenHijing::MakeHeader()
489{
490// Builds the event header, to be called after each event
21ce2e6f 491 AliGenEventHeader* header = new AliGenHijingEventHeader("Hijing");
492 ((AliGenHijingEventHeader*) header)->SetNProduced(fHijing->GetNATT());
493 ((AliGenHijingEventHeader*) header)->SetImpactParameter(fHijing->GetHINT1(19));
494 ((AliGenHijingEventHeader*) header)->SetTotalEnergy(fHijing->GetEATT());
495 ((AliGenHijingEventHeader*) header)->SetHardScatters(fHijing->GetJATT());
496 ((AliGenHijingEventHeader*) header)->SetParticipants(fHijing->GetNP(), fHijing->GetNT());
497 ((AliGenHijingEventHeader*) header)->SetCollisions(fHijing->GetN0(),
3b8bd63f 498 fHijing->GetN01(),
499 fHijing->GetN10(),
500 fHijing->GetN11());
b46f2676 501 ((AliGenHijingEventHeader*) header)->SetSpectators(fSpecn, fSpecp);
21ce2e6f 502 gAlice->SetGenEventHeader(header);
503
3b8bd63f 504}
505
110410f9 506AliGenHijing& AliGenHijing::operator=(const AliGenHijing& rhs)
507{
508// Assignment operator
509 return *this;
510}
608708ba 511
65fb704d 512#ifndef WIN32
513# define rluget_hijing rluget_hijing_
514# define rluset_hijing rluset_hijing_
515# define rlu_hijing rlu_hijing_
516# define type_of_call
517#else
518# define rluget_hijing RLUGET_HIJING
519# define rluset_hijing RLUSET_HIJING
520# define rlu_hijing RLU_HIJING
521# define type_of_call _stdcall
522#endif
523
524
525extern "C" {
526 void type_of_call rluget_hijing(Int_t & /*lfn*/, Int_t & /*move*/)
527 {printf("Dummy version of rluget_hijing reached\n");}
528
529 void type_of_call rluset_hijing(Int_t & /*lfn*/, Int_t & /*move*/)
530 {printf("Dummy version of rluset_hijing reached\n");}
531
532 Double_t type_of_call rlu_hijing(Int_t & /*idum*/)
7498b3ad 533 {
534 Float_t r;
535 do r=sRandom->Rndm(); while(0 >= r || r >= 1);
536 return r;
537 }
65fb704d 538}