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 **************************************************************************/
16 //-------------------------------------------------------------------------
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
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).
47 // cvetan.cheshkov@cern.ch 9/12/2008
48 //-------------------------------------------------------------------------
50 #include <TParticle.h>
53 #include "AliGenPileup.h"
55 #include "AliGenCocktailEventHeader.h"
56 #include "AliGenCocktailEntry.h"
60 ClassImp(AliGenPileup)
62 AliGenPileup::AliGenPileup():
64 fBCMask("bcm","3564H"),
69 // The pileup time window is by default
70 // set to the TPC readout one
72 fTitle= "Beam-beam pileup";
74 fPileUpTimeWindow = 88e-6;
77 AliGenPileup::~AliGenPileup()
82 void AliGenPileup::SetGenerator(AliGenerator *generator, Float_t rate, Bool_t flag)
84 // The method sets the geenrator to be used
85 // for pileup simulation.
86 // The second argument is the pileup rate in terms of
87 // #_of_interactions/bunch-crossing = sigma_tot * luminosity.
88 // There is a protection in case the generator was already set.
90 if (FirstGenerator()) {
91 AliError("Pileup generator has been already set! Nothing done");
95 AddGenerator(generator,"pileup generator",rate);
99 void AliGenPileup::AddGenerator(AliGenerator *Generator,
101 Float_t RateExp , TFormula* /*form*/, Int_t /*ntimes*/)
103 // The method used to add the pileup generator
104 // in the cocktail list.
105 // The method is protected in order to avoid
107 AliGenCocktail::AddGenerator(Generator,Name,RateExp);
110 Bool_t AliGenPileup::SetBCMask(const char *mask)
112 // Set the active bunch-crossings that
113 // will be included in the pileup
114 // simulation. For more details on the
115 // syntax of the mask - see
116 // STEER/AliTriggerBCMask.* and the comments
117 // in the header of this file
118 return fBCMask.SetMask(mask);
121 void AliGenPileup::Generate()
124 // Generate pileup event
125 // For details see the coments inline
127 // Check that the pileup generator is correctly set
128 AliGenCocktailEntry *entry = FirstGenerator();
130 AliFatal("No pileup generator entry is found!");
133 AliGenerator *gen = entry->Generator();
135 AliFatal("No pileup generator specified!");
137 else if (gen->NeedsCollisionGeometry()) {
138 AliFatal("No Collision Geometry Provided");
141 // Check that the pileup rate is correctly set
142 Float_t rate = entry->Rate();
144 AliFatal(Form("Invalid rate value: %f",rate));
147 // Create cocktail header
148 if (fHeader) delete fHeader;
149 fHeader = new AliGenCocktailEventHeader("Pileup Cocktail Header");
151 // Generate time of all
152 // the collisions within one orbit
153 Int_t *nIntBC = new Int_t[3*AliTriggerBCMask::kNBits];
154 Int_t *indexBC = new Int_t[3*AliTriggerBCMask::kNBits];
156 while (nTotBC == 0) {
157 for(Int_t iBC = 0; iBC < AliTriggerBCMask::kNBits; iBC++) {
159 if (!fBCMask.GetMask(iBC)) continue;
161 // Int_t nInteractions = gRandom->Poisson(rate);
164 nInteractions = gRandom->Poisson(rate);
166 nInteractions = TMath::Nint(rate) + 1;
168 if (nInteractions == 0) continue;
170 nIntBC[nTotBC] = nInteractions;
171 indexBC[nTotBC] = iBC;
176 // Select the bunch crossing for triggered event
177 Int_t iTrgBC = gRandom->Integer(nTotBC);
178 // Subtract one from the number of events
179 // generated within this bc (only in case
180 // the user disabled the generation of the trigger
182 if (!fGenTrig) nIntBC[iTrgBC]--;
184 // Remove bunch crossings outside pileup
186 for(Int_t iBC = 0; iBC < nTotBC; iBC++) {
187 if (TMath::Abs(25e-9*(indexBC[iBC]-indexBC[iTrgBC])) > fPileUpTimeWindow)
191 // Generate the two orbits around the central one
192 // taking into account the pileup time window
193 for(Int_t iBC = 0; iBC < AliTriggerBCMask::kNBits; iBC++) {
195 if (!fBCMask.GetMask(iBC)) continue;
197 if (TMath::Abs(25e-9*(iBC-AliTriggerBCMask::kNBits-indexBC[iTrgBC])) > fPileUpTimeWindow) continue;
199 Int_t nInteractions = gRandom->Poisson(rate);
200 if (nInteractions == 0) continue;
202 nIntBC[nTotBC] = nInteractions;
203 indexBC[nTotBC] = iBC-AliTriggerBCMask::kNBits;
206 for(Int_t iBC = 0; iBC < AliTriggerBCMask::kNBits; iBC++) {
208 if (!fBCMask.GetMask(iBC)) continue;
210 if (TMath::Abs(25e-9*(iBC+AliTriggerBCMask::kNBits-indexBC[iTrgBC])) > fPileUpTimeWindow) continue;
212 Int_t nInteractions = gRandom->Poisson(rate);
213 if (nInteractions == 0) continue;
215 nIntBC[nTotBC] = nInteractions;
216 indexBC[nTotBC] = iBC+AliTriggerBCMask::kNBits;
220 // Loop over the generated collision times, call the generator
221 // and correct the partcile times in the stack
222 AliStack *stack = AliRunLoader::Instance()->Stack();
224 entry->SetFirst(lastpart);
226 for(Int_t iBC = 0; iBC < nTotBC; iBC++) {
227 Float_t deltat = 25e-9*(indexBC[iBC] - indexBC[iTrgBC]);
228 for (Int_t i = 0; i < nIntBC[iBC]; i++) {
229 // Generate the vertex position and time
231 TArrayF eventVertex(3);
232 for (Int_t j=0; j < 3; j++) eventVertex[j] = fVertex[j];
233 Double_t vTime = deltat + gRandom->Gaus(0,fOsigma[2]/TMath::Ccgs());
235 gen->SetVertex(fVertex.At(0), fVertex.At(1), fVertex.At(2));
238 for (Int_t k = lastpart; k < stack->GetNprimary(); k++) {
240 stack->Particle(k)->ProductionVertex(v);
242 stack->Particle(k)->SetProductionVertex(v);
244 lastpart = stack->GetNprimary();
246 // Store the interaction header in the container of the headers
247 ((AliGenEventHeader*) fHeader->GetHeaders()->Last())->SetPrimaryVertex(eventVertex);
248 ((AliGenEventHeader*) fHeader->GetHeaders()->Last())->SetInteractionTime(vTime);
254 entry->SetLast(stack->GetNprimary());
256 fHeader->CalcNProduced();
259 fHeader->SetName(fName);
260 fContainer->AddHeader(fHeader);
262 gAlice->SetGenEventHeader(fHeader);
267 void AliGenPileup::SetRandomise(Bool_t /*flag*/)
269 // This setting is not implemented in
270 // case of pileup generation
271 // So the method gives an warning and exits
272 AliWarning("This setting has no effect on the generator!");
275 void AliGenPileup::UsePerEventRates()
277 // This setting is not implemented in
278 // case of pileup generation
279 // So the method gives an warning and exits
280 AliWarning("This setting has no effect on the generator!");