]>
Commit | Line | Data |
---|---|---|
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 | ||
59 | ClassImp(AliGenPileup) | |
60 | ||
61 | AliGenPileup::AliGenPileup(): | |
62 | AliGenCocktail(), | |
63 | fBCMask("bcm","3564H"), | |
64 | fGenTrig(kFALSE) | |
65 | { | |
66 | // Constructor | |
67 | // The pileup time window is by default | |
68 | // set to the TPC readout one | |
69 | fName = "Pileup"; | |
70 | fTitle= "Beam-beam pileup"; | |
71 | ||
72 | fPileUpTimeWindow = 88e-6; | |
73 | } | |
74 | ||
75 | AliGenPileup::~AliGenPileup() | |
76 | { | |
77 | // Destructor | |
78 | } | |
79 | ||
80 | void AliGenPileup::SetGenerator(AliGenerator *generator, Float_t rate) | |
81 | { | |
82 | // The method sets the geenrator to be used | |
83 | // for pileup simulation. | |
84 | // The second argument is the pileup rate in terms of | |
85 | // #_of_interactions/bunch-crossing = sigma_tot * luminosity. | |
86 | // There is a protection in case the generator was already set. | |
87 | if (fEntries) { | |
88 | if (FirstGenerator()) { | |
89 | AliError("Pileup generator has been already set! Nothing done"); | |
90 | return; | |
91 | } | |
92 | } | |
93 | AddGenerator(generator,"pileup generator",rate); | |
94 | } | |
95 | ||
96 | void AliGenPileup::AddGenerator(AliGenerator *Generator, | |
97 | const char* Name, | |
98 | Float_t RateExp ) | |
99 | { | |
100 | // The method used to add the pileup generator | |
101 | // in the cocktail list. | |
102 | // The method is protected in order to avoid | |
103 | // its misusage | |
104 | AliGenCocktail::AddGenerator(Generator,Name,RateExp); | |
105 | } | |
106 | ||
107 | Bool_t AliGenPileup::SetBCMask(const char *mask) | |
108 | { | |
109 | // Set the active bunch-crossings that | |
110 | // will be included in the pileup | |
111 | // simulation. For more details on the | |
112 | // syntax of the mask - see | |
113 | // STEER/AliTriggerBCMask.* and the comments | |
114 | // in the header of this file | |
115 | return fBCMask.SetMask(mask); | |
116 | } | |
117 | ||
118 | void AliGenPileup::Generate() | |
119 | { | |
120 | // | |
121 | // Generate pileup event | |
122 | // For details see the coments inline | |
123 | ||
124 | // Check that the pileup generator is correctly set | |
125 | AliGenCocktailEntry *entry = FirstGenerator(); | |
126 | if (!entry) { | |
127 | AliFatal("No pileup generator entry is found!"); | |
128 | } | |
129 | ||
130 | AliGenerator *gen = entry->Generator(); | |
131 | if (!gen) { | |
132 | AliFatal("No pileup generator specified!"); | |
133 | } | |
134 | else if (gen->NeedsCollisionGeometry()) { | |
135 | AliFatal("No Collision Geometry Provided"); | |
136 | } | |
137 | ||
138 | // Check that the pileup rate is correctly set | |
139 | Float_t rate = entry->Rate(); | |
140 | if (rate <= 0) { | |
141 | AliFatal(Form("Invalid rate value: %f",rate)); | |
142 | } | |
143 | ||
144 | // Create cocktail header | |
145 | if (fHeader) delete fHeader; | |
146 | fHeader = new AliGenCocktailEventHeader("Pileup Cocktail Header"); | |
147 | ||
148 | // Generate time of all | |
149 | // the collisions within one orbit | |
150 | Int_t *nIntBC = new Int_t[3*AliTriggerBCMask::kNBits]; | |
151 | Int_t *indexBC = new Int_t[3*AliTriggerBCMask::kNBits]; | |
152 | Int_t nTotBC = 0; | |
153 | while (nTotBC == 0) { | |
154 | for(Int_t iBC = 0; iBC < AliTriggerBCMask::kNBits; iBC++) { | |
155 | ||
156 | if (!fBCMask.GetMask(iBC)) continue; | |
157 | ||
158 | Int_t nInteractions = gRandom->Poisson(rate); | |
159 | if (nInteractions == 0) continue; | |
160 | ||
161 | nIntBC[nTotBC] = nInteractions; | |
162 | indexBC[nTotBC] = iBC; | |
163 | nTotBC++; | |
164 | } | |
165 | } | |
166 | ||
167 | // Select the bunch crossing for triggered event | |
168 | Int_t iTrgBC = gRandom->Integer(nTotBC); | |
169 | // Subtract one from the number of events | |
170 | // generated within this bc (only in case | |
171 | // the user disabled the generation of the trigger | |
172 | // interaction) | |
173 | if (!fGenTrig) nIntBC[iTrgBC]--; | |
174 | ||
175 | // Remove bunch crossings outside pileup | |
176 | // time window | |
177 | for(Int_t iBC = 0; iBC < nTotBC; iBC++) { | |
178 | if (TMath::Abs(25e-9*(indexBC[iBC]-indexBC[iTrgBC])) > fPileUpTimeWindow) | |
179 | nIntBC[iBC] = 0; | |
180 | } | |
181 | ||
182 | // Generate the two orbits around the central one | |
183 | // taking into account the pileup time window | |
184 | for(Int_t iBC = 0; iBC < AliTriggerBCMask::kNBits; iBC++) { | |
185 | ||
186 | if (!fBCMask.GetMask(iBC)) continue; | |
187 | ||
188 | if (TMath::Abs(25e-9*(iBC-AliTriggerBCMask::kNBits-indexBC[iTrgBC])) > fPileUpTimeWindow) continue; | |
189 | ||
190 | Int_t nInteractions = gRandom->Poisson(rate); | |
191 | if (nInteractions == 0) continue; | |
192 | ||
193 | nIntBC[nTotBC] = nInteractions; | |
194 | indexBC[nTotBC] = iBC-AliTriggerBCMask::kNBits; | |
195 | nTotBC++; | |
196 | } | |
197 | for(Int_t iBC = 0; iBC < AliTriggerBCMask::kNBits; iBC++) { | |
198 | ||
199 | if (!fBCMask.GetMask(iBC)) continue; | |
200 | ||
201 | if (TMath::Abs(25e-9*(iBC+AliTriggerBCMask::kNBits-indexBC[iTrgBC])) > fPileUpTimeWindow) continue; | |
202 | ||
203 | Int_t nInteractions = gRandom->Poisson(rate); | |
204 | if (nInteractions == 0) continue; | |
205 | ||
206 | nIntBC[nTotBC] = nInteractions; | |
207 | indexBC[nTotBC] = iBC+AliTriggerBCMask::kNBits; | |
208 | nTotBC++; | |
209 | } | |
210 | ||
211 | // Loop over the generated collision times, call the generator | |
212 | // and correct the partcile times in the stack | |
213 | AliStack *stack = AliRunLoader::Instance()->Stack(); | |
214 | Int_t lastpart=0; | |
215 | entry->SetFirst(lastpart); | |
216 | ||
217 | for(Int_t iBC = 0; iBC < nTotBC; iBC++) { | |
218 | Float_t deltat = 25e-9*(indexBC[iBC] - indexBC[iTrgBC]); | |
219 | for (Int_t i = 0; i < nIntBC[iBC]; i++) { | |
220 | // Generate the vertex position and time | |
221 | Vertex(); | |
222 | TArrayF eventVertex(3); | |
223 | for (Int_t j=0; j < 3; j++) eventVertex[j] = fVertex[j]; | |
224 | Double_t vTime = deltat + gRandom->Gaus(0,fOsigma[2]/TMath::Ccgs()); | |
225 | ||
226 | gen->SetVertex(fVertex.At(0), fVertex.At(1), fVertex.At(2)); | |
227 | gen->Generate(); | |
228 | ||
229 | for (Int_t k = lastpart; k < stack->GetNprimary(); k++) { | |
230 | TLorentzVector v; | |
231 | stack->Particle(k)->ProductionVertex(v); | |
232 | v[3] = vTime; | |
233 | stack->Particle(k)->SetProductionVertex(v); | |
234 | } | |
235 | lastpart = stack->GetNprimary(); | |
236 | ||
237 | // Store the interaction header in the container of the headers | |
238 | ((AliGenEventHeader*) fHeader->GetHeaders()->Last())->SetPrimaryVertex(eventVertex); | |
239 | } | |
240 | } | |
241 | delete [] nIntBC; | |
242 | delete [] indexBC; | |
243 | ||
244 | entry->SetLast(stack->GetNprimary()); | |
245 | ||
246 | fHeader->CalcNProduced(); | |
247 | ||
248 | if (fContainer) { | |
249 | fContainer->AddHeader(fHeader); | |
250 | } else { | |
251 | gAlice->SetGenEventHeader(fHeader); | |
252 | } | |
253 | ||
254 | } | |
255 | ||
256 | void AliGenPileup::SetRandomise(Bool_t /*flag*/) | |
257 | { | |
258 | // This setting is not implemented in | |
259 | // case of pileup generation | |
260 | // So the method gives an warning and exits | |
261 | AliWarning("This setting has no effect on the generator!"); | |
262 | } | |
263 | ||
264 | void AliGenPileup::UsePerEventRates() | |
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 | } |