Belle II Software development
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
21namespace Belle2 {
26
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>
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);
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}
static const ChargedStable electron
electron particle
Definition Const.h:659
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 subtracting 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
double tan(double a)
tan for double
Definition beamHelpers.h:31
GeneralVector< T > getFourVector(T energy, T angleX, T angleY, bool isHER)
get 4-momentum from energy and angles of beam
T getEcms(GeneralVector< T > p1, GeneralVector< T > p2)
get CMS energy from HER & LER momentum 3-vectors
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,...
static const double me
electron mass
double atan(double a)
atan for double
Definition beamHelpers.h:34
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
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28
std::pair< T, T > getAnglesCMS(GeneralVector< T > p1, GeneralVector< T > p2)
get collision axis angles in CM frame from HER & LER momentum 3-vectors
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,...
T dot(GeneralVector< T > a, GeneralVector< T > b)
dot product of two general vectors
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
GeneralVector(T x, T y, T z)
constructor allowing to set the components of vector
T norm2() const
L2 norm of the vector squared.
T angleY() const
angle in the YZ projection of the vector
T angleX() const
angle in the XZ projection of the vector
T el[3]
elements of the vector