ROOT logo
/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

// Container class for AliGenerator through recursion.
// Container is itself an AliGenerator.
// What is stored are not the pointers to the generators directly but to objects of type
// AliGenCocktail entry.   
// The class provides also iterator functionality.  
// Author: andreas.morsch@cern.ch 
//

#include <TList.h>
#include <TObjArray.h>
#include <TFormula.h>

#include "AliGenCocktail.h"
#include "AliGenCocktailEntry.h"
#include "AliCollisionGeometry.h"
#include "AliRun.h"
#include "AliLog.h"
#include "AliMC.h"
#include "AliGenCocktailEventHeader.h"

ClassImp(AliGenCocktail)

AliGenCocktail::AliGenCocktail()
    :AliGenerator(), 
     fNGenerators(0),
     fTotalRate(0.),
     fSRandom(kFALSE),
     fUsePerEventRate(kFALSE),
     fProb(0),
     fEntries(0),
     flnk1(0),
     flnk2(0), 
     fHeader(0)
{
// Constructor
    fName = "Cocktail";
    fTitle= "Particle Generator using cocktail of generators";
}

AliGenCocktail::~AliGenCocktail()
{
// Destructor
    delete fEntries;
    fEntries = 0;
    //    delete fHeader; // It is removed in AliRunLoader
    fHeader = 0;
}

