doxy: consider comments after last line
[u/mrichter/AliRoot.git] / EVGEN / AliGenCocktailAfterBurner.cxx
CommitLineData
0b359ada 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
88cb7938 16/* $Id$ */
17
0b359ada 18//
19// Container class for AliGenerator and AfterBurners
20// (which are AliGenerators as well) through recursion.
21// The container is itself an AliGenerator a
22// what is stored are not the pointers to the generators directly
23// but to objects of type
24// AliGenCocktailAfterBurner entry.
25// The class provides also iterator functionality.
26// Author: andreas.morsch@cern.ch and piotr.skowronski@cern.ch
27//
2b9786f4 28// 24.09.2001 Piotr Skowronski
29// debug -> gDebug,
124253ee 30// fNEvents replaced with AliRunLoader::GetNumberOfEvents()
2b9786f4 31//
2b9786f4 32
88cb7938 33
34#include <Riostream.h>
35
0b359ada 36#include <TList.h>
88cb7938 37#include <TObjArray.h>
0b359ada 38#include <TParticle.h>
88cb7938 39
40#include "AliGenCocktailAfterBurner.h"
41#include "AliGenCocktailEntry.h"
baf77725 42#include "AliGenCocktailEventHeader.h"
cc41459d 43#include "AliCollisionGeometry.h"
88cb7938 44#include "AliStack.h"
5d12ce38 45#include "AliMC.h"
4a33c50d 46#include "AliRun.h"
0b359ada 47
83cb58d0 48using std::cout;
49using std::endl;
0b359ada 50ClassImp(AliGenCocktailAfterBurner)
2b9786f4 51/*********************************************************************/
52/*********************************************************************/
0b359ada 53
1c56e311 54 AliGenCocktailAfterBurner::AliGenCocktailAfterBurner():
55 fNAfterBurners(0),
4a33c50d 56 fAfterBurnerEntries(0),
1c56e311 57 fGenerationDone(kFALSE),
58 fInternalStacks(0),
59 fCollisionGeometries(0),
9c64a93a 60 fHeaders(0),
1c56e311 61 fCurrentEvent(0),
62 fActiveStack(0),
63 fActiveEvent(-1),
64 fCurrentGenerator(0),
65 fNBgEvents(0)
0b359ada 66{
67// Constructor
2b9786f4 68 if (gDebug > 0)
1c56e311 69 cout<<"AliGenCocktailAfterBurner::AliGenCocktailAfterBurner()"<<endl;
0b359ada 70 SetName("AliGenCocktailAfterBurner");
71 SetTitle("AliGenCocktailAfterBurner");
0b359ada 72}
20dddfab 73
2b9786f4 74/*********************************************************************/
0b359ada 75
76AliGenCocktailAfterBurner::~AliGenCocktailAfterBurner()
77 {
2b9786f4 78//destructor
79
80 if (fInternalStacks) //delete stacks
81 {
82 fInternalStacks->SetOwner();
83 delete fInternalStacks;
84 }
85 if (fAfterBurnerEntries) delete fAfterBurnerEntries; //delete entries
6bcdf1d1 86 Int_t numberOfEvents = AliRunLoader::Instance()->GetNumberOfEventsPerRun();
87 if (fCollisionGeometries) {
88 for (Int_t i = 0; i < (numberOfEvents + fNBgEvents); i++)
89 if (fCollisionGeometries[i]) delete fCollisionGeometries[i];
90 delete[] fCollisionGeometries;
91 }
92 if (fHeaders) {
93 for (Int_t i = 0; i < (numberOfEvents + fNBgEvents); i++)
94 if (fHeaders[i]) delete fHeaders[i];
95 delete[] fHeaders;
96 }
0b359ada 97 }
2b9786f4 98/*********************************************************************/
99/*********************************************************************/
0b359ada 100
101void AliGenCocktailAfterBurner::
f5a3c6e4 102AddAfterBurner(AliGenerator *AfterBurner, const char* Name, Float_t RateExp)
0b359ada 103{
104//
105// Forward parameters to the new AfterBurner
106
2b9786f4 107 if (gDebug>0)cout<<"AliGenCocktailAfterBurner::AddAfterBurner Named "<<Name<<endl;
0b359ada 108
565cc9c0 109 if(TestBit(kPtRange) && !(AfterBurner->TestBit(kPtRange)) && !(AfterBurner->TestBit(kMomentumRange)))
0b359ada 110 AfterBurner->SetPtRange(fPtMin,fPtMax);
565cc9c0 111 if(TestBit(kMomentumRange) && !(AfterBurner->TestBit(kPtRange)) && !(AfterBurner->TestBit(kMomentumRange)))
0b359ada 112 AfterBurner->SetMomentumRange(fPMin,fPMax);
113
565cc9c0 114 if (TestBit(kYRange) && !(AfterBurner->TestBit(kYRange)))
115 AfterBurner->SetYRange(fYMin,fYMax);
116 if (TestBit(kPhiRange) && !(AfterBurner->TestBit(kPhiRange)))
117 AfterBurner->SetPhiRange(fPhiMin*180/TMath::Pi(),fPhiMax*180/TMath::Pi());
118 if (TestBit(kThetaRange) && !(AfterBurner->TestBit(kThetaRange)) && !(AfterBurner->TestBit(kEtaRange)))
119 AfterBurner->SetThetaRange(fThetaMin*180/TMath::Pi(),fThetaMax*180/TMath::Pi());
fd2aa4bf 120 if (!(AfterBurner->TestBit(kVertexRange))) {
565cc9c0 121 AfterBurner->SetOrigin(fOrigin[0], fOrigin[1], fOrigin[2]);
122 AfterBurner->SetSigma(fOsigma[0], fOsigma[1], fOsigma[2]);
123 AfterBurner->SetVertexSmear(fVertexSmear);
124 AfterBurner->SetVertexSource(kContainer);
21391258 125 AfterBurner->SetTimeOrigin(fTimeOrigin);
565cc9c0 126 }
127 AfterBurner->SetTrackingFlag(fTrackIt);
128 //AfterBurner->SetContainer(this);
129
0b359ada 130//
131// Add AfterBurner to list
132
133 AliGenCocktailEntry *entry =
134 new AliGenCocktailEntry(AfterBurner, Name, RateExp);
4a33c50d 135 if (!fAfterBurnerEntries) fAfterBurnerEntries = new TList();
136
0b359ada 137 fAfterBurnerEntries->Add(entry);
138 fNAfterBurners++;
984c69bd 139//
984c69bd 140
0b359ada 141}
2b9786f4 142/*********************************************************************/
143/*********************************************************************/
0b359ada 144
145void AliGenCocktailAfterBurner::Init()
146{
147// Initialisation
6bcdf1d1 148 Int_t numberOfEvents = AliRunLoader::Instance()->GetNumberOfEventsPerRun();
2b9786f4 149 fGenerationDone = kFALSE;
466bfded 150 if (fInternalStacks) //delete stacks
151 {
152 fInternalStacks->SetOwner();
153 fInternalStacks->Delete(); //clean after previous generation cycle
154 }
155
6bcdf1d1 156 if (fCollisionGeometries) {
157 for (Int_t i = 0; i < (numberOfEvents + fNBgEvents); i++)
158 if (fCollisionGeometries[i]) delete fCollisionGeometries[i];
159 delete[] fCollisionGeometries;
160 }
161 if (fHeaders) {
162 for (Int_t i = 0; i < (numberOfEvents + fNBgEvents); i++)
163 if (fHeaders[i]) delete fHeaders[i];
164 delete[] fHeaders;
165 }
166
0b359ada 167 this->AliGenCocktail::Init();
168
2b9786f4 169 if (gDebug>0) cout<<"AliGenCocktailAfterBurner::Init"<<endl;
0b359ada 170 TIter next(fAfterBurnerEntries);
171 AliGenCocktailEntry *entry;
172 //
173 // Loop over generators and initialize
174 while((entry = (AliGenCocktailEntry*)next())) {
175 entry->Generator()->Init();
176 }
177}
2b9786f4 178/*********************************************************************/
179/*********************************************************************/
0b359ada 180
181void AliGenCocktailAfterBurner::Generate()
182{
183//
2b9786f4 184// Generate event
185// Firsts runs each generator for all events
186// than after burners ones for each event
187//
188// It generates and processes all events during
189// first call only.
190// In next calls it just returns already generated
191// and processed events to the gAlice
192
193 if (gDebug>0)
194 cout<<"#####################################"<<endl
195 <<"#AliGenCocktailAfterBurner::Generate#"<<endl
196 <<"#####################################"<<endl;
baf77725 197 // Initialize header
baf77725 198 //
0b359ada 199 Int_t i; //iterator
200 AliStack * stack;
2b9786f4 201
0b359ada 202 if (fGenerationDone)
2b9786f4 203 {//if generation is done (in first call)
204 //just copy particles from the stack to the gAlice
205 SetTracks(++fCurrentEvent);
9c64a93a 206 fHeader = fHeaders[fCurrentEvent];
207 gAlice->SetGenEventHeader(fHeader);
208 cout<<"Returning event " << fCurrentEvent<<endl;
2b9786f4 209 return;
0b359ada 210 }
211 else
2b9786f4 212 { //Here we are in the first call of the method
9c64a93a 213 Int_t numberOfEvents = AliRunLoader::Instance()->GetNumberOfEventsPerRun();
214 cout << "Number of events per run" << numberOfEvents << endl;
215 TArrayF eventVertex;
216 eventVertex.Set(3 * (numberOfEvents + fNBgEvents));
21391258 217 TArrayF eventTime;
218 eventTime.Set(numberOfEvents + fNBgEvents);
9c64a93a 219 fCurrentEvent=0;
2b9786f4 220 //Create stacks
9c64a93a 221 fInternalStacks = new TObjArray(numberOfEvents + fNBgEvents); //Create array of internal stacks
222 fCollisionGeometries = new AliCollisionGeometry*[numberOfEvents + fNBgEvents]; //Create array of collision geometries
223 fHeaders = new AliGenCocktailEventHeader*[numberOfEvents + fNBgEvents]; //Create array of headers
224
225 for(i = 0; i < numberOfEvents + fNBgEvents; i++)
2b9786f4 226 {
9c64a93a 227 stack = new AliStack(10000);
228 stack->Reset();
229 fInternalStacks->Add(stack);
230 Vertex();
231 for (Int_t j = 0; j < 3; j++) eventVertex[3 * i + j] = fVertex[j];
21391258 232 eventTime[i] = fTime;
0709d8b9 233 fHeaders[i] = new AliGenCocktailEventHeader();
ace4fb76 234 fCollisionGeometries[i] = 0;
2b9786f4 235 }
0b359ada 236/*********************************************************************/
2b9786f4 237 TIter next(fEntries);
238 AliGenCocktailEntry *entry;
239 AliGenCocktailEntry *e1;
240 AliGenCocktailEntry *e2;
d94af0c1 241 const TObjArray *partArray;
2b9786f4 242 //
243 // Loop over generators and generate events
244 Int_t igen=0;
245 while((entry = (AliGenCocktailEntry*)next()))
246 {
247 igen++;
248 cout<<"Generator "<<igen<<" : "<<entry->GetName()<<endl;
249/***********************************************/
0b359ada 250//First generator for all evenets, than second for all events, etc...
9c64a93a 251 for(i = 0; i < numberOfEvents + fNBgEvents; i++)
59fe7b77 252 {
253 cout<<" EVENT "<<i << endl;
2b9786f4 254 stack = GetStack(i);
255 partArray = stack->Particles();
256 fCurrentGenerator = entry->Generator();
257 fCurrentGenerator->SetStack(stack);
258 if (igen ==1)
59fe7b77 259 {
2b9786f4 260 entry->SetFirst(0);
59fe7b77 261 }
2b9786f4 262 else
59fe7b77 263 {
2b9786f4 264 entry->SetFirst((partArray->GetEntriesFast())+1);
59fe7b77 265 }
9c64a93a 266 // Set the vertex for the generator
267 Int_t ioff = 3 * i;
268 fCurrentGenerator->SetVertex(eventVertex.At(ioff), eventVertex.At(ioff + 1), eventVertex.At(ioff + 2));
21391258 269 fCurrentGenerator->SetTime(eventTime.At(i));
9c64a93a 270 fHeader = fHeaders[i];
21391258 271 // Set the vertex and time for the cocktail
9c64a93a 272 TArrayF v(3);
273 for (Int_t j=0; j<3; j++) v[j] = eventVertex.At(ioff + j);
274 fHeader->SetPrimaryVertex(v);
21391258 275 fHeader->SetInteractionTime(eventTime.At(i));
9c64a93a 276 // Generate event
59fe7b77 277 fCurrentGenerator->Generate();
9c64a93a 278 //
59fe7b77 279 entry->SetLast(partArray->GetEntriesFast());
280
2f3fd0f1 281 if (fCurrentGenerator->ProvidesCollisionGeometry())
282 fCollisionGeometries[i] =
283 new AliCollisionGeometry(*(fCurrentGenerator->CollisionGeometry()));
9c64a93a 284 } // event loop
2b9786f4 285/***********************************************/
9c64a93a 286 } // generator loop
2b9786f4 287 next.Reset();
288 while((entry = (AliGenCocktailEntry*)next()))
289 {
290 entry->PrintInfo();
291 }
292 for ( entry=FirstGenerator();entry;entry=NextGenerator() )
293 {
294 entry->PrintInfo();
295 }
296 for (FirstGeneratorPair(e1,e2); (e1&&e2); NextGeneratorPair(e1,e2) )
297 {
298 printf("\n -----------------------------");
299 e1->PrintInfo();
300 e2->PrintInfo();
0b359ada 301 }
302
0b359ada 303
2b9786f4 304 /***********************************************/
305 /*******After Burners Processing****************/
306 /***********************************************/
307 TIter nextAfterBurner(fAfterBurnerEntries);
308 AliGenCocktailEntry *afterBurnerEntry;
309 Int_t iab =0; //number of current after burner / counter
310
311 cout<<"\n\nRunning After Burners"<<endl;
312 while((afterBurnerEntry = (AliGenCocktailEntry*)nextAfterBurner()))
313 {
314 cout<<"After Burner "<<iab++<<" :"<<afterBurnerEntry->GetName()<<endl;
315 fCurrentGenerator = afterBurnerEntry->Generator();
316 fCurrentGenerator->Generate();
317 }
318 cout<<endl<<"Finished. Processed "<<iab<<" After Burners"<<endl;
319
320 /***********************************************/
321 /***********************************************/
322 /***********************************************/
0b359ada 323
2b9786f4 324 fGenerationDone=kTRUE;
325 SetTracks(0); //copy event 0 to gAlice stack
0b359ada 326
327/*********************************************************************/
baf77725 328 // Pass the header to gAlice
9c64a93a 329 fHeader = fHeaders[0];
baf77725 330 gAlice->SetGenEventHeader(fHeader);
9c64a93a 331 } //else generated
0b359ada 332}
2b9786f4 333/*********************************************************************/
334/*********************************************************************/
0b359ada 335
20dddfab 336AliStack* AliGenCocktailAfterBurner::GetStack(Int_t n) const
0b359ada 337{
2b9786f4 338//Returns the pointer to the N'th stack (event)
c516e34c 339 if( ( n<0 ) || ( n >= (GetNumberOfEvents()) ) )
0b359ada 340 {
2b9786f4 341 Fatal("AliGenCocktailAfterBurner::GetStack","Asked for non existing stack (%d)",n);
342 return 0;
0b359ada 343 }
2682e810 344 return ((AliStack*) fInternalStacks->At(n) );
0b359ada 345}
cc41459d 346
347/*********************************************************************/
348/*********************************************************************/
349
cc41459d 350AliCollisionGeometry* AliGenCocktailAfterBurner::GetCollisionGeometry(Int_t n) const
351{
352//Returns the pointer to the N'th stack (event)
353 if( ( n<0 ) || ( n>=GetNumberOfEvents() ) )
354 {
355 Fatal("AliGenCocktailAfterBurner::GetCollisionGeometry","Asked for non existing stack (%d)",n);
356 return 0;
357 }
358 return fCollisionGeometries[n];
359}
360
2b9786f4 361/*********************************************************************/
362/*********************************************************************/
0b359ada 363
364void AliGenCocktailAfterBurner::SetActiveEventNumber(Int_t actev)
365{
2b9786f4 366//Set Active Events Number and Active Stack
367//There is only one active event number
368//Made fo convinience of work with AfterBurners (HBT processor)
369
0b359ada 370 fActiveEvent = actev;
371 fActiveStack = GetStack(actev);
372}
2b9786f4 373/*********************************************************************/
374/*********************************************************************/
0b359ada 375
376void AliGenCocktailAfterBurner::SetTracks(Int_t stackno)
377{
2b9786f4 378//Method which copies tracks from given stack to the
379//gAlice's stack
0b359ada 380 AliStack* instack = GetStack(stackno);
381 Int_t done;
382 Int_t parent;
383 Int_t pdg;
384 Double_t px, py, pz, e, vx, vy, vz, tof, polx, poly, polz;
acc86a24 385 TMCProcess mech;
0b359ada 386 Int_t ntr;
387 Float_t weight;
388 TVector3 pol;
e68884ae 389 Int_t is;
0b359ada 390
391 TParticle * p;
20dddfab 392 Int_t n = instack->GetNtrack();
2b9786f4 393 if (gDebug)
0b359ada 394 {
20dddfab 395 cout<<"AliGenCocktailAfterBurner::SetTracks("<<stackno<<"). Number of particles is: "<<n<<"\n";
0b359ada 396 }
397
20dddfab 398 for(Int_t i = 0; i < n; i++)
0b359ada 399 {
400
2b9786f4 401 p = instack->Particle(i);
402 done = !p->TestBit(kDoneBit);
403 parent = p->GetMother(0);
404 pdg = p->GetPdgCode();
405 px = p->Px();
406 py = p->Py();
407 pz = p->Pz();
408 e = p->Energy();
409 vx = p->Vx();
410 vy = p->Vy();
411 vz = p->Vz();
412 tof = p->T();
413 p->GetPolarisation(pol);
414 polx = pol.X();
415 poly = pol.Y();
416 polz = pol.Z();
417 mech = AliGenCocktailAfterBurner::IntToMCProcess(p->GetUniqueID());
418 weight = p->GetWeight();
e68884ae 419 is = p->GetStatusCode();
2b9786f4 420
e68884ae 421 gAlice->GetMCApp()->PushTrack(done, parent, pdg, px, py, pz, e, vx, vy, vz, tof,polx, poly, polz, mech, ntr, weight, is);
cc41459d 422
cc41459d 423 SetHighWaterMark(ntr) ;
cc41459d 424
0b359ada 425 }
426}
2b9786f4 427/*********************************************************************/
428/*********************************************************************/
0b359ada 429
acc86a24 430TMCProcess AliGenCocktailAfterBurner::IntToMCProcess(Int_t no)
0b359ada 431{
acc86a24 432 //Mothod used to convert uniqueID (integer) to TMCProcess type
433 const TMCProcess kMCprocesses[kMaxMCProcess] =
2b9786f4 434 {
435 kPNoProcess, kPMultipleScattering, kPEnergyLoss, kPMagneticFieldL,
0b359ada 436 kPDecay, kPPair, kPCompton, kPPhotoelectric, kPBrem, kPDeltaRay,
437 kPAnnihilation, kPHadronic, kPNoProcess, kPEvaporation, kPNuclearFission,
438 kPNuclearAbsorption, kPPbarAnnihilation, kPNCapture, kPHElastic,
439 kPHInhelastic, kPMuonNuclear, kPTOFlimit,kPPhotoFission, kPNoProcess,
2b9786f4 440 kPRayleigh, kPNoProcess, kPNoProcess, kPNoProcess, kPNull, kPStop
441 };
0b359ada 442
443 for (Int_t i = 0;i<kMaxMCProcess;i++)
444 {
20dddfab 445 if (kMCprocesses[i] == no)
2b9786f4 446 {
20dddfab 447 return kMCprocesses[i];
2b9786f4 448 }
0b359ada 449 }
450 return kPNoProcess;
451}
198bb1c7 452