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.                  *
 **************************************************************************/

//-------------------------------------------------------------------------
//                          Class AliGenPileup
//   This is a generator of beam-beam pileup.
//   It generates interactions within 3 orbits (+-1) around
//   the trigger event. The trigger event itself is chosen
//   randomly among the bunch crossings within the central orbit.
//   The user can decide whenever to include in the simulation the
//   "trigger" interaction or not. This is handled by the
//   GenerateTrigInteraction(Bool_t flag) method.
//   In the case the trigger interaction is included, it is
//   generated using the same settings (vertex smear for example) as
//   the pileup events.
//   In case the trigger simulation is not included, the user can make
//   a cocktail of generator used to produce the trigger interaction and
//   AliGenPileup. In this case in order to avoid a fake increase of the rate around the
//   trigger, the number of background events within the bunch
//   crossing of the trigger is readuced by one.
//   The beam profile (the list of the active bunch crossings) can be
//   controlled via the SetBCMask(const char *mask) method. The syntax
//   follows the one in AliTriggerBCMask class. For example:
//   "3564H" would mean that all the bunch corssings within the orbit
//   are aloowed (which is of course unphysical). In case one wants to simulate
//   one-bunch-crossing-per-orbit scenario, the way to do it is to put something like:
//   "1H3563L" or similar.
//   The SetGenerator(AliGenerator *generator, Float_t rate) method is
//   used in order to define the generator to be used. The second argument is the pileup
//   rate in terms of #_of_interactions/bunch-crossing = sigma_tot * luminosity.
//   The pileup generation time window can be set via
//   AliGenerator::SetPileUpTimeWindow(Float_t pileUpTimeW) method. By the default the
//   window is set to 88micros (= TPC readout window).
//      
// cvetan.cheshkov@cern.ch  9/12/2008
//-------------------------------------------------------------------------

#include <TParticle.h>
#include <TFormula.h>

#include "AliGenPileup.h"
#include "AliLog.h"
#include "AliGenCocktailEventHeader.h"
#include "AliGenCocktailEntry.h"
#include "AliRun.h"
#include "AliStack.h"

ClassImp(AliGenPileup)

AliGenPileup::AliGenPileup():
  AliGenCocktail(),
  fBCMask("bcm","3564H"),
  fGenTrig(kFALSE),
  fFlag(kFALSE)
{
// Constructor
// The pileup time window is by default
// set to the TPC readout one
    fName = "Pileup";
    fTitle= "Beam-beam pileup";

    fPileUpTimeWindow = 88e-6;
}

AliGenPileup::~AliGenPileup()
{
// Destructor
}

void AliGenPileup::SetGenerator(AliGenerator *generator, Float_t rate, Bool_t flag)
{
  // The method sets the geenrator to be used
  // for pileup simulation.
  // The second argument is the pileup rate in terms of
  // #_of_interactions/bunch-crossing = sigma_tot * luminosity.
  // There is a protection in case the generator was already set.
  if (fEntries) {
    if (FirstGenerator()) {
      AliError("Pileup generator has been already set! Nothing done");
      return;
    }
  }
  AddGenerator(generator,"pileup generator",rate);
  fFlag = flag;
}

void AliGenPileup::AddGenerator(AliGenerator *Generator,
				const char* Name,
				Float_t RateExp , TFormula* /*form*/, Int_t /*ntimes*/)
{
  // The method used to add the pileup generator
  // in the cocktail list.
  // The method is protected in order to avoid
  // its misusage
  AliGenCocktail::AddGenerator(Generator,Name,RateExp);
}

Bool_t AliGenPileup::SetBCMask(const char *mask)
{
  // Set the active bunch-crossings that
  // will be included in the pileup
  // simulation. For more details on the
  // syntax of the mask - see
  // STEER/AliTriggerBCMask.* and the comments
  // in the header of this file
  return fBCMask.SetMask(mask);
}