void AliGenCocktail::
AddGenerator(AliGenerator *Generator, const char* Name, Float_t RateExp, TFormula* formula, Int_t ntimes)
{
//
// Add a generator to the list 
// First check that list exists
    if (!fEntries) fEntries = new TList();
    fTotalRate += RateExp;
//
//  Forward parameters to the new generator
    if(TestBit(kPtRange) && !(Generator->TestBit(kPtRange)) && !(Generator->TestBit(kMomentumRange))) 
	Generator->SetPtRange(fPtMin,fPtMax);
    if(TestBit(kMomentumRange) && !(Generator->TestBit(kPtRange)) && !(Generator->TestBit(kMomentumRange)))
	Generator->SetMomentumRange(fPMin,fPMax);
    
    if (TestBit(kYRange) && !(Generator->TestBit(kYRange)))
	Generator->SetYRange(fYMin,fYMax);
    if (TestBit(kPhiRange) && !(Generator->TestBit(kPhiRange)))
	Generator->SetPhiRange(fPhiMin*180/TMath::Pi(),fPhiMax*180/TMath::Pi());
    if (TestBit(kThetaRange) && !(Generator->TestBit(kThetaRange)) && !(Generator->TestBit(kEtaRange)))
	Generator->SetThetaRange(fThetaMin*180/TMath::Pi(),fThetaMax*180/TMath::Pi());
    if (!(Generator->TestBit(kVertexRange))) {
	Generator->SetOrigin(fOrigin[0], fOrigin[1], fOrigin[2]);
	Generator->SetSigma(fOsigma[0], fOsigma[1], fOsigma[2]);
	Generator->SetVertexSmear(fVertexSmear);
	Generator->SetVertexSource(kContainer);
    }
    Generator->SetTrackingFlag(fTrackIt);
    Generator->SetContainer(this);

        
//
//  Add generator to list   
    char theName[256];
    snprintf(theName, 256, "%s_%d",Name, fNGenerators);
    Generator->SetName(theName);

    AliGenCocktailEntry *entry = 
	new AliGenCocktailEntry(Generator, Name, RateExp);
    if (formula) entry->SetFormula(formula);  
    entry->SetNTimes(ntimes);
     fEntries->Add(entry);
     fNGenerators++;
     flnk1 = 0;
     flnk2 = 0;
     fSRandom  = kFALSE;
     fHeader  = 0;
}

  void AliGenCocktail::Init()
{
// Initialisation
    TIter next(fEntries);
    AliGenCocktailEntry *entry;
    //
    // Loop over generators and initialize
    while((entry = (AliGenCocktailEntry*)next())) {
	if (fStack)  entry->Generator()->SetStack(fStack);
	entry->Generator()->Init();
    }  

    next.Reset();

    if (fSRandom) {
	fProb.Set(fNGenerators);
	next.Reset();
	Float_t sum = 0.;
	while((entry = (AliGenCocktailEntry*)next())) {
	    sum += entry->Rate();
	} 

	next.Reset();
	Int_t i = 0;
	Float_t psum = 0.;
	while((entry = (AliGenCocktailEntry*)next())) {
	    psum +=  entry->Rate() / sum;
	    fProb[i++] = psum;
	}
    }
	next.Reset();
}

  void AliGenCocktail::FinishRun()
{
// Initialisation
    TIter next(fEntries);
    AliGenCocktailEntry *entry;
    //
    // Loop over generators and initialize
    while((entry = (AliGenCocktailEntry*)next())) {
	entry->Generator()->FinishRun();
    }  
}

 void AliGenCocktail::Generate()
{
//
// Generate event 
    TIter next(fEntries);
    AliGenCocktailEntry *entry = 0;
    AliGenCocktailEntry *preventry = 0;
    AliGenCocktailEntry *collentry = 0;
    AliGenerator* gen = 0;
    if (fHeader) delete fHeader;

    
    fHeader = new AliGenCocktailEventHeader("Cocktail Header");

    const TObjArray *partArray = gAlice->GetMCApp()->Particles();

//
//  Generate the vertex position used by all generators
//    
    if(fVertexSmear == kPerEvent) Vertex();

    TArrayF eventVertex;
    eventVertex.Set(3);
    for (Int_t j=0; j < 3; j++) eventVertex[j] = fVertex[j];

    if (!fSRandom) {
	//
	// Loop over generators and generate events
	Int_t igen   = 0;
	while((entry = (AliGenCocktailEntry*)next())) {
          Int_t ntimes = entry->NTimes();
	  if (fUsePerEventRate && (gRandom->Rndm() > entry->Rate())) continue;
	  
	  igen++;
	  if (igen ==1) {
	    entry->SetFirst(0);
	  } else {
	    entry->SetFirst((partArray->GetEntriesFast())+1);
	  }
	  gen = entry->Generator();
	  if (gen->ProvidesCollisionGeometry()) collentry = entry; 
	  //
	  //      Handle case in which current generator needs collision geometry from previous generator
          //
	  if (gen->NeedsCollisionGeometry() && (entry->Formula() == 0))
	    {
	      if (preventry && preventry->Generator()->ProvidesCollisionGeometry())
		{
		  gen->SetCollisionGeometry(preventry->Generator()->CollisionGeometry());
		} else {
		Fatal("Generate()", "No Collision Geometry Provided");
	      }
	    }
	  //
	  //      Number of signals is calculated from Collision Geometry
	  //      and entry with given centrality bin is selected
	  //
	  if (entry->Formula() != 0)
	    {
	      if (!collentry) {
		Fatal("Generate()", "No Collision Geometry Provided");
		return;
	      }
	      AliCollisionGeometry* coll = (collentry->Generator())->CollisionGeometry();
	      Float_t b  = coll->ImpactParameter();
	      Int_t nsig = Int_t(entry->Formula()->Eval(b));
	      Int_t bin = entry->Bin() - 100;
	      if (bin > 0) {
		if (bin != nsig) continue;
	      } else {
		if (nsig < 1) nsig = 1;
		AliInfo(Form("Signal Events %13.3f %5d %5d\n", b, coll->HardScatters(), nsig));
		ntimes = nsig;
	      }
	    }
	  gen->SetVertex(fVertex.At(0), fVertex.At(1), fVertex.At(2), fTime);
	  
	  gen->GenerateN(ntimes);
	  entry->SetLast(partArray->GetEntriesFast());
	  preventry = entry;
	}
    } else if (fSRandom) {
	//
	// Select a generator randomly
	//
	Int_t i;
	Float_t p0 =  gRandom->Rndm();

	for (i = 0; i < fNGenerators; i++) {
	    if (p0 < fProb[i]) break;
	}

	entry = (AliGenCocktailEntry*) fEntries->At(i);
	entry->SetFirst(0);
	gen = entry->Generator();
	gen->SetVertex(fVertex.At(0), fVertex.At(1), fVertex.At(2), fTime);
	gen->Generate();
	entry->SetLast(partArray->GetEntriesFast());
    } 
    
    next.Reset();

    // Event Vertex
    fHeader->SetPrimaryVertex(eventVertex);
    fHeader->CalcNProduced();
    if (fContainer) {
      fHeader->SetName(fName);
      fContainer->AddHeader(fHeader);
    } else {
      gAlice->SetGenEventHeader(fHeader);	
    }
}

