654f72146b90ed47699088bdb5c5af8f7598819c
[u/mrichter/AliRoot.git] / THijing / AliGenHijing.cxx
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 /* $Id$ */
17
18 // Generator using HIJING as an external generator
19 // The main HIJING options are accessable for the user through this interface.
20 // Uses the THijing implementation of TGenerator.
21 // Author:
22 // Andreas Morsch    (andreas.morsch@cern.ch)
23 //
24
25 #include <TGraph.h>
26 #include <THijing.h>
27 #include <TLorentzVector.h>
28 #include <TPDGCode.h>
29 #include <TParticle.h>
30
31 #include "AliGenHijing.h"
32 #include "AliGenHijingEventHeader.h"
33 #include "AliRun.h"
34 #include "AliHijingRndm.h"
35
36 ClassImp(AliGenHijing)
37
38 AliGenHijing::AliGenHijing()
39                  :AliGenMC()
40 {
41 // Constructor
42     fParticles = 0;
43     fHijing    = 0;
44     fDsigmaDb  = 0;
45     fDnDb      = 0;
46     AliHijingRndm::SetHijingRandom(GetRandom());
47 }
48
49 AliGenHijing::AliGenHijing(Int_t npart)
50     :AliGenMC(npart)
51 {
52 // Default PbPb collisions at 5. 5 TeV
53 //
54     fName = "Hijing";
55     fTitle= "Particle Generator using HIJING";
56
57     SetEnergyCMS();
58     SetImpactParameterRange();
59     SetBoostLHC();
60     SetJetEtaRange();
61     SetJetPhiRange();
62     
63     fKeep       =  0;
64     fQuench     =  1;
65     fShadowing  =  1;
66     fTrigger    =  0;
67     fDecaysOff  =  1;
68     fEvaluate   =  0;
69     fSelectAll  =  0;
70     fFlavor     =  0;
71     fSpectators =  1;
72     fDsigmaDb   =  0;
73     fDnDb       =  0;
74     fPtMinJet   = -2.5;         
75     fRadiation  =  3;
76     //
77     SetSimpleJets();
78     SetNoGammas();
79 //
80     fParticles = new TClonesArray("TParticle",10000);    
81 //
82 // Set random number generator   
83     AliHijingRndm::SetHijingRandom(GetRandom());
84     fHijing = 0;
85
86 }
87
88 AliGenHijing::AliGenHijing(const AliGenHijing & hijing):
89     AliGenMC(hijing)
90 {
91 // copy constructor
92 }
93
94
95 AliGenHijing::~AliGenHijing()
96 {
97 // Destructor
98     if ( fDsigmaDb) delete  fDsigmaDb;  
99     if ( fDnDb)     delete  fDnDb;  
100     delete fParticles;
101 }
102
103 void AliGenHijing::Init()
104 {
105 // Initialisation
106     fFrame.Resize(8);
107     fTarget.Resize(8);
108     fProjectile.Resize(8);
109     
110     SetMC(new THijing(fEnergyCMS, fFrame, fProjectile, fTarget, 
111                       fAProjectile, fZProjectile, fATarget, fZTarget, 
112                       fMinImpactParam, fMaxImpactParam));
113
114     fHijing=(THijing*) fMCEvGen;
115     fHijing->SetIHPR2(2,  fRadiation);
116     fHijing->SetIHPR2(3,  fTrigger);
117     fHijing->SetIHPR2(6,  fShadowing);
118     fHijing->SetIHPR2(12, fDecaysOff);    
119     fHijing->SetIHPR2(21, fKeep);
120     fHijing->SetHIPR1(10, fPtMinJet);   
121     fHijing->SetHIPR1(50, fSimpleJet);
122 //
123 //  Quenching
124 //
125 //
126 //  fQuench = 0:  no quenching
127 //  fQuench = 1:  hijing default
128 //  fQuench = 2:  new LHC  parameters for HIPR1(11) and HIPR1(14)
129 //  fQuench = 3:  new RHIC parameters for HIPR1(11) and HIPR1(14)
130 //  fQuench = 4:  new LHC  parameters with log(e) dependence
131 //  fQuench = 5:  new RHIC parameters with log(e) dependence
132     fHijing->SetIHPR2(50, 0);
133     if (fQuench > 0) 
134         fHijing->SetIHPR2(4,  1);
135     else
136         fHijing->SetIHPR2(4,  0);
137 // New LHC parameters from Xin-Nian Wang
138     if (fQuench == 2) {
139         fHijing->SetHIPR1(14, 1.1);
140         fHijing->SetHIPR1(11, 3.7);
141     } else if (fQuench == 3) {
142         fHijing->SetHIPR1(14, 0.20);
143         fHijing->SetHIPR1(11, 2.5);
144     } else if (fQuench == 4) {
145         fHijing->SetIHPR2(50, 1);
146         fHijing->SetHIPR1(14, 4.*0.34);
147         fHijing->SetHIPR1(11, 3.7);
148     } else if (fQuench == 5) {
149         fHijing->SetIHPR2(50, 1);
150         fHijing->SetHIPR1(14, 0.34);
151         fHijing->SetHIPR1(11, 2.5);
152     }
153     
154     
155     AliGenMC::Init();
156     
157 //
158 //  Initialize Hijing  
159 //    
160     fHijing->Initialize();
161 //
162     if (fEvaluate) EvaluateCrossSections();
163 //
164 }
165
166 void AliGenHijing::Generate()
167 {
168 // Generate one event
169
170   Float_t polar[3]    =   {0,0,0};
171   Float_t origin[3]   =   {0,0,0};
172   Float_t origin0[3]  =   {0,0,0};
173   Float_t p[3];
174   Float_t tof;
175
176 //  converts from mm/c to s
177   const Float_t kconv = 0.001/2.999792458e8;
178 //
179   Int_t nt  = 0;
180   Int_t jev = 0;
181   Int_t j, kf, ks, imo;
182   kf = 0;
183     
184
185     
186   fTrials = 0;
187   for (j = 0;j < 3; j++) origin0[j] = fOrigin[j];
188   if(fVertexSmear == kPerEvent) {
189       Vertex();
190       for (j=0; j < 3; j++) origin0[j] = fVertex[j];
191   } 
192
193   while(1)
194   {
195 //    Generate one event
196 // --------------------------------------------------------------------------
197       fProjectileSpecn    = 0;  
198       fProjectileSpecp    = 0;
199       fTargetSpecn    = 0;  
200       fTargetSpecp    = 0;
201 // --------------------------------------------------------------------------
202       fHijing->GenerateEvent();
203       fTrials++;
204       fHijing->ImportParticles(fParticles,"All");
205       if (fTrigger != kNoTrigger) {
206           if (!CheckTrigger()) continue;
207       }
208       if (fLHC) Boost();
209       
210       
211       Int_t np = fParticles->GetEntriesFast();
212       printf("\n **************************************************%d\n",np);
213       Int_t nc = 0;
214       if (np == 0 ) continue;
215       Int_t i;
216       Int_t* newPos     = new Int_t[np];
217       Int_t* pSelected  = new Int_t[np];
218
219       for (i = 0; i < np; i++) {
220           newPos[i]    = i;
221           pSelected[i] = 0;
222       }
223       
224 //      Get event vertex
225 //
226       TParticle *  iparticle = (TParticle *) fParticles->At(0);
227       fVertex[0] = origin0[0];
228       fVertex[1] = origin0[1];  
229       fVertex[2] = origin0[2];
230       
231 //
232 //      First select parent particles
233 //
234
235       for (i = 0; i < np; i++) {
236           iparticle = (TParticle *) fParticles->At(i);
237
238 // Is this a parent particle ?
239           if (Stable(iparticle)) continue;
240 //
241           Bool_t  selected             =  kTRUE;
242           Bool_t  hasSelectedDaughters =  kFALSE;
243           
244           
245           kf        = iparticle->GetPdgCode();
246           ks        = iparticle->GetStatusCode();
247           if (kf == 92) continue;
248             
249           if (!fSelectAll) selected = KinematicSelection(iparticle, 0) && 
250                                SelectFlavor(kf);
251           hasSelectedDaughters = DaughtersSelection(iparticle);
252 //
253 // Put particle on the stack if it is either selected or 
254 // it is the mother of at least one seleted particle
255 //
256           if (selected || hasSelectedDaughters) {
257               nc++;
258               pSelected[i] = 1;
259           } // selected
260       } // particle loop parents
261 //
262 // Now select the final state particles
263 //
264
265       for (i = 0; i<np; i++) {
266           TParticle *  iparticle = (TParticle *) fParticles->At(i);
267 // Is this a final state particle ?
268           if (!Stable(iparticle)) continue;
269       
270           Bool_t  selected             =  kTRUE;
271           kf        = iparticle->GetPdgCode();
272           ks        = iparticle->GetStatusCode();
273           
274 // --------------------------------------------------------------------------
275 // Count spectator neutrons and protons
276           if(ks == 0 || ks == 1){
277               if(kf == kNeutron) fProjectileSpecn += 1;
278               if(kf == kProton)  fProjectileSpecp += 1;
279           }
280           else if(ks == 10 || ks == 11){
281               if(kf == kNeutron) fTargetSpecn += 1;
282               if(kf == kProton)  fTargetSpecp += 1;
283           }
284 // --------------------------------------------------------------------------
285 //          
286           if (!fSelectAll) {
287               selected = KinematicSelection(iparticle,0)&&SelectFlavor(kf);
288               if (!fSpectators && selected) selected = (ks != 0 && ks != 1 && ks != 10
289                                                         && ks != 11);
290           }
291 //
292 // Put particle on the stack if selected
293 //
294           if (selected) {
295               nc++;
296               pSelected[i] = 1;
297           } // selected
298       } // particle loop final state
299 //
300 // Write particles to stack
301 //
302       for (i = 0; i<np; i++) {
303           TParticle *  iparticle = (TParticle *) fParticles->At(i);
304           Bool_t  hasMother   = (iparticle->GetFirstMother()     >=0);
305           Bool_t  hasDaughter = (iparticle->GetFirstDaughter()   >=0);
306
307           if (pSelected[i]) {
308               kf   = iparticle->GetPdgCode();
309               ks   = iparticle->GetStatusCode();
310               p[0] = iparticle->Px();
311               p[1] = iparticle->Py();
312               p[2] = iparticle->Pz();
313               origin[0] = origin0[0]+iparticle->Vx()/10;
314               origin[1] = origin0[1]+iparticle->Vy()/10;
315               origin[2] = origin0[2]+iparticle->Vz()/10;
316               tof = kconv*iparticle->T();
317               imo = -1;
318               TParticle* mother = 0;
319               if (hasMother) {
320                   imo = iparticle->GetFirstMother();
321                   mother = (TParticle *) fParticles->At(imo);
322                   imo = (mother->GetPdgCode() != 92) ? imo = newPos[imo] : -1;
323               } // if has mother   
324               Bool_t tFlag = (fTrackIt && !hasDaughter);
325               PushTrack(tFlag,imo,kf,p,origin,polar,
326                        tof,kPNoProcess,nt, 1., ks);
327               KeepTrack(nt);
328               newPos[i] = nt;
329           } // if selected
330       } // particle loop
331       delete[] newPos;
332       delete[] pSelected;
333       
334       printf("\n I've put %i particles on the stack \n",nc);
335       if (nc > 0) {
336           jev += nc;
337           if (jev >= fNpart || fNpart == -1) {
338               fKineBias = Float_t(fNpart)/Float_t(fTrials);
339               printf("\n Trials: %i %i %i\n",fTrials, fNpart, jev);
340               break;
341           }
342       }
343   } // event loop
344   MakeHeader();
345   SetHighWaterMark(nt);
346 }
347
348 void AliGenHijing::KeepFullEvent()
349 {
350     fKeep=1;
351 }
352
353 void AliGenHijing::EvaluateCrossSections()
354 {
355 //     Glauber Calculation of geometrical x-section
356 //
357     Float_t xTot       = 0.;          // barn
358     Float_t xTotHard   = 0.;          // barn 
359     Float_t xPart      = 0.;          // barn
360     Float_t xPartHard  = 0.;          // barn 
361     Float_t sigmaHard  = 0.1;         // mbarn
362     Float_t bMin       = 0.;
363     Float_t bMax       = fHijing->GetHIPR1(34)+fHijing->GetHIPR1(35);
364     const Float_t kdib = 0.2;
365     Int_t   kMax       = Int_t((bMax-bMin)/kdib)+1;
366
367
368     printf("\n Projectile Radius (fm): %f \n",fHijing->GetHIPR1(34));
369     printf("\n Target     Radius (fm): %f \n",fHijing->GetHIPR1(35));    
370     Int_t i;
371     Float_t oldvalue= 0.;
372
373     Float_t* b   = new Float_t[kMax];
374     Float_t* si1 = new Float_t[kMax];    
375     Float_t* si2 = new Float_t[kMax];    
376     
377     for (i = 0; i < kMax; i++)
378     {
379         Float_t xb  = bMin+i*kdib;
380         Float_t ov;
381         ov=fHijing->Profile(xb);
382         Float_t gb  =  2.*0.01*fHijing->GetHIPR1(40)*kdib*xb*(1.-TMath::Exp(-fHijing->GetHINT1(12)*ov));
383         Float_t gbh =  2.*0.01*fHijing->GetHIPR1(40)*kdib*xb*sigmaHard*ov;
384         xTot+=gb;
385         xTotHard += gbh;
386         printf("profile %f %f %f\n", xb, ov, fHijing->GetHINT1(12));
387         
388         if (xb > fMinImpactParam && xb < fMaxImpactParam)
389         {
390             xPart += gb;
391             xPartHard += gbh;
392         }
393         
394         if(oldvalue) if ((xTot-oldvalue)/oldvalue<0.0001) break;
395         oldvalue = xTot;
396         printf("\n Total cross section (barn): %d %f %f \n",i, xb, xTot);
397         printf("\n Hard  cross section (barn): %d %f %f \n\n",i, xb, xTotHard);
398         if (i>0) {
399             si1[i] = gb/kdib;
400             si2[i] = gbh/gb;
401             b[i]  = xb;
402         }
403     }
404
405     printf("\n Total cross section (barn): %f \n",xTot);
406     printf("\n Hard  cross section (barn): %f \n \n",xTotHard);
407     printf("\n Partial       cross section (barn): %f %f \n",xPart, xPart/xTot*100.);
408     printf("\n Partial  hard cross section (barn): %f %f \n",xPartHard, xPartHard/xTotHard*100.);
409
410 //  Store result as a graph
411     b[0] = 0;
412     si1[0] = 0;
413     si2[0]=si2[1];
414     
415     fDsigmaDb  = new TGraph(i, b, si1);
416     fDnDb      = new TGraph(i, b, si2);
417 }
418
419 Bool_t AliGenHijing::DaughtersSelection(TParticle* iparticle)
420 {
421 //
422 // Looks recursively if one of the daughters has been selected
423 //
424 //    printf("\n Consider daughters %d:",iparticle->GetPdgCode());
425     Int_t imin = -1;
426     Int_t imax = -1;
427     Int_t i;
428     Bool_t hasDaughters = (iparticle->GetFirstDaughter() >=0);
429     Bool_t selected = kFALSE;
430     if (hasDaughters) {
431         imin = iparticle->GetFirstDaughter();
432         imax = iparticle->GetLastDaughter();       
433         for (i = imin; i <= imax; i++){
434             TParticle *  jparticle = (TParticle *) fParticles->At(i);   
435             Int_t ip = jparticle->GetPdgCode();
436             if (KinematicSelection(jparticle,0)&&SelectFlavor(ip)) {
437                 selected=kTRUE; break;
438             }
439             if (DaughtersSelection(jparticle)) {selected=kTRUE; break; }
440         }
441     } else {
442         return kFALSE;
443     }
444     return selected;
445 }
446
447
448 Bool_t AliGenHijing::SelectFlavor(Int_t pid)
449 {
450 // Select flavor of particle
451 // 0: all
452 // 4: charm and beauty
453 // 5: beauty
454     Bool_t res = 0;
455     
456     if (fFlavor == 0) {
457         res = kTRUE;
458     } else {
459         Int_t ifl = TMath::Abs(pid/100);
460         if (ifl > 10) ifl/=10;
461         res = (fFlavor == ifl);
462     }
463 //
464 //  This part if gamma writing is inhibited
465     if (fNoGammas) 
466         res = res && (pid != kGamma && pid != kPi0);
467 //
468     return res;
469 }
470
471 Bool_t AliGenHijing::Stable(TParticle*  particle) const
472 {
473 // Return true for a stable particle
474 //
475     
476     if (particle->GetFirstDaughter() < 0 )
477     {
478         return kTRUE;
479     } else {
480         return kFALSE;
481     }
482 }
483
484
485
486 void AliGenHijing::MakeHeader()
487 {
488 // Builds the event header, to be called after each event
489     AliGenEventHeader* header = new AliGenHijingEventHeader("Hijing");
490     ((AliGenHijingEventHeader*) header)->SetNProduced(fHijing->GetNATT());
491     ((AliGenHijingEventHeader*) header)->SetImpactParameter(fHijing->GetHINT1(19));
492     ((AliGenHijingEventHeader*) header)->SetTotalEnergy(fHijing->GetEATT());
493     ((AliGenHijingEventHeader*) header)->SetHardScatters(fHijing->GetJATT());
494     ((AliGenHijingEventHeader*) header)->SetParticipants(fHijing->GetNP(), fHijing->GetNT());
495     ((AliGenHijingEventHeader*) header)->SetCollisions(fHijing->GetN0(),
496                                                        fHijing->GetN01(),
497                                                        fHijing->GetN10(),
498                                                        fHijing->GetN11());
499     ((AliGenHijingEventHeader*) header)->SetSpectators(fProjectileSpecn, fProjectileSpecp,
500                                                        fTargetSpecn,fTargetSpecp);
501
502 // 4-momentum vectors of the triggered jets.
503 //
504 // Before final state gluon radiation.
505     TLorentzVector* jet1 = new TLorentzVector(fHijing->GetHINT1(21), 
506                                               fHijing->GetHINT1(22),
507                                               fHijing->GetHINT1(23),
508                                               fHijing->GetHINT1(24));
509
510     TLorentzVector* jet2 = new TLorentzVector(fHijing->GetHINT1(31), 
511                                               fHijing->GetHINT1(32),
512                                               fHijing->GetHINT1(33),
513                                               fHijing->GetHINT1(34));
514 // After final state gluon radiation.
515     TLorentzVector* jet3 = new TLorentzVector(fHijing->GetHINT1(26), 
516                                               fHijing->GetHINT1(27),
517                                               fHijing->GetHINT1(28),
518                                               fHijing->GetHINT1(29));
519
520     TLorentzVector* jet4 = new TLorentzVector(fHijing->GetHINT1(36), 
521                                               fHijing->GetHINT1(37),
522                                               fHijing->GetHINT1(38),
523                                               fHijing->GetHINT1(39));
524     ((AliGenHijingEventHeader*) header)->SetJets(jet1, jet2, jet3, jet4);
525 // Bookkeeping for kinematic bias
526     ((AliGenHijingEventHeader*) header)->SetTrials(fTrials);
527 // Event Vertex
528     header->SetPrimaryVertex(fVertex);
529     if (gAlice) gAlice->SetGenEventHeader(header);   
530     fCollisionGeometry = (AliGenHijingEventHeader*)  header;
531 }
532
533 Bool_t AliGenHijing::CheckTrigger()
534 {
535 // Check the kinematic trigger condition
536 //
537     Bool_t   triggered = kFALSE;
538  
539     if (fTrigger == 1) {
540 //
541 //  jet-jet Trigger     
542         
543         TLorentzVector* jet1 = new TLorentzVector(fHijing->GetHINT1(26), 
544                                                   fHijing->GetHINT1(27),
545                                                   fHijing->GetHINT1(28),
546                                                   fHijing->GetHINT1(29));
547         
548         TLorentzVector* jet2 = new TLorentzVector(fHijing->GetHINT1(36), 
549                                                   fHijing->GetHINT1(37),
550                                                   fHijing->GetHINT1(38),
551                                                   fHijing->GetHINT1(39));
552         Double_t eta1      = jet1->Eta();
553         Double_t eta2      = jet2->Eta();
554         Double_t phi1      = jet1->Phi();
555         Double_t phi2      = jet2->Phi();
556 //    printf("\n Trigger: %f %f %f %f",
557 //         fEtaMinJet, fEtaMaxJet, fPhiMinJet, fPhiMaxJet);
558         if (
559             (eta1 < fEtaMaxJet && eta1 > fEtaMinJet &&  
560              phi1 < fPhiMaxJet && phi1 > fPhiMinJet) 
561             ||
562             (eta2 < fEtaMaxJet && eta2 > fEtaMinJet &&  
563              phi2 < fPhiMaxJet && phi2 > fPhiMinJet)
564             ) 
565             triggered = kTRUE;
566     } else if (fTrigger == 2) {
567 //  Gamma Jet
568 //
569         Int_t np = fParticles->GetEntriesFast();
570         for (Int_t i = 0; i < np; i++) {
571             TParticle* part = (TParticle*) fParticles->At(i);
572             Int_t kf = part->GetPdgCode();
573             Int_t ks = part->GetStatusCode();
574             if (kf == 22 && ks == 40) {
575                 Float_t phi = part->Phi();
576                 Float_t eta = part->Eta();
577                 if  (eta < fEtaMaxJet && 
578                      eta > fEtaMinJet &&
579                      phi < fPhiMaxJet && 
580                      phi > fPhiMinJet) {
581                     triggered = 1;
582                     break;
583                 } // check phi,eta within limits
584             } // direct gamma ? 
585         } // particle loop
586     } // fTrigger == 2
587     return triggered;
588 }
589
590
591 void AliGenHijing::Copy(TObject &) const
592 {
593   Fatal("Copy","Not implemented!\n");
594 }
595
596 AliGenHijing& AliGenHijing::operator=(const  AliGenHijing& rhs)
597 {
598     rhs.Copy(*this); 
599     return (*this);
600 }
601