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