ATLAS Offline Software
Loading...
Searching...
No Matches
DiamondBounds.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// DiamondBounds.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
39
48
49bool
51{
52 // check the type first not to compare apples with oranges
53 const Trk::DiamondBounds* diabo = dynamic_cast<const Trk::DiamondBounds*>(&sbo);
54 if (!diabo)
55 return false;
56 return (m_boundValues == diabo->m_boundValues);
57}
58
59// checking if inside bounds (Full symmetrical Diamond)
60bool
61Trk::DiamondBounds::inside(const Amg::Vector2D& locpo, double tol1, double tol2) const
62{
63 return this->insideFull(locpo, tol1, tol2);
64}
65
66bool
68 const BoundaryCheck& bchk) const
69{
70 if (bchk.bcType == 0)
71 return DiamondBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2);
72
73 // a fast FALSE
74 double max_ell = bchk.lCovariance(0, 0) > bchk.lCovariance(1, 1)
75 ? bchk.lCovariance(0, 0)
76 : bchk.lCovariance(1, 1);
77 double limit = bchk.nSigmas * sqrt(max_ell);
78 if (locpo[Trk::locY] < -2 * m_boundValues[DiamondBounds::bv_halfY1] - limit)
79 return false;
80 if (locpo[Trk::locY] > 2 * m_boundValues[DiamondBounds::bv_halfY2] + limit)
81 return false;
82 // a fast FALSE
83 double fabsX = std::abs(locpo[Trk::locX]);
84 if (fabsX > (m_boundValues[DiamondBounds::bv_medHalfX] + limit))
85 return false;
86 // a fast TRUE
87 double min_ell = bchk.lCovariance(0, 0) < bchk.lCovariance(1, 1)
88 ? bchk.lCovariance(0, 0)
89 : bchk.lCovariance(1, 1);
90 limit = bchk.nSigmas * sqrt(min_ell);
93 limit))
94 return true;
95 // a fast TRUE
96 if (std::abs(locpo[Trk::locY]) < (fmin(m_boundValues[DiamondBounds::bv_halfY1],
98 limit))
99 return true;
100
101 // compute KDOP and axes for surface polygon
102 std::vector<KDOP> elementKDOP(5);
103 std::vector<Amg::Vector2D> elementP(6);
104 float theta =
105 (bchk.lCovariance(1, 0) != 0 &&
106 (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0)) != 0)
107 ? .5 * bchk.FastArcTan(2 * bchk.lCovariance(1, 0) /
108 (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0)))
109 : 0.;
110 sincosCache scResult = bchk.FastSinCos(theta);
111 AmgMatrix(2, 2) rotMatrix;
112 rotMatrix << scResult.cosC, scResult.sinC, -scResult.sinC, scResult.cosC;
113 AmgMatrix(2, 2) normal;
114 // cppcheck-suppress constStatement
115 normal << 0, -1, 1, 0;
116 // ellipse is always at (0,0), surface is moved to ellipse position and then
117 // rotated
118 Amg::Vector2D p =
121 elementP[0] = (rotMatrix * (p - locpo));
123 elementP[1] = (rotMatrix * (p - locpo));
126 elementP[2] = (rotMatrix * (p - locpo));
129 elementP[3] = (rotMatrix * (p - locpo));
131 elementP[4] = (rotMatrix * (p - locpo));
134 elementP[5] = (rotMatrix * (p - locpo));
135 std::vector<Amg::Vector2D> axis = { normal * (elementP[1] - elementP[0]),
136 normal * (elementP[2] - elementP[1]),
137 normal * (elementP[3] - elementP[2]),
138 normal * (elementP[4] - elementP[3]),
139 normal * (elementP[5] - elementP[4]) };
140 bchk.ComputeKDOP(elementP, axis, elementKDOP);
141 // compute KDOP for error ellipse
142 std::vector<KDOP> errelipseKDOP(5);
143 bchk.ComputeKDOP(bchk.EllipseToPoly(3), axis, errelipseKDOP);
144 // check if KDOPs overlap and return result
145 return bchk.TestKDOPKDOP(elementKDOP, errelipseKDOP);
146}
147
148// checking if inside bounds (Full symmetrical Diamond)
149bool
150Trk::DiamondBounds::insideFull(const Amg::Vector2D& locpo, double tol1, double tol2) const
151{
152 // validity check
154
155 // quick False (radial direction)
156 if (locpo[Trk::locY] < -2. * m_boundValues[DiamondBounds::bv_halfY1] - tol2) return false;
157 if (locpo[Trk::locY] > 2. * m_boundValues[DiamondBounds::bv_halfY2] + tol2) return false;
158
159 double absX = std::abs(locpo[Trk::locX]);
160
161 // quick False (transverse directon)
162 if (absX > m_boundValues[DiamondBounds::bv_medHalfX] + tol1) return false;
163
164 // quick True
165 if (absX < std::min(m_boundValues[DiamondBounds::bv_minHalfX], m_boundValues[DiamondBounds::bv_maxHalfX]) + tol1) return true;
166
171 double k = halfH ? 0.5*(halfBaseUp - halfBaseLo)/halfH : 0.;
172 double sign = (k < 0) ? -1. : 1.;
173 return (absX - tol1 <= m_boundValues[DiamondBounds::bv_medHalfX] + k * (locpo[Trk::locY] + sign*tol2));
174
175}
176
177// opening angle in point A
178double
180{
181 return m_alpha1;
182}
183
184// opening angle in point A'
185double
187{
188 return m_alpha2;
189}
190
191double
193{
194 const int Np = 6;
195
196 double y1 = 2. * m_boundValues[DiamondBounds::bv_halfY1];
197 double y2 = 2. * m_boundValues[DiamondBounds::bv_halfY2];
198
202 double Y[6] = { -y1, 0., y2, y2, 0., -y1 };
203
204 double dm = 1.e+20;
205 double Ao = 0.;
206 bool in = true;
207
208 for (int i = 0; i != Np; ++i) {
209
210 int j = (i == Np-1 ? 0 : i+1);
211
212 double x = X[i] - pos[0];
213 double y = Y[i] - pos[1];
214 double dx = X[j] - X[i];
215 double dy = Y[j] - Y[i];
216 double A = x * dy - y * dx;
217 double S = -(x * dx + y * dy);
218
219 if (S <= 0.) {
220 double d = x * x + y * y;
221 if (d < dm)
222 dm = d;
223 } else {
224 double a = dx * dx + dy * dy;
225 if (S <= a) {
226 double d = (A * A) / a;
227 if (d < dm)
228 dm = d;
229 }
230 }
231 if (i && in && Ao * A < 0.)
232 in = false;
233 Ao = A;
234 }
235 if (in)
236 return -sqrt(dm);
237 return sqrt(dm);
238}
239
240// ostream operator overload
241
242MsgStream&
243Trk::DiamondBounds::dump(MsgStream& sl) const
244{
245 sl << std::setiosflags(std::ios::fixed);
246 sl << std::setprecision(7);
247 sl << "Trk::DiamondBounds: (minHlenghtX, medHlengthX, maxHlengthX, hlengthY1, hlengthY2 ) = ";
251 sl << std::setprecision(-1);
252 return sl;
253}
254
255std::ostream&
256Trk::DiamondBounds::dump(std::ostream& sl) const
257{
258 sl << std::setiosflags(std::ios::fixed);
259 sl << std::setprecision(7);
260 sl << "Trk::DiamondBounds: (minHlenghtX, medHlengthX, maxHlengthX, hlengthY1, hlengthY2 ) = ";
264 sl << std::setprecision(-1);
265 return sl;
266}
#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
Bounds for a double trapezoidal ("diamond"), planar Surface.
virtual bool inside(const Amg::Vector2D &locpo, double tol1=0., double tol2=0.) const override final
The orientation of the Diamond is according to the figure.
virtual MsgStream & dump(MsgStream &sl) const override final
Output Method for MsgStream.
virtual bool operator==(const SurfaceBounds &diabo) const override
Equality operator.
double alpha1() const
This method returns the opening angle alpha in point A.
DiamondBounds()
Default Constructor, needed for persistency.
bool insideFull(const Amg::Vector2D &locpo, double tol1=0., double tol2=0.) const
inside() method for a full symmetric diamond
std::vector< TDD_real_t > m_boundValues
Internal parameters stored in the geometry.
virtual void initCache() override
initialize the alpha1/2 cache - needed also for object persistency
virtual double minDistance(const Amg::Vector2D &pos) const override final
Minimal distance to boundary ( > 0 if outside and <=0 if inside)
double alpha2() const
This method returns the opening angle alpha in point A'.
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