]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PYTHIA6/AliGenPythia.cxx
Option for patching of the omega dalitz decay.
[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
37b09b91 28#include <TClonesArray.h>
8d2cd130 29#include <TDatabasePDG.h>
30#include <TParticle.h>
31#include <TPDGCode.h>
1058d9df 32#include <TObjArray.h>
8d2cd130 33#include <TSystem.h>
34#include <TTree.h>
8d2cd130 35#include "AliConst.h"
36#include "AliDecayerPythia.h"
37#include "AliGenPythia.h"
cd07c39b 38#include "AliFastGlauber.h"
5fa4b20b 39#include "AliHeader.h"
8d2cd130 40#include "AliGenPythiaEventHeader.h"
41#include "AliPythia.h"
7cdba479 42#include "AliPythiaRndm.h"
8d2cd130 43#include "AliRun.h"
7ea3ea5b 44#include "AliStack.h"
45#include "AliRunLoader.h"
5d12ce38 46#include "AliMC.h"
e2d34d35 47#include "PyquenCommon.h"
8d2cd130 48
014a9521 49ClassImp(AliGenPythia)
8d2cd130 50
e8a8adcd 51
52AliGenPythia::AliGenPythia():
53 AliGenMC(),
54 fProcess(kPyCharm),
efe3b1cd 55 fItune(-1),
e8a8adcd 56 fStrucFunc(kCTEQ5L),
e8a8adcd 57 fKineBias(0.),
58 fTrials(0),
59 fTrialsRun(0),
60 fQ(0.),
61 fX1(0.),
62 fX2(0.),
63 fEventTime(0.),
64 fInteractionRate(0.),
65 fTimeWindow(0.),
66 fCurSubEvent(0),
67 fEventsTime(0),
68 fNev(0),
69 fFlavorSelect(0),
70 fXsection(0.),
71 fPythia(0),
72 fPtHardMin(0.),
73 fPtHardMax(1.e4),
74 fYHardMin(-1.e10),
75 fYHardMax(1.e10),
76 fGinit(1),
77 fGfinal(1),
78 fHadronisation(1),
03358a32 79 fPatchOmegaDalitz(0),
e8a8adcd 80 fNpartons(0),
81 fReadFromFile(0),
82 fQuench(0),
cd07c39b 83 fQhat(0.),
84 fLength(0.),
e6fe9b82 85 fImpact(0.),
e8a8adcd 86 fPtKick(1.),
87 fFullEvent(kTRUE),
88 fDecayer(new AliDecayerPythia()),
89 fDebugEventFirst(-1),
90 fDebugEventLast(-1),
91 fEtMinJet(0.),
92 fEtMaxJet(1.e4),
93 fEtaMinJet(-20.),
94 fEtaMaxJet(20.),
95 fPhiMinJet(0.),
96 fPhiMaxJet(2.* TMath::Pi()),
97 fJetReconstruction(kCell),
98 fEtaMinGamma(-20.),
99 fEtaMaxGamma(20.),
100 fPhiMinGamma(0.),
101 fPhiMaxGamma(2. * TMath::Pi()),
102 fPycellEtaMax(2.),
103 fPycellNEta(274),
104 fPycellNPhi(432),
105 fPycellThreshold(0.),
106 fPycellEtSeed(4.),
107 fPycellMinEtJet(10.),
108 fPycellMaxRadius(1.),
109 fStackFillOpt(kFlavorSelection),
110 fFeedDownOpt(kTRUE),
111 fFragmentation(kTRUE),
112 fSetNuclei(kFALSE),
113 fNewMIS(kFALSE),
114 fHFoff(kFALSE),
20e47f08 115 fNucPdf(0),
e8a8adcd 116 fTriggerParticle(0),
117 fTriggerEta(0.9),
700b9416 118 fTriggerMultiplicity(0),
119 fTriggerMultiplicityEta(0),
38112f3f 120 fTriggerMultiplicityPtMin(0),
e8a8adcd 121 fCountMode(kCountAll),
122 fHeader(0),
123 fRL(0),
ec2c406e 124 fFileName(0),
9fd8e520 125 fFragPhotonInCalo(kFALSE),
ec2c406e 126 fPi0InCalo(kFALSE) ,
90a236ce 127 fPhotonInCalo(kFALSE),
9dfe63b3 128 fEleInEMCAL(kFALSE),
9fd8e520 129 fCheckEMCAL(kFALSE),
130 fCheckPHOS(kFALSE),
90a236ce 131 fCheckPHOSeta(kFALSE),
9fd8e520 132 fFragPhotonOrPi0MinPt(0),
90a236ce 133 fPhotonMinPt(0),
9dfe63b3 134 fElectronMinPt(0),
9fd8e520 135 fPHOSMinPhi(219.),
136 fPHOSMaxPhi(321.),
137 fPHOSEta(0.13),
138 fEMCALMinPhi(79.),
139 fEMCALMaxPhi(191.),
140 fEMCALEta(0.71)
ec2c406e 141
8d2cd130 142{
143// Default Constructor
e7c989e4 144 fEnergyCMS = 5500.;
7cdba479 145 if (!AliPythiaRndm::GetPythiaRandom())
e8a8adcd 146 AliPythiaRndm::SetPythiaRandom(GetRandom());
8d2cd130 147}
148
149AliGenPythia::AliGenPythia(Int_t npart)
e8a8adcd 150 :AliGenMC(npart),
151 fProcess(kPyCharm),
efe3b1cd 152 fItune(-1),
e8a8adcd 153 fStrucFunc(kCTEQ5L),
e8a8adcd 154 fKineBias(0.),
155 fTrials(0),
156 fTrialsRun(0),
157 fQ(0.),
158 fX1(0.),
159 fX2(0.),
160 fEventTime(0.),
161 fInteractionRate(0.),
162 fTimeWindow(0.),
163 fCurSubEvent(0),
164 fEventsTime(0),
165 fNev(0),
166 fFlavorSelect(0),
167 fXsection(0.),
168 fPythia(0),
169 fPtHardMin(0.),
170 fPtHardMax(1.e4),
171 fYHardMin(-1.e10),
172 fYHardMax(1.e10),
173 fGinit(kTRUE),
174 fGfinal(kTRUE),
175 fHadronisation(kTRUE),
03358a32 176 fPatchOmegaDalitz(0),
e8a8adcd 177 fNpartons(0),
178 fReadFromFile(kFALSE),
179 fQuench(kFALSE),
cd07c39b 180 fQhat(0.),
181 fLength(0.),
e6fe9b82 182 fImpact(0.),
e8a8adcd 183 fPtKick(1.),
184 fFullEvent(kTRUE),
185 fDecayer(new AliDecayerPythia()),
186 fDebugEventFirst(-1),
187 fDebugEventLast(-1),
188 fEtMinJet(0.),
189 fEtMaxJet(1.e4),
190 fEtaMinJet(-20.),
191 fEtaMaxJet(20.),
192 fPhiMinJet(0.),
193 fPhiMaxJet(2.* TMath::Pi()),
194 fJetReconstruction(kCell),
195 fEtaMinGamma(-20.),
196 fEtaMaxGamma(20.),
197 fPhiMinGamma(0.),
198 fPhiMaxGamma(2. * TMath::Pi()),
199 fPycellEtaMax(2.),
200 fPycellNEta(274),
201 fPycellNPhi(432),
202 fPycellThreshold(0.),
203 fPycellEtSeed(4.),
204 fPycellMinEtJet(10.),
205 fPycellMaxRadius(1.),
206 fStackFillOpt(kFlavorSelection),
207 fFeedDownOpt(kTRUE),
208 fFragmentation(kTRUE),
209 fSetNuclei(kFALSE),
210 fNewMIS(kFALSE),
211 fHFoff(kFALSE),
20e47f08 212 fNucPdf(0),
e8a8adcd 213 fTriggerParticle(0),
214 fTriggerEta(0.9),
700b9416 215 fTriggerMultiplicity(0),
216 fTriggerMultiplicityEta(0),
38112f3f 217 fTriggerMultiplicityPtMin(0),
e8a8adcd 218 fCountMode(kCountAll),
219 fHeader(0),
220 fRL(0),
ec2c406e 221 fFileName(0),
9fd8e520 222 fFragPhotonInCalo(kFALSE),
ec2c406e 223 fPi0InCalo(kFALSE) ,
90a236ce 224 fPhotonInCalo(kFALSE),
9dfe63b3 225 fEleInEMCAL(kFALSE),
9fd8e520 226 fCheckEMCAL(kFALSE),
227 fCheckPHOS(kFALSE),
90a236ce 228 fCheckPHOSeta(kFALSE),
9fd8e520 229 fFragPhotonOrPi0MinPt(0),
90a236ce 230 fPhotonMinPt(0),
9dfe63b3 231 fElectronMinPt(0),
9fd8e520 232 fPHOSMinPhi(219.),
233 fPHOSMaxPhi(321.),
234 fPHOSEta(0.13),
235 fEMCALMinPhi(79.),
236 fEMCALMaxPhi(191.),
237 fEMCALEta(0.71)
8d2cd130 238{
239// default charm production at 5. 5 TeV
240// semimuonic decay
241// structure function GRVHO
242//
e7c989e4 243 fEnergyCMS = 5500.;
8d2cd130 244 fName = "Pythia";
245 fTitle= "Particle Generator using PYTHIA";
8d2cd130 246 SetForceDecay();
8d2cd130 247 // Set random number generator
7cdba479 248 if (!AliPythiaRndm::GetPythiaRandom())
249 AliPythiaRndm::SetPythiaRandom(GetRandom());
76d6ba9a 250 }
8d2cd130 251
8d2cd130 252AliGenPythia::~AliGenPythia()
253{
254// Destructor
9d7108a7 255 if(fEventsTime) delete fEventsTime;
256}
257
258void AliGenPythia::SetInteractionRate(Float_t rate,Float_t timewindow)
259{
260// Generate pileup using user specified rate
261 fInteractionRate = rate;
262 fTimeWindow = timewindow;
263 GeneratePileup();
264}
265
266void AliGenPythia::GeneratePileup()
267{
268// Generate sub events time for pileup
269 fEventsTime = 0;
270 if(fInteractionRate == 0.) {
271 Warning("GeneratePileup","Zero interaction specified. Skipping pileup generation.\n");
272 return;
273 }
274
275 Int_t npart = NumberParticles();
276 if(npart < 0) {
277 Warning("GeneratePileup","Negative number of particles. Skipping pileup generation.\n");
278 return;
279 }
280
281 if(fEventsTime) delete fEventsTime;
282 fEventsTime = new TArrayF(npart);
283 TArrayF &array = *fEventsTime;
284 for(Int_t ipart = 0; ipart < npart; ipart++)
285 array[ipart] = 0.;
286
287 Float_t eventtime = 0.;
288 while(1)
289 {
290 eventtime += (AliPythiaRndm::GetPythiaRandom())->Exp(1./fInteractionRate);
291 if(eventtime > fTimeWindow) break;
292 array.Set(array.GetSize()+1);
293 array[array.GetSize()-1] = eventtime;
294 }
295
296 eventtime = 0.;
297 while(1)
298 {
299 eventtime -= (AliPythiaRndm::GetPythiaRandom())->Exp(1./fInteractionRate);
300 if(TMath::Abs(eventtime) > fTimeWindow) break;
301 array.Set(array.GetSize()+1);
302 array[array.GetSize()-1] = eventtime;
303 }
304
305 SetNumberParticles(fEventsTime->GetSize());
8d2cd130 306}
307
592f8307 308void AliGenPythia::SetPycellParameters(Float_t etamax, Int_t neta, Int_t nphi,
309 Float_t thresh, Float_t etseed, Float_t minet, Float_t r)
310{
311// Set pycell parameters
312 fPycellEtaMax = etamax;
313 fPycellNEta = neta;
314 fPycellNPhi = nphi;
315 fPycellThreshold = thresh;
316 fPycellEtSeed = etseed;
317 fPycellMinEtJet = minet;
318 fPycellMaxRadius = r;
319}
320
321
322
8d2cd130 323void AliGenPythia::SetEventListRange(Int_t eventFirst, Int_t eventLast)
324{
325 // Set a range of event numbers, for which a table
326 // of generated particle will be printed
327 fDebugEventFirst = eventFirst;
328 fDebugEventLast = eventLast;
329 if (fDebugEventLast==-1) fDebugEventLast=fDebugEventFirst;
330}
331
332void AliGenPythia::Init()
333{
334// Initialisation
335
336 SetMC(AliPythia::Instance());
b88f5cea 337 fPythia=(AliPythia*) fMCEvGen;
e2bddf81 338
8d2cd130 339//
340 fParentWeight=1./Float_t(fNpart);
341//
8d2cd130 342
343
344 fPythia->SetCKIN(3,fPtHardMin);
345 fPythia->SetCKIN(4,fPtHardMax);
346 fPythia->SetCKIN(7,fYHardMin);
347 fPythia->SetCKIN(8,fYHardMax);
348
20e47f08 349 if (fAProjectile > 0 && fATarget > 0) fPythia->SetNuclei(fAProjectile, fATarget, fNucPdf);
8d2cd130 350 // Fragmentation?
351 if (fFragmentation) {
352 fPythia->SetMSTP(111,1);
353 } else {
354 fPythia->SetMSTP(111,0);
355 }
356
357
358// initial state radiation
359 fPythia->SetMSTP(61,fGinit);
360// final state radiation
361 fPythia->SetMSTP(71,fGfinal);
362// pt - kick
363 if (fPtKick > 0.) {
364 fPythia->SetMSTP(91,1);
688950ef 365 fPythia->SetPARP(91,fPtKick);
366 fPythia->SetPARP(93, 4. * fPtKick);
8d2cd130 367 } else {
368 fPythia->SetMSTP(91,0);
369 }
370
5fa4b20b 371
372 if (fReadFromFile) {
373 fRL = AliRunLoader::Open(fFileName, "Partons");
374 fRL->LoadKinematics();
375 fRL->LoadHeader();
376 } else {
377 fRL = 0x0;
378 }
fdea4387 379 //
efe3b1cd 380 fPythia->ProcInit(fProcess,fEnergyCMS,fStrucFunc, fItune);
fdea4387 381 // Forward Paramters to the AliPythia object
382 fDecayer->SetForceDecay(fForceDecay);
beac474c 383// Switch off Heavy Flavors on request
384 if (fHFoff) {
51387949 385 // Maximum number of quark flavours used in pdf
beac474c 386 fPythia->SetMSTP(58, 3);
51387949 387 // Maximum number of flavors that can be used in showers
beac474c 388 fPythia->SetMSTJ(45, 3);
51387949 389 // Switch off g->QQbar splitting in decay table
390 ((AliDecayerPythia*) fDecayer)->HeavyFlavourOff();
beac474c 391 }
fdea4387 392
51387949 393 fDecayer->Init();
394
8d2cd130 395
396// Parent and Children Selection
397 switch (fProcess)
398 {
65f2626c 399 case kPyOldUEQ2ordered:
400 case kPyOldUEQ2ordered2:
401 case kPyOldPopcorn:
402 break;
8d2cd130 403 case kPyCharm:
404 case kPyCharmUnforced:
adf4d898 405 case kPyCharmPbPbMNR:
aabc7187 406 case kPyCharmpPbMNR:
e0e89f40 407 case kPyCharmppMNR:
408 case kPyCharmppMNRwmi:
8d2cd130 409 fParentSelect[0] = 411;
410 fParentSelect[1] = 421;
411 fParentSelect[2] = 431;
412 fParentSelect[3] = 4122;
9ccc3d0e 413 fParentSelect[4] = 4232;
414 fParentSelect[5] = 4132;
415 fParentSelect[6] = 4332;
8d2cd130 416 fFlavorSelect = 4;
417 break;
adf4d898 418 case kPyD0PbPbMNR:
419 case kPyD0pPbMNR:
420 case kPyD0ppMNR:
8d2cd130 421 fParentSelect[0] = 421;
422 fFlavorSelect = 4;
423 break;
90d7b703 424 case kPyDPlusPbPbMNR:
425 case kPyDPluspPbMNR:
426 case kPyDPlusppMNR:
427 fParentSelect[0] = 411;
428 fFlavorSelect = 4;
429 break;
e0e89f40 430 case kPyDPlusStrangePbPbMNR:
431 case kPyDPlusStrangepPbMNR:
432 case kPyDPlusStrangeppMNR:
433 fParentSelect[0] = 431;
434 fFlavorSelect = 4;
435 break;
8d2cd130 436 case kPyBeauty:
9dfe63b3 437 case kPyBeautyJets:
adf4d898 438 case kPyBeautyPbPbMNR:
439 case kPyBeautypPbMNR:
440 case kPyBeautyppMNR:
e0e89f40 441 case kPyBeautyppMNRwmi:
8d2cd130 442 fParentSelect[0]= 511;
443 fParentSelect[1]= 521;
444 fParentSelect[2]= 531;
445 fParentSelect[3]= 5122;
446 fParentSelect[4]= 5132;
447 fParentSelect[5]= 5232;
448 fParentSelect[6]= 5332;
449 fFlavorSelect = 5;
450 break;
451 case kPyBeautyUnforced:
452 fParentSelect[0] = 511;
453 fParentSelect[1] = 521;
454 fParentSelect[2] = 531;
455 fParentSelect[3] = 5122;
456 fParentSelect[4] = 5132;
457 fParentSelect[5] = 5232;
458 fParentSelect[6] = 5332;
459 fFlavorSelect = 5;
460 break;
461 case kPyJpsiChi:
462 case kPyJpsi:
463 fParentSelect[0] = 443;
464 break;
f529e69b 465 case kPyMbDefault:
0bd3d7c5 466 case kPyMbAtlasTuneMC09:
8d2cd130 467 case kPyMb:
04081a91 468 case kPyMbWithDirectPhoton:
8d2cd130 469 case kPyMbNonDiffr:
d7de4a67 470 case kPyMbMSEL1:
8d2cd130 471 case kPyJets:
472 case kPyDirectGamma:
e33acb67 473 case kPyLhwgMb:
8d2cd130 474 break;
589380c6 475 case kPyW:
0f6ee828 476 case kPyZ:
589380c6 477 break;
8d2cd130 478 }
479//
592f8307 480//
481// JetFinder for Trigger
482//
483// Configure detector (EMCAL like)
484//
d7de4a67 485 fPythia->SetPARU(51, fPycellEtaMax);
486 fPythia->SetMSTU(51, fPycellNEta);
487 fPythia->SetMSTU(52, fPycellNPhi);
592f8307 488//
489// Configure Jet Finder
490//
d7de4a67 491 fPythia->SetPARU(58, fPycellThreshold);
492 fPythia->SetPARU(52, fPycellEtSeed);
493 fPythia->SetPARU(53, fPycellMinEtJet);
494 fPythia->SetPARU(54, fPycellMaxRadius);
495 fPythia->SetMSTU(54, 2);
592f8307 496//
8d2cd130 497// This counts the total number of calls to Pyevnt() per run.
498 fTrialsRun = 0;
499 fQ = 0.;
500 fX1 = 0.;
501 fX2 = 0.;
502 fNev = 0 ;
503//
1d568bc2 504//
505//
8d2cd130 506 AliGenMC::Init();
1d568bc2 507//
508//
509//
510 if (fSetNuclei) {
511 fDyBoost = 0;
512 Warning("Init","SetNuclei used. Use SetProjectile + SetTarget instead. fDyBoost has been reset to 0\n");
513 }
d7de4a67 514
cd07c39b 515 fPythia->SetPARJ(200, 0.0);
516 fPythia->SetPARJ(199, 0.0);
517 fPythia->SetPARJ(198, 0.0);
518 fPythia->SetPARJ(197, 0.0);
519
520 if (fQuench == 1) {
5fa4b20b 521 fPythia->InitQuenching(0., 0.1, 0.6e6, 0);
32d6ef7d 522 }
3a709cfa 523
b976f7d8 524 if (fQuench == 3) {
525 // Nestor's change of the splittings
526 fPythia->SetPARJ(200, 0.8);
527 fPythia->SetMSTJ(41, 1); // QCD radiation only
528 fPythia->SetMSTJ(42, 2); // angular ordering
529 fPythia->SetMSTJ(44, 2); // option to run alpha_s
530 fPythia->SetMSTJ(47, 0); // No correction back to hard scattering element
531 fPythia->SetMSTJ(50, 0); // No coherence in first branching
532 fPythia->SetPARJ(82, 1.); // Cut off for parton showers
cd07c39b 533 } else if (fQuench == 4) {
534 // Armesto-Cunqueiro-Salgado change of the splittings.
535 AliFastGlauber* glauber = AliFastGlauber::Instance();
536 glauber->Init(2);
537 //read and store transverse almonds corresponding to differnt
538 //impact parameters.
cd07c39b 539 glauber->SetCentralityClass(0.,0.1);
540 fPythia->SetPARJ(200, 1.);
541 fPythia->SetPARJ(198, fQhat);
542 fPythia->SetPARJ(199, fLength);
cd07c39b 543 fPythia->SetMSTJ(42, 2); // angular ordering
544 fPythia->SetMSTJ(44, 2); // option to run alpha_s
cd07c39b 545 fPythia->SetPARJ(82, 1.); // Cut off for parton showers
b976f7d8 546 }
8d2cd130 547}
548
549void AliGenPythia::Generate()
550{
551// Generate one event
19ef8cf0 552 if (!fPythia) fPythia=(AliPythia*) fMCEvGen;
8d2cd130 553 fDecayer->ForceDecay();
554
555 Float_t polar[3] = {0,0,0};
556 Float_t origin[3] = {0,0,0};
a920faf9 557 Float_t p[4];
8d2cd130 558// converts from mm/c to s
559 const Float_t kconv=0.001/2.999792458e8;
560//
561 Int_t nt=0;
562 Int_t jev=0;
563 Int_t j, kf;
564 fTrials=0;
f913ec4f 565 fEventTime = 0.;
566
2590ccf9 567
8d2cd130 568
569 // Set collision vertex position
2590ccf9 570 if (fVertexSmear == kPerEvent) Vertex();
571
8d2cd130 572// event loop
573 while(1)
574 {
32d6ef7d 575//
5fa4b20b 576// Produce event
32d6ef7d 577//
32d6ef7d 578//
5fa4b20b 579// Switch hadronisation off
580//
581 fPythia->SetMSTJ(1, 0);
cd07c39b 582
583 if (fQuench ==4){
584 Double_t bimp;
585 // Quenching comes through medium-modified splitting functions.
586 AliFastGlauber::Instance()->GetRandomBHard(bimp);
e6fe9b82 587 fPythia->SetPARJ(197, bimp);
588 fImpact = bimp;
6c43eccb 589 fPythia->Qpygin0();
cd07c39b 590 }
32d6ef7d 591//
5fa4b20b 592// Either produce new event or read partons from file
593//
594 if (!fReadFromFile) {
beac474c 595 if (!fNewMIS) {
596 fPythia->Pyevnt();
597 } else {
598 fPythia->Pyevnw();
599 }
5fa4b20b 600 fNpartons = fPythia->GetN();
601 } else {
33c3c91a 602 printf("Loading Event %d\n",AliRunLoader::Instance()->GetEventNumber());
603 fRL->GetEvent(AliRunLoader::Instance()->GetEventNumber());
5fa4b20b 604 fPythia->SetN(0);
605 LoadEvent(fRL->Stack(), 0 , 1);
606 fPythia->Pyedit(21);
607 }
608
32d6ef7d 609//
610// Run quenching routine
611//
5fa4b20b 612 if (fQuench == 1) {
613 fPythia->Quench();
614 } else if (fQuench == 2){
615 fPythia->Pyquen(208., 0, 0.);
b976f7d8 616 } else if (fQuench == 3) {
617 // Quenching is via multiplicative correction of the splittings
5fa4b20b 618 }
b976f7d8 619
32d6ef7d 620//
5fa4b20b 621// Switch hadronisation on
32d6ef7d 622//
20e47f08 623 if (fHadronisation) {
624 fPythia->SetMSTJ(1, 1);
5fa4b20b 625//
626// .. and perform hadronisation
aea21c57 627// printf("Calling hadronisation %d\n", fPythia->GetN());
03358a32 628
629 if (fPatchOmegaDalitz) {
630 fPythia->SetMDCY(fPythia->Pycomp(111) ,1, 0);
631 fPythia->Pyexec();
632 fPythia->DalitzDecays();
633 fPythia->SetMDCY(fPythia->Pycomp(111) ,1, 1);
634 }
635 fPythia->Pyexec();
20e47f08 636 }
8d2cd130 637 fTrials++;
8507138f 638 fPythia->ImportParticles(&fParticles,"All");
03358a32 639
df275cfa 640 if (TMath::Abs(fDyBoost) > 1.e-4) Boost();
8d2cd130 641//
642//
643//
644 Int_t i;
645
dbd64db6 646 fNprimaries = 0;
8507138f 647 Int_t np = fParticles.GetEntriesFast();
5fa4b20b 648
7c21f297 649 if (np == 0) continue;
8d2cd130 650//
2590ccf9 651
8d2cd130 652//
653 Int_t* pParent = new Int_t[np];
654 Int_t* pSelected = new Int_t[np];
655 Int_t* trackIt = new Int_t[np];
5fa4b20b 656 for (i = 0; i < np; i++) {
8d2cd130 657 pParent[i] = -1;
658 pSelected[i] = 0;
659 trackIt[i] = 0;
660 }
661
662 Int_t nc = 0; // Total n. of selected particles
663 Int_t nParents = 0; // Selected parents
664 Int_t nTkbles = 0; // Trackable particles
f529e69b 665 if (fProcess != kPyMbDefault &&
666 fProcess != kPyMb &&
6d2ec66d 667 fProcess != kPyMbAtlasTuneMC09 &&
04081a91 668 fProcess != kPyMbWithDirectPhoton &&
f529e69b 669 fProcess != kPyJets &&
8d2cd130 670 fProcess != kPyDirectGamma &&
589380c6 671 fProcess != kPyMbNonDiffr &&
d7de4a67 672 fProcess != kPyMbMSEL1 &&
f529e69b 673 fProcess != kPyW &&
674 fProcess != kPyZ &&
675 fProcess != kPyCharmppMNRwmi &&
9dfe63b3 676 fProcess != kPyBeautyppMNRwmi &&
677 fProcess != kPyBeautyJets) {
8d2cd130 678
5fa4b20b 679 for (i = 0; i < np; i++) {
8507138f 680 TParticle* iparticle = (TParticle *) fParticles.At(i);
8d2cd130 681 Int_t ks = iparticle->GetStatusCode();
682 kf = CheckPDGCode(iparticle->GetPdgCode());
683// No initial state partons
684 if (ks==21) continue;
685//
686// Heavy Flavor Selection
687//
688 // quark ?
689 kf = TMath::Abs(kf);
690 Int_t kfl = kf;
9ff6c04c 691 // Resonance
f913ec4f 692
9ff6c04c 693 if (kfl > 100000) kfl %= 100000;
183a5ca9 694 if (kfl > 10000) kfl %= 10000;
8d2cd130 695 // meson ?
696 if (kfl > 10) kfl/=100;
697 // baryon
698 if (kfl > 10) kfl/=10;
8d2cd130 699 Int_t ipa = iparticle->GetFirstMother()-1;
700 Int_t kfMo = 0;
f913ec4f 701//
702// Establish mother daughter relation between heavy quarks and mesons
703//
704 if (kf >= fFlavorSelect && kf <= 6) {
705 Int_t idau = iparticle->GetFirstDaughter() - 1;
706 if (idau > -1) {
8507138f 707 TParticle* daughter = (TParticle *) fParticles.At(idau);
f913ec4f 708 Int_t pdgD = daughter->GetPdgCode();
709 if (pdgD == 91 || pdgD == 92) {
710 Int_t jmin = daughter->GetFirstDaughter() - 1;
711 Int_t jmax = daughter->GetLastDaughter() - 1;
2ab330c9 712 for (Int_t jp = jmin; jp <= jmax; jp++)
713 ((TParticle *) fParticles.At(jp))->SetFirstMother(i+1);
f913ec4f 714 } // is string or cluster
715 } // has daughter
716 } // heavy quark
8d2cd130 717
f913ec4f 718
8d2cd130 719 if (ipa > -1) {
8507138f 720 TParticle * mother = (TParticle *) fParticles.At(ipa);
8d2cd130 721 kfMo = TMath::Abs(mother->GetPdgCode());
722 }
f913ec4f 723
8d2cd130 724 // What to keep in Stack?
725 Bool_t flavorOK = kFALSE;
726 Bool_t selectOK = kFALSE;
727 if (fFeedDownOpt) {
32d6ef7d 728 if (kfl >= fFlavorSelect) flavorOK = kTRUE;
8d2cd130 729 } else {
32d6ef7d 730 if (kfl > fFlavorSelect) {
731 nc = -1;
732 break;
733 }
734 if (kfl == fFlavorSelect) flavorOK = kTRUE;
8d2cd130 735 }
736 switch (fStackFillOpt) {
737 case kFlavorSelection:
32d6ef7d 738 selectOK = kTRUE;
739 break;
8d2cd130 740 case kParentSelection:
32d6ef7d 741 if (ParentSelected(kf) || kf <= 10) selectOK = kTRUE;
742 break;
8d2cd130 743 }
744 if (flavorOK && selectOK) {
745//
746// Heavy flavor hadron or quark
747//
748// Kinematic seletion on final state heavy flavor mesons
749 if (ParentSelected(kf) && !KinematicSelection(iparticle, 0))
750 {
9ff6c04c 751 continue;
8d2cd130 752 }
753 pSelected[i] = 1;
754 if (ParentSelected(kf)) ++nParents; // Update parent count
755// printf("\n particle (HF) %d %d %d", i, pSelected[i], kf);
756 } else {
757// Kinematic seletion on decay products
758 if (fCutOnChild && ParentSelected(kfMo) && ChildSelected(kf)
9ff6c04c 759 && !KinematicSelection(iparticle, 1))
8d2cd130 760 {
9ff6c04c 761 continue;
8d2cd130 762 }
763//
764// Decay products
765// Select if mother was selected and is not tracked
766
767 if (pSelected[ipa] &&
768 !trackIt[ipa] && // mother will be tracked ?
769 kfMo != 5 && // mother is b-quark, don't store fragments
770 kfMo != 4 && // mother is c-quark, don't store fragments
771 kf != 92) // don't store string
772 {
773//
774// Semi-stable or de-selected: diselect decay products:
775//
776//
777 if (pSelected[i] == -1 || fDecayer->GetLifetime(kf) > fMaxLifeTime)
778 {
779 Int_t ipF = iparticle->GetFirstDaughter();
780 Int_t ipL = iparticle->GetLastDaughter();
781 if (ipF > 0) for (j = ipF-1; j < ipL; j++) pSelected[j] = -1;
782 }
783// printf("\n particle (decay) %d %d %d", i, pSelected[i], kf);
784 pSelected[i] = (pSelected[i] == -1) ? 0 : 1;
785 }
786 }
787 if (pSelected[i] == -1) pSelected[i] = 0;
788 if (!pSelected[i]) continue;
789 // Count quarks only if you did not include fragmentation
790 if (fFragmentation && kf <= 10) continue;
9ff6c04c 791
8d2cd130 792 nc++;
793// Decision on tracking
794 trackIt[i] = 0;
795//
796// Track final state particle
797 if (ks == 1) trackIt[i] = 1;
798// Track semi-stable particles
d25cfd65 799 if ((ks == 1) || (fDecayer->GetLifetime(kf) > fMaxLifeTime)) trackIt[i] = 1;
8d2cd130 800// Track particles selected by process if undecayed.
801 if (fForceDecay == kNoDecay) {
802 if (ParentSelected(kf)) trackIt[i] = 1;
803 } else {
804 if (ParentSelected(kf)) trackIt[i] = 0;
805 }
806 if (trackIt[i] == 1) ++nTkbles; // Update trackable counter
807//
808//
809
810 } // particle selection loop
811 if (nc > 0) {
812 for (i = 0; i<np; i++) {
813 if (!pSelected[i]) continue;
8507138f 814 TParticle * iparticle = (TParticle *) fParticles.At(i);
8d2cd130 815 kf = CheckPDGCode(iparticle->GetPdgCode());
816 Int_t ks = iparticle->GetStatusCode();
817 p[0] = iparticle->Px();
818 p[1] = iparticle->Py();
819 p[2] = iparticle->Pz();
a920faf9 820 p[3] = iparticle->Energy();
821
2590ccf9 822 origin[0] = fVertex[0]+iparticle->Vx()/10; // [cm]
823 origin[1] = fVertex[1]+iparticle->Vy()/10; // [cm]
824 origin[2] = fVertex[2]+iparticle->Vz()/10; // [cm]
825
8d2cd130 826 Float_t tof = kconv*iparticle->T();
827 Int_t ipa = iparticle->GetFirstMother()-1;
828 Int_t iparent = (ipa > -1) ? pParent[ipa] : -1;
a920faf9 829
830 PushTrack(fTrackIt*trackIt[i], iparent, kf,
831 p[0], p[1], p[2], p[3],
832 origin[0], origin[1], origin[2], tof,
833 polar[0], polar[1], polar[2],
834 kPPrimary, nt, 1., ks);
8d2cd130 835 pParent[i] = nt;
dbd64db6 836 KeepTrack(nt);
837 fNprimaries++;
642f15cf 838 } // PushTrack loop
8d2cd130 839 }
840 } else {
841 nc = GenerateMB();
842 } // mb ?
f913ec4f 843
844 GetSubEventTime();
8d2cd130 845
234f6d32 846 delete[] pParent;
847 delete[] pSelected;
848 delete[] trackIt;
8d2cd130 849
850 if (nc > 0) {
851 switch (fCountMode) {
852 case kCountAll:
853 // printf(" Count all \n");
854 jev += nc;
855 break;
856 case kCountParents:
857 // printf(" Count parents \n");
858 jev += nParents;
859 break;
860 case kCountTrackables:
861 // printf(" Count trackable \n");
862 jev += nTkbles;
863 break;
864 }
865 if (jev >= fNpart || fNpart == -1) {
866 fKineBias=Float_t(fNpart)/Float_t(fTrials);
e0e89f40 867
8d2cd130 868 fQ += fPythia->GetVINT(51);
869 fX1 += fPythia->GetVINT(41);
870 fX2 += fPythia->GetVINT(42);
871 fTrialsRun += fTrials;
872 fNev++;
873 MakeHeader();
874 break;
875 }
876 }
877 } // event loop
878 SetHighWaterMark(nt);
879// adjust weight due to kinematic selection
b88f5cea 880// AdjustWeights();
8d2cd130 881// get cross-section
882 fXsection=fPythia->GetPARI(1);
883}
884
885Int_t AliGenPythia::GenerateMB()
886{
887//
888// Min Bias selection and other global selections
889//
890 Int_t i, kf, nt, iparent;
891 Int_t nc = 0;
bf950da8 892 Float_t p[4];
8d2cd130 893 Float_t polar[3] = {0,0,0};
894 Float_t origin[3] = {0,0,0};
895// converts from mm/c to s
896 const Float_t kconv=0.001/2.999792458e8;
897
e0e89f40 898
899
8507138f 900 Int_t np = (fHadronisation) ? fParticles.GetEntriesFast() : fNpartons;
aea21c57 901
5fa4b20b 902
e0e89f40 903
8d2cd130 904 Int_t* pParent = new Int_t[np];
905 for (i=0; i< np; i++) pParent[i] = -1;
2f405d65 906 if (fProcess == kPyJets || fProcess == kPyDirectGamma || fProcess == kPyBeautyJets || fProcess == kPyBeautyppMNRwmi) {
8507138f 907 TParticle* jet1 = (TParticle *) fParticles.At(6);
908 TParticle* jet2 = (TParticle *) fParticles.At(7);
234f6d32 909 if (!CheckTrigger(jet1, jet2)) {
910 delete [] pParent;
911 return 0;
912 }
8d2cd130 913 }
e0e89f40 914
9fd8e520 915 // Select jets with fragmentation photon or pi0 going to PHOS or EMCAL
916 if (fProcess == kPyJets && (fFragPhotonInCalo || fPi0InCalo) ) {
ec2c406e 917
918 Bool_t ok = kFALSE;
919
920 Int_t pdg = 0;
9fd8e520 921 if (fFragPhotonInCalo) pdg = 22 ; // Photon
6d2ec66d 922 else if (fPi0InCalo) pdg = 111 ; // Pi0
ec2c406e 923
924 for (i=0; i< np; i++) {
8507138f 925 TParticle* iparticle = (TParticle *) fParticles.At(i);
ec2c406e 926 if(iparticle->GetStatusCode()==1 && iparticle->GetPdgCode()==pdg &&
9fd8e520 927 iparticle->Pt() > fFragPhotonOrPi0MinPt){
562cbbcf 928 Int_t imother = iparticle->GetFirstMother() - 1;
8507138f 929 TParticle* pmother = (TParticle *) fParticles.At(imother);
9fd8e520 930 if(pdg == 111 ||
82e0bdff 931 (pdg == 22 && pmother->GetStatusCode() != 11)) //No photon from hadron decay
9fd8e520 932 {
933 Float_t phi = iparticle->Phi()*180./TMath::Pi(); //Convert to degrees
82e0bdff 934 Float_t eta =TMath::Abs(iparticle->Eta()); //in calos etamin=-etamax
9fd8e520 935 if((fCheckEMCAL && IsInEMCAL(phi,eta)) ||
936 (fCheckPHOS && IsInPHOS(phi,eta)) )
937 ok =kTRUE;
938 }
ec2c406e 939 }
940 }
941 if(!ok)
942 return 0;
943 }
9dfe63b3 944
945 // Select beauty jets with electron in EMCAL
946 if (fProcess == kPyBeautyJets && fEleInEMCAL) {
947
948 Bool_t ok = kFALSE;
949
950 Int_t pdg = 11; //electron
951
70574ff8 952 Float_t pt = 0.;
953 Float_t eta = 0.;
954 Float_t phi = 0.;
9dfe63b3 955 for (i=0; i< np; i++) {
956 TParticle* iparticle = (TParticle *) fParticles.At(i);
957 if(iparticle->GetStatusCode()==1 && TMath::Abs(iparticle->GetPdgCode())==pdg &&
958 iparticle->Pt() > fElectronMinPt){
959 pt = iparticle->Pt();
960 phi = iparticle->Phi()*180./TMath::Pi(); //Convert to degrees
961 eta =TMath::Abs(iparticle->Eta()); //in calos etamin=-etamax
962 if(IsInEMCAL(phi,eta))
963 ok =kTRUE;
964 }
965 }
966 if(!ok)
967 return 0;
968 AliDebug(5,Form("Found an electron jet (pt,eta,phi) = (%f,%f,%f)",pt,eta,phi));
969 }
700b9416 970 // Check for minimum multiplicity
971 if (fTriggerMultiplicity > 0) {
972 Int_t multiplicity = 0;
973 for (i = 0; i < np; i++) {
8507138f 974 TParticle * iparticle = (TParticle *) fParticles.At(i);
700b9416 975
976 Int_t statusCode = iparticle->GetStatusCode();
977
978 // Initial state particle
e296848e 979 if (statusCode != 1)
700b9416 980 continue;
38112f3f 981 // eta cut
700b9416 982 if (fTriggerMultiplicityEta > 0 && TMath::Abs(iparticle->Eta()) > fTriggerMultiplicityEta)
983 continue;
38112f3f 984 // pt cut
985 if (iparticle->Pt() < fTriggerMultiplicityPtMin)
986 continue;
987
700b9416 988 TParticlePDG* pdgPart = iparticle->GetPDG();
989 if (pdgPart && pdgPart->Charge() == 0)
990 continue;
991
992 ++multiplicity;
993 }
994
995 if (multiplicity < fTriggerMultiplicity) {
996 delete [] pParent;
997 return 0;
998 }
38112f3f 999 Printf("Triggered on event with multiplicity of %d >= %d", multiplicity, fTriggerMultiplicity);
700b9416 1000 }
90a236ce 1001
1002 // Select events with a photon pt > min pt going to PHOS eta acceptance or exactly PHOS eta phi
1003 if ((fProcess == kPyJets || fProcess == kPyDirectGamma) && fPhotonInCalo && (fCheckPHOSeta || fCheckPHOS)){
1004
1005 Bool_t okd = kFALSE;
1006
1007 Int_t pdg = 22;
1008 Int_t iphcand = -1;
1009 for (i=0; i< np; i++) {
8507138f 1010 TParticle* iparticle = (TParticle *) fParticles.At(i);
90a236ce 1011 Float_t phi = iparticle->Phi()*180./TMath::Pi(); //Convert to degrees
1012 Float_t eta =TMath::Abs(iparticle->Eta());//in calos etamin=-etamax
1013
1014 if(iparticle->GetStatusCode() == 1
1015 && iparticle->GetPdgCode() == pdg
1016 && iparticle->Pt() > fPhotonMinPt
04a26b0a 1017 && eta < fPHOSEta){
90a236ce 1018
1019 // first check if the photon is in PHOS phi
1020 if(IsInPHOS(phi,eta)){
1021 okd = kTRUE;
1022 break;
1023 }
1024 if(fCheckPHOSeta) iphcand = i; // candiate photon to rotate in phi
1025
1026 }
1027 }
1028
1029 if(!okd && iphcand != -1) // execute rotation in phi
1030 RotatePhi(iphcand,okd);
1031
1032 if(!okd)
1033 return 0;
1034 }
1035
7ce1321b 1036 if (fTriggerParticle) {
1037 Bool_t triggered = kFALSE;
1038 for (i = 0; i < np; i++) {
8507138f 1039 TParticle * iparticle = (TParticle *) fParticles.At(i);
7ce1321b 1040 kf = CheckPDGCode(iparticle->GetPdgCode());
38db0ee6 1041 if (kf != fTriggerParticle) continue;
7ce1321b 1042 if (iparticle->Pt() == 0.) continue;
1043 if (TMath::Abs(iparticle->Eta()) > fTriggerEta) continue;
1044 triggered = kTRUE;
1045 break;
1046 }
234f6d32 1047 if (!triggered) {
1048 delete [] pParent;
1049 return 0;
1050 }
7ce1321b 1051 }
e0e89f40 1052
1053
1054 // Check if there is a ccbar or bbbar pair with at least one of the two
1055 // in fYMin < y < fYMax
2f405d65 1056
9dfe63b3 1057 if (fProcess == kPyCharmppMNRwmi || fProcess == kPyBeautyppMNRwmi || fProcess == kPyBeautyJets) {
9ccc3d0e 1058 TParticle *partCheck;
1059 TParticle *mother;
e0e89f40 1060 Bool_t theQ=kFALSE,theQbar=kFALSE,inYcut=kFALSE;
9ccc3d0e 1061 Bool_t theChild=kFALSE;
1062 Float_t y;
1063 Int_t pdg,mpdg,mpdgUpperFamily;
e0e89f40 1064 for(i=0; i<np; i++) {
9ccc3d0e 1065 partCheck = (TParticle*)fParticles.At(i);
1066 pdg = partCheck->GetPdgCode();
1067 if(TMath::Abs(pdg) == fFlavorSelect) { // quark
1068 if(pdg>0) { theQ=kTRUE; } else { theQbar=kTRUE; }
1069 y = 0.5*TMath::Log((partCheck->Energy()+partCheck->Pz()+1.e-13)/
1070 (partCheck->Energy()-partCheck->Pz()+1.e-13));
1071 if(y>fYMin && y<fYMax) inYcut=kTRUE;
1072 }
1073 if(fCutOnChild && TMath::Abs(pdg) == fPdgCodeParticleforAcceptanceCut) {
1074 Int_t mi = partCheck->GetFirstMother() - 1;
1075 if(mi<0) continue;
1076 mother = (TParticle*)fParticles.At(mi);
1077 mpdg=TMath::Abs(mother->GetPdgCode());
75fde694 1078 mpdgUpperFamily=(mpdg>1000 ? mpdg+1000 : mpdg+100); // keep e from c from b
9ccc3d0e 1079 if ( ParentSelected(mpdg) ||
1080 (fFlavorSelect==5 && ParentSelected(mpdgUpperFamily))) {
1081 if (KinematicSelection(partCheck,1)) {
1082 theChild=kTRUE;
1083 }
1084 }
1085 }
e0e89f40 1086 }
9ccc3d0e 1087 if (!theQ || !theQbar || !inYcut) { // one of the c/b conditions not satisfied
234f6d32 1088 delete[] pParent;
e0e89f40 1089 return 0;
1090 }
9ccc3d0e 1091 if (fCutOnChild && !theChild) { // one of the child conditions not satisfied
1092 delete[] pParent;
1093 return 0;
1094 }
1095
e0e89f40 1096 }
aea21c57 1097
0f6ee828 1098 //Introducing child cuts in case kPyW, kPyZ, kPyMb, and kPyMbNonDiff
f529e69b 1099 if ( (fProcess == kPyW ||
1100 fProcess == kPyZ ||
1101 fProcess == kPyMbDefault ||
1102 fProcess == kPyMb ||
6d2ec66d 1103 fProcess == kPyMbAtlasTuneMC09 ||
04081a91 1104 fProcess == kPyMbWithDirectPhoton ||
f529e69b 1105 fProcess == kPyMbNonDiffr)
0f6ee828 1106 && (fCutOnChild == 1) ) {
1107 if ( !CheckKinematicsOnChild() ) {
234f6d32 1108 delete[] pParent;
0f6ee828 1109 return 0;
1110 }
aea21c57 1111 }
1112
1113
f913ec4f 1114 for (i = 0; i < np; i++) {
8d2cd130 1115 Int_t trackIt = 0;
8507138f 1116 TParticle * iparticle = (TParticle *) fParticles.At(i);
8d2cd130 1117 kf = CheckPDGCode(iparticle->GetPdgCode());
1118 Int_t ks = iparticle->GetStatusCode();
1119 Int_t km = iparticle->GetFirstMother();
1120 if ((ks == 1 && kf!=0 && KinematicSelection(iparticle, 0)) ||
1121 (ks != 1) ||
9dfe63b3 1122 ((fProcess == kPyJets || fProcess == kPyBeautyJets) && ks == 21 && km == 0 && i>1)) {
8d2cd130 1123 nc++;
1124 if (ks == 1) trackIt = 1;
1125 Int_t ipa = iparticle->GetFirstMother()-1;
1126
1127 iparent = (ipa > -1) ? pParent[ipa] : -1;
1128
1129//
1130// store track information
1131 p[0] = iparticle->Px();
1132 p[1] = iparticle->Py();
1133 p[2] = iparticle->Pz();
a920faf9 1134 p[3] = iparticle->Energy();
1406f599 1135
a920faf9 1136
2590ccf9 1137 origin[0] = fVertex[0]+iparticle->Vx()/10; // [cm]
1138 origin[1] = fVertex[1]+iparticle->Vy()/10; // [cm]
1139 origin[2] = fVertex[2]+iparticle->Vz()/10; // [cm]
1140
f913ec4f 1141 Float_t tof = fEventTime + kconv * iparticle->T();
a920faf9 1142
1143 PushTrack(fTrackIt*trackIt, iparent, kf,
1144 p[0], p[1], p[2], p[3],
1145 origin[0], origin[1], origin[2], tof,
1146 polar[0], polar[1], polar[2],
1147 kPPrimary, nt, 1., ks);
dbd64db6 1148 fNprimaries++;
8d2cd130 1149 KeepTrack(nt);
1150 pParent[i] = nt;
f913ec4f 1151 SetHighWaterMark(nt);
1152
8d2cd130 1153 } // select particle
1154 } // particle loop
1155
234f6d32 1156 delete[] pParent;
e0e89f40 1157
f913ec4f 1158 return 1;
8d2cd130 1159}
1160
1161
1162void AliGenPythia::FinishRun()
1163{
1164// Print x-section summary
1165 fPythia->Pystat(1);
2779fc64 1166
1167 if (fNev > 0.) {
1168 fQ /= fNev;
1169 fX1 /= fNev;
1170 fX2 /= fNev;
1171 }
1172
8d2cd130 1173 printf("\nTotal number of Pyevnt() calls %d\n", fTrialsRun);
1174 printf("\nMean Q, x1, x2: %f %f %f\n", fQ, fX1, fX2);
8d2cd130 1175}
1176
7184e472 1177void AliGenPythia::AdjustWeights() const
8d2cd130 1178{
1179// Adjust the weights after generation of all events
1180//
e2bddf81 1181 if (gAlice) {
1182 TParticle *part;
1183 Int_t ntrack=gAlice->GetMCApp()->GetNtrack();
1184 for (Int_t i=0; i<ntrack; i++) {
1185 part= gAlice->GetMCApp()->Particle(i);
1186 part->SetWeight(part->GetWeight()*fKineBias);
1187 }
8d2cd130 1188 }
1189}
1190
20e47f08 1191void AliGenPythia::SetNuclei(Int_t a1, Int_t a2, Int_t pdfset)
8d2cd130 1192{
1193// Treat protons as inside nuclei with mass numbers a1 and a2
1d568bc2 1194
1a626d4e 1195 fAProjectile = a1;
1196 fATarget = a2;
20e47f08 1197 fNucPdf = pdfset; // 0 EKS98 1 EPS08
1d568bc2 1198 fSetNuclei = kTRUE;
8d2cd130 1199}
1200
1201
1202void AliGenPythia::MakeHeader()
1203{
7184e472 1204//
1205// Make header for the simulated event
1206//
183a5ca9 1207 if (gAlice) {
1208 if (gAlice->GetEvNumber()>=fDebugEventFirst &&
f913ec4f 1209 gAlice->GetEvNumber()<=fDebugEventLast) fPythia->Pylist(2);
183a5ca9 1210 }
1211
8d2cd130 1212// Builds the event header, to be called after each event
e5c87a3d 1213 if (fHeader) delete fHeader;
1214 fHeader = new AliGenPythiaEventHeader("Pythia");
8d2cd130 1215//
1216// Event type
e5c87a3d 1217 ((AliGenPythiaEventHeader*) fHeader)->SetProcessType(fPythia->GetMSTI(1));
8d2cd130 1218//
1219// Number of trials
e5c87a3d 1220 ((AliGenPythiaEventHeader*) fHeader)->SetTrials(fTrials);
8d2cd130 1221//
1222// Event Vertex
d25cfd65 1223 fHeader->SetPrimaryVertex(fVertex);
d07f0af2 1224 fHeader->SetInteractionTime(fEventTime);
dbd64db6 1225//
1226// Number of primaries
1227 fHeader->SetNProduced(fNprimaries);
8d2cd130 1228//
1229// Jets that have triggered
f913ec4f 1230
9dfe63b3 1231 //Need to store jets for b-jet studies too!
2f405d65 1232 if (fProcess == kPyJets || fProcess == kPyDirectGamma || fProcess == kPyBeautyJets || fProcess == kPyBeautyppMNRwmi)
8d2cd130 1233 {
1234 Int_t ntrig, njet;
1235 Float_t jets[4][10];
1236 GetJets(njet, ntrig, jets);
9ff6c04c 1237
8d2cd130 1238
1239 for (Int_t i = 0; i < ntrig; i++) {
e5c87a3d 1240 ((AliGenPythiaEventHeader*) fHeader)->AddJet(jets[0][i], jets[1][i], jets[2][i],
8d2cd130 1241 jets[3][i]);
1242 }
1243 }
5fa4b20b 1244//
1245// Copy relevant information from external header, if present.
1246//
1247 Float_t uqJet[4];
1248
1249 if (fRL) {
1250 AliGenPythiaEventHeader* exHeader = (AliGenPythiaEventHeader*) (fRL->GetHeader()->GenEventHeader());
1251 for (Int_t i = 0; i < exHeader->NTriggerJets(); i++)
1252 {
1253 printf("Adding Jet %d %d \n", i, exHeader->NTriggerJets());
1254
1255
1256 exHeader->TriggerJet(i, uqJet);
1257 ((AliGenPythiaEventHeader*) fHeader)->AddUQJet(uqJet[0], uqJet[1], uqJet[2], uqJet[3]);
1258 }
1259 }
1260//
1261// Store quenching parameters
1262//
1263 if (fQuench){
1264 Double_t z[4];
1265 Double_t xp, yp;
7c21f297 1266 if (fQuench == 1) {
1267 // Pythia::Quench()
1268 fPythia->GetQuenchingParameters(xp, yp, z);
1bab4b79 1269 } else if (fQuench == 2){
7c21f297 1270 // Pyquen
1271 Double_t r1 = PARIMP.rb1;
1272 Double_t r2 = PARIMP.rb2;
1273 Double_t b = PARIMP.b1;
1274 Double_t r = 0.5 * TMath::Sqrt(2. * (r1 * r1 + r2 * r2) - b * b);
1275 Double_t phi = PARIMP.psib1;
1276 xp = r * TMath::Cos(phi);
1277 yp = r * TMath::Sin(phi);
1278
1bab4b79 1279 } else if (fQuench == 4) {
1280 // QPythia
5831e75f 1281 Double_t xy[2];
e9719084 1282 Double_t i0i1[2];
1283 AliFastGlauber::Instance()->GetSavedXY(xy);
1284 AliFastGlauber::Instance()->GetSavedI0I1(i0i1);
5831e75f 1285 xp = xy[0];
1286 yp = xy[1];
e6fe9b82 1287 ((AliGenPythiaEventHeader*) fHeader)->SetImpactParameter(fImpact);
7c21f297 1288 }
1bab4b79 1289
7c21f297 1290 ((AliGenPythiaEventHeader*) fHeader)->SetXYJet(xp, yp);
1291 ((AliGenPythiaEventHeader*) fHeader)->SetZQuench(z);
1bab4b79 1292 }
beac474c 1293//
1294// Store pt^hard
1295 ((AliGenPythiaEventHeader*) fHeader)->SetPtHard(fPythia->GetVINT(47));
5fa4b20b 1296//
cf57b268 1297// Pass header
5fa4b20b 1298//
cf57b268 1299 AddHeader(fHeader);
4c4eac97 1300 fHeader = 0x0;
8d2cd130 1301}
cf57b268 1302
8d2cd130 1303Bool_t AliGenPythia::CheckTrigger(TParticle* jet1, TParticle* jet2)
1304{
1305// Check the kinematic trigger condition
1306//
1307 Double_t eta[2];
1308 eta[0] = jet1->Eta();
1309 eta[1] = jet2->Eta();
1310 Double_t phi[2];
1311 phi[0] = jet1->Phi();
1312 phi[1] = jet2->Phi();
1313 Int_t pdg[2];
1314 pdg[0] = jet1->GetPdgCode();
1315 pdg[1] = jet2->GetPdgCode();
1316 Bool_t triggered = kFALSE;
1317
2f405d65 1318 if (fProcess == kPyJets || fProcess == kPyBeautyJets || fProcess == kPyBeautyppMNRwmi) {
8d2cd130 1319 Int_t njets = 0;
1320 Int_t ntrig = 0;
1321 Float_t jets[4][10];
1322//
1323// Use Pythia clustering on parton level to determine jet axis
1324//
1325 GetJets(njets, ntrig, jets);
1326
76d6ba9a 1327 if (ntrig || fEtMinJet == 0.) triggered = kTRUE;
8d2cd130 1328//
1329 } else {
1330 Int_t ij = 0;
1331 Int_t ig = 1;
1332 if (pdg[0] == kGamma) {
1333 ij = 1;
1334 ig = 0;
1335 }
1336 //Check eta range first...
1337 if ((eta[ij] < fEtaMaxJet && eta[ij] > fEtaMinJet) &&
1338 (eta[ig] < fEtaMaxGamma && eta[ig] > fEtaMinGamma))
1339 {
1340 //Eta is okay, now check phi range
1341 if ((phi[ij] < fPhiMaxJet && phi[ij] > fPhiMinJet) &&
1342 (phi[ig] < fPhiMaxGamma && phi[ig] > fPhiMinGamma))
1343 {
1344 triggered = kTRUE;
1345 }
1346 }
1347 }
1348 return triggered;
1349}
aea21c57 1350
1351
aea21c57 1352
7184e472 1353Bool_t AliGenPythia::CheckKinematicsOnChild(){
1354//
1355//Checking Kinematics on Child (status code 1, particle code ?, kin cuts
1356//
aea21c57 1357 Bool_t checking = kFALSE;
1358 Int_t j, kcode, ks, km;
1359 Int_t nPartAcc = 0; //number of particles in the acceptance range
1360 Int_t numberOfAcceptedParticles = 1;
1361 if (fNumberOfAcceptedParticles != 0) { numberOfAcceptedParticles = fNumberOfAcceptedParticles; }
8507138f 1362 Int_t npart = fParticles.GetEntriesFast();
aea21c57 1363
0f6ee828 1364 for (j = 0; j<npart; j++) {
8507138f 1365 TParticle * jparticle = (TParticle *) fParticles.At(j);
aea21c57 1366 kcode = TMath::Abs( CheckPDGCode(jparticle->GetPdgCode()) );
1367 ks = jparticle->GetStatusCode();
1368 km = jparticle->GetFirstMother();
1369
1370 if( (ks == 1) && (kcode == fPdgCodeParticleforAcceptanceCut) && (KinematicSelection(jparticle,1)) ){
1371 nPartAcc++;
1372 }
0f6ee828 1373 if( numberOfAcceptedParticles <= nPartAcc){
1374 checking = kTRUE;
1375 break;
1376 }
aea21c57 1377 }
0f6ee828 1378
aea21c57 1379 return checking;
aea21c57 1380}
1381
5fa4b20b 1382void AliGenPythia::LoadEvent(AliStack* stack, Int_t flag, Int_t reHadr)
8d2cd130 1383{
1058d9df 1384 //
1385 // Load event into Pythia Common Block
1386 //
1387
1388 Int_t npart = stack -> GetNprimary();
1389 Int_t n0 = 0;
1390
1391 if (!flag) {
1392 (fPythia->GetPyjets())->N = npart;
1393 } else {
1394 n0 = (fPythia->GetPyjets())->N;
1395 (fPythia->GetPyjets())->N = n0 + npart;
1396 }
1397
1398
1399 for (Int_t part = 0; part < npart; part++) {
1400 TParticle *mPart = stack->Particle(part);
32d6ef7d 1401
1058d9df 1402 Int_t kf = mPart->GetPdgCode();
1403 Int_t ks = mPart->GetStatusCode();
1404 Int_t idf = mPart->GetFirstDaughter();
1405 Int_t idl = mPart->GetLastDaughter();
1406
1407 if (reHadr) {
1408 if (ks == 11 || ks == 12) {
1409 ks -= 10;
1410 idf = -1;
1411 idl = -1;
1412 }
32d6ef7d 1413 }
1414
1058d9df 1415 Float_t px = mPart->Px();
1416 Float_t py = mPart->Py();
1417 Float_t pz = mPart->Pz();
1418 Float_t e = mPart->Energy();
1419 Float_t m = mPart->GetCalcMass();
32d6ef7d 1420
1058d9df 1421
1422 (fPythia->GetPyjets())->P[0][part+n0] = px;
1423 (fPythia->GetPyjets())->P[1][part+n0] = py;
1424 (fPythia->GetPyjets())->P[2][part+n0] = pz;
1425 (fPythia->GetPyjets())->P[3][part+n0] = e;
1426 (fPythia->GetPyjets())->P[4][part+n0] = m;
1427
1428 (fPythia->GetPyjets())->K[1][part+n0] = kf;
1429 (fPythia->GetPyjets())->K[0][part+n0] = ks;
1430 (fPythia->GetPyjets())->K[3][part+n0] = idf + 1;
1431 (fPythia->GetPyjets())->K[4][part+n0] = idl + 1;
1432 (fPythia->GetPyjets())->K[2][part+n0] = mPart->GetFirstMother() + 1;
1433 }
1434}
1435
1436void AliGenPythia::LoadEvent(TObjArray* stack, Int_t flag, Int_t reHadr)
1437{
1438 //
1439 // Load event into Pythia Common Block
1440 //
1441
1442 Int_t npart = stack -> GetEntries();
1443 Int_t n0 = 0;
1444
1445 if (!flag) {
1446 (fPythia->GetPyjets())->N = npart;
1447 } else {
1448 n0 = (fPythia->GetPyjets())->N;
1449 (fPythia->GetPyjets())->N = n0 + npart;
1450 }
1451
1452
1453 for (Int_t part = 0; part < npart; part++) {
1454 TParticle *mPart = dynamic_cast<TParticle *>(stack->At(part));
1455 Int_t kf = mPart->GetPdgCode();
1456 Int_t ks = mPart->GetStatusCode();
1457 Int_t idf = mPart->GetFirstDaughter();
1458 Int_t idl = mPart->GetLastDaughter();
1459
1460 if (reHadr) {
5fa4b20b 1461 if (ks == 11 || ks == 12) {
1058d9df 1462 ks -= 10;
1463 idf = -1;
1464 idl = -1;
5fa4b20b 1465 }
8d2cd130 1466 }
1058d9df 1467
1468 Float_t px = mPart->Px();
1469 Float_t py = mPart->Py();
1470 Float_t pz = mPart->Pz();
1471 Float_t e = mPart->Energy();
1472 Float_t m = mPart->GetCalcMass();
1473
1474
1475 (fPythia->GetPyjets())->P[0][part+n0] = px;
1476 (fPythia->GetPyjets())->P[1][part+n0] = py;
1477 (fPythia->GetPyjets())->P[2][part+n0] = pz;
1478 (fPythia->GetPyjets())->P[3][part+n0] = e;
1479 (fPythia->GetPyjets())->P[4][part+n0] = m;
1480
1481 (fPythia->GetPyjets())->K[1][part+n0] = kf;
1482 (fPythia->GetPyjets())->K[0][part+n0] = ks;
1483 (fPythia->GetPyjets())->K[3][part+n0] = idf + 1;
1484 (fPythia->GetPyjets())->K[4][part+n0] = idl + 1;
1485 (fPythia->GetPyjets())->K[2][part+n0] = mPart->GetFirstMother() + 1;
1486 }
8d2cd130 1487}
1488
5fa4b20b 1489
014a9521 1490void AliGenPythia::RecJetsUA1(Int_t& njets, Float_t jets [4][50])
8d2cd130 1491{
1492//
1493// Calls the Pythia jet finding algorithm to find jets in the current event
1494//
1495//
8d2cd130 1496//
1497// Save jets
1498 Int_t n = fPythia->GetN();
1499
1500//
1501// Run Jet Finder
1502 fPythia->Pycell(njets);
1503 Int_t i;
1504 for (i = 0; i < njets; i++) {
1505 Float_t px = (fPythia->GetPyjets())->P[0][n+i];
1506 Float_t py = (fPythia->GetPyjets())->P[1][n+i];
1507 Float_t pz = (fPythia->GetPyjets())->P[2][n+i];
1508 Float_t e = (fPythia->GetPyjets())->P[3][n+i];
1509
1510 jets[0][i] = px;
1511 jets[1][i] = py;
1512 jets[2][i] = pz;
1513 jets[3][i] = e;
1514 }
1515}
1516
1517
1518
1519void AliGenPythia::GetJets(Int_t& nJets, Int_t& nJetsTrig, Float_t jets[4][10])
1520{
1521//
1522// Calls the Pythia clustering algorithm to find jets in the current event
1523//
1524 Int_t n = fPythia->GetN();
1525 nJets = 0;
1526 nJetsTrig = 0;
1527 if (fJetReconstruction == kCluster) {
1528//
1529// Configure cluster algorithm
1530//
1531 fPythia->SetPARU(43, 2.);
1532 fPythia->SetMSTU(41, 1);
1533//
1534// Call cluster algorithm
1535//
1536 fPythia->Pyclus(nJets);
1537//
1538// Loading jets from common block
1539//
1540 } else {
592f8307 1541
8d2cd130 1542//
1543// Run Jet Finder
1544 fPythia->Pycell(nJets);
1545 }
1546
1547 Int_t i;
1548 for (i = 0; i < nJets; i++) {
1549 Float_t px = (fPythia->GetPyjets())->P[0][n+i];
1550 Float_t py = (fPythia->GetPyjets())->P[1][n+i];
1551 Float_t pz = (fPythia->GetPyjets())->P[2][n+i];
1552 Float_t e = (fPythia->GetPyjets())->P[3][n+i];
1553 Float_t pt = TMath::Sqrt(px * px + py * py);
a920faf9 1554 Float_t phi = TMath::Pi() + TMath::ATan2(-py, -px);
8d2cd130 1555 Float_t theta = TMath::ATan2(pt,pz);
1556 Float_t et = e * TMath::Sin(theta);
1557 Float_t eta = -TMath::Log(TMath::Tan(theta / 2.));
8d2cd130 1558 if (
1559 eta > fEtaMinJet && eta < fEtaMaxJet &&
675eb105 1560 phi > fPhiMinJet && phi < fPhiMaxJet &&
8d2cd130 1561 et > fEtMinJet && et < fEtMaxJet
1562 )
1563 {
1564 jets[0][nJetsTrig] = px;
1565 jets[1][nJetsTrig] = py;
1566 jets[2][nJetsTrig] = pz;
1567 jets[3][nJetsTrig] = e;
1568 nJetsTrig++;
5fa4b20b 1569// printf("\n........-Jet #%d: %10.3f %10.3f %10.3f %10.3f \n", i, pt, et, eta, phi * kRaddeg);
8d2cd130 1570 } else {
1571// printf("\n........-Jet #%d: %10.3f %10.3f %10.3f %10.3f \n", i, pt, et, eta, phi * kRaddeg);
1572 }
1573 }
1574}
1575
f913ec4f 1576void AliGenPythia::GetSubEventTime()
1577{
1578 // Calculates time of the next subevent
9d7108a7 1579 fEventTime = 0.;
1580 if (fEventsTime) {
1581 TArrayF &array = *fEventsTime;
1582 fEventTime = array[fCurSubEvent++];
1583 }
1584 // printf(" Event time: %d %f %p",fCurSubEvent,fEventTime,fEventsTime);
1585 return;
f913ec4f 1586}
8d2cd130 1587
ec2c406e 1588Bool_t AliGenPythia::IsInEMCAL(Float_t phi, Float_t eta)
1589{
1590 // Is particle in EMCAL acceptance?
ec2c406e 1591 // phi in degrees, etamin=-etamax
9fd8e520 1592 if(phi > fEMCALMinPhi && phi < fEMCALMaxPhi &&
1593 eta < fEMCALEta )
ec2c406e 1594 return kTRUE;
1595 else
1596 return kFALSE;
1597}
1598
1599Bool_t AliGenPythia::IsInPHOS(Float_t phi, Float_t eta)
1600{
1601 // Is particle in PHOS acceptance?
1602 // Acceptance slightly larger considered.
1603 // phi in degrees, etamin=-etamax
9fd8e520 1604 if(phi > fPHOSMinPhi && phi < fPHOSMaxPhi &&
1605 eta < fPHOSEta )
ec2c406e 1606 return kTRUE;
1607 else
1608 return kFALSE;
1609}
1610
90a236ce 1611void AliGenPythia::RotatePhi(Int_t iphcand, Bool_t& okdd)
1612{
1613 //calculate the new position random between fPHOSMinPhi and fPHOSMaxPhi
1614 Double_t phiPHOSmin = TMath::Pi()*fPHOSMinPhi/180;
1615 Double_t phiPHOSmax = TMath::Pi()*fPHOSMaxPhi/180;
1616 Double_t phiPHOS = gRandom->Uniform(phiPHOSmin,phiPHOSmax);
1617
1618 //calculate deltaphi
8507138f 1619 TParticle* ph = (TParticle *) fParticles.At(iphcand);
90a236ce 1620 Double_t phphi = ph->Phi();
1621 Double_t deltaphi = phiPHOS - phphi;
1622
1623
1624
1625 //loop for all particles and produce the phi rotation
8507138f 1626 Int_t np = (fHadronisation) ? fParticles.GetEntriesFast() : fNpartons;
90a236ce 1627 Double_t oldphi, newphi;
1628 Double_t newVx, newVy, R, Vz, time;
1629 Double_t newPx, newPy, pt, Pz, e;
1630 for(Int_t i=0; i< np; i++) {
8507138f 1631 TParticle* iparticle = (TParticle *) fParticles.At(i);
90a236ce 1632 oldphi = iparticle->Phi();
1633 newphi = oldphi + deltaphi;
1634 if(newphi < 0) newphi = 2*TMath::Pi() + newphi; // correct angle
1635 if(newphi > 2*TMath::Pi()) newphi = newphi - 2*TMath::Pi(); // correct angle
1636
1637 R = iparticle->R();
1638 newVx = R*TMath::Cos(newphi);
1639 newVy = R*TMath::Sin(newphi);
1640 Vz = iparticle->Vz(); // don't transform
1641 time = iparticle->T(); // don't transform
1642
1643 pt = iparticle->Pt();
1644 newPx = pt*TMath::Cos(newphi);
1645 newPy = pt*TMath::Sin(newphi);
1646 Pz = iparticle->Pz(); // don't transform
1647 e = iparticle->Energy(); // don't transform
1648
1649 // apply rotation
1650 iparticle->SetProductionVertex(newVx, newVy, Vz, time);
1651 iparticle->SetMomentum(newPx, newPy, Pz, e);
1652
1653 } //end particle loop
1654
1655 // now let's check that we put correctly the candidate photon in PHOS
1656 Float_t phi = ph->Phi()*180./TMath::Pi(); //Convert to degrees
1657 Float_t eta =TMath::Abs(ph->Eta());//in calos etamin=-etamax
1658 if(IsInPHOS(phi,eta))
1659 okdd = kTRUE;
1660}
ec2c406e 1661
1662
8d2cd130 1663#ifdef never
1664void AliGenPythia::Streamer(TBuffer &R__b)
1665{
1666 // Stream an object of class AliGenPythia.
1667
1668 if (R__b.IsReading()) {
1669 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1670 AliGenerator::Streamer(R__b);
1671 R__b >> (Int_t&)fProcess;
1672 R__b >> (Int_t&)fStrucFunc;
1673 R__b >> (Int_t&)fForceDecay;
1674 R__b >> fEnergyCMS;
1675 R__b >> fKineBias;
1676 R__b >> fTrials;
1677 fParentSelect.Streamer(R__b);
1678 fChildSelect.Streamer(R__b);
1679 R__b >> fXsection;
1680// (AliPythia::Instance())->Streamer(R__b);
1681 R__b >> fPtHardMin;
1682 R__b >> fPtHardMax;
1683// if (fDecayer) fDecayer->Streamer(R__b);
1684 } else {
1685 R__b.WriteVersion(AliGenPythia::IsA());
1686 AliGenerator::Streamer(R__b);
1687 R__b << (Int_t)fProcess;
1688 R__b << (Int_t)fStrucFunc;
1689 R__b << (Int_t)fForceDecay;
1690 R__b << fEnergyCMS;
1691 R__b << fKineBias;
1692 R__b << fTrials;
1693 fParentSelect.Streamer(R__b);
1694 fChildSelect.Streamer(R__b);
1695 R__b << fXsection;
1696// R__b << fPythia;
1697 R__b << fPtHardMin;
1698 R__b << fPtHardMax;
1699 // fDecayer->Streamer(R__b);
1700 }
1701}
1702#endif
1703
90d7b703 1704
589380c6 1705