void AliGenPileup::Generate()
{
  //
  // Generate pileup event 
  // For details see the coments inline

  // Check that the pileup generator is correctly set
  AliGenCocktailEntry *entry = FirstGenerator();
  if (!entry) {
    AliFatal("No pileup generator entry is found!");
  }

  AliGenerator *gen = entry->Generator();
  if (!gen) {
    AliFatal("No pileup generator specified!");
  }
  else if (gen->NeedsCollisionGeometry()) {
    AliFatal("No Collision Geometry Provided");
  }

  // Check that the pileup rate is correctly set
  Float_t rate = entry->Rate();
  if (rate <= 0) {
    AliFatal(Form("Invalid rate value: %f",rate));
  }

  // Create cocktail header
  if (fHeader) delete fHeader;
  fHeader = new AliGenCocktailEventHeader("Pileup Cocktail Header");

  // Generate time of all
  // the collisions within one orbit
  Int_t *nIntBC = new Int_t[3*AliTriggerBCMask::kNBits];
  Int_t *indexBC = new Int_t[3*AliTriggerBCMask::kNBits];
  Int_t nTotBC = 0;
  while (nTotBC == 0) {
    for(Int_t iBC = 0; iBC <  AliTriggerBCMask::kNBits; iBC++) {

      if (!fBCMask.GetMask(iBC)) continue;

      //      Int_t nInteractions = gRandom->Poisson(rate);
      Int_t nInteractions;
      if (!fFlag) 
	nInteractions = gRandom->Poisson(rate);
      else 
	nInteractions = TMath::Nint(rate) + 1;

      if (nInteractions == 0) continue;

      nIntBC[nTotBC] = nInteractions;
      indexBC[nTotBC] = iBC;
      nTotBC++;
    }
  }

  // Select the bunch crossing for triggered event
  Int_t iTrgBC = gRandom->Integer(nTotBC);
  // Subtract one from the number of events
  // generated within this bc (only in case
  // the user disabled the generation of the trigger
  // interaction)
  if (!fGenTrig) nIntBC[iTrgBC]--;

  // Remove bunch crossings outside pileup
  // time window
  for(Int_t iBC = 0; iBC <  nTotBC; iBC++) {
   if (TMath::Abs(25e-9*(indexBC[iBC]-indexBC[iTrgBC])) > fPileUpTimeWindow)
     nIntBC[iBC] = 0;
  }

  // Generate the two orbits around the central one
  // taking into account the pileup time window
  for(Int_t iBC = 0; iBC <  AliTriggerBCMask::kNBits; iBC++) {

    if (!fBCMask.GetMask(iBC)) continue;

    if (TMath::Abs(25e-9*(iBC-AliTriggerBCMask::kNBits-indexBC[iTrgBC])) > fPileUpTimeWindow) continue;

    Int_t nInteractions = gRandom->Poisson(rate);
    if (nInteractions == 0) continue;

    nIntBC[nTotBC] = nInteractions;
    indexBC[nTotBC] = iBC-AliTriggerBCMask::kNBits;
    nTotBC++;
  }
  for(Int_t iBC = 0; iBC <  AliTriggerBCMask::kNBits; iBC++) {

    if (!fBCMask.GetMask(iBC)) continue;

    if (TMath::Abs(25e-9*(iBC+AliTriggerBCMask::kNBits-indexBC[iTrgBC])) > fPileUpTimeWindow) continue;

    Int_t nInteractions = gRandom->Poisson(rate);
    if (nInteractions == 0) continue;

    nIntBC[nTotBC] = nInteractions;
    indexBC[nTotBC] = iBC+AliTriggerBCMask::kNBits;
    nTotBC++;
  }

  // Loop over the generated collision times, call the generator
  // and correct the partcile times in the stack
  AliStack *stack = AliRunLoader::Instance()->Stack();
  Int_t lastpart=0;
  entry->SetFirst(lastpart);

  for(Int_t iBC = 0; iBC <  nTotBC; iBC++) {
    Float_t deltat = 25e-9*(indexBC[iBC] - indexBC[iTrgBC]);
    for (Int_t i = 0; i < nIntBC[iBC]; i++) {
      //  Generate the vertex position and time
      Vertex();
      TArrayF eventVertex(3);
      for (Int_t j=0; j < 3; j++) eventVertex[j] = fVertex[j];
      Double_t vTime = deltat + gRandom->Gaus(0,fOsigma[2]/TMath::Ccgs());
    
      gen->SetVertex(fVertex.At(0), fVertex.At(1), fVertex.At(2));
      gen->Generate();

      for (Int_t k = lastpart; k < stack->GetNprimary(); k++) {
	TLorentzVector v;
	stack->Particle(k)->ProductionVertex(v);
	v[3] = vTime;
	stack->Particle(k)->SetProductionVertex(v);
      }
      lastpart = stack->GetNprimary();

      // Store the interaction header in the container of the headers
      ((AliGenEventHeader*) fHeader->GetHeaders()->Last())->SetPrimaryVertex(eventVertex);
      ((AliGenEventHeader*) fHeader->GetHeaders()->Last())->SetInteractionTime(vTime);
    }
  }
  delete [] nIntBC;
  delete [] indexBC;

  entry->SetLast(stack->GetNprimary());

  fHeader->CalcNProduced();

  if (fContainer) {
    fHeader->SetName(fName);
    fContainer->AddHeader(fHeader);
  } else {
    gAlice->SetGenEventHeader(fHeader);	
  }
 
}

