]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PYTHIA6/AliGenPythia.cxx
Coding conventions (Annalisa)
[u/mrichter/AliRoot.git] / PYTHIA6 / AliGenPythia.cxx
CommitLineData
8d2cd130 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
7cdba479 16/* $Id$ */
8d2cd130 17
18//
19// Generator using the TPythia interface (via AliPythia)
20// to generate pp collisions.
21// Using SetNuclei() also nuclear modifications to the structure functions
22// can be taken into account. This makes, of course, only sense for the
23// generation of the products of hard processes (heavy flavor, jets ...)
24//
25// andreas.morsch@cern.ch
26//
27
28#include <TDatabasePDG.h>
29#include <TParticle.h>
30#include <TPDGCode.h>
31#include <TSystem.h>
32#include <TTree.h>
8d2cd130 33#include "AliConst.h"
34#include "AliDecayerPythia.h"
35#include "AliGenPythia.h"
5fa4b20b 36#include "AliHeader.h"
8d2cd130 37#include "AliGenPythiaEventHeader.h"
38#include "AliPythia.h"
7cdba479 39#include "AliPythiaRndm.h"
8d2cd130 40#include "AliRun.h"
7ea3ea5b 41#include "AliStack.h"
42#include "AliRunLoader.h"
5d12ce38 43#include "AliMC.h"
7c21f297 44#include "pyquenCommon.h"
8d2cd130 45
014a9521 46ClassImp(AliGenPythia)
8d2cd130 47
48AliGenPythia::AliGenPythia()
49 :AliGenMC()
50{
51// Default Constructor
52 fParticles = 0;
53 fPythia = 0;
e5c87a3d 54 fHeader = 0;
5fffd0fe 55 fReadFromFile = 0;
f913ec4f 56 fEventTime = 0.;
8ec89232 57 fInteractionRate = 0.;
9d7108a7 58 fTimeWindow = 0.;
59 fEventsTime = 0;
60 fCurSubEvent = 0;
8d2cd130 61 fDecayer = new AliDecayerPythia();
62 SetEventListRange();
63 SetJetPhiRange();
64 SetJetEtaRange();
65 SetJetEtRange();
66 SetGammaPhiRange();
67 SetGammaEtaRange();
68 SetPtKick();
7ea3ea5b 69 SetQuench();
5fa4b20b 70 SetHadronisation();
e0e89f40 71 SetTriggerParticle();
1d568bc2 72 fSetNuclei = kFALSE;
beac474c 73 fNewMIS = kFALSE;
74 fHFoff = kFALSE;
7cdba479 75 if (!AliPythiaRndm::GetPythiaRandom())
76 AliPythiaRndm::SetPythiaRandom(GetRandom());
8d2cd130 77}
78
79AliGenPythia::AliGenPythia(Int_t npart)
80 :AliGenMC(npart)
81{
82// default charm production at 5. 5 TeV
83// semimuonic decay
84// structure function GRVHO
85//
86 fName = "Pythia";
87 fTitle= "Particle Generator using PYTHIA";
88 fXsection = 0.;
5fffd0fe 89 fReadFromFile = 0;
f913ec4f 90 fEventTime = 0.;
8ec89232 91 fInteractionRate = 0.;
9d7108a7 92 fTimeWindow = 0.;
93 fEventsTime = 0;
94 fCurSubEvent = 0;
8d2cd130 95 SetProcess();
96 SetStrucFunc();
97 SetForceDecay();
98 SetPtHard();
99 SetYHard();
100 SetEnergyCMS();
101 fDecayer = new AliDecayerPythia();
102 // Set random number generator
7cdba479 103 if (!AliPythiaRndm::GetPythiaRandom())
104 AliPythiaRndm::SetPythiaRandom(GetRandom());
8d2cd130 105 fFlavorSelect = 0;
106 // Produced particles
107 fParticles = new TClonesArray("TParticle",1000);
e5c87a3d 108 fHeader = 0;
8d2cd130 109 SetEventListRange();
110 SetJetPhiRange();
111 SetJetEtaRange();
112 SetJetEtRange();
113 SetGammaPhiRange();
114 SetGammaEtaRange();
115 SetJetReconstructionMode();
7ea3ea5b 116 SetQuench();
5fa4b20b 117 SetHadronisation();
8d2cd130 118 SetPtKick();
e0e89f40 119 SetTriggerParticle();
8d2cd130 120 // Options determining what to keep in the stack (Heavy flavour generation)
121 fStackFillOpt = kFlavorSelection; // Keep particle with selected flavor
122 fFeedDownOpt = kTRUE; // allow feed down from higher family
123 // Fragmentation on/off
124 fFragmentation = kTRUE;
125 // Default counting mode
126 fCountMode = kCountAll;
592f8307 127 // Pycel
128 SetPycellParameters();
1d568bc2 129 fSetNuclei = kFALSE;
beac474c 130 fNewMIS = kFALSE;
131 fHFoff = kFALSE;
8d2cd130 132}
133
134AliGenPythia::AliGenPythia(const AliGenPythia & Pythia)
f936b8ea 135 :AliGenMC(Pythia)
8d2cd130 136{
137// copy constructor
138 Pythia.Copy(*this);
139}
140
141AliGenPythia::~AliGenPythia()
142{
143// Destructor
9d7108a7 144 if(fEventsTime) delete fEventsTime;
145}
146
147void AliGenPythia::SetInteractionRate(Float_t rate,Float_t timewindow)
148{
149// Generate pileup using user specified rate
150 fInteractionRate = rate;
151 fTimeWindow = timewindow;
152 GeneratePileup();
153}
154
155void AliGenPythia::GeneratePileup()
156{
157// Generate sub events time for pileup
158 fEventsTime = 0;
159 if(fInteractionRate == 0.) {
160 Warning("GeneratePileup","Zero interaction specified. Skipping pileup generation.\n");
161 return;
162 }
163
164 Int_t npart = NumberParticles();
165 if(npart < 0) {
166 Warning("GeneratePileup","Negative number of particles. Skipping pileup generation.\n");
167 return;
168 }
169
170 if(fEventsTime) delete fEventsTime;
171 fEventsTime = new TArrayF(npart);
172 TArrayF &array = *fEventsTime;
173 for(Int_t ipart = 0; ipart < npart; ipart++)
174 array[ipart] = 0.;
175
176 Float_t eventtime = 0.;
177 while(1)
178 {
179 eventtime += (AliPythiaRndm::GetPythiaRandom())->Exp(1./fInteractionRate);
180 if(eventtime > fTimeWindow) break;
181 array.Set(array.GetSize()+1);
182 array[array.GetSize()-1] = eventtime;
183 }
184
185 eventtime = 0.;
186 while(1)
187 {
188 eventtime -= (AliPythiaRndm::GetPythiaRandom())->Exp(1./fInteractionRate);
189 if(TMath::Abs(eventtime) > fTimeWindow) break;
190 array.Set(array.GetSize()+1);
191 array[array.GetSize()-1] = eventtime;
192 }
193
194 SetNumberParticles(fEventsTime->GetSize());
8d2cd130 195}
196
592f8307 197void AliGenPythia::SetPycellParameters(Float_t etamax, Int_t neta, Int_t nphi,
198 Float_t thresh, Float_t etseed, Float_t minet, Float_t r)
199{
200// Set pycell parameters
201 fPycellEtaMax = etamax;
202 fPycellNEta = neta;
203 fPycellNPhi = nphi;
204 fPycellThreshold = thresh;
205 fPycellEtSeed = etseed;
206 fPycellMinEtJet = minet;
207 fPycellMaxRadius = r;
208}
209
210
211
8d2cd130 212void AliGenPythia::SetEventListRange(Int_t eventFirst, Int_t eventLast)
213{
214 // Set a range of event numbers, for which a table
215 // of generated particle will be printed
216 fDebugEventFirst = eventFirst;
217 fDebugEventLast = eventLast;
218 if (fDebugEventLast==-1) fDebugEventLast=fDebugEventFirst;
219}
220
221void AliGenPythia::Init()
222{
223// Initialisation
224
225 SetMC(AliPythia::Instance());
b88f5cea 226 fPythia=(AliPythia*) fMCEvGen;
e2bddf81 227
8d2cd130 228//
229 fParentWeight=1./Float_t(fNpart);
230//
231// Forward Paramters to the AliPythia object
232 fDecayer->SetForceDecay(fForceDecay);
233 fDecayer->Init();
234
235
236 fPythia->SetCKIN(3,fPtHardMin);
237 fPythia->SetCKIN(4,fPtHardMax);
238 fPythia->SetCKIN(7,fYHardMin);
239 fPythia->SetCKIN(8,fYHardMax);
240
1a626d4e 241 if (fAProjectile > 0 && fATarget > 0) fPythia->SetNuclei(fAProjectile, fATarget);
8d2cd130 242 // Fragmentation?
243 if (fFragmentation) {
244 fPythia->SetMSTP(111,1);
245 } else {
246 fPythia->SetMSTP(111,0);
247 }
248
249
250// initial state radiation
251 fPythia->SetMSTP(61,fGinit);
252// final state radiation
253 fPythia->SetMSTP(71,fGfinal);
254// pt - kick
255 if (fPtKick > 0.) {
256 fPythia->SetMSTP(91,1);
257 fPythia->SetPARP(91,fPtKick);
258 } else {
259 fPythia->SetMSTP(91,0);
260 }
261
5fa4b20b 262
263 if (fReadFromFile) {
264 fRL = AliRunLoader::Open(fFileName, "Partons");
265 fRL->LoadKinematics();
266 fRL->LoadHeader();
267 } else {
268 fRL = 0x0;
269 }
beac474c 270// Switch off Heavy Flavors on request
271 if (fHFoff) {
272 fPythia->SetMSTP(58, 3);
273 fPythia->SetMSTJ(45, 3);
274 for (Int_t i = 156; i <= 160; i++) fPythia->SetMDME(i, 1, 0);
275 }
8d2cd130 276 //
277 fPythia->ProcInit(fProcess,fEnergyCMS,fStrucFunc);
278
279// Parent and Children Selection
280 switch (fProcess)
281 {
65f2626c 282 case kPyOldUEQ2ordered:
283 case kPyOldUEQ2ordered2:
284 case kPyOldPopcorn:
285 break;
8d2cd130 286 case kPyCharm:
287 case kPyCharmUnforced:
adf4d898 288 case kPyCharmPbPbMNR:
aabc7187 289 case kPyCharmpPbMNR:
e0e89f40 290 case kPyCharmppMNR:
291 case kPyCharmppMNRwmi:
8d2cd130 292 fParentSelect[0] = 411;
293 fParentSelect[1] = 421;
294 fParentSelect[2] = 431;
295 fParentSelect[3] = 4122;
296 fFlavorSelect = 4;
297 break;
adf4d898 298 case kPyD0PbPbMNR:
299 case kPyD0pPbMNR:
300 case kPyD0ppMNR:
8d2cd130 301 fParentSelect[0] = 421;
302 fFlavorSelect = 4;
303 break;
90d7b703 304 case kPyDPlusPbPbMNR:
305 case kPyDPluspPbMNR:
306 case kPyDPlusppMNR:
307 fParentSelect[0] = 411;
308 fFlavorSelect = 4;
309 break;
e0e89f40 310 case kPyDPlusStrangePbPbMNR:
311 case kPyDPlusStrangepPbMNR:
312 case kPyDPlusStrangeppMNR:
313 fParentSelect[0] = 431;
314 fFlavorSelect = 4;
315 break;
8d2cd130 316 case kPyBeauty:
adf4d898 317 case kPyBeautyPbPbMNR:
318 case kPyBeautypPbMNR:
319 case kPyBeautyppMNR:
e0e89f40 320 case kPyBeautyppMNRwmi:
8d2cd130 321 fParentSelect[0]= 511;
322 fParentSelect[1]= 521;
323 fParentSelect[2]= 531;
324 fParentSelect[3]= 5122;
325 fParentSelect[4]= 5132;
326 fParentSelect[5]= 5232;
327 fParentSelect[6]= 5332;
328 fFlavorSelect = 5;
329 break;
330 case kPyBeautyUnforced:
331 fParentSelect[0] = 511;
332 fParentSelect[1] = 521;
333 fParentSelect[2] = 531;
334 fParentSelect[3] = 5122;
335 fParentSelect[4] = 5132;
336 fParentSelect[5] = 5232;
337 fParentSelect[6] = 5332;
338 fFlavorSelect = 5;
339 break;
340 case kPyJpsiChi:
341 case kPyJpsi:
342 fParentSelect[0] = 443;
343 break;
344 case kPyMb:
345 case kPyMbNonDiffr:
d7de4a67 346 case kPyMbMSEL1:
8d2cd130 347 case kPyJets:
348 case kPyDirectGamma:
349 break;
589380c6 350 case kPyW:
0f6ee828 351 case kPyZ:
589380c6 352 break;
8d2cd130 353 }
354//
592f8307 355//
356// JetFinder for Trigger
357//
358// Configure detector (EMCAL like)
359//
d7de4a67 360 fPythia->SetPARU(51, fPycellEtaMax);
361 fPythia->SetMSTU(51, fPycellNEta);
362 fPythia->SetMSTU(52, fPycellNPhi);
592f8307 363//
364// Configure Jet Finder
365//
d7de4a67 366 fPythia->SetPARU(58, fPycellThreshold);
367 fPythia->SetPARU(52, fPycellEtSeed);
368 fPythia->SetPARU(53, fPycellMinEtJet);
369 fPythia->SetPARU(54, fPycellMaxRadius);
370 fPythia->SetMSTU(54, 2);
592f8307 371//
8d2cd130 372// This counts the total number of calls to Pyevnt() per run.
373 fTrialsRun = 0;
374 fQ = 0.;
375 fX1 = 0.;
376 fX2 = 0.;
377 fNev = 0 ;
378//
1d568bc2 379//
380//
8d2cd130 381 AliGenMC::Init();
1d568bc2 382//
383//
384//
385 if (fSetNuclei) {
386 fDyBoost = 0;
387 Warning("Init","SetNuclei used. Use SetProjectile + SetTarget instead. fDyBoost has been reset to 0\n");
388 }
d7de4a67 389
32d6ef7d 390 if (fQuench) {
5fa4b20b 391 fPythia->InitQuenching(0., 0.1, 0.6e6, 0);
32d6ef7d 392 }
8d2cd130 393}
394
395void AliGenPythia::Generate()
396{
397// Generate one event
e5c87a3d 398
8d2cd130 399 fDecayer->ForceDecay();
400
401 Float_t polar[3] = {0,0,0};
402 Float_t origin[3] = {0,0,0};
a920faf9 403 Float_t p[4];
8d2cd130 404// converts from mm/c to s
405 const Float_t kconv=0.001/2.999792458e8;
406//
407 Int_t nt=0;
408 Int_t jev=0;
409 Int_t j, kf;
410 fTrials=0;
f913ec4f 411 fEventTime = 0.;
412
2590ccf9 413
8d2cd130 414
415 // Set collision vertex position
2590ccf9 416 if (fVertexSmear == kPerEvent) Vertex();
417
8d2cd130 418// event loop
419 while(1)
420 {
32d6ef7d 421//
5fa4b20b 422// Produce event
32d6ef7d 423//
32d6ef7d 424//
5fa4b20b 425// Switch hadronisation off
426//
427 fPythia->SetMSTJ(1, 0);
32d6ef7d 428//
5fa4b20b 429// Either produce new event or read partons from file
430//
431 if (!fReadFromFile) {
beac474c 432 if (!fNewMIS) {
433 fPythia->Pyevnt();
434 } else {
435 fPythia->Pyevnw();
436 }
5fa4b20b 437 fNpartons = fPythia->GetN();
438 } else {
439 printf("Loading Event %d\n",AliRunLoader::GetRunLoader()->GetEventNumber());
440 fRL->GetEvent(AliRunLoader::GetRunLoader()->GetEventNumber());
441 fPythia->SetN(0);
442 LoadEvent(fRL->Stack(), 0 , 1);
443 fPythia->Pyedit(21);
444 }
445
32d6ef7d 446//
447// Run quenching routine
448//
5fa4b20b 449 if (fQuench == 1) {
450 fPythia->Quench();
451 } else if (fQuench == 2){
452 fPythia->Pyquen(208., 0, 0.);
453 }
32d6ef7d 454//
5fa4b20b 455// Switch hadronisation on
32d6ef7d 456//
aea21c57 457 fPythia->SetMSTJ(1, 1);
5fa4b20b 458//
459// .. and perform hadronisation
aea21c57 460// printf("Calling hadronisation %d\n", fPythia->GetN());
5fa4b20b 461 fPythia->Pyexec();
8d2cd130 462 fTrials++;
8d2cd130 463 fPythia->ImportParticles(fParticles,"All");
1d568bc2 464 Boost();
8d2cd130 465//
466//
467//
468 Int_t i;
469
5fa4b20b 470
8d2cd130 471 Int_t np = fParticles->GetEntriesFast();
5fa4b20b 472
7c21f297 473 if (np == 0) continue;
8d2cd130 474//
2590ccf9 475
8d2cd130 476//
477 Int_t* pParent = new Int_t[np];
478 Int_t* pSelected = new Int_t[np];
479 Int_t* trackIt = new Int_t[np];
5fa4b20b 480 for (i = 0; i < np; i++) {
8d2cd130 481 pParent[i] = -1;
482 pSelected[i] = 0;
483 trackIt[i] = 0;
484 }
485
486 Int_t nc = 0; // Total n. of selected particles
487 Int_t nParents = 0; // Selected parents
488 Int_t nTkbles = 0; // Trackable particles
489 if (fProcess != kPyMb && fProcess != kPyJets &&
490 fProcess != kPyDirectGamma &&
589380c6 491 fProcess != kPyMbNonDiffr &&
d7de4a67 492 fProcess != kPyMbMSEL1 &&
e0e89f40 493 fProcess != kPyW && fProcess != kPyZ &&
494 fProcess != kPyCharmppMNRwmi && fProcess != kPyBeautyppMNRwmi) {
8d2cd130 495
5fa4b20b 496 for (i = 0; i < np; i++) {
2590ccf9 497 TParticle* iparticle = (TParticle *) fParticles->At(i);
8d2cd130 498 Int_t ks = iparticle->GetStatusCode();
499 kf = CheckPDGCode(iparticle->GetPdgCode());
500// No initial state partons
501 if (ks==21) continue;
502//
503// Heavy Flavor Selection
504//
505 // quark ?
506 kf = TMath::Abs(kf);
507 Int_t kfl = kf;
9ff6c04c 508 // Resonance
f913ec4f 509
9ff6c04c 510 if (kfl > 100000) kfl %= 100000;
183a5ca9 511 if (kfl > 10000) kfl %= 10000;
8d2cd130 512 // meson ?
513 if (kfl > 10) kfl/=100;
514 // baryon
515 if (kfl > 10) kfl/=10;
8d2cd130 516 Int_t ipa = iparticle->GetFirstMother()-1;
517 Int_t kfMo = 0;
f913ec4f 518//
519// Establish mother daughter relation between heavy quarks and mesons
520//
521 if (kf >= fFlavorSelect && kf <= 6) {
522 Int_t idau = iparticle->GetFirstDaughter() - 1;
523 if (idau > -1) {
524 TParticle* daughter = (TParticle *) fParticles->At(idau);
525 Int_t pdgD = daughter->GetPdgCode();
526 if (pdgD == 91 || pdgD == 92) {
527 Int_t jmin = daughter->GetFirstDaughter() - 1;
528 Int_t jmax = daughter->GetLastDaughter() - 1;
529 for (Int_t j = jmin; j <= jmax; j++)
530 ((TParticle *) fParticles->At(j))->SetFirstMother(i+1);
531 } // is string or cluster
532 } // has daughter
533 } // heavy quark
8d2cd130 534
f913ec4f 535
8d2cd130 536 if (ipa > -1) {
537 TParticle * mother = (TParticle *) fParticles->At(ipa);
538 kfMo = TMath::Abs(mother->GetPdgCode());
539 }
f913ec4f 540
8d2cd130 541 // What to keep in Stack?
542 Bool_t flavorOK = kFALSE;
543 Bool_t selectOK = kFALSE;
544 if (fFeedDownOpt) {
32d6ef7d 545 if (kfl >= fFlavorSelect) flavorOK = kTRUE;
8d2cd130 546 } else {
32d6ef7d 547 if (kfl > fFlavorSelect) {
548 nc = -1;
549 break;
550 }
551 if (kfl == fFlavorSelect) flavorOK = kTRUE;
8d2cd130 552 }
553 switch (fStackFillOpt) {
554 case kFlavorSelection:
32d6ef7d 555 selectOK = kTRUE;
556 break;
8d2cd130 557 case kParentSelection:
32d6ef7d 558 if (ParentSelected(kf) || kf <= 10) selectOK = kTRUE;
559 break;
8d2cd130 560 }
561 if (flavorOK && selectOK) {
562//
563// Heavy flavor hadron or quark
564//
565// Kinematic seletion on final state heavy flavor mesons
566 if (ParentSelected(kf) && !KinematicSelection(iparticle, 0))
567 {
9ff6c04c 568 continue;
8d2cd130 569 }
570 pSelected[i] = 1;
571 if (ParentSelected(kf)) ++nParents; // Update parent count
572// printf("\n particle (HF) %d %d %d", i, pSelected[i], kf);
573 } else {
574// Kinematic seletion on decay products
575 if (fCutOnChild && ParentSelected(kfMo) && ChildSelected(kf)
9ff6c04c 576 && !KinematicSelection(iparticle, 1))
8d2cd130 577 {
9ff6c04c 578 continue;
8d2cd130 579 }
580//
581// Decay products
582// Select if mother was selected and is not tracked
583
584 if (pSelected[ipa] &&
585 !trackIt[ipa] && // mother will be tracked ?
586 kfMo != 5 && // mother is b-quark, don't store fragments
587 kfMo != 4 && // mother is c-quark, don't store fragments
588 kf != 92) // don't store string
589 {
590//
591// Semi-stable or de-selected: diselect decay products:
592//
593//
594 if (pSelected[i] == -1 || fDecayer->GetLifetime(kf) > fMaxLifeTime)
595 {
596 Int_t ipF = iparticle->GetFirstDaughter();
597 Int_t ipL = iparticle->GetLastDaughter();
598 if (ipF > 0) for (j = ipF-1; j < ipL; j++) pSelected[j] = -1;
599 }
600// printf("\n particle (decay) %d %d %d", i, pSelected[i], kf);
601 pSelected[i] = (pSelected[i] == -1) ? 0 : 1;
602 }
603 }
604 if (pSelected[i] == -1) pSelected[i] = 0;
605 if (!pSelected[i]) continue;
606 // Count quarks only if you did not include fragmentation
607 if (fFragmentation && kf <= 10) continue;
9ff6c04c 608
8d2cd130 609 nc++;
610// Decision on tracking
611 trackIt[i] = 0;
612//
613// Track final state particle
614 if (ks == 1) trackIt[i] = 1;
615// Track semi-stable particles
d25cfd65 616 if ((ks == 1) || (fDecayer->GetLifetime(kf) > fMaxLifeTime)) trackIt[i] = 1;
8d2cd130 617// Track particles selected by process if undecayed.
618 if (fForceDecay == kNoDecay) {
619 if (ParentSelected(kf)) trackIt[i] = 1;
620 } else {
621 if (ParentSelected(kf)) trackIt[i] = 0;
622 }
623 if (trackIt[i] == 1) ++nTkbles; // Update trackable counter
624//
625//
626
627 } // particle selection loop
628 if (nc > 0) {
629 for (i = 0; i<np; i++) {
630 if (!pSelected[i]) continue;
631 TParticle * iparticle = (TParticle *) fParticles->At(i);
632 kf = CheckPDGCode(iparticle->GetPdgCode());
633 Int_t ks = iparticle->GetStatusCode();
634 p[0] = iparticle->Px();
635 p[1] = iparticle->Py();
636 p[2] = iparticle->Pz();
a920faf9 637 p[3] = iparticle->Energy();
638
2590ccf9 639 origin[0] = fVertex[0]+iparticle->Vx()/10; // [cm]
640 origin[1] = fVertex[1]+iparticle->Vy()/10; // [cm]
641 origin[2] = fVertex[2]+iparticle->Vz()/10; // [cm]
642
8d2cd130 643 Float_t tof = kconv*iparticle->T();
644 Int_t ipa = iparticle->GetFirstMother()-1;
645 Int_t iparent = (ipa > -1) ? pParent[ipa] : -1;
a920faf9 646
647 PushTrack(fTrackIt*trackIt[i], iparent, kf,
648 p[0], p[1], p[2], p[3],
649 origin[0], origin[1], origin[2], tof,
650 polar[0], polar[1], polar[2],
651 kPPrimary, nt, 1., ks);
8d2cd130 652 pParent[i] = nt;
653 KeepTrack(nt);
642f15cf 654 } // PushTrack loop
8d2cd130 655 }
656 } else {
657 nc = GenerateMB();
658 } // mb ?
f913ec4f 659
660 GetSubEventTime();
8d2cd130 661
662 if (pParent) delete[] pParent;
663 if (pSelected) delete[] pSelected;
664 if (trackIt) delete[] trackIt;
665
666 if (nc > 0) {
667 switch (fCountMode) {
668 case kCountAll:
669 // printf(" Count all \n");
670 jev += nc;
671 break;
672 case kCountParents:
673 // printf(" Count parents \n");
674 jev += nParents;
675 break;
676 case kCountTrackables:
677 // printf(" Count trackable \n");
678 jev += nTkbles;
679 break;
680 }
681 if (jev >= fNpart || fNpart == -1) {
682 fKineBias=Float_t(fNpart)/Float_t(fTrials);
e0e89f40 683
8d2cd130 684 fQ += fPythia->GetVINT(51);
685 fX1 += fPythia->GetVINT(41);
686 fX2 += fPythia->GetVINT(42);
687 fTrialsRun += fTrials;
688 fNev++;
689 MakeHeader();
690 break;
691 }
692 }
693 } // event loop
694 SetHighWaterMark(nt);
695// adjust weight due to kinematic selection
b88f5cea 696// AdjustWeights();
8d2cd130 697// get cross-section
698 fXsection=fPythia->GetPARI(1);
699}
700
701Int_t AliGenPythia::GenerateMB()
702{
703//
704// Min Bias selection and other global selections
705//
706 Int_t i, kf, nt, iparent;
707 Int_t nc = 0;
bf950da8 708 Float_t p[4];
8d2cd130 709 Float_t polar[3] = {0,0,0};
710 Float_t origin[3] = {0,0,0};
711// converts from mm/c to s
712 const Float_t kconv=0.001/2.999792458e8;
713
e0e89f40 714
715
5fa4b20b 716 Int_t np = (fHadronisation) ? fParticles->GetEntriesFast() : fNpartons;
aea21c57 717
5fa4b20b 718
e0e89f40 719
8d2cd130 720 Int_t* pParent = new Int_t[np];
721 for (i=0; i< np; i++) pParent[i] = -1;
722 if (fProcess == kPyJets || fProcess == kPyDirectGamma) {
723 TParticle* jet1 = (TParticle *) fParticles->At(6);
724 TParticle* jet2 = (TParticle *) fParticles->At(7);
aea21c57 725 if (!CheckTrigger(jet1, jet2)) return 0;
8d2cd130 726 }
e0e89f40 727
7ce1321b 728 if (fTriggerParticle) {
729 Bool_t triggered = kFALSE;
730 for (i = 0; i < np; i++) {
731 TParticle * iparticle = (TParticle *) fParticles->At(i);
732 kf = CheckPDGCode(iparticle->GetPdgCode());
38db0ee6 733 if (kf != fTriggerParticle) continue;
7ce1321b 734 if (iparticle->Pt() == 0.) continue;
735 if (TMath::Abs(iparticle->Eta()) > fTriggerEta) continue;
736 triggered = kTRUE;
737 break;
738 }
739 if (!triggered) return 0;
740 }
e0e89f40 741
742
743 // Check if there is a ccbar or bbbar pair with at least one of the two
744 // in fYMin < y < fYMax
745 if (fProcess == kPyCharmppMNRwmi || fProcess == kPyBeautyppMNRwmi) {
746 TParticle *hvq;
747 Bool_t theQ=kFALSE,theQbar=kFALSE,inYcut=kFALSE;
748 Float_t yQ;
749 Int_t pdgQ;
750 for(i=0; i<np; i++) {
751 hvq = (TParticle*)fParticles->At(i);
752 pdgQ = hvq->GetPdgCode();
753 if(TMath::Abs(pdgQ) != fFlavorSelect) continue;
754 if(pdgQ>0) { theQ=kTRUE; } else { theQbar=kTRUE; }
755 yQ = 0.5*TMath::Log((hvq->Energy()+hvq->Pz()+1.e-13)/
756 (hvq->Energy()-hvq->Pz()+1.e-13));
757 if(yQ>fYMin && yQ<fYMax) inYcut=kTRUE;
758 }
759 if (!theQ || !theQbar || !inYcut) {
760 if (pParent) delete[] pParent;
761 return 0;
762 }
763 }
aea21c57 764
0f6ee828 765 //Introducing child cuts in case kPyW, kPyZ, kPyMb, and kPyMbNonDiff
766 if ( (fProcess == kPyW || fProcess == kPyZ || fProcess == kPyMb || fProcess == kPyMbNonDiffr)
767 && (fCutOnChild == 1) ) {
768 if ( !CheckKinematicsOnChild() ) {
769 if (pParent) delete[] pParent;
770 return 0;
771 }
aea21c57 772 }
773
774
f913ec4f 775 for (i = 0; i < np; i++) {
8d2cd130 776 Int_t trackIt = 0;
777 TParticle * iparticle = (TParticle *) fParticles->At(i);
778 kf = CheckPDGCode(iparticle->GetPdgCode());
779 Int_t ks = iparticle->GetStatusCode();
780 Int_t km = iparticle->GetFirstMother();
781 if ((ks == 1 && kf!=0 && KinematicSelection(iparticle, 0)) ||
782 (ks != 1) ||
783 (fProcess == kPyJets && ks == 21 && km == 0 && i>1)) {
784 nc++;
785 if (ks == 1) trackIt = 1;
786 Int_t ipa = iparticle->GetFirstMother()-1;
787
788 iparent = (ipa > -1) ? pParent[ipa] : -1;
789
790//
791// store track information
792 p[0] = iparticle->Px();
793 p[1] = iparticle->Py();
794 p[2] = iparticle->Pz();
a920faf9 795 p[3] = iparticle->Energy();
1406f599 796
a920faf9 797
2590ccf9 798 origin[0] = fVertex[0]+iparticle->Vx()/10; // [cm]
799 origin[1] = fVertex[1]+iparticle->Vy()/10; // [cm]
800 origin[2] = fVertex[2]+iparticle->Vz()/10; // [cm]
801
f913ec4f 802 Float_t tof = fEventTime + kconv * iparticle->T();
a920faf9 803
804 PushTrack(fTrackIt*trackIt, iparent, kf,
805 p[0], p[1], p[2], p[3],
806 origin[0], origin[1], origin[2], tof,
807 polar[0], polar[1], polar[2],
808 kPPrimary, nt, 1., ks);
5fa4b20b 809 //
810 // Special Treatment to store color-flow
811 //
812 if (ks == 3 || ks == 13 || ks == 14) {
813 TParticle* particle = 0;
814 if (fStack) {
815 particle = fStack->Particle(nt);
816 } else {
817 particle = gAlice->Stack()->Particle(nt);
818 }
819 particle->SetFirstDaughter(fPythia->GetK(2, i));
820 particle->SetLastDaughter(fPythia->GetK(3, i));
821 }
822
8d2cd130 823 KeepTrack(nt);
824 pParent[i] = nt;
f913ec4f 825 SetHighWaterMark(nt);
826
8d2cd130 827 } // select particle
828 } // particle loop
829
830 if (pParent) delete[] pParent;
e0e89f40 831
f913ec4f 832 return 1;
8d2cd130 833}
834
835
836void AliGenPythia::FinishRun()
837{
838// Print x-section summary
839 fPythia->Pystat(1);
2779fc64 840
841 if (fNev > 0.) {
842 fQ /= fNev;
843 fX1 /= fNev;
844 fX2 /= fNev;
845 }
846
8d2cd130 847 printf("\nTotal number of Pyevnt() calls %d\n", fTrialsRun);
848 printf("\nMean Q, x1, x2: %f %f %f\n", fQ, fX1, fX2);
8d2cd130 849}
850
851void AliGenPythia::AdjustWeights()
852{
853// Adjust the weights after generation of all events
854//
e2bddf81 855 if (gAlice) {
856 TParticle *part;
857 Int_t ntrack=gAlice->GetMCApp()->GetNtrack();
858 for (Int_t i=0; i<ntrack; i++) {
859 part= gAlice->GetMCApp()->Particle(i);
860 part->SetWeight(part->GetWeight()*fKineBias);
861 }
8d2cd130 862 }
863}
864
865void AliGenPythia::SetNuclei(Int_t a1, Int_t a2)
866{
867// Treat protons as inside nuclei with mass numbers a1 and a2
1d568bc2 868
1a626d4e 869 fAProjectile = a1;
870 fATarget = a2;
1d568bc2 871 fSetNuclei = kTRUE;
8d2cd130 872}
873
874
875void AliGenPythia::MakeHeader()
876{
183a5ca9 877 if (gAlice) {
878 if (gAlice->GetEvNumber()>=fDebugEventFirst &&
f913ec4f 879 gAlice->GetEvNumber()<=fDebugEventLast) fPythia->Pylist(2);
183a5ca9 880 }
881
8d2cd130 882// Builds the event header, to be called after each event
e5c87a3d 883 if (fHeader) delete fHeader;
884 fHeader = new AliGenPythiaEventHeader("Pythia");
8d2cd130 885//
886// Event type
e5c87a3d 887 ((AliGenPythiaEventHeader*) fHeader)->SetProcessType(fPythia->GetMSTI(1));
8d2cd130 888//
889// Number of trials
e5c87a3d 890 ((AliGenPythiaEventHeader*) fHeader)->SetTrials(fTrials);
8d2cd130 891//
892// Event Vertex
d25cfd65 893 fHeader->SetPrimaryVertex(fVertex);
8d2cd130 894//
895// Jets that have triggered
f913ec4f 896
8d2cd130 897 if (fProcess == kPyJets)
898 {
899 Int_t ntrig, njet;
900 Float_t jets[4][10];
901 GetJets(njet, ntrig, jets);
9ff6c04c 902
8d2cd130 903
904 for (Int_t i = 0; i < ntrig; i++) {
e5c87a3d 905 ((AliGenPythiaEventHeader*) fHeader)->AddJet(jets[0][i], jets[1][i], jets[2][i],
8d2cd130 906 jets[3][i]);
907 }
908 }
5fa4b20b 909//
910// Copy relevant information from external header, if present.
911//
912 Float_t uqJet[4];
913
914 if (fRL) {
915 AliGenPythiaEventHeader* exHeader = (AliGenPythiaEventHeader*) (fRL->GetHeader()->GenEventHeader());
916 for (Int_t i = 0; i < exHeader->NTriggerJets(); i++)
917 {
918 printf("Adding Jet %d %d \n", i, exHeader->NTriggerJets());
919
920
921 exHeader->TriggerJet(i, uqJet);
922 ((AliGenPythiaEventHeader*) fHeader)->AddUQJet(uqJet[0], uqJet[1], uqJet[2], uqJet[3]);
923 }
924 }
925//
926// Store quenching parameters
927//
928 if (fQuench){
929 Double_t z[4];
930 Double_t xp, yp;
7c21f297 931 if (fQuench == 1) {
932 // Pythia::Quench()
933 fPythia->GetQuenchingParameters(xp, yp, z);
934 } else {
935 // Pyquen
936 Double_t r1 = PARIMP.rb1;
937 Double_t r2 = PARIMP.rb2;
938 Double_t b = PARIMP.b1;
939 Double_t r = 0.5 * TMath::Sqrt(2. * (r1 * r1 + r2 * r2) - b * b);
940 Double_t phi = PARIMP.psib1;
941 xp = r * TMath::Cos(phi);
942 yp = r * TMath::Sin(phi);
943
944 }
945 ((AliGenPythiaEventHeader*) fHeader)->SetXYJet(xp, yp);
946 ((AliGenPythiaEventHeader*) fHeader)->SetZQuench(z);
947 }
beac474c 948//
949// Store pt^hard
950 ((AliGenPythiaEventHeader*) fHeader)->SetPtHard(fPythia->GetVINT(47));
5fa4b20b 951//
cf57b268 952// Pass header
5fa4b20b 953//
cf57b268 954 AddHeader(fHeader);
8d2cd130 955}
cf57b268 956
957void AliGenPythia::AddHeader(AliGenEventHeader* header)
958{
959 // Add header to container or runloader
960 if (fContainer) {
961 fContainer->AddHeader(header);
962 } else {
963 AliRunLoader::GetRunLoader()->GetHeader()->SetGenEventHeader(header);
964 }
965}
966
8d2cd130 967
968Bool_t AliGenPythia::CheckTrigger(TParticle* jet1, TParticle* jet2)
969{
970// Check the kinematic trigger condition
971//
972 Double_t eta[2];
973 eta[0] = jet1->Eta();
974 eta[1] = jet2->Eta();
975 Double_t phi[2];
976 phi[0] = jet1->Phi();
977 phi[1] = jet2->Phi();
978 Int_t pdg[2];
979 pdg[0] = jet1->GetPdgCode();
980 pdg[1] = jet2->GetPdgCode();
981 Bool_t triggered = kFALSE;
982
983 if (fProcess == kPyJets) {
984 Int_t njets = 0;
985 Int_t ntrig = 0;
986 Float_t jets[4][10];
987//
988// Use Pythia clustering on parton level to determine jet axis
989//
990 GetJets(njets, ntrig, jets);
991
992 if (ntrig) triggered = kTRUE;
993//
994 } else {
995 Int_t ij = 0;
996 Int_t ig = 1;
997 if (pdg[0] == kGamma) {
998 ij = 1;
999 ig = 0;
1000 }
1001 //Check eta range first...
1002 if ((eta[ij] < fEtaMaxJet && eta[ij] > fEtaMinJet) &&
1003 (eta[ig] < fEtaMaxGamma && eta[ig] > fEtaMinGamma))
1004 {
1005 //Eta is okay, now check phi range
1006 if ((phi[ij] < fPhiMaxJet && phi[ij] > fPhiMinJet) &&
1007 (phi[ig] < fPhiMaxGamma && phi[ig] > fPhiMinGamma))
1008 {
1009 triggered = kTRUE;
1010 }
1011 }
1012 }
1013 return triggered;
1014}
aea21c57 1015
1016
1017//Checking Kinematics on Child (status code 1, particle code ?, kin cuts
1018Bool_t AliGenPythia::CheckKinematicsOnChild(){
1019
1020 Bool_t checking = kFALSE;
1021 Int_t j, kcode, ks, km;
1022 Int_t nPartAcc = 0; //number of particles in the acceptance range
1023 Int_t numberOfAcceptedParticles = 1;
1024 if (fNumberOfAcceptedParticles != 0) { numberOfAcceptedParticles = fNumberOfAcceptedParticles; }
1025 Int_t npart = fParticles->GetEntriesFast();
1026
0f6ee828 1027 for (j = 0; j<npart; j++) {
aea21c57 1028 TParticle * jparticle = (TParticle *) fParticles->At(j);
1029 kcode = TMath::Abs( CheckPDGCode(jparticle->GetPdgCode()) );
1030 ks = jparticle->GetStatusCode();
1031 km = jparticle->GetFirstMother();
1032
1033 if( (ks == 1) && (kcode == fPdgCodeParticleforAcceptanceCut) && (KinematicSelection(jparticle,1)) ){
1034 nPartAcc++;
1035 }
0f6ee828 1036 if( numberOfAcceptedParticles <= nPartAcc){
1037 checking = kTRUE;
1038 break;
1039 }
aea21c57 1040 }
0f6ee828 1041
aea21c57 1042 return checking;
aea21c57 1043}
1044
8d2cd130 1045
1046AliGenPythia& AliGenPythia::operator=(const AliGenPythia& rhs)
1047{
1048// Assignment operator
014a9521 1049 rhs.Copy(*this);
8d2cd130 1050 return *this;
1051}
1052
5fa4b20b 1053void AliGenPythia::LoadEvent(AliStack* stack, Int_t flag, Int_t reHadr)
8d2cd130 1054{
1055//
1056// Load event into Pythia Common Block
1057//
5fa4b20b 1058
32d6ef7d 1059 Int_t npart = stack -> GetNprimary();
1060 Int_t n0 = 0;
1061
1062 if (!flag) {
1063 (fPythia->GetPyjets())->N = npart;
1064 } else {
1065 n0 = (fPythia->GetPyjets())->N;
1066 (fPythia->GetPyjets())->N = n0 + npart;
1067 }
1068
1069
8d2cd130 1070 for (Int_t part = 0; part < npart; part++) {
32d6ef7d 1071 TParticle *MPart = stack->Particle(part);
1072
5fa4b20b 1073 Int_t kf = MPart->GetPdgCode();
1074 Int_t ks = MPart->GetStatusCode();
1075 Int_t idf = MPart->GetFirstDaughter();
1076 Int_t idl = MPart->GetLastDaughter();
1077
1078 if (reHadr) {
1079 if (ks == 11 || ks == 12) {
1080 ks -= 10;
1081 idf = -1;
1082 idl = -1;
1083 }
1084 }
32d6ef7d 1085
8d2cd130 1086 Float_t px = MPart->Px();
1087 Float_t py = MPart->Py();
1088 Float_t pz = MPart->Pz();
1089 Float_t e = MPart->Energy();
a920faf9 1090 Float_t m = MPart->GetCalcMass();
8d2cd130 1091
1092
32d6ef7d 1093 (fPythia->GetPyjets())->P[0][part+n0] = px;
1094 (fPythia->GetPyjets())->P[1][part+n0] = py;
1095 (fPythia->GetPyjets())->P[2][part+n0] = pz;
1096 (fPythia->GetPyjets())->P[3][part+n0] = e;
1097 (fPythia->GetPyjets())->P[4][part+n0] = m;
8d2cd130 1098
32d6ef7d 1099 (fPythia->GetPyjets())->K[1][part+n0] = kf;
1100 (fPythia->GetPyjets())->K[0][part+n0] = ks;
5fa4b20b 1101 (fPythia->GetPyjets())->K[3][part+n0] = idf + 1;
1102 (fPythia->GetPyjets())->K[4][part+n0] = idl + 1;
1103 (fPythia->GetPyjets())->K[2][part+n0] = MPart->GetFirstMother() + 1;
8d2cd130 1104 }
1105}
1106
5fa4b20b 1107
014a9521 1108void AliGenPythia::RecJetsUA1(Int_t& njets, Float_t jets [4][50])
8d2cd130 1109{
1110//
1111// Calls the Pythia jet finding algorithm to find jets in the current event
1112//
1113//
8d2cd130 1114//
1115// Save jets
1116 Int_t n = fPythia->GetN();
1117
1118//
1119// Run Jet Finder
1120 fPythia->Pycell(njets);
1121 Int_t i;
1122 for (i = 0; i < njets; i++) {
1123 Float_t px = (fPythia->GetPyjets())->P[0][n+i];
1124 Float_t py = (fPythia->GetPyjets())->P[1][n+i];
1125 Float_t pz = (fPythia->GetPyjets())->P[2][n+i];
1126 Float_t e = (fPythia->GetPyjets())->P[3][n+i];
1127
1128 jets[0][i] = px;
1129 jets[1][i] = py;
1130 jets[2][i] = pz;
1131 jets[3][i] = e;
1132 }
1133}
1134
1135
1136
1137void AliGenPythia::GetJets(Int_t& nJets, Int_t& nJetsTrig, Float_t jets[4][10])
1138{
1139//
1140// Calls the Pythia clustering algorithm to find jets in the current event
1141//
1142 Int_t n = fPythia->GetN();
1143 nJets = 0;
1144 nJetsTrig = 0;
1145 if (fJetReconstruction == kCluster) {
1146//
1147// Configure cluster algorithm
1148//
1149 fPythia->SetPARU(43, 2.);
1150 fPythia->SetMSTU(41, 1);
1151//
1152// Call cluster algorithm
1153//
1154 fPythia->Pyclus(nJets);
1155//
1156// Loading jets from common block
1157//
1158 } else {
592f8307 1159
8d2cd130 1160//
1161// Run Jet Finder
1162 fPythia->Pycell(nJets);
1163 }
1164
1165 Int_t i;
1166 for (i = 0; i < nJets; i++) {
1167 Float_t px = (fPythia->GetPyjets())->P[0][n+i];
1168 Float_t py = (fPythia->GetPyjets())->P[1][n+i];
1169 Float_t pz = (fPythia->GetPyjets())->P[2][n+i];
1170 Float_t e = (fPythia->GetPyjets())->P[3][n+i];
1171 Float_t pt = TMath::Sqrt(px * px + py * py);
a920faf9 1172 Float_t phi = TMath::Pi() + TMath::ATan2(-py, -px);
8d2cd130 1173 Float_t theta = TMath::ATan2(pt,pz);
1174 Float_t et = e * TMath::Sin(theta);
1175 Float_t eta = -TMath::Log(TMath::Tan(theta / 2.));
8d2cd130 1176 if (
1177 eta > fEtaMinJet && eta < fEtaMaxJet &&
675eb105 1178 phi > fPhiMinJet && phi < fPhiMaxJet &&
8d2cd130 1179 et > fEtMinJet && et < fEtMaxJet
1180 )
1181 {
1182 jets[0][nJetsTrig] = px;
1183 jets[1][nJetsTrig] = py;
1184 jets[2][nJetsTrig] = pz;
1185 jets[3][nJetsTrig] = e;
1186 nJetsTrig++;
5fa4b20b 1187// printf("\n........-Jet #%d: %10.3f %10.3f %10.3f %10.3f \n", i, pt, et, eta, phi * kRaddeg);
8d2cd130 1188 } else {
1189// printf("\n........-Jet #%d: %10.3f %10.3f %10.3f %10.3f \n", i, pt, et, eta, phi * kRaddeg);
1190 }
1191 }
1192}
1193
f913ec4f 1194void AliGenPythia::GetSubEventTime()
1195{
1196 // Calculates time of the next subevent
9d7108a7 1197 fEventTime = 0.;
1198 if (fEventsTime) {
1199 TArrayF &array = *fEventsTime;
1200 fEventTime = array[fCurSubEvent++];
1201 }
1202 // printf(" Event time: %d %f %p",fCurSubEvent,fEventTime,fEventsTime);
1203 return;
f913ec4f 1204}
8d2cd130 1205
1206#ifdef never
1207void AliGenPythia::Streamer(TBuffer &R__b)
1208{
1209 // Stream an object of class AliGenPythia.
1210
1211 if (R__b.IsReading()) {
1212 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1213 AliGenerator::Streamer(R__b);
1214 R__b >> (Int_t&)fProcess;
1215 R__b >> (Int_t&)fStrucFunc;
1216 R__b >> (Int_t&)fForceDecay;
1217 R__b >> fEnergyCMS;
1218 R__b >> fKineBias;
1219 R__b >> fTrials;
1220 fParentSelect.Streamer(R__b);
1221 fChildSelect.Streamer(R__b);
1222 R__b >> fXsection;
1223// (AliPythia::Instance())->Streamer(R__b);
1224 R__b >> fPtHardMin;
1225 R__b >> fPtHardMax;
1226// if (fDecayer) fDecayer->Streamer(R__b);
1227 } else {
1228 R__b.WriteVersion(AliGenPythia::IsA());
1229 AliGenerator::Streamer(R__b);
1230 R__b << (Int_t)fProcess;
1231 R__b << (Int_t)fStrucFunc;
1232 R__b << (Int_t)fForceDecay;
1233 R__b << fEnergyCMS;
1234 R__b << fKineBias;
1235 R__b << fTrials;
1236 fParentSelect.Streamer(R__b);
1237 fChildSelect.Streamer(R__b);
1238 R__b << fXsection;
1239// R__b << fPythia;
1240 R__b << fPtHardMin;
1241 R__b << fPtHardMax;
1242 // fDecayer->Streamer(R__b);
1243 }
1244}
1245#endif
1246
90d7b703 1247
589380c6 1248