Belle II Software  release-06-01-15
Sutool.cc
1 // -*- C++ -*-
2 //
3 // Package: <package>
4 // Module: Sutool
5 //
6 // Description: <one line class summary>
7 // Tools collected by S.Uehara for kinematics
8 // Implimentation:
9 // <Notes on implimentation>
10 //
11 // Author: Sadaharu Uehara
12 // Created: Thu May 8 15:04:07 JST 1997
13 // $Id$
14 //
15 // Revision history
16 // Update on 31-Mar-1998 S.U. for 3-body case for impoving approximation
17 // of phase-space volume
18 // Modofied to be suitable to Belle II style
19 // $Log$
20 
21 // system include files
22 #include <iostream>
23 #include <fstream>
24 #include <math.h>
25 #include <TVector3.h>
26 #include <TLorentzVector.h>
27 
28 #include <framework/logging/Logger.h>
29 
30 // user include files
31 #include <generators/treps/Sutool.h>
32 
33 using namespace std;
34 
35 namespace Belle2 {
41  extern "C" {
42  extern void aaubrn_(float*, float[20], int*, float*);
43  }
44 
45  //
46  // member functions
47  //
48 
49 
50  double Sutool::p2bdy(double m0, double m1, double m2, int& jcode)
51  {
52  // two-body decay kinematics translated from EPOCS P2BDY$
53  if (m0 <= 0.0 || m1 < 0.0 || m2 < 0.0) {
54  B2FATAL(" Invalid mass value in two-body decay:" <<
55  m0 << " " << m1 << " " << m2) ;
56  jcode = 0;
57  return 0.0 ;
58  }
59 
60  if (m0 >= (m1 + m2)) {
61  double pp = (m0 - m1 - m2) * (m0 + m1 - m2)
62  * (m0 - m1 + m2) * (m0 + m1 + m2);
63  if (pp < 0.0) pp = 0.0 ;
64  jcode = 1;
65  double pcm = sqrt(pp) / 2. / m0 ;
66  return pcm ;
67  } else {
68  jcode = 0;
69  return 0.0 ;
70  }
71  return 0.0 ;
72  }
73 
74  int Sutool::pdecy(double mpr, double* mse,
75  const TVector3& ppri, TLorentzVector* psec, int nums)
76  // multi-body decay by phase space
77  // translated from EPOCS PDECY$
78  // original EPOCS version gives a good approximation for nums = 3
79  // but, bad approximation for nums > 3.
80  // I improved that to get an exact answer for nums = 3, and to get
81  // good approximations for nums > 3 using AAUB (S.Uehara)
82  {
83  if (nums < 2) {
84  B2FATAL(" Number of secondaries must be >=2");
85  return 0;
86  }
87 
88  double m0 = mpr ;
89  int n = nums ;
90  TVector3 pcms = ppri ;
91 
92  int jcode;
93  double w, p, pf;
94 
95  do {
96  if (n == 2) {
97  p = p2bdy(m0, mse[0], mse[1], jcode);
98  if (jcode == 0) return 0 ;
99  w = mse[0];
100  } else {
101  double mx = m0 - mse[n - 1];
102  double mi = 0.0 ;
103  for (int l = 1 ; l <= n - 1 ; l++) mi = mi + mse[l - 1];
104  double bmx = mx * mx ;
105  double bmi = mi * mi ;
106  double pmx = p2bdy(m0, mi, mse[n - 1], jcode);
107  if (jcode == 0) return 0 ;
108 
109  do {
110  double w2 = bmi + (bmx - bmi) * gRandom->Uniform() ;
111  w = sqrt(w2) ;
112  p = p2bdy(m0, w, mse[n - 1], jcode);
113  if (jcode == 0) return 0;
114 
115  if (n == 3) {
116  pf = 2.*p2bdy(w, mse[0], mse[1], jcode) / w;
117  if (jcode == 0) return 0;
118  } else {
119  // Use AAUB
120  float pfmax, pff;
121  float m0f = (float)m0;
122  float wf = (float)w;
123  int nsub = n - 1;
124  float msef[20];
125  for (int l = 0 ; l < nsub ; l++) msef[l] = (float)mse[l];
126  aaubrn_(&m0f, msef, &nsub, &pfmax);
127  aaubrn_(&wf, msef, &nsub, &pff);
128  pf = (double)(pff / pfmax);
129  }
130  } while (pmx * gRandom->Uniform() > p * pf);
131 
132  }
133  const double twopi = 2.*3.14159265 ;
134  double phi = twopi * gRandom->Uniform();
135  double cth = 2.*gRandom->Uniform() - 1. ;
136  double sth = sqrt(1. - cth * cth);
137 
138  psec[n - 1] = TLorentzVector(p * sth * cos(phi), p * sth * sin(phi),
139  p * cth, sqrt(p * p + mse[n - 1] * mse[n - 1]));
140  psec[n - 2] = TLorentzVector(-p * sth * cos(phi), -p * sth * sin(phi),
141  -p * cth, sqrt(p * p + w * w));
142 
143  psec[n - 1].Boost(pcms);
144  psec[n - 2].Boost(pcms);
145 
146  if (n == 2) break ;
147 
148  m0 = w;
149  pcms = (1. / psec[n - 2].T()) * psec[n - 2].Vect();
150 
151  n--;
152  } while (1);
153  return jcode;
154  }
155 
156  void Sutool::rotate(TLorentzVector& p, double th, double phi)
157  {
158  // Some rotation of the 3Vector in a LorentzVector
159  double ct = cos(th);
160  double st = sin(th);
161  double cp = cos(phi);
162  double sp = sin(phi);
163 
164  TLorentzVector q = TLorentzVector(
165  cp * ct * p.X() + sp * p.Y() + cp * st * p.Z(),
166  -sp * ct * p.X() + cp * p.Y() - sp * st * p.Z(),
167  -st * p.X() + ct * p.Z(),
168  p.T());
169  p = q;
170  }
171 
172  float Sutool::interp(float a1, float a2, float a3, float a4, float f)
173  {
174  float b1, b2, b3, c1, c2, d1;
175  float g2, g3;
176  // added by S.Uehara Sept.26,1997
177  b1 = a2 - a1; b2 = a3 - a2 ; b3 = a4 - a3;
178  c1 = b2 - b1; c2 = b3 - b2 ; d1 = c2 - c1;
179  g2 = 0.25 * f * (f - 1.);
180  g3 = 2. / 3. * g2 * (f - 0.5);
181 
182  return a2 + f * b2 + g2 * (c1 + c2) + g3 * d1;
183  }
184 
185  int Sutool::poisson(double m)
186  {
187  return gRandom->Poisson(m);
188  }
189 
191 }
Abstract base class for different kinds of events.