void AliGenPileup::SetRandomise(Bool_t /*flag*/)
{
  // This setting is not implemented in
  // case of pileup generation
  // So the method gives an warning and exits
  AliWarning("This setting has no effect on the generator!");
}

void AliGenPileup::UsePerEventRates()
{
  // This setting is not implemented in
  // case of pileup generation
  // So the method gives an warning and exits
  AliWarning("This setting has no effect on the generator!");
}
 AliGenPileup.cxx:1
 AliGenPileup.cxx:2
 AliGenPileup.cxx:3
 AliGenPileup.cxx:4
 AliGenPileup.cxx:5
 AliGenPileup.cxx:6
 AliGenPileup.cxx:7
 AliGenPileup.cxx:8
 AliGenPileup.cxx:9
 AliGenPileup.cxx:10
 AliGenPileup.cxx:11
 AliGenPileup.cxx:12
 AliGenPileup.cxx:13
 AliGenPileup.cxx:14
 AliGenPileup.cxx:15
 AliGenPileup.cxx:16
 AliGenPileup.cxx:17
 AliGenPileup.cxx:18
 AliGenPileup.cxx:19
 AliGenPileup.cxx:20
 AliGenPileup.cxx:21
 AliGenPileup.cxx:22
 AliGenPileup.cxx:23
 AliGenPileup.cxx:24
 AliGenPileup.cxx:25
 AliGenPileup.cxx:26
 AliGenPileup.cxx:27
 AliGenPileup.cxx:28
 AliGenPileup.cxx:29
 AliGenPileup.cxx:30
 AliGenPileup.cxx:31
 AliGenPileup.cxx:32
 AliGenPileup.cxx:33
 AliGenPileup.cxx:34
 AliGenPileup.cxx:35
 AliGenPileup.cxx:36
 AliGenPileup.cxx:37
 AliGenPileup.cxx:38
 AliGenPileup.cxx:39
 AliGenPileup.cxx:40
 AliGenPileup.cxx:41
 AliGenPileup.cxx:42
 AliGenPileup.cxx:43
 AliGenPileup.cxx:44
 AliGenPileup.cxx:45
 AliGenPileup.cxx:46
 AliGenPileup.cxx:47
 AliGenPileup.cxx:48
 AliGenPileup.cxx:49
 AliGenPileup.cxx:50
 AliGenPileup.cxx:51
 AliGenPileup.cxx:52
 AliGenPileup.cxx:53
 AliGenPileup.cxx:54
 AliGenPileup.cxx:55
 AliGenPileup.cxx:56
 AliGenPileup.cxx:57
 AliGenPileup.cxx:58
 AliGenPileup.cxx:59
 AliGenPileup.cxx:60
 AliGenPileup.cxx:61
 AliGenPileup.cxx:62
 AliGenPileup.cxx:63
 AliGenPileup.cxx:64
 AliGenPileup.cxx:65
 AliGenPileup.cxx:66
 AliGenPileup.cxx:67
 AliGenPileup.cxx:68
 AliGenPileup.cxx:69
 AliGenPileup.cxx:70
 AliGenPileup.cxx:71
 AliGenPileup.cxx:72
 AliGenPileup.cxx:73
 AliGenPileup.cxx:74
 AliGenPileup.cxx:75
 AliGenPileup.cxx:76
 AliGenPileup.cxx:77
 AliGenPileup.cxx:78
 AliGenPileup.cxx:79
 AliGenPileup.cxx:80
 AliGenPileup.cxx:81
 AliGenPileup.cxx:82
 AliGenPileup.cxx:83
 AliGenPileup.cxx:84
 AliGenPileup.cxx:85
 AliGenPileup.cxx:86
 AliGenPileup.cxx:87
 AliGenPileup.cxx:88
 AliGenPileup.cxx:89
 AliGenPileup.cxx:90
 AliGenPileup.cxx:91
 AliGenPileup.cxx:92
 AliGenPileup.cxx:93
 AliGenPileup.cxx:94
 AliGenPileup.cxx:95
 AliGenPileup.cxx:96
 AliGenPileup.cxx:97
 AliGenPileup.cxx:98
 AliGenPileup.cxx:99
 AliGenPileup.cxx:100
 AliGenPileup.cxx:101
 AliGenPileup.cxx:102
 AliGenPileup.cxx:103
 AliGenPileup.cxx:104
 AliGenPileup.cxx:105
 AliGenPileup.cxx:106
 AliGenPileup.cxx:107
 AliGenPileup.cxx:108
 AliGenPileup.cxx:109
 AliGenPileup.cxx:110
 AliGenPileup.cxx:111
 AliGenPileup.cxx:112
 AliGenPileup.cxx:113
 AliGenPileup.cxx:114
 AliGenPileup.cxx:115
 AliGenPileup.cxx:116
 AliGenPileup.cxx:117
 AliGenPileup.cxx:118
 AliGenPileup.cxx:119
 AliGenPileup.cxx:120
 AliGenPileup.cxx:121
 AliGenPileup.cxx:122
 AliGenPileup.cxx:123
 AliGenPileup.cxx:124
 AliGenPileup.cxx:125
 AliGenPileup.cxx:126
 AliGenPileup.cxx:127
 AliGenPileup.cxx:128
 AliGenPileup.cxx:129
 AliGenPileup.cxx:130
 AliGenPileup.cxx:131
 AliGenPileup.cxx:132
 AliGenPileup.cxx:133
 AliGenPileup.cxx:134
 AliGenPileup.cxx:135
 AliGenPileup.cxx:136
 AliGenPileup.cxx:137
 AliGenPileup.cxx:138
 AliGenPileup.cxx:139
 AliGenPileup.cxx:140
 AliGenPileup.cxx:141
 AliGenPileup.cxx:142
 AliGenPileup.cxx:143
 AliGenPileup.cxx:144
 AliGenPileup.cxx:145
 AliGenPileup.cxx:146
 AliGenPileup.cxx:147
 AliGenPileup.cxx:148
 AliGenPileup.cxx:149
 AliGenPileup.cxx:150
 AliGenPileup.cxx:151
 AliGenPileup.cxx:152
 AliGenPileup.cxx:153
 AliGenPileup.cxx:154
 AliGenPileup.cxx:155
 AliGenPileup.cxx:156
 AliGenPileup.cxx:157
 AliGenPileup.cxx:158
 AliGenPileup.cxx:159
 AliGenPileup.cxx:160
 AliGenPileup.cxx:161
 AliGenPileup.cxx:162
 AliGenPileup.cxx:163
 AliGenPileup.cxx:164
 AliGenPileup.cxx:165
 AliGenPileup.cxx:166
 AliGenPileup.cxx:167
 AliGenPileup.cxx:168
 AliGenPileup.cxx:169
 AliGenPileup.cxx:170
 AliGenPileup.cxx:171
 AliGenPileup.cxx:172
 AliGenPileup.cxx:173
 AliGenPileup.cxx:174
 AliGenPileup.cxx:175
 AliGenPileup.cxx:176
 AliGenPileup.cxx:177
 AliGenPileup.cxx:178
 AliGenPileup.cxx:179
 AliGenPileup.cxx:180
 AliGenPileup.cxx:181
 AliGenPileup.cxx:182
 AliGenPileup.cxx:183
 AliGenPileup.cxx:184
 AliGenPileup.cxx:185
 AliGenPileup.cxx:186
 AliGenPileup.cxx:187
 AliGenPileup.cxx:188
 AliGenPileup.cxx:189
 AliGenPileup.cxx:190
 AliGenPileup.cxx:191
 AliGenPileup.cxx:192
 AliGenPileup.cxx:193
 AliGenPileup.cxx:194
 AliGenPileup.cxx:195
 AliGenPileup.cxx:196
 AliGenPileup.cxx:197
 AliGenPileup.cxx:198
 AliGenPileup.cxx:199
 AliGenPileup.cxx:200
 AliGenPileup.cxx:201
 AliGenPileup.cxx:202
 AliGenPileup.cxx:203
 AliGenPileup.cxx:204
 AliGenPileup.cxx:205
 AliGenPileup.cxx:206
 AliGenPileup.cxx:207
 AliGenPileup.cxx:208
 AliGenPileup.cxx:209
 AliGenPileup.cxx:210
 AliGenPileup.cxx:211
 AliGenPileup.cxx:212
 AliGenPileup.cxx:213
 AliGenPileup.cxx:214
 AliGenPileup.cxx:215
 AliGenPileup.cxx:216
 AliGenPileup.cxx:217
 AliGenPileup.cxx:218
 AliGenPileup.cxx:219
 AliGenPileup.cxx:220
 AliGenPileup.cxx:221
 AliGenPileup.cxx:222
 AliGenPileup.cxx:223
 AliGenPileup.cxx:224
 AliGenPileup.cxx:225
 AliGenPileup.cxx:226
 AliGenPileup.cxx:227
 AliGenPileup.cxx:228
 AliGenPileup.cxx:229
 AliGenPileup.cxx:230
 AliGenPileup.cxx:231
 AliGenPileup.cxx:232
 AliGenPileup.cxx:233
 AliGenPileup.cxx:234
 AliGenPileup.cxx:235
 AliGenPileup.cxx:236
 AliGenPileup.cxx:237
 AliGenPileup.cxx:238
 AliGenPileup.cxx:239
 AliGenPileup.cxx:240
 AliGenPileup.cxx:241
 AliGenPileup.cxx:242
 AliGenPileup.cxx:243
 AliGenPileup.cxx:244
 AliGenPileup.cxx:245
 AliGenPileup.cxx:246
 AliGenPileup.cxx:247
 AliGenPileup.cxx:248
 AliGenPileup.cxx:249
 AliGenPileup.cxx:250
 AliGenPileup.cxx:251
 AliGenPileup.cxx:252
 AliGenPileup.cxx:253
 AliGenPileup.cxx:254
 AliGenPileup.cxx:255
 AliGenPileup.cxx:256
 AliGenPileup.cxx:257
 AliGenPileup.cxx:258
 AliGenPileup.cxx:259
 AliGenPileup.cxx:260
 AliGenPileup.cxx:261
 AliGenPileup.cxx:262
 AliGenPileup.cxx:263
 AliGenPileup.cxx:264
 AliGenPileup.cxx:265
 AliGenPileup.cxx:266
 AliGenPileup.cxx:267
 AliGenPileup.cxx:268
 AliGenPileup.cxx:269
 AliGenPileup.cxx:270
 AliGenPileup.cxx:271
 AliGenPileup.cxx:272
 AliGenPileup.cxx:273
 AliGenPileup.cxx:274
 AliGenPileup.cxx:275
 AliGenPileup.cxx:276
 AliGenPileup.cxx:277
 AliGenPileup.cxx:278
 AliGenPileup.cxx:279
 AliGenPileup.cxx:280
 AliGenPileup.cxx:281