void AliGenCocktail::SetVertexSmear(VertexSmear_t smear)
{
// Set vertex smearing and propagate it to the generators

  AliGenerator::SetVertexSmear(smear);
  TIter next(fEntries);
  while (AliGenCocktailEntry* entry = (AliGenCocktailEntry*)next()) {
    entry->Generator()->SetVertexSmear(smear);
  }
}

AliGenCocktailEntry *  AliGenCocktail::FirstGenerator()
{
// Iterator over generators: Initialisation
    flnk1 = fEntries->FirstLink();
    if (flnk1) {
	return (AliGenCocktailEntry*) (flnk1->GetObject());
    } else {
	return 0;
    }
}

AliGenCocktailEntry*  AliGenCocktail::NextGenerator()
{
// Iterator over generators: Increment
    flnk1 = flnk1->Next();
    if (flnk1) {
	return (AliGenCocktailEntry*) (flnk1->GetObject());
    } else {
	return 0;
    }
}

void AliGenCocktail::
FirstGeneratorPair(AliGenCocktailEntry*& e1, AliGenCocktailEntry*& e2)
{
// Iterator over generator pairs: Initialisation
    flnk2 = flnk1 = fEntries->FirstLink();
    if (flnk1) {
	e2 = e1 = (AliGenCocktailEntry*) (flnk1->GetObject());
    } else {
	e2= e1 = 0;
    }
}

void AliGenCocktail::
NextGeneratorPair(AliGenCocktailEntry*& e1, AliGenCocktailEntry*& e2)
{
// Iterator over generators: Increment
    flnk2 = flnk2->Next();
    if (flnk2) {
	e1 = (AliGenCocktailEntry*) (flnk1->GetObject());
	e2 = (AliGenCocktailEntry*) (flnk2->GetObject());	
    } else {
	flnk2 = flnk1 = flnk1->Next();
	if (flnk1) {
	    e1 = (AliGenCocktailEntry*) (flnk1->GetObject());
	    e2 = (AliGenCocktailEntry*) (flnk2->GetObject());
	} else {
	    e1=0;
	    e2=0;
	}
    }
}

