ATLAS Offline Software
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
20  : m_boundValues(RotatedTrapezoidBounds::bv_length, 0.)
21 {}
22 
23 // constructor from arguments I
24 Trk::RotatedTrapezoidBounds::RotatedTrapezoidBounds(double halex, double minhalex, double maxhalex, double alpha):
25  RotatedTrapezoidBounds(halex, minhalex, maxhalex){
26  m_rotMat = Eigen::Rotation2D{alpha};
27 }
28 Trk::RotatedTrapezoidBounds::RotatedTrapezoidBounds(double halex, double minhalex, double maxhalex)
29  : m_boundValues(RotatedTrapezoidBounds::bv_length, 0.)
30 
31 {
35  // swap if needed
38  // assign kappa and delta
40 }
41 
43  m_kappa = 0.5 *
44  (m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] -
45  m_boundValues[RotatedTrapezoidBounds::bv_minHalfY]) /
46  m_boundValues[RotatedTrapezoidBounds::bv_halfX];
47  m_delta = 0.5 * (m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] +
49 }
50 
51 bool
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 
61 bool
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);
76  if (fabsX > (m_boundValues[RotatedTrapezoidBounds::bv_halfX] + limit))
77  return false;
78  // a fast FALSE
79  const double fabsY = std::abs(locpo[Trk::locY]);
80  if (fabsY > (m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] + 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 (fabsY < (m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] + limit) &&
88  fabsX < (m_boundValues[RotatedTrapezoidBounds::bv_halfX] + 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
108  Amg::Vector2D p =
110  m_boundValues[RotatedTrapezoidBounds::bv_minHalfY]);
111  elementP[0] = (rotMatrix * (p - locpo));
113  -m_boundValues[RotatedTrapezoidBounds::bv_minHalfY]);
114  elementP[1] = (rotMatrix * (p - locpo));
116  m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]);
117  elementP[2] = (rotMatrix * (p - locpo));
119  -m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]);
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
133 bool
134 Trk::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
142  if (fabsX > (m_boundValues[RotatedTrapezoidBounds::bv_halfX] + tol1))
143  return false;
144  // (2) a fast FALSE
145  if (fabsY > (m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] + tol2))
146  return false;
147  // (3) a fast TRUE
148  if (fabsY < (m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] + tol2))
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
155 bool
156 Trk::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 
162 double
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],
169  -m_boundValues[RotatedTrapezoidBounds::bv_halfX],
170  m_boundValues[RotatedTrapezoidBounds::bv_halfX],
171  m_boundValues[RotatedTrapezoidBounds::bv_halfX] };
172  const std::array<double,4> Y{ -m_boundValues[RotatedTrapezoidBounds::bv_minHalfY],
175  -m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] };
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 
216 MsgStream&
218 {
219  sl << std::setiosflags(std::ios::fixed);
220  sl << std::setprecision(7);
221  sl << "Trk::RotatedTrapezoidBounds: (halfX, minHalfX, maxHalfY) = "
222  << "(" << m_boundValues[RotatedTrapezoidBounds::bv_halfX] << ", "
223  << m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] << ", " << m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]
224  << ")";
225  sl << std::setprecision(-1);
226  return sl;
227 }
228 
229 std::ostream&
230 Trk::RotatedTrapezoidBounds::dump(std::ostream& sl) const
231 {
232  sl << std::setiosflags(std::ios::fixed);
233  sl << std::setprecision(7);
234  sl << "Trk::RotatedTrapezoidBounds: (halfX, minHalfX, maxHalfY) = "
235  << "(" << m_boundValues[RotatedTrapezoidBounds::bv_halfX] << ", "
236  << m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] << ", " << m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]
237  << ")";
238  sl << std::setprecision(-1);
239  return sl;
240 }
Trk::RotatedTrapezoidBounds::m_boundValues
std::vector< TDD_real_t > m_boundValues
The internal storage of the bounds can be float/double.
Definition: RotatedTrapezoidBounds.h:161
Trk::y
@ y
Definition: ParamDefs.h:62
Trk::AmgMatrix
AmgMatrix(3, 3) NeutralParticleParameterCalculator
Definition: NeutralParticleParameterCalculator.cxx:233
Trk::RotatedTrapezoidBounds::isBelow
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
Definition: RotatedTrapezoidBounds.cxx:156
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
Trk::locX
@ locX
Definition: ParamDefs.h:43
Trk::locY
@ locY
local cartesian
Definition: ParamDefs.h:44
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
hist_file_dump.d
d
Definition: hist_file_dump.py:137
Trk::SurfaceBounds
Definition: SurfaceBounds.h:47
Trk::RotatedTrapezoidBounds
Definition: RotatedTrapezoidBounds.h:45
Trk::SurfaceBounds::swap
void swap(double &b1, double &b2)
Swap method to be called from DiscBounds or TrapezoidalBounds.
Definition: SurfaceBounds.h:133
Trk::RotatedTrapezoidBounds::operator==
virtual bool operator==(const SurfaceBounds &trabo) const override final
Equality operator.
Definition: RotatedTrapezoidBounds.cxx:52
yodamerge_tmp.axis
list axis
Definition: yodamerge_tmp.py:241
JetTiledMap::S
@ S
Definition: TiledEtaPhiMap.h:44
Trk::RotatedTrapezoidBounds::minDistance
virtual double minDistance(const Amg::Vector2D &pos) const override final
Minimal distance to boundary ( > 0 if outside and <=0 if inside)
Definition: RotatedTrapezoidBounds.cxx:163
Monitored::X
@ X
Definition: HistogramFillerUtils.h:24
Trk::RotatedTrapezoidBounds::initCache
virtual void initCache() override final
Helper function for angle parameter initialization.
Definition: RotatedTrapezoidBounds.cxx:42
Trk::BoundaryCheck::EllipseToPoly
std::vector< Amg::Vector2D > EllipseToPoly(int resolution=3) const
Trk::BoundaryCheck::toleranceLoc1
double toleranceLoc1
absolute tolerance in local 1 coordinate
Definition: BoundaryCheck.h:68
lumiFormat.i
int i
Definition: lumiFormat.py:92
Trk::theta
@ theta
Definition: ParamDefs.h:72
Trk::BoundaryCheck::bcType
BoundaryCheckType bcType
Definition: BoundaryCheck.h:70
Trk::sincosCache
Definition: BoundaryCheck.h:45
Trk::RotatedTrapezoidBounds::bv_maxHalfY
@ bv_maxHalfY
Definition: RotatedTrapezoidBounds.h:53
Trk::BoundaryCheck::TestKDOPKDOP
bool TestKDOPKDOP(const std::vector< KDOP > &a, const std::vector< KDOP > &b) const
Trk::RotatedTrapezoidBounds::dump
virtual MsgStream & dump(MsgStream &sl) const override final
Output Method for MsgStream.
Definition: RotatedTrapezoidBounds.cxx:217
Trk::RotatedTrapezoidBounds::bv_halfX
@ bv_halfX
Definition: RotatedTrapezoidBounds.h:51
ReadCellNoiseFromCool.dm
dm
Definition: ReadCellNoiseFromCool.py:235
Monitored::Y
@ Y
Definition: HistogramFillerUtils.h:24
Trk::sincosCache::sinC
double sinC
Definition: BoundaryCheck.h:46
Trk::BoundaryCheck::nSigmas
int nSigmas
allowed sigmas for chi2 boundary check
Definition: BoundaryCheck.h:67
Trk::BoundaryCheck::ComputeKDOP
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.
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
Trk::BoundaryCheck::FastArcTan
double FastArcTan(double x) const
makeTRTBarrelCans.dy
tuple dy
Definition: makeTRTBarrelCans.py:21
a
TList * a
Definition: liststreamerinfos.cxx:10
Trk::BoundaryCheck
Definition: BoundaryCheck.h:51
Trk::sincosCache::cosC
double cosC
Definition: BoundaryCheck.h:47
makeTRTBarrelCans.dx
tuple dx
Definition: makeTRTBarrelCans.py:20
Trk::BoundaryCheck::FastSinCos
sincosCache FastSinCos(double x) const
Trk::RotatedTrapezoidBounds::bv_minHalfY
@ bv_minHalfY
Definition: RotatedTrapezoidBounds.h:52
Trk::BoundaryCheck::toleranceLoc2
double toleranceLoc2
absolute tolerance in local 2 coordinate
Definition: BoundaryCheck.h:69
Trk::x
@ x
Definition: ParamDefs.h:61
RotatedTrapezoidBounds.h
updateCoolNtuple.limit
int limit
Definition: updateCoolNtuple.py:45
Trk::RotatedTrapezoidBounds::inside
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...
Definition: RotatedTrapezoidBounds.cxx:134
Trk::RotatedTrapezoidBounds::RotatedTrapezoidBounds
RotatedTrapezoidBounds()
Default Constructor, needed for persistency.
Definition: RotatedTrapezoidBounds.cxx:19