ATLAS Offline Software
Loading...
Searching...
No Matches
TrapezoidBounds.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
6// TrapezoidBounds.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
24
25// constructor from arguments I
37
38// constructor from arguments II
39Trk::TrapezoidBounds::TrapezoidBounds(double minhalex, double haley, double alpha, double beta)
41 , m_alpha(alpha)
42 , m_beta(beta)
43{
44 double gamma = (alpha > beta) ? (alpha - 0.5 * M_PI) : (beta - 0.5 * M_PI);
45 // now fill them
46 m_boundValues[TrapezoidBounds::bv_minHalfX] = std::abs(minhalex);
49}
50
51
52bool
54{
55 // check the type first not to compare apples with oranges
56 const Trk::TrapezoidBounds* trabo = dynamic_cast<const Trk::TrapezoidBounds*>(&sbo);
57 if (!trabo)
58 return false;
59 return (m_boundValues == trabo->m_boundValues);
60}
61
62bool
64 const BoundaryCheck& bchk) const
65{
66 if (bchk.bcType == 0)
68 locpo, bchk.toleranceLoc1, bchk.toleranceLoc2);
69
70 // a fast FALSE
71 double fabsY = std::abs(locpo[Trk::locY]);
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);
76 if (fabsY > (m_boundValues[TrapezoidBounds::bv_halfY] + limit))
77 return false;
78 // a fast FALSE
79 double fabsX = std::abs(locpo[Trk::locX]);
80 if (fabsX > (m_boundValues[TrapezoidBounds::bv_maxHalfX] + limit))
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);
87 if (fabsX < (m_boundValues[TrapezoidBounds::bv_minHalfX] + limit) &&
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
110 elementP[0] = (rotMatrix * (p - locpo));
113 elementP[1] = (rotMatrix * (p - locpo));
114 scResult = bchk.FastSinCos(m_beta);
117 (scResult.sinC / scResult.cosC),
119 elementP[2] = (rotMatrix * (p - locpo));
120 scResult = bchk.FastSinCos(m_alpha);
123 (scResult.sinC / scResult.cosC)),
125 elementP[3] = (rotMatrix * (p - locpo));
126 std::vector<Amg::Vector2D> axis = { normal * (elementP[1] - elementP[0]),
127 normal * (elementP[3] - elementP[1]),
128 normal * (elementP[2] - elementP[0]) };
129 bchk.ComputeKDOP(elementP, axis, elementKDOP);
130 // compute KDOP for error ellipse
131 std::vector<KDOP> errelipseKDOP(3);
132 bchk.ComputeKDOP(bchk.EllipseToPoly(3), axis, errelipseKDOP);
133 // check if KDOPs overlap and return result
134 return bchk.TestKDOPKDOP(elementKDOP, errelipseKDOP);
135}
136
137// checking if inside bounds
138bool
139Trk::TrapezoidBounds::inside(const Amg::Vector2D& locpo, double tol1, double tol2) const
140{
141 if (m_alpha == 0.)
142 return insideFull(locpo, tol1, tol2);
143 return (insideFull(locpo, tol1, tol2) && !insideExclude(locpo, tol1, tol2));
144}
145
146// checking if inside bounds (Full symmetrical Trapezoid)
147bool
148Trk::TrapezoidBounds::insideFull(const Amg::Vector2D& locpo, double tol1, double tol2) const
149{
150 // the cases:
151 double fabsX = std::abs(locpo[Trk::locX]);
152 double fabsY = std::abs(locpo[Trk::locY]);
153 // (1) a fast FALSE
154 if (fabsY > (m_boundValues[TrapezoidBounds::bv_halfY] + tol2))
155 return false;
156 // (2) a fast FALSE
157 if (fabsX > (m_boundValues[TrapezoidBounds::bv_maxHalfX] + tol1))
158 return false;
159 // (3) a fast TRUE
160 if (fabsX < (m_boundValues[TrapezoidBounds::bv_minHalfX] + tol1))
161 return true;
162 // (4) particular case - a rectangle
164 return true;
165 // (5) /** use basic calculation of a straight line */
166 double k = 2.0 * m_boundValues[TrapezoidBounds::bv_halfY] /
168 ((locpo[Trk::locX] > 0.) ? 1.0 : -1.0);
169 double d =
171 return (isAbove(locpo, tol1, tol2, k, d));
172}
173
174// checking if local point is inside the exclude area
175bool
176Trk::TrapezoidBounds::insideExclude(const Amg::Vector2D& locpo, double tol1, double tol2) const
177{
178
179 // line a
180 bool alphaBiggerBeta(m_alpha > m_beta);
181 double ka = alphaBiggerBeta ? tan(M_PI - m_alpha) : tan(m_alpha);
182 double kb = alphaBiggerBeta ? tan(M_PI - m_beta) : tan(m_beta);
183 double sign = alphaBiggerBeta ? -1. : 1.;
186
187 return (isAbove(locpo, tol1, tol2, ka, da) && isAbove(locpo, tol1, tol2, kb, db));
188}
189
190// checking if local point lies above a line
191bool
192Trk::TrapezoidBounds::isAbove(const Amg::Vector2D& locpo, double tol1, double tol2, double k, double d)
193{
194 // the most tolerant approach for tol1 and tol2
195 double sign = k > 0. ? -1. : +1.;
196 return (locpo[Trk::locY] + tol2 > (k * (locpo[Trk::locX] + sign * tol1) + d));
197}
198
199double
201{
202 const int Np = 4;
203
206 if (m_alpha != 0.) {
208 } else if (m_beta != 0.) {
210 }
216
217 double dm = 1.e+20;
218 double Ao = 0.;
219 bool in = true;
220
221 for (int i = 0; i != Np; ++i) {
222
223 int j = (i == Np-1 ? 0 : i+1);
224
225 double x = X[i] - pos[0];
226 double y = Y[i] - pos[1];
227 double dx = X[j] - X[i];
228 double dy = Y[j] - Y[i];
229 double A = x * dy - y * dx;
230 double S = -(x * dx + y * dy);
231
232 if (S <= 0.) {
233 double d = x * x + y * y;
234 if (d < dm)
235 dm = d;
236 } else {
237 double a = dx * dx + dy * dy;
238 if (S <= a) {
239 double d = (A * A) / a;
240 if (d < dm)
241 dm = d;
242 }
243 }
244 if (i && in && Ao * A < 0.)
245 in = false;
246 Ao = A;
247 }
248 if (in){
249 return -sqrt(dm);
250 }
251 return sqrt(dm);
252}
253
254// ostream operator overload
255
256MsgStream&
257Trk::TrapezoidBounds::dump(MsgStream& sl) const
258{
259 sl << std::setiosflags(std::ios::fixed);
260 sl << std::setprecision(7);
261 sl << "Trk::TrapezoidBounds: (minHlenghtX, maxHlengthX, hlengthY) = "
263 << ", " << m_boundValues[TrapezoidBounds::bv_halfY] << ")";
264 sl << std::setprecision(-1);
265 return sl;
266}
267
268std::ostream&
269Trk::TrapezoidBounds::dump(std::ostream& sl) const
270{
271 sl << std::setiosflags(std::ios::fixed);
272 sl << std::setprecision(7);
273 sl << "Trk::TrapezoidBounds: (minHlenghtX, maxHlengthX, hlengthY) = "
275 << ", " << m_boundValues[TrapezoidBounds::bv_halfY] << ")";
276 sl << std::setprecision(-1);
277 return sl;
278}
#define M_PI
#define AmgMatrix(rows, cols)
static Double_t a
int sign(int 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
Abstract base class for surface bounds to be specified.
void swap(double &b1, double &b2)
Swap method to be called from DiscBounds or TrapezoidalBounds.
Bounds for a trapezoidal, planar Surface.
double beta() const
This method returns the opening angle beta in point B (positive local phi)
virtual bool operator==(const SurfaceBounds &trabo) const override
Equality operator.
static bool isAbove(const Amg::Vector2D &locpo, double tol1, double tol2, double k, double d)
isAbove() method for checking whether a point lies above or under a straight line
virtual MsgStream & dump(MsgStream &sl) const override
Output Method for MsgStream.
std::vector< TDD_real_t > m_boundValues
double alpha() const
This method returns the opening angle alpha in point A (negative local phi)
virtual bool inside(const Amg::Vector2D &locpo, double tol1=0., double tol2=0.) const override
The orientation of the Trapezoid is according to the figure above, in words: the shorter of the two p...
virtual double minDistance(const Amg::Vector2D &pos) const override
Minimal distance to boundary ( > 0 if outside and <=0 if inside)
TrapezoidBounds()
Default Constructor, needed for persistency.
bool insideFull(const Amg::Vector2D &locpo, double tol1=0., double tol2=0.) const
inside() method for a full symmetric trapezoid
bool insideExclude(const Amg::Vector2D &locpo, double tol1=0., double tol2=0.) const
inside() method for the triangular exclude area for an arbitrary trapezoid
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