Belle II Software  release-08-01-10
beamHelpers.h
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #pragma once
10 
11 #include <framework/gearbox/Const.h>
12 
13 #include <cmath>
14 #include <tuple>
15 #include <utility>
16 #include <vector>
17 
18 #include <Eigen/Dense>
19 
20 
21 namespace Belle2 {
28  inline double sqrt(double a) { return std::sqrt(a); }
29 
31  inline double tan(double a) { return std::tan(a); }
32 
34  inline double atan(double a) { return std::atan(a); }
35 
38  struct DualNumber {
39  double x;
40  double dx;
41 
43  DualNumber(double X, double dX) : x(X), dx(dX) {}
44 
46  DualNumber() : x(0), dx(0) {}
47  };
48 
49 
52  {
53  return DualNumber(a.x + b.x, a.dx + b.dx);
54  }
55 
56 
58  inline DualNumber operator+(DualNumber a, double b)
59  {
60  return DualNumber(a.x + b, a.dx);
61  }
62 
63 
65  inline DualNumber operator-(DualNumber a, double b)
66  {
67  return DualNumber(a.x - b, a.dx);
68  }
69 
70 
72  inline DualNumber operator-(double a, DualNumber b)
73  {
74  return DualNumber(a - b.x, -b.dx);
75  }
76 
77 
79  inline DualNumber operator/(double a, DualNumber b)
80  {
81  return DualNumber(a / b.x, - a / (b.x * b.x) * b.dx);
82  }
83 
84 
87  {
88  return DualNumber(a.x / b.x, (a.dx * b.x - a.x * b.dx) / (b.x * b.x));
89  }
90 
91 
94  {
95  return DualNumber(a.x - b.x, a.dx - b.dx);
96  }
97 
98 
101  {
102  return DualNumber(a.x * b.x, a.x * b.dx + b.x * a.dx);
103  }
104 
105 
107  inline DualNumber operator*(double a, DualNumber b)
108  {
109  return DualNumber(a * b.x, a * b.dx);
110  }
111 
112 
115  {
116  return DualNumber(std::sqrt(a.x), 1. / (2 * std::sqrt(a.x)) * a.dx);
117  }
118 
119 
122  {
123  return DualNumber(std::atan(a.x), 1. / (1 + a.x * a.x) * a.dx);
124  }
125 
126 
129  {
130  return DualNumber(std::tan(a.x), (1.0 + std::tan(a.x) * std::tan(a.x)) * a.dx);
131  }
132 
133 
135  template<typename T>
136  struct GeneralVector {
137  T el[3];
138 
140  GeneralVector(T x, T y, T z) { el[0] = x; el[1] = y; el[2] = z; }
141 
143  T norm2() const { return (el[0] * el[0] + el[1] * el[1] + el[2] * el[2]); }
144 
146  T angleX() const { return atan(el[0] / el[2]); }
147 
149  T angleY() const { return atan(el[1] / el[2]); }
150  };
151 
152 
154  template<typename T>
156  {
157  return GeneralVector<T>(a.el[0] + b.el[0], a.el[1] + b.el[1], a.el[2] + b.el[2]);
158  }
159 
160 
162  template<typename T>
164  {
165  return (a.el[0] * b.el[0] + a.el[1] * b.el[1] + a.el[2] * b.el[2]);
166  }
167 
168 
170  template<typename T>
172  {
173  return GeneralVector<T>(a * b.el[0], a * b.el[1], a * b.el[2]);
174  }
175 
177  static const double me = Const::electron.getMass();
178 
179 
181  template<typename T>
183  {
184  T E1 = sqrt(p1.norm2() + me * me);
185  T E2 = sqrt(p2.norm2() + me * me);
186 
187  return sqrt((E1 + E2) * (E1 + E2) - (p1 + p2).norm2());
188  }
189 
190 
192  template<typename T>
194  {
195  T E1 = sqrt(p1.norm2() + me * me);
196  T E2 = sqrt(p2.norm2() + me * me);
197 
198  return 1. / (E1 + E2) * (p1 + p2);
199  }
200 
201 
203  template<typename T>
205  {
206  GeneralVector<T> bv = getBoost(p1, p2);
207 
208  T gamma = 1.0 / sqrt(1 - bv.norm2());
209 
210  T E1 = sqrt(p1.norm2() + me * me);
211 
212  GeneralVector<T> pCMS = p1 + ((gamma - 1) / bv.norm2() * dot(p1, bv) - gamma * E1) * bv;
213 
214  return std::make_pair(pCMS.angleX(), pCMS.angleY());
215  }
216 
217 
219  template<typename T>
220  GeneralVector<T> getFourVector(T energy, T angleX, T angleY, bool isHER)
221  {
222  T p = sqrt(energy * energy - me * me);
223 
224  double dir = isHER ? 1 : -1;
225 
226  T pz = dir * p / sqrt(tan(angleX) * tan(angleX) + tan(angleY) * tan(angleY) + 1.0);
227 
228  return GeneralVector<T>(pz * tan(angleX), pz * tan(angleY), pz);
229  }
230 
231 
233  inline Eigen::MatrixXd getGradientMatrix(double eH, double thXH, double thYH,
234  double eL, double thXL, double thYL)
235  {
236  Eigen::MatrixXd grad(6, 6);
237 
238  //calculate derivatives wrt all 6 input variables
239  for (int j = 0; j < 6; ++j) {
240 
241  std::vector<double> eps(6, 0.0);
242  eps[j] = 1.0;
243 
244  GeneralVector<DualNumber> pH = getFourVector(DualNumber(eH, eps[0]), DualNumber(thXH, eps[1]), DualNumber(thYH, eps[2]), true);
245  GeneralVector<DualNumber> pL = getFourVector(DualNumber(eL, eps[3]), DualNumber(thXL, eps[4]), DualNumber(thYL, eps[5]), false);
246 
247 
248  DualNumber Ecms = getEcms(pH, pL);
249  GeneralVector<DualNumber> boost = getBoost(pH, pL);
250 
251  DualNumber angleX, angleY;
252  std::tie(angleX, angleY) = getAnglesCMS(pH, pL);
253 
254  grad(0, j) = Ecms.dx;
255  grad(1, j) = boost.el[0].dx;
256  grad(2, j) = boost.el[1].dx;
257  grad(3, j) = boost.el[2].dx;
258  grad(4, j) = angleX.dx;
259  grad(5, j) = angleY.dx;
260  }
261 
262  return grad;
263  }
264 
265 
267  inline Eigen::VectorXd getCentralValues(double eH, double thXH, double thYH,
268  double eL, double thXL, double thYL)
269  {
270  Eigen::VectorXd mu(6);
271 
272  GeneralVector<double> pH = getFourVector<double>(eH, thXH, thYH, true);
273  GeneralVector<double> pL = getFourVector<double>(eL, thXL, thYL, false);
274 
275  double Ecms = getEcms<double>(pH, pL);
276  GeneralVector<double> boost = getBoost<double>(pH, pL);
277 
278  double angleX, angleY;
279  std::tie(angleX, angleY) = getAnglesCMS<double>(pH, pL);
280 
281  mu(0) = Ecms;
282  mu(1) = boost.el[0];
283  mu(2) = boost.el[1];
284  mu(3) = boost.el[2];
285  mu(4) = angleX;
286  mu(5) = angleY;
287 
288  return mu;
289  }
290 
291 
293  inline Eigen::MatrixXd transformCov(const Eigen::MatrixXd& covHER, const Eigen::MatrixXd& covLER, const Eigen::MatrixXd& grad)
294  {
295 
296  Eigen::MatrixXd cov = Eigen::MatrixXd::Zero(6, 6);
297  cov.block<3, 3>(0, 0) = covHER;
298  cov.block<3, 3>(3, 3) = covLER;
299 
300  Eigen::MatrixXd covNew = grad * cov * grad.transpose();
301 
302  return covNew;
303 
304  }
305 
306 
308 }
double getMass() const
Particle mass.
Definition: UnitConst.cc:356
static const ChargedStable electron
electron particle
Definition: Const.h:650
B2Vector3< DataType > operator*(DataType a, const B2Vector3< DataType > &p)
non-memberfunction Scaling of 3-vectors with a real number
Definition: B2Vector3.h:537
B2Vector3< DataType > operator-(const TVector3 &a, const B2Vector3< DataType > &b)
non-memberfunction for substracting a TVector3 from a B2Vector3
Definition: B2Vector3.h:551
B2Vector3< DataType > operator+(const TVector3 &a, const B2Vector3< DataType > &b)
non-memberfunction for adding a TVector3 to a B2Vector3
Definition: B2Vector3.h:544
DualNumber operator/(double a, DualNumber b)
division of double and dual number
Definition: beamHelpers.h:79
GeneralVector< T > getBoost(GeneralVector< T > p1, GeneralVector< T > p2)
get boost vector from HER & LER momentum 3-vectors
Definition: beamHelpers.h:193
Eigen::VectorXd getCentralValues(double eH, double thXH, double thYH, double eL, double thXL, double thYL)
get vector including (Ecms, boostX, boostY, boostZ, angleXZ, angleYZ) from beam energies and angles
Definition: beamHelpers.h:267
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Eigen::MatrixXd transformCov(const Eigen::MatrixXd &covHER, const Eigen::MatrixXd &covLER, const Eigen::MatrixXd &grad)
transform covariance matrix to the variables (Ecms, boostX, boostY, boostZ, angleXZ,...
Definition: beamHelpers.h:293
DualNumber sqrt(DualNumber a)
sqrt of dual number
Definition: beamHelpers.h:114
static const double me
electron mass
Definition: beamHelpers.h:177
GeneralVector< T > getFourVector(T energy, T angleX, T angleY, bool isHER)
get 4-momentum from energy and angles of beam
Definition: beamHelpers.h:220
double atan(double a)
atan for double
Definition: beamHelpers.h:34
Eigen::MatrixXd getGradientMatrix(double eH, double thXH, double thYH, double eL, double thXL, double thYL)
get gradient matrix of (eH, thXH, thYH, eL, thXL, thYL) -> (eCMS, boostX, boostY, boostY,...
Definition: beamHelpers.h:233
T dot(GeneralVector< T > a, GeneralVector< T > b)
dot product of two general vectors
Definition: beamHelpers.h:163
T getEcms(GeneralVector< T > p1, GeneralVector< T > p2)
get CMS energy from HER & LER momentum 3-vectors
Definition: beamHelpers.h:182
double tan(double a)
tan for double
Definition: beamHelpers.h:31
DualNumber atan(DualNumber a)
atan of dual number
Definition: beamHelpers.h:121
std::pair< T, T > getAnglesCMS(GeneralVector< T > p1, GeneralVector< T > p2)
get collision axis angles in CM frame from HER & LER momentum 3-vectors
Definition: beamHelpers.h:204
DualNumber tan(DualNumber a)
tan of dual number
Definition: beamHelpers.h:128
Abstract base class for different kinds of events.
Simple structure implementing dual numbers which are used for exact evaluation of the derivatives,...
Definition: beamHelpers.h:38
double dx
differential value of dual number, should be 1 if derivative is calculated
Definition: beamHelpers.h:40
DualNumber()
constructor setting values to zero
Definition: beamHelpers.h:46
DualNumber(double X, double dX)
constructor allowing to set the values
Definition: beamHelpers.h:43
double x
nominal value of dual number
Definition: beamHelpers.h:39
3-vector with members of arbitrary type, especially members can be dual numbers
Definition: beamHelpers.h:136
GeneralVector(T x, T y, T z)
constructor allowing to set the components of vector
Definition: beamHelpers.h:140
T norm2() const
L2 norm of the vector squared
Definition: beamHelpers.h:143
T angleY() const
angle in the YZ projection of the vector
Definition: beamHelpers.h:149
T angleX() const
angle in the XZ projection of the vector
Definition: beamHelpers.h:146
T el[3]
elements of the vector
Definition: beamHelpers.h:137