]>
Commit | Line | Data |
---|---|---|
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 | ||
59 | ClassImp(AliGenPileup) | |
60 | ||
61 | AliGenPileup::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 | ||
76 | AliGenPileup::~AliGenPileup() | |
77 | { | |
78 | // Destructor | |
79 | } | |
80 | ||
aa0d2074 | 81 | void 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 | ||
98 | void 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 | ||
109 | Bool_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 | ||
120 | void 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); | |
d07f0af2 | 247 | ((AliGenEventHeader*) fHeader->GetHeaders()->Last())->SetInteractionTime(vTime); |
56f3f4a4 | 248 | } |
249 | } | |
250 | delete [] nIntBC; | |
251 | delete [] indexBC; | |
252 | ||
253 | entry->SetLast(stack->GetNprimary()); | |
254 | ||
255 | fHeader->CalcNProduced(); | |
256 | ||
257 | if (fContainer) { | |
258 | fContainer->AddHeader(fHeader); | |
259 | } else { | |
260 | gAlice->SetGenEventHeader(fHeader); | |
261 | } | |
262 | ||
263 | } | |
264 | ||
265 | void AliGenPileup::SetRandomise(Bool_t /*flag*/) | |
266 | { | |
267 | // This setting is not implemented in | |
268 | // case of pileup generation | |
269 | // So the method gives an warning and exits | |
270 | AliWarning("This setting has no effect on the generator!"); | |
271 | } | |
272 | ||
273 | void AliGenPileup::UsePerEventRates() | |
274 | { | |
275 | // This setting is not implemented in | |
276 | // case of pileup generation | |
277 | // So the method gives an warning and exits | |
278 | AliWarning("This setting has no effect on the generator!"); | |
279 | } |