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 **************************************************************************/
19 // Generator using Herwig as an external generator
20 // The main Herwig options are accessable for the user through this interface.
21 // Uses the THerwig implementation of TGenerator.
24 #include <Riostream.h>
25 #include <TClonesArray.h>
26 #include <TParticle.h>
30 #include "AliGenHerwig.h"
31 #include "AliGenHerwigEventHeader.h"
32 #include "AliHerwigRndm.h"
40 ClassImp(AliGenHerwig)
43 AliGenHerwig::AliGenHerwig() :
72 fPhiMaxParton(2.* TMath::Pi()),
76 fPhiMaxGamma(2. * TMath::Pi()),
83 AliGenHerwig::AliGenHerwig(Int_t npart)
112 fPhiMaxParton(2.* TMath::Pi()),
116 fPhiMaxGamma(2. * TMath::Pi()),
123 // Set random number generator
124 AliHerwigRndm::SetHerwigRandom(GetRandom());
127 AliGenHerwig::~AliGenHerwig()
132 void AliGenHerwig::SetEventListRange(Int_t eventFirst, Int_t eventLast)
136 if ( fEv2Pr == -1 ) fEv2Pr = fEv1Pr;
139 void AliGenHerwig::Init()
143 fProjectile.Resize(8);
144 SetMC(new THerwig6());
145 fHerwig=(THerwig6*) fMCEvGen;
146 // initialize common blocks
147 fHerwig->Initialize(fProjectile.Data(), fTarget.Data(), fMomentum1, fMomentum2, fProcess); //
148 // reset parameters according to user needs
150 fHerwig->SetPTMIN(fPtHardMin);
151 fHerwig->SetPTMAX(fPtHardMax);
152 fHerwig->SetPTRMS(fPtRMS);
153 fHerwig->SetMAXPR(fMaxPr);
154 fHerwig->SetMAXER(fMaxErrors);
155 fHerwig->SetENSOF(fEnSoft);
156 // C---D,U,S,C,B,T QUARK AND GLUON MASSES (IN THAT ORDER)
165 fHerwig->SetRMASS(4,1.2);
166 fHerwig->SetRMASS(5,4.75);
168 if ( fProcess < 0 ) strncpy(VVJIN.QQIN,fFileName.Data(), 49);
170 //fHerwig->Hwusta("PI0 ");
172 // compute parameter dependent constants
173 fHerwig->PrepareRun();
176 void AliGenHerwig::InitJimmy()
180 fProjectile.Resize(8);
181 SetMC(new THerwig6());
182 fHerwig=(THerwig6*) fMCEvGen;
183 // initialize common blocks
184 fHerwig->InitializeJimmy(fProjectile, fTarget, fMomentum1, fMomentum2, fProcess);
185 // reset parameters according to user needs
187 fHerwig->SetPTMIN(fPtHardMin);
188 fHerwig->SetPTRMS(fPtRMS);
189 fHerwig->SetMAXPR(fMaxPr);
190 fHerwig->SetMAXER(fMaxErrors);
191 fHerwig->SetENSOF(fEnSoft);
193 // C---D,U,S,C,B,T QUARK AND GLUON MASSES (IN THAT ORDER)
202 fHerwig->SetRMASS(4,1.2);
203 fHerwig->SetRMASS(5,4.75);
205 if ( fProcess < 0 ) strncpy(VVJIN.QQIN,fFileName.Data(), 49);
207 // fHerwig->Hwusta("PI0 ");
209 // compute parameter dependent constants
210 fHerwig->PrepareRunJimmy();
213 void AliGenHerwig::InitPDF()
218 // ONLY USES LHAPDF STRUCTURE FUNCTIONS
259 // case kMRST2004nlo:
261 // fAutPDF="HWLHAPDF";
264 cerr << "This structure function is not inplemented " << fStrucFunc << endl;
268 fHerwig->SetMODPDF(1,fModPDF);
269 fHerwig->SetMODPDF(2,fModPDF);
270 fHerwig->SetAUTPDF(1,fAutPDF);
271 fHerwig->SetAUTPDF(2,fAutPDF);
274 void AliGenHerwig::Generate()
276 // Generate one event
278 Float_t polar[3] = {0,0,0};
279 Float_t origin[3] = {0,0,0};
282 static TClonesArray *particles;
283 // converts from mm/c to s
284 const Float_t kconv=0.001/2.999792458e8;
291 if(!particles) particles=new TClonesArray("TParticle",10000);
295 // Set collision vertex position
296 if (fVertexSmear == kPerEvent) Vertex();
300 fHerwig->GenerateEvent();
302 fHerwig->ImportParticles(particles,"All");
303 Int_t np = particles->GetEntriesFast()-1;
304 if (np == 0 ) continue;
306 //Check hard partons or direct gamma in kine range
308 if (fProcess == kHeJets || fProcess == kHeDirectGamma) {
309 TParticle* parton1 = (TParticle *) particles->At(6);
310 TParticle* parton2 = (TParticle *) particles->At(7);
311 if (!CheckParton(parton1, parton2)) continue ;
316 if (gAlice->GetEvNumber()>=fEv1Pr &&
317 gAlice->GetEvNumber()<=fEv2Pr) fHerwig->PrintEvt();
325 Int_t * newPos = new Int_t[np];
326 for (Int_t i = 0; i<np; i++) *(newPos+i)=-1;
328 for (Int_t i = 0; i<np; i++) {
329 TParticle * iparticle = (TParticle *) particles->At(i);
330 imo = iparticle->GetFirstMother();
331 kf = iparticle->GetPdgCode();
332 ks = iparticle->GetStatusCode();
334 KinematicSelection(iparticle,0))
337 p[0]=iparticle->Px();
338 p[1]=iparticle->Py();
339 p[2]=iparticle->Pz();
340 p[3]=iparticle->Energy();
342 origin[0] = fVertex[0] + iparticle->Vx()/10; // [cm]
343 origin[1] = fVertex[1] + iparticle->Vy()/10; // [cm]
344 origin[2] = fVertex[2] + iparticle->Vz()/10; // [cm]
346 Float_t tof = fTime + kconv*iparticle->T();
347 Int_t iparent = (imo > -1) ? newPos[imo] : -1;
348 Int_t trackIt = (ks == 1) && fTrackIt;
349 PushTrack(trackIt, iparent, kf,
350 p[0], p[1], p[2], p[3],
351 origin[0], origin[1], origin[2],
353 polar[0], polar[1], polar[2],
354 kPPrimary, nt, fHerwig->GetEVWGT(), ks);
358 } // end of if: selection of particle
359 } // end of for: particle loop
360 if (newPos) delete[] newPos;
363 if (jev >= fNpart || fNpart == -1) {
364 fKineBias=Float_t(fNpart)/Float_t(fTrials);
372 SetHighWaterMark(nt);
373 // adjust weight due to kinematic selection
376 fXsection=fHerwig->GetAVWGT();
377 //printf(">> trials << %d\n",fTrials);
380 Bool_t AliGenHerwig::CheckParton(const TParticle* parton1, const TParticle* parton2)
382 // Check the kinematic trigger condition
384 //Select events with parton max energy
385 if(fPtHardMax < parton1->Pt()) return kFALSE;
387 // Select events within angular window
389 eta[0] = parton1->Eta();
390 eta[1] = parton2->Eta();
392 phi[0] = parton1->Phi();
393 phi[1] = parton2->Phi();
395 pdg[0] = parton1->GetPdgCode();
396 pdg[1] = parton2->GetPdgCode();
397 printf("min %f, max %f\n",fPtHardMin, fPtHardMax);
398 printf("Parton 1: %s, pT= %2.2f, eta = %1.2f, phi = %2.2f\n", parton1->GetName(),parton1->Pt(), eta[0],phi[0]*TMath::RadToDeg());
399 printf("Parton 2: %s, pT= %2.2f, eta = %1.2f, phi = %2.2f\n", parton2->GetName(),parton2->Pt(), eta[1],phi[1]*TMath::RadToDeg());
401 if (fProcess == kHeJets) {
402 //Check if one of the 2 outgoing partons are in the eta-phi window
403 for(Int_t i = 0; i < 2; i++)
404 if ((eta[i] < fEtaMaxParton && eta[i] > fEtaMinParton) &&
405 (phi[i] < fPhiMaxParton && phi[i] > fPhiMinParton)) return kTRUE ;
409 //Check if the gamma and the jet are in the eta-phi window
412 if(pdg[0] == 22) ijj=1;
414 if ((eta[ijj] < fEtaMaxParton && eta[ijj] > fEtaMinParton) &&
415 (phi[ijj] < fPhiMaxParton && phi[ijj] > fPhiMinParton)) {
417 if ((eta[igj] < fEtaMaxGamma && eta[igj] > fEtaMinGamma) &&
418 (phi[igj] < fPhiMaxGamma && phi[igj] > fPhiMinGamma)) return kTRUE;
426 void AliGenHerwig::AdjustWeights()
428 // Adjust the weights after generation of all events
430 Int_t ntrack=gAlice->GetMCApp()->GetNtrack();
431 for (Int_t i=0; i<ntrack; i++) {
432 part= gAlice->GetMCApp()->Particle(i);
433 part->SetWeight(part->GetWeight()*fKineBias);
438 void AliGenHerwig::KeepFullEvent()
443 Bool_t AliGenHerwig::DaughtersSelection(const TParticle* iparticle, const TClonesArray* particles)
446 // Looks recursively if one of the daughters has been selected
448 // printf("\n Consider daughters %d:",iparticle->GetPdgCode());
452 Bool_t hasDaughters= (iparticle->GetFirstDaughter() >=0);
453 Bool_t selected=kFALSE;
455 imin=iparticle->GetFirstDaughter();
456 imax=iparticle->GetLastDaughter();
457 for (i=imin; i<= imax; i++){
458 TParticle * jparticle = (TParticle *) particles->At(i);
459 Int_t ip=jparticle->GetPdgCode();
460 if (KinematicSelection(jparticle,0)&&SelectFlavor(ip)) {
461 selected=kTRUE; break;
463 if (DaughtersSelection(jparticle, particles)) {selected=kTRUE; break; }
473 Bool_t AliGenHerwig::SelectFlavor(Int_t pid) const
475 // Select flavor of particle
477 // 4: charm and beauty
479 if (fFlavor == 0) return kTRUE;
481 Int_t ifl=TMath::Abs(pid/100);
482 if (ifl > 10) ifl/=10;
483 return (fFlavor == ifl);
486 Bool_t AliGenHerwig::Stable(const TParticle* particle) const
488 // Return true for a stable particle
490 Int_t kf = TMath::Abs(particle->GetPdgCode());
492 if ( (particle->GetFirstDaughter() < 0 ) || (kf == 1000*fFlavor+122))
501 void AliGenHerwig::FinishRun()
506 void AliGenHerwig::FinishRunJimmy()
514 void AliGenHerwig::MakeHeader()
517 // Make header for the simulated event
519 if (fHeader) delete fHeader;
520 fHeader = new AliGenHerwigEventHeader("Herwig");
523 ((AliGenHerwigEventHeader*) fHeader)->SetProcessType(fHerwig->GetIHPRO());
526 ((AliGenHerwigEventHeader*) fHeader)->SetTrials(fTrials);
528 // Event weight (cross section)
529 ((AliGenHerwigEventHeader*) fHeader)->SetWeight(fHerwig->GetEVWGT());
532 fHeader->SetPrimaryVertex(fVertex);
533 fHeader->SetInteractionTime(fTime);
535 // Number of primaries
536 fHeader->SetNProduced(fNprimaries);