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