16 #include <type_traits>
18 namespace ActsFatras {
23 float particleMomentum)
const {
25 if (particleMomentum <= parametrisation.front().first) {
26 return parametrisation.front().second;
28 if (particleMomentum >= parametrisation.back().first) {
29 return parametrisation.back().second;
33 const auto lowerBound = std::lower_bound(
34 parametrisation.begin(), parametrisation.end(), particleMomentum,
35 [](
const std::pair<
const float,
38 const float mom) {
return params.first < mom; });
39 const float momentumUpperNeighbour = lowerBound->first;
40 const float momentumLowerNeighbour = std::prev(lowerBound, 1)->first;
43 const float weight = (momentumUpperNeighbour - particleMomentum) /
44 (momentumUpperNeighbour - momentumLowerNeighbour);
45 return (rnd < weight) ? std::prev(lowerBound, 1)->second : lowerBound->second;
53 if (distribution.second.empty()) {
58 const uint32_t int_rnd =
static_cast<uint32_t
>(UINT32_MAX *
rnd);
59 const auto it = std::upper_bound(distribution.second.begin(),
60 distribution.second.end(), int_rnd);
62 distribution.second.size() - 1);
65 return static_cast<unsigned int>(distribution.first[iBin]);
74 if (distribution.second.empty()) {
75 return std::numeric_limits<Scalar>::infinity();
79 const uint32_t int_rnd =
static_cast<uint32_t
>(UINT32_MAX *
rnd);
81 if (int_rnd > distribution.second.back()) {
82 return std::numeric_limits<Scalar>::infinity();
84 const auto it = std::upper_bound(distribution.second.begin(),
85 distribution.second.end(), int_rnd);
87 distribution.second.size() - 1);
92 const uint32_t basecont = (iBin > 0 ? distribution.second[iBin - 1] : 0);
93 const uint32_t dcont = distribution.second[iBin] - basecont;
94 return distribution.first[iBin] +
95 (distribution.first[iBin + 1] - distribution.first[iBin]) *
96 (dcont > 0 ? (int_rnd - basecont) / dcont : 0.5);
98 return distribution.first[iBin];
105 distribution)
const {
109 std::pair<ActsFatras::Particle::Scalar, ActsFatras::Particle::Scalar>
112 float theta2)
const {
115 rotY(0, 0) = std::cos(theta1);
116 rotY(0, 2) = std::sin(theta1);
118 rotY(2, 0) = -std::sin(theta1);
119 rotY(2, 2) = std::cos(theta1);
123 rotZ(0, 0) = std::cos(phi1);
124 rotZ(0, 1) = -std::sin(phi1);
125 rotZ(1, 0) = std::sin(phi1);
126 rotZ(1, 1) = std::cos(phi1);
130 const Acts::Vector3 vector2(std::sin(theta2) * std::cos(phi2),
131 std::sin(theta2) * std::sin(phi2),
136 const float theta = std::acos(vectorSum.z() / vectorSum.norm());
137 const float phi = std::atan2(vectorSum.y(), vectorSum.x());
139 return std::make_pair(phi, theta);
144 float parametrizedMomentum)
const {
145 const unsigned int size = momenta.size();
146 for (
unsigned int i = 0;
i <
size;
i++) {
149 const float invariantMass = invariantMasses[
i];
150 const float p1p2 = 2. * momentum * parametrizedMomentum;
151 const float costheta = 1. - invariantMass * invariantMass / p1p2;
154 if (std::abs(costheta) > 1) {