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))
109 AfterBurner->SetPtRange(fPtMin,fPtMax);
110 if(TestBit(kMomentumRange))
111 AfterBurner->SetMomentumRange(fPMin,fPMax);
113 AfterBurner->SetYRange(fYMin,fYMax);
114 AfterBurner->SetPhiRange(fPhiMin*180/TMath::Pi(),fPhiMax*180/TMath::Pi());
115 AfterBurner->SetThetaRange(fThetaMin*180/TMath::Pi(),fThetaMax*180/TMath::Pi());
116 AfterBurner->SetOrigin(fOrigin[0], fOrigin[1], fOrigin[2]);
117 AfterBurner->SetSigma(fOsigma[0], fOsigma[1], fOsigma[2]);
118 AfterBurner->SetVertexSmear(fVertexSmear);
119 AfterBurner->SetTrackingFlag(fTrackIt);
120 AfterBurner->SetVertexSource(kContainer);
122 // Add AfterBurner to list
124 AliGenCocktailEntry *entry =
125 new AliGenCocktailEntry(AfterBurner, Name, RateExp);
126 if (!fAfterBurnerEntries) fAfterBurnerEntries = new TList();
128 fAfterBurnerEntries->Add(entry);
133 /*********************************************************************/
134 /*********************************************************************/
136 void AliGenCocktailAfterBurner::Init()
139 Int_t numberOfEvents = AliRunLoader::Instance()->GetNumberOfEventsPerRun();
140 fGenerationDone = kFALSE;
141 if (fInternalStacks) //delete stacks
143 fInternalStacks->SetOwner();
144 fInternalStacks->Delete(); //clean after previous generation cycle
147 if (fCollisionGeometries) {
148 for (Int_t i = 0; i < (numberOfEvents + fNBgEvents); i++)
149 if (fCollisionGeometries[i]) delete fCollisionGeometries[i];
150 delete[] fCollisionGeometries;
153 for (Int_t i = 0; i < (numberOfEvents + fNBgEvents); i++)
154 if (fHeaders[i]) delete fHeaders[i];
158 this->AliGenCocktail::Init();
160 if (gDebug>0) cout<<"AliGenCocktailAfterBurner::Init"<<endl;
161 TIter next(fAfterBurnerEntries);
162 AliGenCocktailEntry *entry;
164 // Loop over generators and initialize
165 while((entry = (AliGenCocktailEntry*)next())) {
166 entry->Generator()->Init();
169 /*********************************************************************/
170 /*********************************************************************/
172 void AliGenCocktailAfterBurner::Generate()
176 // Firsts runs each generator for all events
177 // than after burners ones for each event
179 // It generates and processes all events during
181 // In next calls it just returns already generated
182 // and processed events to the gAlice
185 cout<<"#####################################"<<endl
186 <<"#AliGenCocktailAfterBurner::Generate#"<<endl
187 <<"#####################################"<<endl;
194 {//if generation is done (in first call)
195 //just copy particles from the stack to the gAlice
196 SetTracks(++fCurrentEvent);
197 fHeader = fHeaders[fCurrentEvent];
198 gAlice->SetGenEventHeader(fHeader);
199 cout<<"Returning event " << fCurrentEvent<<endl;
203 { //Here we are in the first call of the method
204 Int_t numberOfEvents = AliRunLoader::Instance()->GetNumberOfEventsPerRun();
205 cout << "Number of events per run" << numberOfEvents << endl;
207 eventVertex.Set(3 * (numberOfEvents + fNBgEvents));
210 fInternalStacks = new TObjArray(numberOfEvents + fNBgEvents); //Create array of internal stacks
211 fCollisionGeometries = new AliCollisionGeometry*[numberOfEvents + fNBgEvents]; //Create array of collision geometries
212 fHeaders = new AliGenCocktailEventHeader*[numberOfEvents + fNBgEvents]; //Create array of headers
214 for(i = 0; i < numberOfEvents + fNBgEvents; i++)
216 stack = new AliStack(10000);
218 fInternalStacks->Add(stack);
220 for (Int_t j = 0; j < 3; j++) eventVertex[3 * i + j] = fVertex[j];
221 fHeaders[i] = new AliGenCocktailEventHeader();
222 fCollisionGeometries[i] = 0;
224 /*********************************************************************/
225 TIter next(fEntries);
226 AliGenCocktailEntry *entry;
227 AliGenCocktailEntry *e1;
228 AliGenCocktailEntry *e2;
229 const TObjArray *partArray;
231 // Loop over generators and generate events
233 while((entry = (AliGenCocktailEntry*)next()))
236 cout<<"Generator "<<igen<<" : "<<entry->GetName()<<endl;
237 /***********************************************/
238 //First generator for all evenets, than second for all events, etc...
239 for(i = 0; i < numberOfEvents + fNBgEvents; i++)
241 cout<<" EVENT "<<i << endl;
243 partArray = stack->Particles();
244 fCurrentGenerator = entry->Generator();
245 fCurrentGenerator->SetStack(stack);
252 entry->SetFirst((partArray->GetEntriesFast())+1);
254 // Set the vertex for the generator
256 fCurrentGenerator->SetVertex(eventVertex.At(ioff), eventVertex.At(ioff + 1), eventVertex.At(ioff + 2));
257 fHeader = fHeaders[i];
258 // Set the vertex for the cocktail
260 for (Int_t j=0; j<3; j++) v[j] = eventVertex.At(ioff + j);
261 fHeader->SetPrimaryVertex(v);
263 fCurrentGenerator->Generate();
265 entry->SetLast(partArray->GetEntriesFast());
267 if (fCurrentGenerator->ProvidesCollisionGeometry())
268 fCollisionGeometries[i] =
269 new AliCollisionGeometry(*(fCurrentGenerator->CollisionGeometry()));
271 /***********************************************/
274 while((entry = (AliGenCocktailEntry*)next()))
278 for ( entry=FirstGenerator();entry;entry=NextGenerator() )
282 for (FirstGeneratorPair(e1,e2); (e1&&e2); NextGeneratorPair(e1,e2) )
284 printf("\n -----------------------------");
290 /***********************************************/
291 /*******After Burners Processing****************/
292 /***********************************************/
293 TIter nextAfterBurner(fAfterBurnerEntries);
294 AliGenCocktailEntry *afterBurnerEntry;
295 Int_t iab =0; //number of current after burner / counter
297 cout<<"\n\nRunning After Burners"<<endl;
298 while((afterBurnerEntry = (AliGenCocktailEntry*)nextAfterBurner()))
300 cout<<"After Burner "<<iab++<<" :"<<afterBurnerEntry->GetName()<<endl;
301 fCurrentGenerator = afterBurnerEntry->Generator();
302 fCurrentGenerator->Generate();
304 cout<<endl<<"Finished. Processed "<<iab<<" After Burners"<<endl;
306 /***********************************************/
307 /***********************************************/
308 /***********************************************/
310 fGenerationDone=kTRUE;
311 SetTracks(0); //copy event 0 to gAlice stack
313 /*********************************************************************/
314 // Pass the header to gAlice
315 fHeader = fHeaders[0];
316 gAlice->SetGenEventHeader(fHeader);
319 /*********************************************************************/
320 /*********************************************************************/
322 AliStack* AliGenCocktailAfterBurner::GetStack(Int_t n) const
324 //Returns the pointer to the N'th stack (event)
325 if( ( n<0 ) || ( n >= (GetNumberOfEvents()) ) )
327 Fatal("AliGenCocktailAfterBurner::GetStack","Asked for non existing stack (%d)",n);
330 return ((AliStack*) fInternalStacks->At(n) );
333 /*********************************************************************/
334 /*********************************************************************/
336 AliCollisionGeometry* AliGenCocktailAfterBurner::GetCollisionGeometry(Int_t n) const
338 //Returns the pointer to the N'th stack (event)
339 if( ( n<0 ) || ( n>=GetNumberOfEvents() ) )
341 Fatal("AliGenCocktailAfterBurner::GetCollisionGeometry","Asked for non existing stack (%d)",n);
344 return fCollisionGeometries[n];
347 /*********************************************************************/
348 /*********************************************************************/
350 void AliGenCocktailAfterBurner::SetActiveEventNumber(Int_t actev)
352 //Set Active Events Number and Active Stack
353 //There is only one active event number
354 //Made fo convinience of work with AfterBurners (HBT processor)
356 fActiveEvent = actev;
357 fActiveStack = GetStack(actev);
359 /*********************************************************************/
360 /*********************************************************************/
362 void AliGenCocktailAfterBurner::SetTracks(Int_t stackno)
364 //Method which copies tracks from given stack to the
366 AliStack* instack = GetStack(stackno);
370 Double_t px, py, pz, e, vx, vy, vz, tof, polx, poly, polz;
377 Int_t n = instack->GetNtrack();
380 cout<<"AliGenCocktailAfterBurner::SetTracks("<<stackno<<"). Number of particles is: "<<n<<"\n";
383 for(Int_t i = 0; i < n; i++)
386 p = instack->Particle(i);
387 done = !p->TestBit(kDoneBit);
388 parent = p->GetMother(0);
389 pdg = p->GetPdgCode();
398 p->GetPolarisation(pol);
402 mech = AliGenCocktailAfterBurner::IntToMCProcess(p->GetUniqueID());
403 weight = p->GetWeight();
405 gAlice->GetMCApp()->PushTrack(done, parent, pdg, px, py, pz, e, vx, vy, vz, tof,polx, poly, polz, mech, ntr, weight);
407 SetHighWaterMark(ntr) ;
411 /*********************************************************************/
412 /*********************************************************************/
414 TMCProcess AliGenCocktailAfterBurner::IntToMCProcess(Int_t no)
416 //Mothod used to convert uniqueID (integer) to TMCProcess type
417 const TMCProcess kMCprocesses[kMaxMCProcess] =
419 kPNoProcess, kPMultipleScattering, kPEnergyLoss, kPMagneticFieldL,
420 kPDecay, kPPair, kPCompton, kPPhotoelectric, kPBrem, kPDeltaRay,
421 kPAnnihilation, kPHadronic, kPNoProcess, kPEvaporation, kPNuclearFission,
422 kPNuclearAbsorption, kPPbarAnnihilation, kPNCapture, kPHElastic,
423 kPHInhelastic, kPMuonNuclear, kPTOFlimit,kPPhotoFission, kPNoProcess,
424 kPRayleigh, kPNoProcess, kPNoProcess, kPNoProcess, kPNull, kPStop
427 for (Int_t i = 0;i<kMaxMCProcess;i++)
429 if (kMCprocesses[i] == no)
431 return kMCprocesses[i];