1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
19 // 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
28 // 24.09.2001 Piotr Skowronski
30 // fNEvents replaced with AliRunLoader::GetNumberOfEvents()
34 #include <Riostream.h>
37 #include <TObjArray.h>
38 #include <TParticle.h>
40 #include "AliGenCocktailAfterBurner.h"
41 #include "AliGenCocktailEntry.h"
42 #include "AliGenCocktailEventHeader.h"
43 #include "AliCollisionGeometry.h"
49 ClassImp(AliGenCocktailAfterBurner)
50 /*********************************************************************/
51 /*********************************************************************/
53 AliGenCocktailAfterBurner::AliGenCocktailAfterBurner():
55 fAfterBurnerEntries(0),
56 fGenerationDone(kFALSE),
58 fCollisionGeometries(0),
68 cout<<"AliGenCocktailAfterBurner::AliGenCocktailAfterBurner()"<<endl;
69 SetName("AliGenCocktailAfterBurner");
70 SetTitle("AliGenCocktailAfterBurner");
73 /*********************************************************************/
75 AliGenCocktailAfterBurner::~AliGenCocktailAfterBurner()
79 if (fInternalStacks) //delete stacks
81 fInternalStacks->SetOwner();
82 delete fInternalStacks;
84 if (fAfterBurnerEntries) delete fAfterBurnerEntries; //delete entries
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;
92 for (Int_t i = 0; i < (numberOfEvents + fNBgEvents); i++)
93 if (fHeaders[i]) delete fHeaders[i];
97 /*********************************************************************/
98 /*********************************************************************/
100 void AliGenCocktailAfterBurner::
101 AddAfterBurner(AliGenerator *AfterBurner, char* Name, Float_t RateExp)
104 // Forward parameters to the new AfterBurner
106 if (gDebug>0)cout<<"AliGenCocktailAfterBurner::AddAfterBurner Named "<<Name<<endl;
108 if(TestBit(kPtRange) && !(AfterBurner->TestBit(kPtRange)) && !(AfterBurner->TestBit(kMomentumRange)))
109 AfterBurner->SetPtRange(fPtMin,fPtMax);
110 if(TestBit(kMomentumRange) && !(AfterBurner->TestBit(kPtRange)) && !(AfterBurner->TestBit(kMomentumRange)))
111 AfterBurner->SetMomentumRange(fPMin,fPMax);
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 (!(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);
124 AfterBurner->SetTimeOrigin(fTimeOrigin);
126 AfterBurner->SetTrackingFlag(fTrackIt);
127 //AfterBurner->SetContainer(this);
130 // Add AfterBurner to list
132 AliGenCocktailEntry *entry =
133 new AliGenCocktailEntry(AfterBurner, Name, RateExp);
134 if (!fAfterBurnerEntries) fAfterBurnerEntries = new TList();
136 fAfterBurnerEntries->Add(entry);
141 /*********************************************************************/
142 /*********************************************************************/
144 void AliGenCocktailAfterBurner::Init()
147 Int_t numberOfEvents = AliRunLoader::Instance()->GetNumberOfEventsPerRun();
148 fGenerationDone = kFALSE;
149 if (fInternalStacks) //delete stacks
151 fInternalStacks->SetOwner();
152 fInternalStacks->Delete(); //clean after previous generation cycle
155 if (fCollisionGeometries) {
156 for (Int_t i = 0; i < (numberOfEvents + fNBgEvents); i++)
157 if (fCollisionGeometries[i]) delete fCollisionGeometries[i];
158 delete[] fCollisionGeometries;
161 for (Int_t i = 0; i < (numberOfEvents + fNBgEvents); i++)
162 if (fHeaders[i]) delete fHeaders[i];
166 this->AliGenCocktail::Init();
168 if (gDebug>0) cout<<"AliGenCocktailAfterBurner::Init"<<endl;
169 TIter next(fAfterBurnerEntries);
170 AliGenCocktailEntry *entry;
172 // Loop over generators and initialize
173 while((entry = (AliGenCocktailEntry*)next())) {
174 entry->Generator()->Init();
177 /*********************************************************************/
178 /*********************************************************************/
180 void AliGenCocktailAfterBurner::Generate()
184 // Firsts runs each generator for all events
185 // than after burners ones for each event
187 // It generates and processes all events during
189 // In next calls it just returns already generated
190 // and processed events to the gAlice
193 cout<<"#####################################"<<endl
194 <<"#AliGenCocktailAfterBurner::Generate#"<<endl
195 <<"#####################################"<<endl;
202 {//if generation is done (in first call)
203 //just copy particles from the stack to the gAlice
204 SetTracks(++fCurrentEvent);
205 fHeader = fHeaders[fCurrentEvent];
206 gAlice->SetGenEventHeader(fHeader);
207 cout<<"Returning event " << fCurrentEvent<<endl;
211 { //Here we are in the first call of the method
212 Int_t numberOfEvents = AliRunLoader::Instance()->GetNumberOfEventsPerRun();
213 cout << "Number of events per run" << numberOfEvents << endl;
215 eventVertex.Set(3 * (numberOfEvents + fNBgEvents));
217 eventTime.Set(numberOfEvents + fNBgEvents);
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
224 for(i = 0; i < numberOfEvents + fNBgEvents; i++)
226 stack = new AliStack(10000);
228 fInternalStacks->Add(stack);
230 for (Int_t j = 0; j < 3; j++) eventVertex[3 * i + j] = fVertex[j];
231 eventTime[i] = fTime;
232 fHeaders[i] = new AliGenCocktailEventHeader();
233 fCollisionGeometries[i] = 0;
235 /*********************************************************************/
236 TIter next(fEntries);
237 AliGenCocktailEntry *entry;
238 AliGenCocktailEntry *e1;
239 AliGenCocktailEntry *e2;
240 const TObjArray *partArray;
242 // Loop over generators and generate events
244 while((entry = (AliGenCocktailEntry*)next()))
247 cout<<"Generator "<<igen<<" : "<<entry->GetName()<<endl;
248 /***********************************************/
249 //First generator for all evenets, than second for all events, etc...
250 for(i = 0; i < numberOfEvents + fNBgEvents; i++)
252 cout<<" EVENT "<<i << endl;
254 partArray = stack->Particles();
255 fCurrentGenerator = entry->Generator();
256 fCurrentGenerator->SetStack(stack);
263 entry->SetFirst((partArray->GetEntriesFast())+1);
265 // Set the vertex for the generator
267 fCurrentGenerator->SetVertex(eventVertex.At(ioff), eventVertex.At(ioff + 1), eventVertex.At(ioff + 2));
268 fCurrentGenerator->SetTime(eventTime.At(i));
269 fHeader = fHeaders[i];
270 // Set the vertex and time for the cocktail
272 for (Int_t j=0; j<3; j++) v[j] = eventVertex.At(ioff + j);
273 fHeader->SetPrimaryVertex(v);
274 fHeader->SetInteractionTime(eventTime.At(i));
276 fCurrentGenerator->Generate();
278 entry->SetLast(partArray->GetEntriesFast());
280 if (fCurrentGenerator->ProvidesCollisionGeometry())
281 fCollisionGeometries[i] =
282 new AliCollisionGeometry(*(fCurrentGenerator->CollisionGeometry()));
284 /***********************************************/
287 while((entry = (AliGenCocktailEntry*)next()))
291 for ( entry=FirstGenerator();entry;entry=NextGenerator() )
295 for (FirstGeneratorPair(e1,e2); (e1&&e2); NextGeneratorPair(e1,e2) )
297 printf("\n -----------------------------");
303 /***********************************************/
304 /*******After Burners Processing****************/
305 /***********************************************/
306 TIter nextAfterBurner(fAfterBurnerEntries);
307 AliGenCocktailEntry *afterBurnerEntry;
308 Int_t iab =0; //number of current after burner / counter
310 cout<<"\n\nRunning After Burners"<<endl;
311 while((afterBurnerEntry = (AliGenCocktailEntry*)nextAfterBurner()))
313 cout<<"After Burner "<<iab++<<" :"<<afterBurnerEntry->GetName()<<endl;
314 fCurrentGenerator = afterBurnerEntry->Generator();
315 fCurrentGenerator->Generate();
317 cout<<endl<<"Finished. Processed "<<iab<<" After Burners"<<endl;
319 /***********************************************/
320 /***********************************************/
321 /***********************************************/
323 fGenerationDone=kTRUE;
324 SetTracks(0); //copy event 0 to gAlice stack
326 /*********************************************************************/
327 // Pass the header to gAlice
328 fHeader = fHeaders[0];
329 gAlice->SetGenEventHeader(fHeader);
332 /*********************************************************************/
333 /*********************************************************************/
335 AliStack* AliGenCocktailAfterBurner::GetStack(Int_t n) const
337 //Returns the pointer to the N'th stack (event)
338 if( ( n<0 ) || ( n >= (GetNumberOfEvents()) ) )
340 Fatal("AliGenCocktailAfterBurner::GetStack","Asked for non existing stack (%d)",n);
343 return ((AliStack*) fInternalStacks->At(n) );
346 /*********************************************************************/
347 /*********************************************************************/
349 AliCollisionGeometry* AliGenCocktailAfterBurner::GetCollisionGeometry(Int_t n) const
351 //Returns the pointer to the N'th stack (event)
352 if( ( n<0 ) || ( n>=GetNumberOfEvents() ) )
354 Fatal("AliGenCocktailAfterBurner::GetCollisionGeometry","Asked for non existing stack (%d)",n);
357 return fCollisionGeometries[n];
360 /*********************************************************************/
361 /*********************************************************************/
363 void AliGenCocktailAfterBurner::SetActiveEventNumber(Int_t actev)
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)
369 fActiveEvent = actev;
370 fActiveStack = GetStack(actev);
372 /*********************************************************************/
373 /*********************************************************************/
375 void AliGenCocktailAfterBurner::SetTracks(Int_t stackno)
377 //Method which copies tracks from given stack to the
379 AliStack* instack = GetStack(stackno);
383 Double_t px, py, pz, e, vx, vy, vz, tof, polx, poly, polz;
390 Int_t n = instack->GetNtrack();
393 cout<<"AliGenCocktailAfterBurner::SetTracks("<<stackno<<"). Number of particles is: "<<n<<"\n";
396 for(Int_t i = 0; i < n; i++)
399 p = instack->Particle(i);
400 done = !p->TestBit(kDoneBit);
401 parent = p->GetMother(0);
402 pdg = p->GetPdgCode();
411 p->GetPolarisation(pol);
415 mech = AliGenCocktailAfterBurner::IntToMCProcess(p->GetUniqueID());
416 weight = p->GetWeight();
418 gAlice->GetMCApp()->PushTrack(done, parent, pdg, px, py, pz, e, vx, vy, vz, tof,polx, poly, polz, mech, ntr, weight);
420 SetHighWaterMark(ntr) ;
424 /*********************************************************************/
425 /*********************************************************************/
427 TMCProcess AliGenCocktailAfterBurner::IntToMCProcess(Int_t no)
429 //Mothod used to convert uniqueID (integer) to TMCProcess type
430 const TMCProcess kMCprocesses[kMaxMCProcess] =
432 kPNoProcess, kPMultipleScattering, kPEnergyLoss, kPMagneticFieldL,
433 kPDecay, kPPair, kPCompton, kPPhotoelectric, kPBrem, kPDeltaRay,
434 kPAnnihilation, kPHadronic, kPNoProcess, kPEvaporation, kPNuclearFission,
435 kPNuclearAbsorption, kPPbarAnnihilation, kPNCapture, kPHElastic,
436 kPHInhelastic, kPMuonNuclear, kPTOFlimit,kPPhotoFission, kPNoProcess,
437 kPRayleigh, kPNoProcess, kPNoProcess, kPNoProcess, kPNull, kPStop
440 for (Int_t i = 0;i<kMaxMCProcess;i++)
442 if (kMCprocesses[i] == no)
444 return kMCprocesses[i];