MCBooster  1.0.1
Tool to generate MC phase space samples in parallel.
DecayMothers.h
Go to the documentation of this file.
1 /*
2  * DecayMothers.cuh
3  *
4  * Copyright 2016 Antonio Augusto Alves Junior
5  *
6  * Created on : Feb 25, 2016
7  * Author: Antonio Augusto Alves Junior
8  */
9 
10 /*
11  * This file is part of MCBooster.
12  *
13  * MCBooster is free software: you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation, either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * MCBooster is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with MCBooster. If not, see <http://www.gnu.org/licenses/>.
25  */
26 
27 #ifndef DECAYMOTHERS_H_
28 #define DECAYMOTHERS_H_
29 
30 
31 #include <mcbooster/Config.h>
32 #include <mcbooster/GTypes.h>
33 #include <mcbooster/GContainers.h>
34 #include <mcbooster/Vector3R.h>
35 #include <mcbooster/Vector4R.h>
36 #include <thrust/tuple.h>
37 #include <thrust/iterator/zip_iterator.h>
38 
39 using namespace std;
40 
41 namespace MCBooster
42 {
43 
45 {
46  const GInt_t fSeed;
48  const GReal_t* __restrict__ fMasses;
49 
50  //constructor
52  const GInt_t _ndaughters, const GInt_t _seed ):
53  fMasses(thrust::raw_pointer_cast(_masses.data())),
54  fNDaughters(_ndaughters),
55  fSeed(_seed)
56  {
57  }
58 
59  __host__ __device__ GReal_t pdk(const GReal_t a, const GReal_t b,
60  const GReal_t c) const
61  {
62  //the PDK function
63  GReal_t x = (a - b - c) * (a + b + c) * (a - b + c) * (a + b - c);
64  x = sqrt(x) / (2 * a);
65  return x;
66  }
67 
68  __host__ __device__ void bbsort(GReal_t *array, GInt_t n)
69  {
70  // Improved bubble sort
71  for (GInt_t c = 0; c < n; c++)
72  {
73  GInt_t nswap = 0;
74 
75  for (GInt_t d = 0; d < n - c - 1; d++)
76  {
77  if (array[d] > array[d + 1]) /* For decreasing order use < */
78  {
79  GReal_t swap = array[d];
80  array[d] = array[d + 1];
81  array[d + 1] = swap;
82  nswap++;
83  }
84  }
85  if (nswap == 0)
86  break;
87  }
88 
89  }
90 
91  __host__ __device__ GUInt_t hash(GUInt_t a)
92  {
93  a = (a + 0x7ed55d16) + (a << 12);
94  a = (a ^ 0xc761c23c) ^ (a >> 19);
95  a = (a + 0x165667b1) + (a << 5);
96  a = (a + 0xd3a2646c) ^ (a << 9);
97  a = (a + 0xfd7046c5) + (a << 3);
98  a = (a ^ 0xb55a4f09) ^ (a >> 16);
99  return a;
100  }
101 
102  __host__ __device__ GReal_t process(const GInt_t evt, Vector4R** particles)
103  {
104 
105 
106  thrust::random::default_random_engine randEng( hash(evt)*fSeed);
107  thrust::uniform_real_distribution<GReal_t> uniDist(0.0, 1.0);
108 
109  GReal_t fTeCmTm = 0.0, fWtMax = 0.0;
110 
111  fTeCmTm = particles[0]->mass(); // total energy in C.M. minus the sum of the masses
112 
113  #pragma unroll 9
114  for (size_t n = 0; n < fNDaughters; n++)
115  {
116  fTeCmTm -= fMasses[n];
117  }
118 
119  GReal_t emmax = fTeCmTm + fMasses[0];
120  GReal_t emmin = 0.0;
121  GReal_t wtmax = 1.0;
122 
123  #pragma unroll 9
124  for (size_t n = 1; n < fNDaughters; n++)
125  {
126  emmin += fMasses[n - 1];
127  emmax += fMasses[n];
128  wtmax *= pdk(emmax, emmin, fMasses[n]);
129  }
130  fWtMax = 1.0 / wtmax;
131  //
132  //----> get the betas of the decaying particle
133  //
134  GReal_t fBeta[3];
135  fBeta[0]=0, fBeta[1]=0, fBeta[2] = 0.0;
136 
137  GReal_t _beta = particles[0]->d3mag() / particles[0]->get(0);
138 
139  if (_beta)
140  {
141  GReal_t w = _beta / particles[0]->d3mag();
142  fBeta[0] = particles[0]->get(0) * w;
143  fBeta[1] = particles[0]->get(1) * w;
144  fBeta[2] = particles[0]->get(2) * w;
145  }
146 
147  GReal_t rno[kMAXP];
148  rno[0] = 0.0;
149 
150  if (fNDaughters > 2)
151  {
152  #pragma unroll 9
153  for (size_t n = 1; n < fNDaughters - 1; n++)
154  rno[n] = uniDist(randEng) ;
155  bbsort(&rno[1], fNDaughters - 2);
156 
157  }
158  rno[fNDaughters - 1] = 1;
159 
160  GReal_t invMas[kMAXP], sum = 0.0;
161 
162  #pragma unroll 9
163  for (size_t n = 0; n < fNDaughters; n++)
164  {
165  sum += fMasses[n];
166  invMas[n] = rno[n] * fTeCmTm + sum;
167  }
168 
169  //
170  //-----> compute the weight of the current event
171  //
172 
173  GReal_t wt = 1.0 / wtmax;
174 
175  GReal_t pd[kMAXP];
176 
177  #pragma unroll 9
178  for (size_t n = 0; n < fNDaughters - 1; n++)
179  {
180  pd[n] = pdk(invMas[n + 1], invMas[n], fMasses[n + 1]);
181  wt *= pd[n];
182  }
183 
184  //
185  //-----> complete specification of event (Raubold-Lynch method)
186  //
187 
188  particles[1]->set(sqrt(pd[0] * pd[0] + fMasses[0] * fMasses[0]), 0.0,
189  pd[0], 0.0);
190 
191  #pragma unroll 9
192  for (size_t i = 1; i < fNDaughters; i++)
193  {
194 
195  particles[i + 1]->set(
196  sqrt(pd[i - 1] * pd[i - 1] + fMasses[i] * fMasses[i]), 0.0,
197  -pd[i - 1], 0.0);
198 
199  GReal_t cZ = 2 * uniDist(randEng) -1 ;
200  GReal_t sZ = sqrt(1 - cZ * cZ);
201  GReal_t angY = 2.0 * PI * uniDist(randEng);
202  GReal_t cY = cos(angY);
203  GReal_t sY = sin(angY);
204  for (size_t j = 0; j <= i; j++)
205  {
206 
207  GReal_t x = particles[j + 1]->get(1);
208  GReal_t y = particles[j + 1]->get(2);
209  particles[j + 1]->set(1, cZ * x - sZ * y);
210  particles[j + 1]->set(2, sZ * x + cZ * y); // rotation around Z
211 
212  x = particles[j + 1]->get(1);
213  GReal_t z = particles[j + 1]->get(3);
214  particles[j + 1]->set(1, cY * x - sY * z);
215  particles[j + 1]->set(3, sY * x + cY * z); // rotation around Y
216  }
217 
218  if (i == (fNDaughters - 1))
219  break;
220 
221  GReal_t beta = pd[i] / sqrt(pd[i] * pd[i] + invMas[i] * invMas[i]);
222  for (size_t j = 0; j <= i; j++)
223  {
224 
225  particles[j + 1]->applyBoostTo(0, beta, 0);
226  }
227 
228  //i++;
229  }
230 
231  //
232  //---> final boost of all particles to the mother's frame
233  //
234  #pragma unroll 9
235  for (size_t n = 0; n < fNDaughters; n++)
236  {
237 
238  particles[n + 1]->applyBoostTo(*particles[0]);
239 
240  }
241 
242  //
243  //---> return the weight of event
244  //
245 
246  return wt;
247 
248  }
249 
250  __host__ __device__ GReal_t operator()(const GInt_t evt, GT2 &particles)
251  {
252  //do nothing, will never be called
253  return 0.0;
254 
255  }
256 
257  __host__ __device__ GReal_t operator()(const GInt_t evt, GT3& particles)
258  {
259  Vector4R* _Particles[3];
260 
261  _Particles[0] = &thrust::get<0>(particles);
262  _Particles[1] = &thrust::get<1>(particles);
263  _Particles[2] = &thrust::get<2>(particles);
264 
265  return process(evt, _Particles);
266 
267  }
268 
269  __host__ __device__ GReal_t operator()(const GInt_t evt, GT4& particles)
270  {
271 
272  Vector4R* _Particles[4];
273 
274  _Particles[0] = &thrust::get<0>(particles);
275  _Particles[1] = &thrust::get<1>(particles);
276  _Particles[2] = &thrust::get<2>(particles);
277  _Particles[3] = &thrust::get<3>(particles);
278 
279  return process(evt, _Particles);
280 
281  }
282 
283  __host__ __device__ GReal_t operator()(const GInt_t evt, GT5& particles)
284  {
285  Vector4R* _Particles[5];
286 
287  _Particles[0] = &thrust::get<0>(particles);
288  _Particles[1] = &thrust::get<1>(particles);
289  _Particles[2] = &thrust::get<2>(particles);
290  _Particles[3] = &thrust::get<3>(particles);
291  _Particles[4] = &thrust::get<4>(particles);
292 
293  return process(evt, _Particles);
294 
295  }
296 
297  __host__ __device__ GReal_t operator()(const GInt_t evt, GT6& particles)
298  {
299  Vector4R* _Particles[6];
300 
301  _Particles[0] = &thrust::get<0>(particles);
302  _Particles[1] = &thrust::get<1>(particles);
303  _Particles[2] = &thrust::get<2>(particles);
304  _Particles[3] = &thrust::get<3>(particles);
305  _Particles[4] = &thrust::get<4>(particles);
306  _Particles[5] = &thrust::get<5>(particles);
307 
308  return process(evt, _Particles);
309 
310  }
311 
312  __host__ __device__ GReal_t operator()(const GInt_t evt, GT7& particles)
313  {
314  Vector4R* _Particles[7];
315 
316  _Particles[0] = &thrust::get<0>(particles);
317  _Particles[1] = &thrust::get<1>(particles);
318  _Particles[2] = &thrust::get<2>(particles);
319  _Particles[3] = &thrust::get<3>(particles);
320  _Particles[4] = &thrust::get<4>(particles);
321  _Particles[5] = &thrust::get<5>(particles);
322  _Particles[6] = &thrust::get<6>(particles);
323 
324  return process(evt, _Particles);
325 
326  }
327 
328  __host__ __device__ GReal_t operator()(const GInt_t evt, GT8& particles)
329  {
330  Vector4R* _Particles[8];
331 
332  _Particles[0] = &thrust::get<0>(particles);
333  _Particles[1] = &thrust::get<1>(particles);
334  _Particles[2] = &thrust::get<2>(particles);
335  _Particles[3] = &thrust::get<3>(particles);
336  _Particles[4] = &thrust::get<4>(particles);
337  _Particles[5] = &thrust::get<5>(particles);
338  _Particles[6] = &thrust::get<6>(particles);
339  _Particles[7] = &thrust::get<7>(particles);
340 
341  return process(evt, _Particles);
342 
343  }
344 
345  __host__ __device__ GReal_t operator()(const GInt_t evt, GT9& particles)
346  {
347  Vector4R* _Particles[9];
348 
349  _Particles[0] = &thrust::get<0>(particles);
350  _Particles[1] = &thrust::get<1>(particles);
351  _Particles[2] = &thrust::get<2>(particles);
352  _Particles[3] = &thrust::get<3>(particles);
353  _Particles[4] = &thrust::get<4>(particles);
354  _Particles[5] = &thrust::get<5>(particles);
355  _Particles[6] = &thrust::get<6>(particles);
356  _Particles[7] = &thrust::get<7>(particles);
357  _Particles[8] = &thrust::get<8>(particles);
358 
359  return process(evt, _Particles);
360 
361  }
362 
363  __host__ __device__ GReal_t operator()(const GInt_t evt, GT10& particles)
364  {
365  Vector4R* _Particles[10];
366 
367  _Particles[0] = &thrust::get<0>(particles);
368  _Particles[1] = &thrust::get<1>(particles);
369  _Particles[2] = &thrust::get<2>(particles);
370  _Particles[3] = &thrust::get<3>(particles);
371  _Particles[4] = &thrust::get<4>(particles);
372  _Particles[5] = &thrust::get<5>(particles);
373  _Particles[6] = &thrust::get<6>(particles);
374  _Particles[7] = &thrust::get<7>(particles);
375  _Particles[8] = &thrust::get<8>(particles);
376  _Particles[9] = &thrust::get<9>(particles);
377 
378  return process(evt, _Particles);
379 
380  }
381 
382 };
383 
384 }
385 
386 #endif /* DECAYMOTHERS_H_ */
__host__ __device__ GReal_t operator()(const GInt_t evt, GT9 &particles)
Definition: DecayMothers.h:345
thrust::detail::tuple_of_iterator_references< Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type > GT5
GT5 iterator is a typedef for thrust::detail::tuple_of_iterator_references
Definition: GContainers.h:148
__host__ __device__ GReal_t get(GInt_t i) const
Definition: Vector4R.h:231
thrust::detail::tuple_of_iterator_references< Vector4R &, Vector4R &, Vector4R &, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type > GT3
GT3 iterator is a typedef for thrust::detail::tuple_of_iterator_references
Definition: GContainers.h:136
__host__ __device__ void bbsort(GReal_t *array, GInt_t n)
Definition: DecayMothers.h:68
const GInt_t fNDaughters
Definition: DecayMothers.h:47
__host__ __device__ GReal_t operator()(const GInt_t evt, GT6 &particles)
Definition: DecayMothers.h:297
unsigned int GUInt_t
Unsigned integer 4 bytes (unsigned int)
Definition: GTypes.h:38
__host__ __device__ GReal_t operator()(const GInt_t evt, GT3 &particles)
Definition: DecayMothers.h:257
__host__ __device__ GReal_t d3mag() const
Definition: Vector4R.h:504
__host__ __device__ GReal_t operator()(const GInt_t evt, GT4 &particles)
Definition: DecayMothers.h:269
__host__ __device__ GReal_t operator()(const GInt_t evt, GT5 &particles)
Definition: DecayMothers.h:283
STL namespace.
Typedef for useful container classes used in MCBooster.
const GReal_t *__restrict__ fMasses
Definition: DecayMothers.h:48
thrust::detail::tuple_of_iterator_references< Vector4R &, Vector4R &, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type > GT2
GT2 iterator is a typedef for thrust::detail::tuple_of_iterator_references
Definition: GContainers.h:130
thrust::detail::tuple_of_iterator_references< Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, thrust::null_type > GT9
GT9 iterator is a typedef for thrust::detail::tuple_of_iterator_references
Definition: GContainers.h:170
#define kMAXP
Definition: GTypes.h:65
__host__ __device__ GReal_t process(const GInt_t evt, Vector4R **particles)
Definition: DecayMothers.h:102
thrust::detail::tuple_of_iterator_references< Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R & > GT10
GT10 iterator is a typedef for thrust::detail::tuple_of_iterator_references
Definition: GContainers.h:175
#define PI
Definition: GTypes.h:66
__host__ __device__ GReal_t pdk(const GReal_t a, const GReal_t b, const GReal_t c) const
Definition: DecayMothers.h:59
__host__ __device__ GUInt_t hash(GUInt_t a)
Definition: DecayMothers.h:91
__host__ __device__ void set(GInt_t i, GReal_t d)
Definition: Vector4R.h:236
thrust::detail::tuple_of_iterator_references< Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, thrust::null_type, thrust::null_type, thrust::null_type > GT7
GT7 iterator is a typedef for thrust::detail::tuple_of_iterator_references
Definition: GContainers.h:159
__host__ __device__ GReal_t operator()(const GInt_t evt, GT10 &particles)
Definition: DecayMothers.h:363
DecayMothers(const mc_device_vector< GReal_t > &_masses, const GInt_t _ndaughters, const GInt_t _seed)
Definition: DecayMothers.h:51
double GReal_t
Double 8 bytes or float 4 bytes.
Definition: GTypes.h:52
__host__ __device__ void applyBoostTo(const Vector4R &p4, bool inverse=false)
Definition: Vector4R.h:355
thrust::detail::tuple_of_iterator_references< Vector4R &, Vector4R &, Vector4R &, Vector4R &, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type > GT4
GT4 iterator is a typedef for thrust::detail::tuple_of_iterator_references
Definition: GContainers.h:142
__host__ __device__ GReal_t operator()(const GInt_t evt, GT8 &particles)
Definition: DecayMothers.h:328
__host__ __device__ GReal_t operator()(const GInt_t evt, GT7 &particles)
Definition: DecayMothers.h:312
int GInt_t
Signed integer 4 bytes (int)
Definition: GTypes.h:37
thrust::host_vector< T > mc_device_vector
Generic template typedef for thrust::host_vector.
Definition: GContainers.h:60
__host__ __device__ GReal_t mass() const
Definition: Vector4R.h:280
thrust::detail::tuple_of_iterator_references< Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type > GT6
GT6 iterator is a typedef for thrust::detail::tuple_of_iterator_references
Definition: GContainers.h:154
thrust::detail::tuple_of_iterator_references< Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, Vector4R &, thrust::null_type, thrust::null_type > GT8
GT8 iterator is a typedef for thrust::detail::tuple_of_iterator_references
Definition: GContainers.h:164
__host__ __device__ GReal_t operator()(const GInt_t evt, GT2 &particles)
Definition: DecayMothers.h:250