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 (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);
125 AfterBurner->SetTrackingFlag(fTrackIt);
126 //AfterBurner->SetContainer(this);
129 // Add AfterBurner to list
131 AliGenCocktailEntry *entry =
132 new AliGenCocktailEntry(AfterBurner, Name, RateExp);
133 if (!fAfterBurnerEntries) fAfterBurnerEntries = new TList();
135 fAfterBurnerEntries->Add(entry);
140 /*********************************************************************/
141 /*********************************************************************/
143 void AliGenCocktailAfterBurner::Init()
146 Int_t numberOfEvents = AliRunLoader::Instance()->GetNumberOfEventsPerRun();
147 fGenerationDone = kFALSE;
148 if (fInternalStacks) //delete stacks
150 fInternalStacks->SetOwner();
151 fInternalStacks->Delete(); //clean after previous generation cycle
154 if (fCollisionGeometries) {
155 for (Int_t i = 0; i < (numberOfEvents + fNBgEvents); i++)
156 if (fCollisionGeometries[i]) delete fCollisionGeometries[i];
157 delete[] fCollisionGeometries;
160 for (Int_t i = 0; i < (numberOfEvents + fNBgEvents); i++)
161 if (fHeaders[i]) delete fHeaders[i];
165 this->AliGenCocktail::Init();
167 if (gDebug>0) cout<<"AliGenCocktailAfterBurner::Init"<<endl;
168 TIter next(fAfterBurnerEntries);
169 AliGenCocktailEntry *entry;
171 // Loop over generators and initialize
172 while((entry = (AliGenCocktailEntry*)next())) {
173 entry->Generator()->Init();
176 /*********************************************************************/
177 /*********************************************************************/
179 void AliGenCocktailAfterBurner::Generate()
183 // Firsts runs each generator for all events
184 // than after burners ones for each event
186 // It generates and processes all events during
188 // In next calls it just returns already generated
189 // and processed events to the gAlice
192 cout<<"#####################################"<<endl
193 <<"#AliGenCocktailAfterBurner::Generate#"<<endl
194 <<"#####################################"<<endl;
201 {//if generation is done (in first call)
202 //just copy particles from the stack to the gAlice
203 SetTracks(++fCurrentEvent);
204 fHeader = fHeaders[fCurrentEvent];
205 gAlice->SetGenEventHeader(fHeader);
206 cout<<"Returning event " << fCurrentEvent<<endl;
210 { //Here we are in the first call of the method
211 Int_t numberOfEvents = AliRunLoader::Instance()->GetNumberOfEventsPerRun();
212 cout << "Number of events per run" << numberOfEvents << endl;
214 eventVertex.Set(3 * (numberOfEvents + fNBgEvents));
217 fInternalStacks = new TObjArray(numberOfEvents + fNBgEvents); //Create array of internal stacks
218 fCollisionGeometries = new AliCollisionGeometry*[numberOfEvents + fNBgEvents]; //Create array of collision geometries
219 fHeaders = new AliGenCocktailEventHeader*[numberOfEvents + fNBgEvents]; //Create array of headers
221 for(i = 0; i < numberOfEvents + fNBgEvents; i++)
223 stack = new AliStack(10000);
225 fInternalStacks->Add(stack);
227 for (Int_t j = 0; j < 3; j++) eventVertex[3 * i + j] = fVertex[j];
228 fHeaders[i] = new AliGenCocktailEventHeader();
229 fCollisionGeometries[i] = 0;
231 /*********************************************************************/
232 TIter next(fEntries);
233 AliGenCocktailEntry *entry;
234 AliGenCocktailEntry *e1;
235 AliGenCocktailEntry *e2;
236 const TObjArray *partArray;
238 // Loop over generators and generate events
240 while((entry = (AliGenCocktailEntry*)next()))
243 cout<<"Generator "<<igen<<" : "<<entry->GetName()<<endl;
244 /***********************************************/
245 //First generator for all evenets, than second for all events, etc...
246 for(i = 0; i < numberOfEvents + fNBgEvents; i++)
248 cout<<" EVENT "<<i << endl;
250 partArray = stack->Particles();
251 fCurrentGenerator = entry->Generator();
252 fCurrentGenerator->SetStack(stack);
259 entry->SetFirst((partArray->GetEntriesFast())+1);
261 // Set the vertex for the generator
263 fCurrentGenerator->SetVertex(eventVertex.At(ioff), eventVertex.At(ioff + 1), eventVertex.At(ioff + 2));
264 fHeader = fHeaders[i];
265 // Set the vertex for the cocktail
267 for (Int_t j=0; j<3; j++) v[j] = eventVertex.At(ioff + j);
268 fHeader->SetPrimaryVertex(v);
270 fCurrentGenerator->Generate();
272 entry->SetLast(partArray->GetEntriesFast());
274 if (fCurrentGenerator->ProvidesCollisionGeometry())
275 fCollisionGeometries[i] =
276 new AliCollisionGeometry(*(fCurrentGenerator->CollisionGeometry()));
278 /***********************************************/
281 while((entry = (AliGenCocktailEntry*)next()))
285 for ( entry=FirstGenerator();entry;entry=NextGenerator() )
289 for (FirstGeneratorPair(e1,e2); (e1&&e2); NextGeneratorPair(e1,e2) )
291 printf("\n -----------------------------");
297 /***********************************************/
298 /*******After Burners Processing****************/
299 /***********************************************/
300 TIter nextAfterBurner(fAfterBurnerEntries);
301 AliGenCocktailEntry *afterBurnerEntry;
302 Int_t iab =0; //number of current after burner / counter
304 cout<<"\n\nRunning After Burners"<<endl;
305 while((afterBurnerEntry = (AliGenCocktailEntry*)nextAfterBurner()))
307 cout<<"After Burner "<<iab++<<" :"<<afterBurnerEntry->GetName()<<endl;
308 fCurrentGenerator = afterBurnerEntry->Generator();
309 fCurrentGenerator->Generate();
311 cout<<endl<<"Finished. Processed "<<iab<<" After Burners"<<endl;
313 /***********************************************/
314 /***********************************************/
315 /***********************************************/
317 fGenerationDone=kTRUE;
318 SetTracks(0); //copy event 0 to gAlice stack
320 /*********************************************************************/
321 // Pass the header to gAlice
322 fHeader = fHeaders[0];
323 gAlice->SetGenEventHeader(fHeader);
326 /*********************************************************************/
327 /*********************************************************************/
329 AliStack* AliGenCocktailAfterBurner::GetStack(Int_t n) const
331 //Returns the pointer to the N'th stack (event)
332 if( ( n<0 ) || ( n >= (GetNumberOfEvents()) ) )
334 Fatal("AliGenCocktailAfterBurner::GetStack","Asked for non existing stack (%d)",n);
337 return ((AliStack*) fInternalStacks->At(n) );
340 /*********************************************************************/
341 /*********************************************************************/
343 AliCollisionGeometry* AliGenCocktailAfterBurner::GetCollisionGeometry(Int_t n) const
345 //Returns the pointer to the N'th stack (event)
346 if( ( n<0 ) || ( n>=GetNumberOfEvents() ) )
348 Fatal("AliGenCocktailAfterBurner::GetCollisionGeometry","Asked for non existing stack (%d)",n);
351 return fCollisionGeometries[n];
354 /*********************************************************************/
355 /*********************************************************************/
357 void AliGenCocktailAfterBurner::SetActiveEventNumber(Int_t actev)
359 //Set Active Events Number and Active Stack
360 //There is only one active event number
361 //Made fo convinience of work with AfterBurners (HBT processor)
363 fActiveEvent = actev;
364 fActiveStack = GetStack(actev);
366 /*********************************************************************/
367 /*********************************************************************/
369 void AliGenCocktailAfterBurner::SetTracks(Int_t stackno)
371 //Method which copies tracks from given stack to the
373 AliStack* instack = GetStack(stackno);
377 Double_t px, py, pz, e, vx, vy, vz, tof, polx, poly, polz;
384 Int_t n = instack->GetNtrack();
387 cout<<"AliGenCocktailAfterBurner::SetTracks("<<stackno<<"). Number of particles is: "<<n<<"\n";
390 for(Int_t i = 0; i < n; i++)
393 p = instack->Particle(i);
394 done = !p->TestBit(kDoneBit);
395 parent = p->GetMother(0);
396 pdg = p->GetPdgCode();
405 p->GetPolarisation(pol);
409 mech = AliGenCocktailAfterBurner::IntToMCProcess(p->GetUniqueID());
410 weight = p->GetWeight();
412 gAlice->GetMCApp()->PushTrack(done, parent, pdg, px, py, pz, e, vx, vy, vz, tof,polx, poly, polz, mech, ntr, weight);
414 SetHighWaterMark(ntr) ;
418 /*********************************************************************/
419 /*********************************************************************/
421 TMCProcess AliGenCocktailAfterBurner::IntToMCProcess(Int_t no)
423 //Mothod used to convert uniqueID (integer) to TMCProcess type
424 const TMCProcess kMCprocesses[kMaxMCProcess] =
426 kPNoProcess, kPMultipleScattering, kPEnergyLoss, kPMagneticFieldL,
427 kPDecay, kPPair, kPCompton, kPPhotoelectric, kPBrem, kPDeltaRay,
428 kPAnnihilation, kPHadronic, kPNoProcess, kPEvaporation, kPNuclearFission,
429 kPNuclearAbsorption, kPPbarAnnihilation, kPNCapture, kPHElastic,
430 kPHInhelastic, kPMuonNuclear, kPTOFlimit,kPPhotoFission, kPNoProcess,
431 kPRayleigh, kPNoProcess, kPNoProcess, kPNoProcess, kPNull, kPStop
434 for (Int_t i = 0;i<kMaxMCProcess;i++)
436 if (kMCprocesses[i] == no)
438 return kMCprocesses[i];