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"
50 ClassImp(AliGenCocktailAfterBurner)
51 /*********************************************************************/
52 /*********************************************************************/
54 AliGenCocktailAfterBurner::AliGenCocktailAfterBurner():
56 fAfterBurnerEntries(0),
57 fGenerationDone(kFALSE),
59 fCollisionGeometries(0),
69 cout<<"AliGenCocktailAfterBurner::AliGenCocktailAfterBurner()"<<endl;
70 SetName("AliGenCocktailAfterBurner");
71 SetTitle("AliGenCocktailAfterBurner");
74 /*********************************************************************/
76 AliGenCocktailAfterBurner::~AliGenCocktailAfterBurner()
80 if (fInternalStacks) //delete stacks
82 fInternalStacks->SetOwner();
83 delete fInternalStacks;
85 if (fAfterBurnerEntries) delete fAfterBurnerEntries; //delete entries
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;
93 for (Int_t i = 0; i < (numberOfEvents + fNBgEvents); i++)
94 if (fHeaders[i]) delete fHeaders[i];
98 /*********************************************************************/
99 /*********************************************************************/
101 void AliGenCocktailAfterBurner::
102 AddAfterBurner(AliGenerator *AfterBurner, char* Name, Float_t RateExp)
105 // Forward parameters to the new AfterBurner
107 if (gDebug>0)cout<<"AliGenCocktailAfterBurner::AddAfterBurner Named "<<Name<<endl;
109 if(TestBit(kPtRange) && !(AfterBurner->TestBit(kPtRange)) && !(AfterBurner->TestBit(kMomentumRange)))
110 AfterBurner->SetPtRange(fPtMin,fPtMax);
111 if(TestBit(kMomentumRange) && !(AfterBurner->TestBit(kPtRange)) && !(AfterBurner->TestBit(kMomentumRange)))
112 AfterBurner->SetMomentumRange(fPMin,fPMax);
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());
120 if (!(AfterBurner->TestBit(kVertexRange))) {
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);
125 AfterBurner->SetTimeOrigin(fTimeOrigin);
127 AfterBurner->SetTrackingFlag(fTrackIt);
128 //AfterBurner->SetContainer(this);
131 // Add AfterBurner to list
133 AliGenCocktailEntry *entry =
134 new AliGenCocktailEntry(AfterBurner, Name, RateExp);
135 if (!fAfterBurnerEntries) fAfterBurnerEntries = new TList();
137 fAfterBurnerEntries->Add(entry);
142 /*********************************************************************/
143 /*********************************************************************/
145 void AliGenCocktailAfterBurner::Init()
148 Int_t numberOfEvents = AliRunLoader::Instance()->GetNumberOfEventsPerRun();
149 fGenerationDone = kFALSE;
150 if (fInternalStacks) //delete stacks
152 fInternalStacks->SetOwner();
153 fInternalStacks->Delete(); //clean after previous generation cycle
156 if (fCollisionGeometries) {
157 for (Int_t i = 0; i < (numberOfEvents + fNBgEvents); i++)
158 if (fCollisionGeometries[i]) delete fCollisionGeometries[i];
159 delete[] fCollisionGeometries;
162 for (Int_t i = 0; i < (numberOfEvents + fNBgEvents); i++)
163 if (fHeaders[i]) delete fHeaders[i];
167 this->AliGenCocktail::Init();
169 if (gDebug>0) cout<<"AliGenCocktailAfterBurner::Init"<<endl;
170 TIter next(fAfterBurnerEntries);
171 AliGenCocktailEntry *entry;
173 // Loop over generators and initialize
174 while((entry = (AliGenCocktailEntry*)next())) {
175 entry->Generator()->Init();
178 /*********************************************************************/
179 /*********************************************************************/
181 void AliGenCocktailAfterBurner::Generate()
185 // Firsts runs each generator for all events
186 // than after burners ones for each event
188 // It generates and processes all events during
190 // In next calls it just returns already generated
191 // and processed events to the gAlice
194 cout<<"#####################################"<<endl
195 <<"#AliGenCocktailAfterBurner::Generate#"<<endl
196 <<"#####################################"<<endl;
203 {//if generation is done (in first call)
204 //just copy particles from the stack to the gAlice
205 SetTracks(++fCurrentEvent);
206 fHeader = fHeaders[fCurrentEvent];
207 gAlice->SetGenEventHeader(fHeader);
208 cout<<"Returning event " << fCurrentEvent<<endl;
212 { //Here we are in the first call of the method
213 Int_t numberOfEvents = AliRunLoader::Instance()->GetNumberOfEventsPerRun();
214 cout << "Number of events per run" << numberOfEvents << endl;
216 eventVertex.Set(3 * (numberOfEvents + fNBgEvents));
218 eventTime.Set(numberOfEvents + fNBgEvents);
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
225 for(i = 0; i < numberOfEvents + fNBgEvents; i++)
227 stack = new AliStack(10000);
229 fInternalStacks->Add(stack);
231 for (Int_t j = 0; j < 3; j++) eventVertex[3 * i + j] = fVertex[j];
232 eventTime[i] = fTime;
233 fHeaders[i] = new AliGenCocktailEventHeader();
234 fCollisionGeometries[i] = 0;
236 /*********************************************************************/
237 TIter next(fEntries);
238 AliGenCocktailEntry *entry;
239 AliGenCocktailEntry *e1;
240 AliGenCocktailEntry *e2;
241 const TObjArray *partArray;
243 // Loop over generators and generate events
245 while((entry = (AliGenCocktailEntry*)next()))
248 cout<<"Generator "<<igen<<" : "<<entry->GetName()<<endl;
249 /***********************************************/
250 //First generator for all evenets, than second for all events, etc...
251 for(i = 0; i < numberOfEvents + fNBgEvents; i++)
253 cout<<" EVENT "<<i << endl;
255 partArray = stack->Particles();
256 fCurrentGenerator = entry->Generator();
257 fCurrentGenerator->SetStack(stack);
264 entry->SetFirst((partArray->GetEntriesFast())+1);
266 // Set the vertex for the generator
268 fCurrentGenerator->SetVertex(eventVertex.At(ioff), eventVertex.At(ioff + 1), eventVertex.At(ioff + 2));
269 fCurrentGenerator->SetTime(eventTime.At(i));
270 fHeader = fHeaders[i];
271 // Set the vertex and time for the cocktail
273 for (Int_t j=0; j<3; j++) v[j] = eventVertex.At(ioff + j);
274 fHeader->SetPrimaryVertex(v);
275 fHeader->SetInteractionTime(eventTime.At(i));
277 fCurrentGenerator->Generate();
279 entry->SetLast(partArray->GetEntriesFast());
281 if (fCurrentGenerator->ProvidesCollisionGeometry())
282 fCollisionGeometries[i] =
283 new AliCollisionGeometry(*(fCurrentGenerator->CollisionGeometry()));
285 /***********************************************/
288 while((entry = (AliGenCocktailEntry*)next()))
292 for ( entry=FirstGenerator();entry;entry=NextGenerator() )
296 for (FirstGeneratorPair(e1,e2); (e1&&e2); NextGeneratorPair(e1,e2) )
298 printf("\n -----------------------------");
304 /***********************************************/
305 /*******After Burners Processing****************/
306 /***********************************************/
307 TIter nextAfterBurner(fAfterBurnerEntries);
308 AliGenCocktailEntry *afterBurnerEntry;
309 Int_t iab =0; //number of current after burner / counter
311 cout<<"\n\nRunning After Burners"<<endl;
312 while((afterBurnerEntry = (AliGenCocktailEntry*)nextAfterBurner()))
314 cout<<"After Burner "<<iab++<<" :"<<afterBurnerEntry->GetName()<<endl;
315 fCurrentGenerator = afterBurnerEntry->Generator();
316 fCurrentGenerator->Generate();
318 cout<<endl<<"Finished. Processed "<<iab<<" After Burners"<<endl;
320 /***********************************************/
321 /***********************************************/
322 /***********************************************/
324 fGenerationDone=kTRUE;
325 SetTracks(0); //copy event 0 to gAlice stack
327 /*********************************************************************/
328 // Pass the header to gAlice
329 fHeader = fHeaders[0];
330 gAlice->SetGenEventHeader(fHeader);
333 /*********************************************************************/
334 /*********************************************************************/
336 AliStack* AliGenCocktailAfterBurner::GetStack(Int_t n) const
338 //Returns the pointer to the N'th stack (event)
339 if( ( n<0 ) || ( n >= (GetNumberOfEvents()) ) )
341 Fatal("AliGenCocktailAfterBurner::GetStack","Asked for non existing stack (%d)",n);
344 return ((AliStack*) fInternalStacks->At(n) );
347 /*********************************************************************/
348 /*********************************************************************/
350 AliCollisionGeometry* AliGenCocktailAfterBurner::GetCollisionGeometry(Int_t n) const
352 //Returns the pointer to the N'th stack (event)
353 if( ( n<0 ) || ( n>=GetNumberOfEvents() ) )
355 Fatal("AliGenCocktailAfterBurner::GetCollisionGeometry","Asked for non existing stack (%d)",n);
358 return fCollisionGeometries[n];
361 /*********************************************************************/
362 /*********************************************************************/
364 void AliGenCocktailAfterBurner::SetActiveEventNumber(Int_t actev)
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)
370 fActiveEvent = actev;
371 fActiveStack = GetStack(actev);
373 /*********************************************************************/
374 /*********************************************************************/
376 void AliGenCocktailAfterBurner::SetTracks(Int_t stackno)
378 //Method which copies tracks from given stack to the
380 AliStack* instack = GetStack(stackno);
384 Double_t px, py, pz, e, vx, vy, vz, tof, polx, poly, polz;
391 Int_t n = instack->GetNtrack();
394 cout<<"AliGenCocktailAfterBurner::SetTracks("<<stackno<<"). Number of particles is: "<<n<<"\n";
397 for(Int_t i = 0; i < n; i++)
400 p = instack->Particle(i);
401 done = !p->TestBit(kDoneBit);
402 parent = p->GetMother(0);
403 pdg = p->GetPdgCode();
412 p->GetPolarisation(pol);
416 mech = AliGenCocktailAfterBurner::IntToMCProcess(p->GetUniqueID());
417 weight = p->GetWeight();
419 gAlice->GetMCApp()->PushTrack(done, parent, pdg, px, py, pz, e, vx, vy, vz, tof,polx, poly, polz, mech, ntr, weight);
421 SetHighWaterMark(ntr) ;
425 /*********************************************************************/
426 /*********************************************************************/
428 TMCProcess AliGenCocktailAfterBurner::IntToMCProcess(Int_t no)
430 //Mothod used to convert uniqueID (integer) to TMCProcess type
431 const TMCProcess kMCprocesses[kMaxMCProcess] =
433 kPNoProcess, kPMultipleScattering, kPEnergyLoss, kPMagneticFieldL,
434 kPDecay, kPPair, kPCompton, kPPhotoelectric, kPBrem, kPDeltaRay,
435 kPAnnihilation, kPHadronic, kPNoProcess, kPEvaporation, kPNuclearFission,
436 kPNuclearAbsorption, kPPbarAnnihilation, kPNCapture, kPHElastic,
437 kPHInhelastic, kPMuonNuclear, kPTOFlimit,kPPhotoFission, kPNoProcess,
438 kPRayleigh, kPNoProcess, kPNoProcess, kPNoProcess, kPNull, kPStop
441 for (Int_t i = 0;i<kMaxMCProcess;i++)
443 if (kMCprocesses[i] == no)
445 return kMCprocesses[i];