New reader for the pedestal run and vdrift (Julian) and some bug fixing (Raphaelle)
[u/mrichter/AliRoot.git] / EVGEN / AliGenPileup.cxx
CommitLineData
56f3f4a4 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16//-------------------------------------------------------------------------
17// Class AliGenPileup
18// This is a generator of beam-beam pileup.
19// It generates interactions within 3 orbits (+-1) around
20// the trigger event. The trigger event itself is chosen
21// randomly among the bunch crossings within the central orbit.
22// The user can decide whenever to include in the simulation the
23// "trigger" interaction or not. This is handled by the
24// GenerateTrigInteraction(Bool_t flag) method.
25// In the case the trigger interaction is included, it is
26// generated using the same settings (vertex smear for example) as
27// the pileup events.
28// In case the trigger simulation is not included, the user can make
29// a cocktail of generator used to produce the trigger interaction and
30// AliGenPileup. In this case in order to avoid a fake increase of the rate around the
31// trigger, the number of background events within the bunch
32// crossing of the trigger is readuced by one.
33// The beam profile (the list of the active bunch crossings) can be
34// controlled via the SetBCMask(const char *mask) method. The syntax
35// follows the one in AliTriggerBCMask class. For example:
36// "3564H" would mean that all the bunch corssings within the orbit
37// are aloowed (which is of course unphysical). In case one wants to simulate
38// one-bunch-crossing-per-orbit scenario, the way to do it is to put something like:
39// "1H3563L" or similar.
40// The SetGenerator(AliGenerator *generator, Float_t rate) method is
41// used in order to define the generator to be used. The second argument is the pileup
42// rate in terms of #_of_interactions/bunch-crossing = sigma_tot * luminosity.
43// The pileup generation time window can be set via
44// AliGenerator::SetPileUpTimeWindow(Float_t pileUpTimeW) method. By the default the
45// window is set to 88micros (= TPC readout window).
46//
47// cvetan.cheshkov@cern.ch 9/12/2008
48//-------------------------------------------------------------------------
49
50#include <TParticle.h>
51
52#include "AliGenPileup.h"
53#include "AliLog.h"
54#include "AliGenCocktailEventHeader.h"
55#include "AliGenCocktailEntry.h"
56#include "AliRun.h"
57#include "AliStack.h"
58
59ClassImp(AliGenPileup)
60
61AliGenPileup::AliGenPileup():
62 AliGenCocktail(),
63 fBCMask("bcm","3564H"),
aa0d2074 64 fGenTrig(kFALSE),
65 fFlag(kFALSE)
56f3f4a4 66{
67// Constructor
68// The pileup time window is by default
69// set to the TPC readout one
70 fName = "Pileup";
71 fTitle= "Beam-beam pileup";
72
73 fPileUpTimeWindow = 88e-6;
74}
75
76AliGenPileup::~AliGenPileup()
77{
78// Destructor
79}
80
aa0d2074 81void AliGenPileup::SetGenerator(AliGenerator *generator, Float_t rate, Bool_t flag)
56f3f4a4 82{
83 // The method sets the geenrator to be used
84 // for pileup simulation.
85 // The second argument is the pileup rate in terms of
86 // #_of_interactions/bunch-crossing = sigma_tot * luminosity.
87 // There is a protection in case the generator was already set.
88 if (fEntries) {
89 if (FirstGenerator()) {
90 AliError("Pileup generator has been already set! Nothing done");
91 return;
92 }
93 }
94 AddGenerator(generator,"pileup generator",rate);
aa0d2074 95 fFlag = flag;
56f3f4a4 96}
97
98void AliGenPileup::AddGenerator(AliGenerator *Generator,
99 const char* Name,
100 Float_t RateExp )
101{
102 // The method used to add the pileup generator
103 // in the cocktail list.
104 // The method is protected in order to avoid
105 // its misusage
106 AliGenCocktail::AddGenerator(Generator,Name,RateExp);
107}
108
109Bool_t AliGenPileup::SetBCMask(const char *mask)
110{
111 // Set the active bunch-crossings that
112 // will be included in the pileup
113 // simulation. For more details on the
114 // syntax of the mask - see
115 // STEER/AliTriggerBCMask.* and the comments
116 // in the header of this file
117 return fBCMask.SetMask(mask);
118}
119
120void AliGenPileup::Generate()
121{
122 //
123 // Generate pileup event
124 // For details see the coments inline
125
126 // Check that the pileup generator is correctly set
127 AliGenCocktailEntry *entry = FirstGenerator();
128 if (!entry) {
129 AliFatal("No pileup generator entry is found!");
130 }
131
132 AliGenerator *gen = entry->Generator();
133 if (!gen) {
134 AliFatal("No pileup generator specified!");
135 }
136 else if (gen->NeedsCollisionGeometry()) {
137 AliFatal("No Collision Geometry Provided");
138 }
139
140 // Check that the pileup rate is correctly set
141 Float_t rate = entry->Rate();
142 if (rate <= 0) {
143 AliFatal(Form("Invalid rate value: %f",rate));
144 }
145
146 // Create cocktail header
147 if (fHeader) delete fHeader;
148 fHeader = new AliGenCocktailEventHeader("Pileup Cocktail Header");
149
150 // Generate time of all
151 // the collisions within one orbit
152 Int_t *nIntBC = new Int_t[3*AliTriggerBCMask::kNBits];
153 Int_t *indexBC = new Int_t[3*AliTriggerBCMask::kNBits];
154 Int_t nTotBC = 0;
660b9a45 155 while (nTotBC == 0) {
156 for(Int_t iBC = 0; iBC < AliTriggerBCMask::kNBits; iBC++) {
56f3f4a4 157
660b9a45 158 if (!fBCMask.GetMask(iBC)) continue;
56f3f4a4 159
aa0d2074 160 // Int_t nInteractions = gRandom->Poisson(rate);
161 Int_t nInteractions;
162 if (!fFlag)
163 nInteractions = gRandom->Poisson(rate);
164 else
165 nInteractions = TMath::Nint(rate) + 1;
166
660b9a45 167 if (nInteractions == 0) continue;
56f3f4a4 168
660b9a45 169 nIntBC[nTotBC] = nInteractions;
170 indexBC[nTotBC] = iBC;
171 nTotBC++;
172 }
56f3f4a4 173 }
174
175 // Select the bunch crossing for triggered event
176 Int_t iTrgBC = gRandom->Integer(nTotBC);
177 // Subtract one from the number of events
178 // generated within this bc (only in case
179 // the user disabled the generation of the trigger
180 // interaction)
aee85673 181 if (!fGenTrig) nIntBC[iTrgBC]--;
56f3f4a4 182
183 // Remove bunch crossings outside pileup
184 // time window
185 for(Int_t iBC = 0; iBC < nTotBC; iBC++) {
186 if (TMath::Abs(25e-9*(indexBC[iBC]-indexBC[iTrgBC])) > fPileUpTimeWindow)
187 nIntBC[iBC] = 0;
188 }
189
190 // Generate the two orbits around the central one
191 // taking into account the pileup time window
192 for(Int_t iBC = 0; iBC < AliTriggerBCMask::kNBits; iBC++) {
193
194 if (!fBCMask.GetMask(iBC)) continue;
195
196 if (TMath::Abs(25e-9*(iBC-AliTriggerBCMask::kNBits-indexBC[iTrgBC])) > fPileUpTimeWindow) continue;
197
198 Int_t nInteractions = gRandom->Poisson(rate);
199 if (nInteractions == 0) continue;
200
201 nIntBC[nTotBC] = nInteractions;
202 indexBC[nTotBC] = iBC-AliTriggerBCMask::kNBits;
203 nTotBC++;
204 }
205 for(Int_t iBC = 0; iBC < AliTriggerBCMask::kNBits; iBC++) {
206
207 if (!fBCMask.GetMask(iBC)) continue;
208
209 if (TMath::Abs(25e-9*(iBC+AliTriggerBCMask::kNBits-indexBC[iTrgBC])) > fPileUpTimeWindow) continue;
210
211 Int_t nInteractions = gRandom->Poisson(rate);
212 if (nInteractions == 0) continue;
213
214 nIntBC[nTotBC] = nInteractions;
215 indexBC[nTotBC] = iBC+AliTriggerBCMask::kNBits;
216 nTotBC++;
217 }
218
219 // Loop over the generated collision times, call the generator
220 // and correct the partcile times in the stack
33c3c91a 221 AliStack *stack = AliRunLoader::Instance()->Stack();
56f3f4a4 222 Int_t lastpart=0;
223 entry->SetFirst(lastpart);
224
225 for(Int_t iBC = 0; iBC < nTotBC; iBC++) {
226 Float_t deltat = 25e-9*(indexBC[iBC] - indexBC[iTrgBC]);
227 for (Int_t i = 0; i < nIntBC[iBC]; i++) {
228 // Generate the vertex position and time
229 Vertex();
230 TArrayF eventVertex(3);
231 for (Int_t j=0; j < 3; j++) eventVertex[j] = fVertex[j];
232 Double_t vTime = deltat + gRandom->Gaus(0,fOsigma[2]/TMath::Ccgs());
233
234 gen->SetVertex(fVertex.At(0), fVertex.At(1), fVertex.At(2));
235 gen->Generate();
236
237 for (Int_t k = lastpart; k < stack->GetNprimary(); k++) {
238 TLorentzVector v;
239 stack->Particle(k)->ProductionVertex(v);
240 v[3] = vTime;
241 stack->Particle(k)->SetProductionVertex(v);
242 }
243 lastpart = stack->GetNprimary();
244
245 // Store the interaction header in the container of the headers
246 ((AliGenEventHeader*) fHeader->GetHeaders()->Last())->SetPrimaryVertex(eventVertex);
247 }
248 }
249 delete [] nIntBC;
250 delete [] indexBC;
251
252 entry->SetLast(stack->GetNprimary());
253
254 fHeader->CalcNProduced();
255
256 if (fContainer) {
257 fContainer->AddHeader(fHeader);
258 } else {
259 gAlice->SetGenEventHeader(fHeader);
260 }
261
262}
263
264void AliGenPileup::SetRandomise(Bool_t /*flag*/)
265{
266 // This setting is not implemented in
267 // case of pileup generation
268 // So the method gives an warning and exits
269 AliWarning("This setting has no effect on the generator!");
270}
271
272void AliGenPileup::UsePerEventRates()
273{
274 // This setting is not implemented in
275 // case of pileup generation
276 // So the method gives an warning and exits
277 AliWarning("This setting has no effect on the generator!");
278}