23#include "HepMC3/FourVector.h"
24#include "HepMC3/GenParticle.h"
27#include "marley/Error.hh"
28#include "marley/RotationMatrix.hh"
29#include "marley/hepmc3_utils.hh"
31using ThreeVector = std::array<double, 3>;
37 void cross_product(ThreeVector& dest,
38 const ThreeVector& v1,
const ThreeVector& v2)
40 dest[0] = v1[1] * v2[2] - v1[2] * v2[1];
41 dest[1] = v1[2] * v2[0] - v1[0] * v2[2];
42 dest[2] = v1[0] * v2[1] - v1[1] * v2[0];
46 double dot_product(
const ThreeVector& v1,
47 const ThreeVector& v2)
49 return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
53 void subtract(ThreeVector& dest,
54 const ThreeVector& v1,
const ThreeVector& v2)
56 dest[0] = v1[0] - v2[0];
57 dest[1] = v1[1] - v2[1];
58 dest[2] = v1[2] - v2[2];
64 :
matrix_{{ {{ 1., 0., 0.}}, {{ 0., 1., 0.}}, {{ 0., 0., 1.}} }}
68ThreeVector marley::RotationMatrix::normalize(
const ThreeVector& v)
70 static ThreeVector nv({0., 0., 0.});
71 double norm_factor = std::sqrt(std::pow(v[0], 2) + std::pow(v[1], 2)
73 if (norm_factor <= 0.)
throw marley::Error(std::string(
"Invalid vector")
74 +
" magnitude encountered in marley::RotationMatrix::normalize()");
75 else norm_factor = 1. / norm_factor;
76 nv[0] = norm_factor * v[0];
77 nv[1] = norm_factor * v[1];
78 nv[2] = norm_factor * v[2];
85 ThreeVector rv = {0., 0., 0.};
86 for (
unsigned i = 0; i < 3; ++i) rv[i] = dot_product(
matrix_[i], v);
93 ThreeVector rv = {0., 0., 0.};
94 for (
unsigned i = 0; i < 3; ++i) rv[i] = dot_product(
matrix_[i], v);
103 ThreeVector rv = { 0., 0., 0. };
104 ThreeVector three_momentum = { mom4.
px(), mom4.
py(), mom4.
pz() };
106 for (
unsigned i = 0; i < 3; ++i)
107 rv[i] = dot_product(
matrix_[i], three_momentum );
123 const ThreeVector& to_vec)
125 static constexpr ThreeVector null_three_vector = { 0., 0., 0. };
127 if (from_vec == null_three_vector)
129 +
" passed to constructor of marley::RotationMatrix");
130 else if (to_vec == null_three_vector)
132 +
" passed to constructor of marley::RotationMatrix");
136 ThreeVector from = normalize(from_vec);
137 ThreeVector to = normalize(to_vec);
139 double e = dot_product(from, to);
140 double f = std::abs(e);
142 static constexpr double EPSILON = 0.000001;
143 if (f > 1.0 - EPSILON) {
151 x[0] = std::abs(from[0]);
152 x[1] = std::abs(from[1]);
153 x[2] = std::abs(from[2]);
159 x[0] = 1.0; x[1] = x[2] = 0.0;
163 x[2] = 1.0; x[0] = x[1] = 0.0;
170 x[1] = 1.0; x[0] = x[2] = 0.0;
174 x[2] = 1.0; x[0] = x[1] = 0.0;
179 subtract(u, x, from);
185 double c1 = 2.0 / dot_product(u, u);
186 double c2 = 2.0 / dot_product(v, v);
187 double c3 = c1 * c2 * dot_product(u, v);
189 for (
unsigned i = 0; i < 3; ++i) {
190 for (
unsigned j = 0; j < 3; ++j) {
191 matrix_[i][j] = - c1 * u[i] * u[j] - c2 * v[i] * v[j]
200 cross_product(v, from, to);
204 double hvx, hvz, hvxy, hvxz, hvyz;
205 double h = 1.0 / (1.0 + e);
212 matrix_[0][0] = e + hvx * v[0];
217 matrix_[1][1] = e + h * v[1] * v[1];
222 matrix_[2][2] = e + hvz * v[2];
void set_py(double pyy)
Set y-component of momentum.
void set_px(double pxx)
Set x-component of momentum.
double px() const
x-component of momentum
double py() const
y-component of momentum
double pz() const
z-component of momentum
void set_pz(double pzz)
Set z-component of momentum.
Stores particle-related information.
void set_momentum(const FourVector &momentum)
Set momentum.
const FourVector & momentum() const
Get momentum.
Base class for all exceptions thrown by MARLEY functions.
void rotate_inplace(ThreeVector &v)
Rotate a 3-vector v in place.
RotationMatrix()
Creates a 3×3 identity matrix.
void rotate_particle_inplace(HepMC3::GenParticle &p)
Rotate the 3-momentum of a marley::Particle in place.
ThreeVector rotate_copy(const ThreeVector &v)
Create a rotated copy of the 3-vector v.
ThreeThreeMatrix matrix_
3×3 rotation matrix