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 **************************************************************************/
17 // Generator using DPMJET as an external generator
18 // The main DPMJET options are accessable for the user through this interface.
19 // Uses the TDPMjet implementation of TGenerator.
24 #include <TParticle.h>
26 #include <TDatabasePDG.h>
27 #include <TParticlePDG.h>
28 #include <TParticleClassPDG.h>
30 #include <TLorentzVector.h>
31 #include <TClonesArray.h>
32 #include "AliRunLoader.h"
33 #include "AliGenDPMjet.h"
34 #include "AliGenDPMjetEventHeader.h"
36 #include "AliDpmJetRndm.h"
37 #include "AliHeader.h"
41 ClassImp(AliGenDPMjet)
43 //______________________________________________________________________________
44 AliGenDPMjet::AliGenDPMjet()
63 fTriggerMultiplicity(0),
64 fTriggerMultiplicityEta(0),
65 fTriggerMultiplicityPtMin(0),
71 AliDpmJetRndm::SetDpmJetRandom(GetRandom());
75 //______________________________________________________________________________
76 AliGenDPMjet::AliGenDPMjet(Int_t npart)
95 fTriggerMultiplicity(0),
96 fTriggerMultiplicityEta(0),
97 fTriggerMultiplicityPtMin(0),
101 // Default PbPb collisions at 5. 5 TeV
105 fTitle= "Particle Generator using DPMJET";
109 AliDpmJetRndm::SetDpmJetRandom(GetRandom());
112 AliGenDPMjet::AliGenDPMjet(const AliGenDPMjet &/*Dpmjet*/)
131 fTriggerMultiplicity(0),
132 fTriggerMultiplicityEta(0),
133 fTriggerMultiplicityPtMin(0),
137 // Dummy copy constructor
141 //______________________________________________________________________________
142 AliGenDPMjet::~AliGenDPMjet()
146 //______________________________________________________________________________
147 void AliGenDPMjet::Init()
151 SetMC(new TDPMjet(fProcess, fAProjectile, fZProjectile, fATarget, fZTarget,
152 fBeamEn,fEnergyCMS));
154 fDPMjet=(TDPMjet*) fMCEvGen;
156 // **** Flag to force central production
157 // fICentr=1. central production forced
158 // fICentr<0 && fICentr>-100 -> bmin = fMinImpactParam, bmax = fMaxImpactParam
159 // fICentr<-99 -> fraction of x-sec. = XSFRAC
160 // fICentr=-1. -> evaporation/fzc suppressed
161 // fICentr<-1. -> evaporation/fzc suppressed
162 if (fAProjectile == 1 && TMath::Abs(fZProjectile == 1)) fDPMjet->SetfIdp(1);
164 fDPMjet->SetfFCentr(fICentr);
165 fDPMjet->SetbRange(fMinImpactParam, fMaxImpactParam);
166 fDPMjet->SetPi0Decay(fPi0Decay);
167 fDPMjet->SetDecayAll(fDecayAll);
171 fDPMjet->Initialize();
175 //______________________________________________________________________________
176 void AliGenDPMjet::Generate()
178 // Generate one event
180 Double_t polar[3] = {0,0,0};
181 Double_t origin[3] = {0,0,0};
185 // converts from mm/c to s
186 const Float_t kconv = 0.001/2.999792458e8;
192 // Set collision vertex position
193 if (fVertexSmear == kPerEvent) Vertex();
197 // Generate one event
198 // --------------------------------------------------------------------------
201 // --------------------------------------------------------------------------
202 fDPMjet->GenerateEvent();
206 fDPMjet->ImportParticles(&fParticles,"All");
210 fGenImpPar = fDPMjet->GetBImpac();
212 if(TMath::Abs(fXingAngleY) > 1.e-10) BeamCrossAngle();
214 Int_t np = fParticles.GetEntriesFast();
216 // Multiplicity Trigger
217 if (fTriggerMultiplicity > 0) {
218 Int_t multiplicity = 0;
219 for (Int_t i = 0; i < np; i++) {
220 TParticle * iparticle = (TParticle *) fParticles.At(i);
222 Int_t statusCode = iparticle->GetStatusCode();
224 // Initial state particle
228 if (fTriggerMultiplicityEta > 0 && TMath::Abs(iparticle->Eta()) > fTriggerMultiplicityEta)
231 if (iparticle->Pt() < fTriggerMultiplicityPtMin)
234 TParticlePDG* pdgPart = iparticle->GetPDG();
235 if (pdgPart && pdgPart->Charge() == 0)
241 if (multiplicity < fTriggerMultiplicity) continue;
242 Printf("Triggered on event with multiplicity of %d >= %d", multiplicity, fTriggerMultiplicity);
246 if(fkTuneForDiff && (TMath::Abs(fEnergyCMS - 900) < 1)) {
247 if(!CheckDiffraction() ) continue;
252 if (np == 0) continue;
255 Int_t* newPos = new Int_t[np];
256 Int_t* pSelected = new Int_t[np];
258 for (i = 0; i<np; i++) {
263 // First select parent particles
265 for (i = 0; i<np; i++) {
266 TParticle *iparticle = (TParticle *) fParticles.At(i);
268 // Is this a parent particle ?
270 if (Stable(iparticle)) continue;
272 Bool_t selected = kTRUE;
273 Bool_t hasSelectedDaughters = kFALSE;
275 kf = iparticle->GetPdgCode();
276 if (kf == 92 || kf == 99999) continue;
277 ks = iparticle->GetStatusCode();
278 // No initial state partons
279 if (ks==21) continue;
281 if (!fSelectAll) selected = KinematicSelection(iparticle, 0) &&
285 hasSelectedDaughters = DaughtersSelection(iparticle);
288 // Put particle on the stack if it is either selected or
289 // it is the mother of at least one seleted particle
291 if (selected || hasSelectedDaughters) {
295 } // particle loop parents
297 // Now select the final state particles
300 for (i=0; i<np; i++) {
301 TParticle *iparticle = (TParticle *) fParticles.At(i);
303 // Is this a final state particle ?
305 if (!Stable(iparticle)) continue;
307 Bool_t selected = kTRUE;
308 kf = iparticle->GetPdgCode();
309 ks = iparticle->GetStatusCode();
311 // --------------------------------------------------------------------------
312 // Count spectator neutrons and protons (ks == 13, 14)
313 if(ks == 13 || ks == 14){
314 if(kf == kNeutron) fSpecn += 1;
315 if(kf == kProton) fSpecp += 1;
317 // --------------------------------------------------------------------------
320 selected = KinematicSelection(iparticle,0)&&SelectFlavor(kf);
321 if (!fSpectators && selected) selected = (ks == 13 || ks == 14);
324 // Put particle on the stack if selected
330 } // particle loop final state
332 // Write particles to stack
334 for (i = 0; i<np; i++) {
335 TParticle * iparticle = (TParticle *) fParticles.At(i);
336 Bool_t hasMother = (iparticle->GetFirstMother()>=0);
339 kf = iparticle->GetPdgCode();
340 ks = iparticle->GetStatusCode();
342 p[0] = iparticle->Px();
343 p[1] = iparticle->Py();
344 p[2] = iparticle->Pz();
345 p[3] = iparticle->Energy();
346 origin[0] = fVertex[0]+iparticle->Vx()/10; // [cm]
347 origin[1] = fVertex[1]+iparticle->Vy()/10; // [cm]
348 origin[2] = fVertex[2]+iparticle->Vz()/10; // [cm]
350 tof = fTime + kconv*iparticle->T();
353 TParticle* mother = 0;
355 imo = iparticle->GetFirstMother();
356 mother = (TParticle *) fParticles.At(imo);
357 imo = (mother->GetPdgCode() != 92 && mother->GetPdgCode() != 99999) ? newPos[imo] : -1;
362 Bool_t tFlag = (fTrackIt && (ks == 1));
363 PushTrack(tFlag, imo, kf,
364 p[0], p[1], p[2], p[3],
365 origin[0], origin[1], origin[2], tof,
366 polar[0], polar[1], polar[2],
367 kPNoProcess, nt, 1., ks);
376 if (jev >= fNpart || fNpart == -1) {
382 SetHighWaterMark(nt);
385 //______________________________________________________________________________
386 Bool_t AliGenDPMjet::DaughtersSelection(TParticle* iparticle)
389 // Looks recursively if one of the daughters has been selected
391 // printf("\n Consider daughters %d:",iparticle->GetPdgCode());
395 Bool_t hasDaughters = (iparticle->GetFirstDaughter() >=0);
396 Bool_t selected = kFALSE;
398 imin = iparticle->GetFirstDaughter();
399 imax = iparticle->GetLastDaughter();
400 for (i = imin; i <= imax; i++){
401 TParticle * jparticle = (TParticle *) fParticles.At(i);
402 Int_t ip = jparticle->GetPdgCode();
403 if (KinematicSelection(jparticle,0)&&SelectFlavor(ip)) {
404 selected=kTRUE; break;
406 if (DaughtersSelection(jparticle)) {selected=kTRUE; break; }
416 //______________________________________________________________________________
417 Bool_t AliGenDPMjet::SelectFlavor(Int_t pid)
419 // Select flavor of particle
421 // 4: charm and beauty
428 Int_t ifl = TMath::Abs(pid/100);
429 if (ifl > 10) ifl/=10;
430 res = (fFlavor == ifl);
433 // This part if gamma writing is inhibited
435 res = res && (pid != kGamma && pid != kPi0);
440 //______________________________________________________________________________
441 Bool_t AliGenDPMjet::Stable(TParticle* particle)
443 // Return true for a stable particle
446 // if (particle->GetFirstDaughter() < 0 ) return kTRUE;
447 if (particle->GetStatusCode() == 1) return kTRUE;
452 //______________________________________________________________________________
453 void AliGenDPMjet::MakeHeader()
455 // printf("MakeHeader %13.3f \n", fDPMjet->GetBImpac());
456 // Builds the event header, to be called after each event
457 AliGenEventHeader* header = new AliGenDPMjetEventHeader("DPMJET");
458 ((AliGenDPMjetEventHeader*) header)->SetNProduced(fDPMjet->GetNumStablePc());
459 ((AliGenDPMjetEventHeader*) header)->SetImpactParameter(fDPMjet->GetBImpac());
460 ((AliGenDPMjetEventHeader*) header)->SetTotalEnergy(fDPMjet->GetTotEnergy());
461 ((AliGenDPMjetEventHeader*) header)->SetParticipants(fDPMjet->GetProjParticipants(),
462 fDPMjet->GetTargParticipants());
465 ((AliGenDPMjetEventHeader*) header)->SetProcessType(fProcDiff);
468 ((AliGenDPMjetEventHeader*) header)->SetProcessType(fDPMjet->GetProcessCode());
470 // Bookkeeping for kinematic bias
471 ((AliGenDPMjetEventHeader*) header)->SetTrials(fTrials);
473 header->SetPrimaryVertex(fVertex);
474 header->SetInteractionTime(fTime);
475 gAlice->SetGenEventHeader(header);
479 void AliGenDPMjet::AddHeader(AliGenEventHeader* header)
481 // Add header to container or runloader
483 fContainer->AddHeader(header);
485 AliRunLoader::Instance()->GetHeader()->SetGenEventHeader(header);
490 //______________________________________________________________________________
491 AliGenDPMjet& AliGenDPMjet::operator=(const AliGenDPMjet& /*rhs*/)
493 // Assignment operator
498 void AliGenDPMjet::FinishRun()
500 // Print run statistics
501 fDPMjet->Dt_Dtuout();
506 Bool_t AliGenDPMjet::CheckDiffraction()
511 Int_t np = fParticles.GetEntriesFast();
519 const Int_t kNstable=20;
520 const Int_t pdgStable[20] = {
523 12, // Electron Neutrino
543 for (Int_t i = 0; i < np; i++) {
544 TParticle * part = (TParticle *) fParticles.At(i);
546 Int_t statusCode = part->GetStatusCode();
548 // Initial state particle
552 Int_t pdg = TMath::Abs(part->GetPdgCode());
553 Bool_t isStable = kFALSE;
554 for (Int_t i1 = 0; i1 < kNstable; i1++) {
555 if (pdg == pdgStable[i1]) {
563 Double_t y = part->Y();
577 if(iPart1<0 || iPart2<0) return kFALSE;
582 TParticle * part1 = (TParticle *) fParticles.At(iPart1);
583 TParticle * part2 = (TParticle *) fParticles.At(iPart2);
585 Int_t pdg1 = part1->GetPdgCode();
586 Int_t pdg2 = part2->GetPdgCode();
590 if (pdg1 == 2212 && pdg2 == 2212)
598 if((AliDpmJetRndm::GetDpmJetRandom())->Uniform(0.,1.)>0.5) iPart = iPart2;
601 else if (pdg1 == 2212)
603 else if (pdg2 == 2212)
612 TParticle * part = (TParticle *) fParticles.At(iPart);
613 Double_t E= part->Energy();
614 Double_t P= part->P();
615 M= TMath::Sqrt((fEnergyCMS-E-P)*(fEnergyCMS-E+P));
618 const Int_t nbin=120;
620 1.080000, 1.274258, 1.468516, 1.662773, 1.857031, 2.051289,
621 2.245547, 2.439805, 2.634062, 2.828320, 3.022578, 3.216836,
622 3.411094, 3.605352, 3.799609, 3.993867, 4.188125, 4.382383,
623 4.576641, 4.770898, 4.965156, 5.547930, 6.130703, 6.713477,
624 7.296250, 7.879023, 8.461797, 9.044570, 9.627344, 10.210117,
625 10.792891, 11.375664, 11.958437, 12.541211, 13.123984, 13.706758,
626 14.289531, 14.872305, 15.455078, 16.037852, 16.620625, 17.203398,
627 17.786172, 18.368945, 18.951719, 19.534492, 20.117266, 20.700039,
628 21.282812, 21.865586, 22.448359, 23.031133, 23.613906, 24.196680,
629 24.779453, 25.362227, 25.945000, 26.527773, 27.110547, 27.693320,
630 28.276094, 28.858867, 29.441641, 30.024414, 30.607187, 31.189961,
631 31.772734, 32.355508, 32.938281, 33.521055, 34.103828, 34.686602,
632 35.269375, 35.852148, 36.434922, 37.017695, 37.600469, 38.183242,
633 38.766016, 39.348789, 39.931562, 40.514336, 41.097109, 41.679883,
634 42.262656, 42.845430, 43.428203, 44.010977, 44.593750, 45.176523,
635 45.759297, 46.342070, 46.924844, 47.507617, 48.090391, 48.673164,
636 49.255937, 49.838711, 50.421484, 57.220508, 64.019531, 70.818555,
637 77.617578, 84.416602, 91.215625, 98.014648, 104.813672, 111.612695,
638 118.411719, 125.210742, 132.009766, 138.808789, 145.607812, 152.406836,
639 159.205859, 166.004883, 172.803906, 179.602930, 186.401953, 193.200977,
642 1.000000, 0.367136, 0.239268, 0.181139, 0.167470, 0.160072,
643 0.147832, 0.162765, 0.176103, 0.156382, 0.146040, 0.143375,
644 0.134038, 0.126747, 0.123152, 0.119424, 0.113839, 0.109433,
645 0.107180, 0.104690, 0.096427, 0.090603, 0.083706, 0.077206,
646 0.074603, 0.069698, 0.067315, 0.064980, 0.063560, 0.059573,
647 0.058712, 0.057581, 0.055944, 0.055442, 0.053272, 0.051769,
648 0.051672, 0.049284, 0.048980, 0.048797, 0.047434, 0.047039,
649 0.046395, 0.046227, 0.044288, 0.044743, 0.043772, 0.043902,
650 0.042771, 0.043232, 0.042222, 0.041668, 0.041988, 0.040858,
651 0.039672, 0.040069, 0.040274, 0.039438, 0.039903, 0.039083,
652 0.038741, 0.038182, 0.037664, 0.038610, 0.038759, 0.038688,
653 0.038039, 0.038220, 0.038145, 0.037445, 0.036765, 0.037333,
654 0.036753, 0.036405, 0.036339, 0.037659, 0.036139, 0.036706,
655 0.035393, 0.037136, 0.036570, 0.035234, 0.036832, 0.035560,
656 0.035509, 0.035579, 0.035100, 0.035471, 0.035421, 0.034494,
657 0.035596, 0.034935, 0.035810, 0.034324, 0.035355, 0.034323,
658 0.033486, 0.034622, 0.034805, 0.034419, 0.033946, 0.033927,
659 0.034224, 0.033942, 0.034088, 0.034190, 0.034620, 0.035294,
660 0.035650, 0.035378, 0.036028, 0.035933, 0.036753, 0.037171,
661 0.037528, 0.037985, 0.039589, 0.039359, 0.040269, 0.040755};
664 Double_t wDD=0.100418;
665 Double_t wND=0.050277;
667 if(M>-1 && M<bin[0]) return kFALSE;
668 if(M>bin[nbin]) M=-1;
670 Int_t procType=fDPMjet->GetProcessCode();//fPythia->GetMSTI(1);
672 if(procType== 7) proc0=1;
673 if(procType== 5 || procType== 6) proc0=0;
676 // printf("M = %f bin[nbin] = %f\n",M, bin[nbin]);
680 else if(proc0==1) proc=1;
682 if(proc==0 && (AliDpmJetRndm::GetDpmJetRandom())->Uniform(0.,1.) > wSD) return kFALSE;
683 if(proc==1 && (AliDpmJetRndm::GetDpmJetRandom())->Uniform(0.,1.) > wDD) return kFALSE;
684 if(proc==2 && (AliDpmJetRndm::GetDpmJetRandom())->Uniform(0.,1.) > wND) return kFALSE;
687 // if(proc==1 || proc==2) return kFALSE;
690 if(proc0!=0) fProcDiff = procType;
696 for(Int_t i=1; i<=nbin; i++)
699 // printf("Mi> %f && Mi< %f\n", bin[i-1], bin[i]);
703 // printf("w[ibin] = %f\n", w[ibin]);
705 if((AliDpmJetRndm::GetDpmJetRandom())->Uniform(0.,1.)> w[ibin]) return kFALSE;
707 // printf("iPart = %d\n", iPart);
709 if(iPart==iPart1) fProcDiff=5;
710 else if(iPart==iPart2) fProcDiff=6;
712 printf("EROOR: iPart!=iPart1 && iPart!=iPart2\n");
720 //______________________________________________________________________________