void AliGenCocktail::AddHeader(AliGenEventHeader* header)
{
// Add a header to the list 
    if (fHeader) fHeader->AddHeader(header);
}




 AliGenCocktail.cxx:1
 AliGenCocktail.cxx:2
 AliGenCocktail.cxx:3
 AliGenCocktail.cxx:4
 AliGenCocktail.cxx:5
 AliGenCocktail.cxx:6
 AliGenCocktail.cxx:7
 AliGenCocktail.cxx:8
 AliGenCocktail.cxx:9
 AliGenCocktail.cxx:10
 AliGenCocktail.cxx:11
 AliGenCocktail.cxx:12
 AliGenCocktail.cxx:13
 AliGenCocktail.cxx:14
 AliGenCocktail.cxx:15
 AliGenCocktail.cxx:16
 AliGenCocktail.cxx:17
 AliGenCocktail.cxx:18
 AliGenCocktail.cxx:19
 AliGenCocktail.cxx:20
 AliGenCocktail.cxx:21
 AliGenCocktail.cxx:22
 AliGenCocktail.cxx:23
 AliGenCocktail.cxx:24
 AliGenCocktail.cxx:25
 AliGenCocktail.cxx:26
 AliGenCocktail.cxx:27
 AliGenCocktail.cxx:28
 AliGenCocktail.cxx:29
 AliGenCocktail.cxx:30
 AliGenCocktail.cxx:31
 AliGenCocktail.cxx:32
 AliGenCocktail.cxx:33
 AliGenCocktail.cxx:34
 AliGenCocktail.cxx:35
 AliGenCocktail.cxx:36
 AliGenCocktail.cxx:37
 AliGenCocktail.cxx:38
 AliGenCocktail.cxx:39
 AliGenCocktail.cxx:40
 AliGenCocktail.cxx:41
 AliGenCocktail.cxx:42
 AliGenCocktail.cxx:43
 AliGenCocktail.cxx:44
 AliGenCocktail.cxx:45
 AliGenCocktail.cxx:46
 AliGenCocktail.cxx:47
 AliGenCocktail.cxx:48
 AliGenCocktail.cxx:49
 AliGenCocktail.cxx:50
 AliGenCocktail.cxx:51
 AliGenCocktail.cxx:52
 AliGenCocktail.cxx:53
 AliGenCocktail.cxx:54
 AliGenCocktail.cxx:55
 AliGenCocktail.cxx:56
 AliGenCocktail.cxx:57
 AliGenCocktail.cxx:58
 AliGenCocktail.cxx:59
 AliGenCocktail.cxx:60
 AliGenCocktail.cxx:61
 AliGenCocktail.cxx:62
 AliGenCocktail.cxx:63
 AliGenCocktail.cxx:64
 AliGenCocktail.cxx:65
 AliGenCocktail.cxx:66
 AliGenCocktail.cxx:67
 AliGenCocktail.cxx:68
 AliGenCocktail.cxx:69
 AliGenCocktail.cxx:70
 AliGenCocktail.cxx:71
 AliGenCocktail.cxx:72
 AliGenCocktail.cxx:73
 AliGenCocktail.cxx:74
 AliGenCocktail.cxx:75
 AliGenCocktail.cxx:76
 AliGenCocktail.cxx:77
 AliGenCocktail.cxx:78
 AliGenCocktail.cxx:79
 AliGenCocktail.cxx:80
 AliGenCocktail.cxx:81
 AliGenCocktail.cxx:82
 AliGenCocktail.cxx:83
 AliGenCocktail.cxx:84
 AliGenCocktail.cxx:85
 AliGenCocktail.cxx:86
 AliGenCocktail.cxx:87
 AliGenCocktail.cxx:88
 AliGenCocktail.cxx:89
 AliGenCocktail.cxx:90
 AliGenCocktail.cxx:91
 AliGenCocktail.cxx:92
 AliGenCocktail.cxx:93
 AliGenCocktail.cxx:94
 AliGenCocktail.cxx:95
 AliGenCocktail.cxx:96
 AliGenCocktail.cxx:97
 AliGenCocktail.cxx:98
 AliGenCocktail.cxx:99
 AliGenCocktail.cxx:100
 AliGenCocktail.cxx:101
 AliGenCocktail.cxx:102
 AliGenCocktail.cxx:103
 AliGenCocktail.cxx:104
 AliGenCocktail.cxx:105
 AliGenCocktail.cxx:106
 AliGenCocktail.cxx:107
 AliGenCocktail.cxx:108
 AliGenCocktail.cxx:109
 AliGenCocktail.cxx:110
 AliGenCocktail.cxx:111
 AliGenCocktail.cxx:112
 AliGenCocktail.cxx:113
 AliGenCocktail.cxx:114
 AliGenCocktail.cxx:115
 AliGenCocktail.cxx:116
 AliGenCocktail.cxx:117
 AliGenCocktail.cxx:118
 AliGenCocktail.cxx:119
 AliGenCocktail.cxx:120
 AliGenCocktail.cxx:121
 AliGenCocktail.cxx:122
 AliGenCocktail.cxx:123
 AliGenCocktail.cxx:124
 AliGenCocktail.cxx:125
 AliGenCocktail.cxx:126
 AliGenCocktail.cxx:127
 AliGenCocktail.cxx:128
 AliGenCocktail.cxx:129
 AliGenCocktail.cxx:130
 AliGenCocktail.cxx:131
 AliGenCocktail.cxx:132
 AliGenCocktail.cxx:133
 AliGenCocktail.cxx:134
 AliGenCocktail.cxx:135
 AliGenCocktail.cxx:136
 AliGenCocktail.cxx:137
 AliGenCocktail.cxx:138
 AliGenCocktail.cxx:139
 AliGenCocktail.cxx:140
 AliGenCocktail.cxx:141
 AliGenCocktail.cxx:142
 AliGenCocktail.cxx:143
 AliGenCocktail.cxx:144
 AliGenCocktail.cxx:145
 AliGenCocktail.cxx:146
 AliGenCocktail.cxx:147
 AliGenCocktail.cxx:148
 AliGenCocktail.cxx:149
 AliGenCocktail.cxx:150
 AliGenCocktail.cxx:151
 AliGenCocktail.cxx:152
 AliGenCocktail.cxx:153
 AliGenCocktail.cxx:154
 AliGenCocktail.cxx:155
 AliGenCocktail.cxx:156
 AliGenCocktail.cxx:157
 AliGenCocktail.cxx:158
 AliGenCocktail.cxx:159
 AliGenCocktail.cxx:160
 AliGenCocktail.cxx:161
 AliGenCocktail.cxx:162
 AliGenCocktail.cxx:163
 AliGenCocktail.cxx:164
 AliGenCocktail.cxx:165
 AliGenCocktail.cxx:166
 AliGenCocktail.cxx:167
 AliGenCocktail.cxx:168
 AliGenCocktail.cxx:169
 AliGenCocktail.cxx:170
 AliGenCocktail.cxx:171
 AliGenCocktail.cxx:172
 AliGenCocktail.cxx:173
 AliGenCocktail.cxx:174
 AliGenCocktail.cxx:175
 AliGenCocktail.cxx:176
 AliGenCocktail.cxx:177
 AliGenCocktail.cxx:178
 AliGenCocktail.cxx:179
 AliGenCocktail.cxx:180
 AliGenCocktail.cxx:181
 AliGenCocktail.cxx:182
 AliGenCocktail.cxx:183
 AliGenCocktail.cxx:184
 AliGenCocktail.cxx:185
 AliGenCocktail.cxx:186
 AliGenCocktail.cxx:187
 AliGenCocktail.cxx:188
 AliGenCocktail.cxx:189
 AliGenCocktail.cxx:190
 AliGenCocktail.cxx:191
 AliGenCocktail.cxx:192
 AliGenCocktail.cxx:193
 AliGenCocktail.cxx:194
 AliGenCocktail.cxx:195
 AliGenCocktail.cxx:196
 AliGenCocktail.cxx:197
 AliGenCocktail.cxx:198
 AliGenCocktail.cxx:199
 AliGenCocktail.cxx:200
 AliGenCocktail.cxx:201
 AliGenCocktail.cxx:202
 AliGenCocktail.cxx:203
 AliGenCocktail.cxx:204
 AliGenCocktail.cxx:205
 AliGenCocktail.cxx:206
 AliGenCocktail.cxx:207
 AliGenCocktail.cxx:208
 AliGenCocktail.cxx:209
 AliGenCocktail.cxx:210
 AliGenCocktail.cxx:211
 AliGenCocktail.cxx:212
 AliGenCocktail.cxx:213
 AliGenCocktail.cxx:214
 AliGenCocktail.cxx:215
 AliGenCocktail.cxx:216
 AliGenCocktail.cxx:217
 AliGenCocktail.cxx:218
 AliGenCocktail.cxx:219
 AliGenCocktail.cxx:220
 AliGenCocktail.cxx:221
 AliGenCocktail.cxx:222
 AliGenCocktail.cxx:223
 AliGenCocktail.cxx:224
 AliGenCocktail.cxx:225
 AliGenCocktail.cxx:226
 AliGenCocktail.cxx:227
 AliGenCocktail.cxx:228
 AliGenCocktail.cxx:229
 AliGenCocktail.cxx:230
 AliGenCocktail.cxx:231
 AliGenCocktail.cxx:232
 AliGenCocktail.cxx:233
 AliGenCocktail.cxx:234
 AliGenCocktail.cxx:235
 AliGenCocktail.cxx:236
 AliGenCocktail.cxx:237
 AliGenCocktail.cxx:238
 AliGenCocktail.cxx:239
 AliGenCocktail.cxx:240
 AliGenCocktail.cxx:241
 AliGenCocktail.cxx:242
 AliGenCocktail.cxx:243
 AliGenCocktail.cxx:244
 AliGenCocktail.cxx:245
 AliGenCocktail.cxx:246
 AliGenCocktail.cxx:247
 AliGenCocktail.cxx:248
 AliGenCocktail.cxx:249
 AliGenCocktail.cxx:250
 AliGenCocktail.cxx:251
 AliGenCocktail.cxx:252
 AliGenCocktail.cxx:253
 AliGenCocktail.cxx:254
 AliGenCocktail.cxx:255
 AliGenCocktail.cxx:256
 AliGenCocktail.cxx:257
 AliGenCocktail.cxx:258
 AliGenCocktail.cxx:259
 AliGenCocktail.cxx:260
 AliGenCocktail.cxx:261
 AliGenCocktail.cxx:262
 AliGenCocktail.cxx:263
 AliGenCocktail.cxx:264
 AliGenCocktail.cxx:265
 AliGenCocktail.cxx:266
 AliGenCocktail.cxx:267
 AliGenCocktail.cxx:268
 AliGenCocktail.cxx:269
 AliGenCocktail.cxx:270
 AliGenCocktail.cxx:271
 AliGenCocktail.cxx:272
 AliGenCocktail.cxx:273
 AliGenCocktail.cxx:274
 AliGenCocktail.cxx:275
 AliGenCocktail.cxx:276
 AliGenCocktail.cxx:277
 AliGenCocktail.cxx:278
 AliGenCocktail.cxx:279
 AliGenCocktail.cxx:280
 AliGenCocktail.cxx:281
 AliGenCocktail.cxx:282
 AliGenCocktail.cxx:283
 AliGenCocktail.cxx:284
 AliGenCocktail.cxx:285
 AliGenCocktail.cxx:286
 AliGenCocktail.cxx:287
 AliGenCocktail.cxx:288
 AliGenCocktail.cxx:289
 AliGenCocktail.cxx:290
 AliGenCocktail.cxx:291
 AliGenCocktail.cxx:292
 AliGenCocktail.cxx:293
 AliGenCocktail.cxx:294
 AliGenCocktail.cxx:295
 AliGenCocktail.cxx:296
 AliGenCocktail.cxx:297
 AliGenCocktail.cxx:298
 AliGenCocktail.cxx:299
 AliGenCocktail.cxx:300
 AliGenCocktail.cxx:301
 AliGenCocktail.cxx:302
 AliGenCocktail.cxx:303
 AliGenCocktail.cxx:304
 AliGenCocktail.cxx:305
 AliGenCocktail.cxx:306
 AliGenCocktail.cxx:307
 AliGenCocktail.cxx:308
 AliGenCocktail.cxx:309
 AliGenCocktail.cxx:310
 AliGenCocktail.cxx:311
 AliGenCocktail.cxx:312
 AliGenCocktail.cxx:313
 AliGenCocktail.cxx:314
 AliGenCocktail.cxx:315
 AliGenCocktail.cxx:316
 AliGenCocktail.cxx:317
 AliGenCocktail.cxx:318
 AliGenCocktail.cxx:319
 AliGenCocktail.cxx:320
 AliGenCocktail.cxx:321
 AliGenCocktail.cxx:322
 AliGenCocktail.cxx:323
 AliGenCocktail.cxx:324
 AliGenCocktail.cxx:325
 AliGenCocktail.cxx:326
 AliGenCocktail.cxx:327
 AliGenCocktail.cxx:328
 AliGenCocktail.cxx:329
 AliGenCocktail.cxx:330
 AliGenCocktail.cxx:331
 AliGenCocktail.cxx:332
 AliGenCocktail.cxx:333
 AliGenCocktail.cxx:334
 AliGenCocktail.cxx:335
 AliGenCocktail.cxx:336
 AliGenCocktail.cxx:337
 AliGenCocktail.cxx:338
 AliGenCocktail.cxx:339
 AliGenCocktail.cxx:340
 AliGenCocktail.cxx:341
 AliGenCocktail.cxx:342
 AliGenCocktail.cxx:343
 AliGenCocktail.cxx:344
 AliGenCocktail.cxx:345
 AliGenCocktail.cxx:346