]>
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"), | |
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 | for(Int_t iBC = 0; iBC < AliTriggerBCMask::kNBits; iBC++) { | |
154 | ||
155 | if (!fBCMask.GetMask(iBC)) continue; | |
156 | ||
157 | Int_t nInteractions = gRandom->Poisson(rate); | |
158 | if (nInteractions == 0) continue; | |
159 | ||
160 | nIntBC[nTotBC] = nInteractions; | |
161 | indexBC[nTotBC] = iBC; | |
162 | nTotBC++; | |
163 | } | |
164 | ||
165 | // Select the bunch crossing for triggered event | |
166 | Int_t iTrgBC = gRandom->Integer(nTotBC); | |
167 | // Subtract one from the number of events | |
168 | // generated within this bc (only in case | |
169 | // the user disabled the generation of the trigger | |
170 | // interaction) | |
aee85673 | 171 | if (!fGenTrig) nIntBC[iTrgBC]--; |
56f3f4a4 | 172 | |
173 | // Remove bunch crossings outside pileup | |
174 | // time window | |
175 | for(Int_t iBC = 0; iBC < nTotBC; iBC++) { | |
176 | if (TMath::Abs(25e-9*(indexBC[iBC]-indexBC[iTrgBC])) > fPileUpTimeWindow) | |
177 | nIntBC[iBC] = 0; | |
178 | } | |
179 | ||
180 | // Generate the two orbits around the central one | |
181 | // taking into account the pileup time window | |
182 | for(Int_t iBC = 0; iBC < AliTriggerBCMask::kNBits; iBC++) { | |
183 | ||
184 | if (!fBCMask.GetMask(iBC)) continue; | |
185 | ||
186 | if (TMath::Abs(25e-9*(iBC-AliTriggerBCMask::kNBits-indexBC[iTrgBC])) > fPileUpTimeWindow) continue; | |
187 | ||
188 | Int_t nInteractions = gRandom->Poisson(rate); | |
189 | if (nInteractions == 0) continue; | |
190 | ||
191 | nIntBC[nTotBC] = nInteractions; | |
192 | indexBC[nTotBC] = iBC-AliTriggerBCMask::kNBits; | |
193 | nTotBC++; | |
194 | } | |
195 | for(Int_t iBC = 0; iBC < AliTriggerBCMask::kNBits; iBC++) { | |
196 | ||
197 | if (!fBCMask.GetMask(iBC)) continue; | |
198 | ||
199 | if (TMath::Abs(25e-9*(iBC+AliTriggerBCMask::kNBits-indexBC[iTrgBC])) > fPileUpTimeWindow) continue; | |
200 | ||
201 | Int_t nInteractions = gRandom->Poisson(rate); | |
202 | if (nInteractions == 0) continue; | |
203 | ||
204 | nIntBC[nTotBC] = nInteractions; | |
205 | indexBC[nTotBC] = iBC+AliTriggerBCMask::kNBits; | |
206 | nTotBC++; | |
207 | } | |
208 | ||
209 | // Loop over the generated collision times, call the generator | |
210 | // and correct the partcile times in the stack | |
211 | AliStack *stack = AliRunLoader::GetRunLoader()->Stack(); | |
212 | Int_t lastpart=0; | |
213 | entry->SetFirst(lastpart); | |
214 | ||
215 | for(Int_t iBC = 0; iBC < nTotBC; iBC++) { | |
216 | Float_t deltat = 25e-9*(indexBC[iBC] - indexBC[iTrgBC]); | |
217 | for (Int_t i = 0; i < nIntBC[iBC]; i++) { | |
218 | // Generate the vertex position and time | |
219 | Vertex(); | |
220 | TArrayF eventVertex(3); | |
221 | for (Int_t j=0; j < 3; j++) eventVertex[j] = fVertex[j]; | |
222 | Double_t vTime = deltat + gRandom->Gaus(0,fOsigma[2]/TMath::Ccgs()); | |
223 | ||
224 | gen->SetVertex(fVertex.At(0), fVertex.At(1), fVertex.At(2)); | |
225 | gen->Generate(); | |
226 | ||
227 | for (Int_t k = lastpart; k < stack->GetNprimary(); k++) { | |
228 | TLorentzVector v; | |
229 | stack->Particle(k)->ProductionVertex(v); | |
230 | v[3] = vTime; | |
231 | stack->Particle(k)->SetProductionVertex(v); | |
232 | } | |
233 | lastpart = stack->GetNprimary(); | |
234 | ||
235 | // Store the interaction header in the container of the headers | |
236 | ((AliGenEventHeader*) fHeader->GetHeaders()->Last())->SetPrimaryVertex(eventVertex); | |
237 | } | |
238 | } | |
239 | delete [] nIntBC; | |
240 | delete [] indexBC; | |
241 | ||
242 | entry->SetLast(stack->GetNprimary()); | |
243 | ||
244 | fHeader->CalcNProduced(); | |
245 | ||
246 | if (fContainer) { | |
247 | fContainer->AddHeader(fHeader); | |
248 | } else { | |
249 | gAlice->SetGenEventHeader(fHeader); | |
250 | } | |
251 | ||
252 | } | |
253 | ||
254 | void AliGenPileup::SetRandomise(Bool_t /*flag*/) | |
255 | { | |
256 | // This setting is not implemented in | |
257 | // case of pileup generation | |
258 | // So the method gives an warning and exits | |
259 | AliWarning("This setting has no effect on the generator!"); | |
260 | } | |
261 | ||
262 | void AliGenPileup::UsePerEventRates() | |
263 | { | |
264 | // This setting is not implemented in | |
265 | // case of pileup generation | |
266 | // So the method gives an warning and exits | |
267 | AliWarning("This setting has no effect on the generator!"); | |
268 | } |