11#include <framework/geometry/VectorUtil.h>
13#include <tracking/trackingUtilities/numerics/EForwardBackward.h>
14#include <tracking/trackingUtilities/numerics/ERightLeft.h>
15#include <tracking/trackingUtilities/numerics/ERotation.h>
16#include <tracking/trackingUtilities/numerics/ESign.h>
19#include <Math/Vector3D.h>
20#include <Math/Vector2D.h>
21#include <Math/VectorUtil.h>
29 namespace VectorUtil {
31 inline bool hasNAN(
const ROOT::Math::XYVector& a)
33 return std::isnan(a.X()) or std::isnan(a.Y());
36 inline
bool hasNAN(const ROOT::Math::XYZVector& a)
38 return std::isnan(a.X()) or std::isnan(a.Y()) or std::isnan(a.Z());
41 inline
bool isNull(const ROOT::Math::XYVector& a)
43 return a.X() == 0.0 and a.Y() == 0.0;
46 inline bool isNull(
const ROOT::Math::XYZVector& a)
48 return a.X() == 0.0 and a.Y() == 0.0 and a.Z() == 0.0;
56 inline ROOT::Math::XYVector average(
const ROOT::Math::XYVector& a,
const ROOT::Math::XYVector& b)
60 }
else if (hasNAN(b)) {
63 return ROOT::Math::XYVector((a.X() + b.X()) / 2.0, (a.Y() + b.Y()) / 2.0);
72 inline ROOT::Math::XYVector average(
const ROOT::Math::XYVector& a,
const ROOT::Math::XYVector& b,
const ROOT::Math::XYVector& c)
76 }
else if (hasNAN(b)) {
78 }
else if (hasNAN(c)) {
81 return ROOT::Math::XYVector((a.X() + b.X() + c.X()) / 3.0,
82 (a.Y() + b.Y() + c.Y()) / 3.0);
91 inline ROOT::Math::XYZVector average(
const ROOT::Math::XYZVector& a,
const ROOT::Math::XYZVector& b)
95 }
else if (hasNAN(b)) {
98 return ROOT::Math::XYZVector((a.x() + b.x()) / 2.0,
99 (a.y() + b.y()) / 2.0,
100 (a.z() + b.z()) / 2.0);
110 inline ROOT::Math::XYVector compose(
const ROOT::Math::XYVector& coordinateVec,
const double parallelCoor,
const double orthoCoor)
112 return ROOT::Math::XYVector(coordinateVec.x() * parallelCoor - coordinateVec.y() * orthoCoor,
113 coordinateVec.y() * parallelCoor + coordinateVec.x() * orthoCoor);
117 template<
class Vector>
118 inline Vector unit(
const Vector& a)
127 return tmp / tmp.R();
131 inline ROOT::Math::XYVector Phi(
const double phi)
133 return std::isnan(phi) ? ROOT::Math::XYVector(0.0, 0.0) : ROOT::Math::XYVector(std::cos(phi), std::sin(phi));
137 inline ROOT::Math::XYVector Orthogonal(
const ROOT::Math::XYVector& a,
const TrackingUtilities::ERotation ccwInfo)
139 return isValid(ccwInfo) ? ROOT::Math::XYVector(-
static_cast<double>(ccwInfo) * a.Y(),
140 static_cast<double>(ccwInfo) * a.X()) : ROOT::Math::XYVector();
144 inline double Distance(
const ROOT::Math::XYVector& from,
const ROOT::Math::XYVector& to = ROOT::Math::XYVector(0.0, 0.0))
146 return (from - to).R();
150 inline double Distance(
const ROOT::Math::XYZVector& from,
const ROOT::Math::XYZVector& to = ROOT::Math::XYZVector(0.0, 0.0, 0.0))
152 return (from - to).R();
161 template<
class Vector>
162 inline double unnormalizedParallelComp(
const Vector& v1,
const Vector& relativTo)
164 return relativTo.Dot(v1);
173 template<
class Vector>
174 inline double orthogonalComp(
const Vector& v1,
const Vector& relativTo)
176 return Cross(relativTo, v1) / relativTo.R();
186 inline double unnormalizedOrthogonalComp(
const ROOT::Math::XYVector& v1,
const ROOT::Math::XYVector& relativTo)
188 return Cross(relativTo, v1);
195 inline ROOT::Math::XYVector passiveRotatedBy(
const ROOT::Math::XYVector& v1,
const ROOT::Math::XYVector& phiVec)
197 return ROOT::Math::XYVector(unnormalizedParallelComp(v1, phiVec), unnormalizedOrthogonalComp(v1, phiVec));
202 inline TrackingUtilities::ERightLeft isRightOrLeftOf(
const ROOT::Math::XYVector& toCheck,
const ROOT::Math::XYVector& rhs)
204 return static_cast<TrackingUtilities::ERightLeft
>(-TrackingUtilities::sign(unnormalizedOrthogonalComp(toCheck, rhs)));
208 inline bool isLeftOf(
const ROOT::Math::XYVector& toCheck,
const ROOT::Math::XYVector& rhs)
210 return isRightOrLeftOf(toCheck, rhs) == TrackingUtilities::ERightLeft::c_Left;
214 inline bool isRightOf(
const ROOT::Math::XYVector& toCheck,
const ROOT::Math::XYVector& rhs)
216 return isRightOrLeftOf(toCheck, rhs) == TrackingUtilities::ERightLeft::c_Right;
220 inline bool sameSign(
float n1,
float n2,
float n3)
222 return ((n1 > 0 and n2 > 0 and n3 > 0) or (n1 < 0 and n2 < 0 and n3 < 0));
230 inline bool isBetween(
const ROOT::Math::XYVector& toCheck,
const ROOT::Math::XYVector& lower,
const ROOT::Math::XYVector& upper)
238 const double det = Cross(lower, upper);
241 return isRightOf(toCheck, lower) and isLeftOf(toCheck, upper);
243 const bool flipsOrientation = det < 0;
244 const double transformedX = Cross(toCheck, upper);
245 const double transformedY = -Cross(toCheck, lower);
246 bool inFirstQuadrant = sameSign(det, transformedX, transformedY);
247 if (flipsOrientation) {
248 inFirstQuadrant = not inFirstQuadrant;
250 return inFirstQuadrant;
256 inline TrackingUtilities::EForwardBackward isForwardOrBackwardOf(
const ROOT::Math::XYVector& toCheck,
257 const ROOT::Math::XYVector& rhs)
259 return static_cast<TrackingUtilities::EForwardBackward
>(TrackingUtilities::sign(unnormalizedParallelComp(toCheck, rhs)));
269 inline bool smaller(
const ROOT::Math::XYVector& lhs,
const ROOT::Math::XYVector& rhs)
271 return lhs.Mag2() < rhs.Mag2() or
272 (lhs.Mag2() == rhs.Mag2() and (lhs.Phi() < rhs.Phi()));
283 inline bool smaller(
const ROOT::Math::XYZVector& lhs,
const ROOT::Math::XYZVector& rhs)
285 return lhs.R() < rhs.R() or (lhs.R() == rhs.R() and
286 (lhs.z() < rhs.z() or (lhs.z() == rhs.z() and (lhs.Phi() < rhs.Phi()))));
290 inline ROOT::Math::XYVector getXYVector(
const ROOT::Math::XYZVector& a)
292 return ROOT::Math::XYVector(a.X(), a.Y());
bool isValid(EForwardBackward eForwardBackward)
Check whether the given enum instance is one of the valid values.
Abstract base class for different kinds of events.