ATLAS Offline Software
Loading...
Searching...
No Matches
RotatedTrapezoidBounds.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
6// RotatedTrapezoidBounds.cxx, (c) ATLAS Detector Software
8
9// Trk
11// Gaudi
12#include "GaudiKernel/MsgStream.h"
13// STD
14#include <cmath>
15#include <iomanip>
16#include <iostream>
17
18// default constructor
22
23// constructor from arguments I
24Trk::RotatedTrapezoidBounds::RotatedTrapezoidBounds(double halex, double minhalex, double maxhalex, double alpha):
25 RotatedTrapezoidBounds(halex, minhalex, maxhalex){
26 m_rotMat = Eigen::Rotation2D{alpha};
27}
41
50
51bool
53{
54 // check the type first not to compare apples with oranges
55 const Trk::RotatedTrapezoidBounds* trabo = dynamic_cast<const Trk::RotatedTrapezoidBounds*>(&sbo);
56 if (!trabo)
57 return false;
58 return (m_boundValues == trabo->m_boundValues);
59}
60
61bool
63 const BoundaryCheck& bchk) const
64{
65 const Amg::Vector2D locpo = m_rotMat * pos;
66 if (bchk.bcType == 0)
68 locpo, bchk.toleranceLoc1, bchk.toleranceLoc2);
69
70 // a fast FALSE
71 const double fabsX = std::abs(locpo[Trk::locX]);
72 double max_ell = bchk.lCovariance(0, 0) > bchk.lCovariance(1, 1)
73 ? bchk.lCovariance(0, 0)
74 : bchk.lCovariance(1, 1);
75 double limit = bchk.nSigmas * sqrt(max_ell);
77 return false;
78 // a fast FALSE
79 const double fabsY = std::abs(locpo[Trk::locY]);
81 return false;
82 // a fast TRUE
83 double min_ell = bchk.lCovariance(0, 0) < bchk.lCovariance(1, 1)
84 ? bchk.lCovariance(0, 0)
85 : bchk.lCovariance(1, 1);
86 limit = bchk.nSigmas * sqrt(min_ell);
89 return true;
90
91 // compute KDOP and axes for surface polygon
92 std::vector<KDOP> elementKDOP(3);
93 std::vector<Amg::Vector2D> elementP(4);
94 float theta =
95 (bchk.lCovariance(1, 0) != 0 &&
96 (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0)) != 0)
97 ? .5 * bchk.FastArcTan(2 * bchk.lCovariance(1, 0) /
98 (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0)))
99 : 0.;
100 sincosCache scResult = bchk.FastSinCos(theta);
101 AmgMatrix(2, 2) rotMatrix;
102 rotMatrix << scResult.cosC, scResult.sinC, -scResult.sinC, scResult.cosC;
103 AmgMatrix(2, 2) normal;
104 // cppcheck-suppress constStatement
105 normal << 0, -1, 1, 0;
106 // ellipse is always at (0,0), surface is moved to ellipse position and then
107 // rotated
108 Amg::Vector2D p =
111 elementP[0] = (rotMatrix * (p - locpo));
114 elementP[1] = (rotMatrix * (p - locpo));
117 elementP[2] = (rotMatrix * (p - locpo));
120 elementP[3] = (rotMatrix * (p - locpo));
121 std::vector<Amg::Vector2D> axis = { normal * (elementP[1] - elementP[0]),
122 normal * (elementP[3] - elementP[1]),
123 normal * (elementP[2] - elementP[0]) };
124 bchk.ComputeKDOP(elementP, axis, elementKDOP);
125 // compute KDOP for error ellipse
126 std::vector<KDOP> errelipseKDOP(3);
127 bchk.ComputeKDOP(bchk.EllipseToPoly(3), axis, errelipseKDOP);
128 // check if KDOPs overlap and return result
129 return bchk.TestKDOPKDOP(elementKDOP, errelipseKDOP);
130}
131
132// checking if inside bounds
133bool
134Trk::RotatedTrapezoidBounds::inside(const Amg::Vector2D& pos, double tol1, double tol2) const
135{
136
137 // the cases:
138 const Amg::Vector2D locpo = m_rotMat * pos;
139 double fabsX = std::abs(locpo[Trk::locX]);
140 double fabsY = std::abs(locpo[Trk::locY]);
141 // (1) a fast FALSE
143 return false;
144 // (2) a fast FALSE
146 return false;
147 // (3) a fast TRUE
149 return true;
150 // (4) it is inside the rectangular shape solve the isBelow
151 return (isBelow(locpo[Trk::locX], fabsY, tol1, tol2));
152}
153
154// checking if local point lies above a line
155bool
156Trk::RotatedTrapezoidBounds::isBelow(double locX, double fabsLocY, double tol1, double tol2) const
157{
158 // the most tolerant approach for tol1 and tol2
159 return ((m_kappa * (locX + tol1) + m_delta) > fabsLocY - tol2);
160}
161
162double
164{
165 const Amg::Vector2D pos = m_rotMat * locpo;
166 constexpr int Np = 4;
167
168 const std::array<double,4> X{ -m_boundValues[RotatedTrapezoidBounds::bv_halfX],
172 const std::array<double,4> Y{ -m_boundValues[RotatedTrapezoidBounds::bv_minHalfY],
176
177 double dm = 1.e+20;
178 double Ao = 0.;
179 bool in = true;
180
181 for (int i = 0; i != Np; ++i) {
182
183 int j = (i == Np-1 ? 0 : i+1);
184
185 double x = X[i] - pos[0];
186 double y = Y[i] - pos[1];
187 double dx = X[j] - X[i];
188 double dy = Y[j] - Y[i];
189 double A = x * dy - y * dx;
190 double S = -(x * dx + y * dy);
191
192 if (S <= 0.) {
193 double d = x * x + y * y;
194 if (d < dm)
195 dm = d;
196 } else {
197 double a = dx * dx + dy * dy;
198 if (S <= a) {
199 double d = (A * A) / a;
200 if (d < dm)
201 dm = d;
202 }
203 }
204 if (i && in && Ao * A < 0.)
205 in = false;
206 Ao = A;
207 }
208 if (in){
209 return -std::sqrt(dm);
210 }
211 return std::sqrt(dm);
212}
213
214// ostream operator overload
215
216MsgStream&
218{
219 sl << std::setiosflags(std::ios::fixed);
220 sl << std::setprecision(7);
221 sl << "Trk::RotatedTrapezoidBounds: (halfX, minHalfX, maxHalfY) = "
224 << ")";
225 sl << std::setprecision(-1);
226 return sl;
227}
228
229std::ostream&
231{
232 sl << std::setiosflags(std::ios::fixed);
233 sl << std::setprecision(7);
234 sl << "Trk::RotatedTrapezoidBounds: (halfX, minHalfX, maxHalfY) = "
237 << ")";
238 sl << std::setprecision(-1);
239 return sl;
240}
#define AmgMatrix(rows, cols)
static Double_t a
The BoundaryCheck class allows to steer the way surface boundaries are used for inside/outside checks...
int nSigmas
allowed sigmas for chi2 boundary check
BoundaryCheckType bcType
std::vector< Amg::Vector2D > EllipseToPoly(int resolution=3) const
bool TestKDOPKDOP(const std::vector< KDOP > &a, const std::vector< KDOP > &b) const
void ComputeKDOP(const std::vector< Amg::Vector2D > &v, const std::vector< Amg::Vector2D > &KDOPAxes, std::vector< KDOP > &kdop) const
Each Bounds has a method inside, which checks if a LocalPosition is inside the bounds.
double toleranceLoc2
absolute tolerance in local 2 coordinate
double FastArcTan(double x) const
sincosCache FastSinCos(double x) const
double toleranceLoc1
absolute tolerance in local 1 coordinate
Bounds for a rotated trapezoidal, planar Surface.
std::vector< TDD_real_t > m_boundValues
The internal storage of the bounds can be float/double.
virtual void initCache() override final
Helper function for angle parameter initialization.
virtual bool inside(const Amg::Vector2D &locpo, double tol1=0., double tol2=0.) const override final
The orientation of the Trapezoid is according to the figure above, in words: the shorter of the two p...
bool isBelow(double locX, double fabsLocY, double tol1, double tol2) const
isBelow() method for checking whether a point lies above or under a straight line
virtual double minDistance(const Amg::Vector2D &pos) const override final
Minimal distance to boundary ( > 0 if outside and <=0 if inside)
RotatedTrapezoidBounds()
Default Constructor, needed for persistency.
virtual MsgStream & dump(MsgStream &sl) const override final
Output Method for MsgStream.
virtual bool operator==(const SurfaceBounds &trabo) const override final
Equality operator.
Abstract base class for surface bounds to be specified.
void swap(double &b1, double &b2)
Swap method to be called from DiscBounds or TrapezoidalBounds.
Eigen::Matrix< double, 2, 1 > Vector2D
@ locY
local cartesian
Definition ParamDefs.h:38
@ x
Definition ParamDefs.h:55
@ locX
Definition ParamDefs.h:37
@ theta
Definition ParamDefs.h:66
@ y
Definition ParamDefs.h:56
hold the test vectors and ease the comparison