Belle II Software  release-08-01-10
Angle.h
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #pragma once
10 
11 #include <TMath.h>
12 
13 #include <utility>
14 
15 namespace Belle2 {
24  class BaseAngle {
25  public:
30  BaseAngle(double angle, double error) : m_angle(angle), m_error(error) {};
31 
33  virtual ~BaseAngle() {};
34 
37  double getAngle() const { return m_angle; }
38 
41  double getError() const { return m_error; }
42 
45  double getAngleInDeg() const { return m_angle * TMath::RadToDeg(); }
46 
49  double getErrorInDeg() const { return m_error * TMath::RadToDeg(); }
50 
55  double getLowerIntervalBoundary(double sigma = 1) const { return m_angle - sigma * m_error; }
56 
61  double getUpperIntervalBoundary(double sigma = 1) const { return m_angle + sigma * m_error; }
62 
63  protected:
64  typedef std::pair<double, double> Interval;
66  double m_angle;
67  double m_error;
76  bool intervalsCompatible(const Interval& x_interval, const Interval& y_interval) const
77  {
78  const double xCenter = (x_interval.second + x_interval.first) / 2.;
79  const double yCenter = (y_interval.second + y_interval.first) / 2.;
80  const double delta = std::fabs(yCenter - xCenter);
81 
82  if (delta >= 0) {
83  const double xArm = x_interval.second - xCenter;
84  const double yArm = yCenter - y_interval.first;
85  const double sigmaSum = xArm + yArm;
86  if (delta < sigmaSum) return true;
87  return false;
88  } else {
89  const double xArm = xCenter - x_interval.first;
90  const double yArm = y_interval.second - yCenter;
91  const double sigmaSum = xArm + yArm;
92  if (std::fabs(delta) < sigmaSum) return true;
93  return false;
94  }
95 
96  }
97 
98  };
99 
100 
105  class ThetaAngle : public BaseAngle {
106  public:
113  ThetaAngle(double angle, double error) : BaseAngle(angle, error)
114  {
115  m_angle = std::fabs(std::fmod(m_angle, TMath::Pi()));
116  }
117 
122  bool contains(const ThetaAngle& angle) const
123  {
124  return containsIn(angle, 1);
125  }
126 
132  bool containsIn(const ThetaAngle& angle, double sigma) const
133  {
135  const Interval y(angle.getLowerIntervalBoundary(sigma), angle.getUpperIntervalBoundary(sigma));
136 
137  if (intervalsCompatible(x, y)) return true;
138 
139  return false;
140  }
141  };
142 
143 
148  class PhiAngle : public BaseAngle {
149  public:
156  PhiAngle(double angle, double error) : BaseAngle(angle, error)
157  {
158  m_angle = std::fabs(std::fmod(m_angle, TMath::TwoPi()));
159  }
160 
165  bool contains(const PhiAngle& angle) const
166  {
167  return containsIn(angle, 1);
168  }
169 
175  bool containsIn(const PhiAngle& angle, double sigma) const
176  {
177  const double twoPi = TMath::TwoPi();
179  const Interval y(angle.getLowerIntervalBoundary(sigma), angle.getUpperIntervalBoundary(sigma));
180 
181  //Transform intervals
182  const double shift = x.first;
183  const Interval xShifted(x.first - shift, x.second - shift);
184  const Interval yShifted(y.first - shift, y.second - shift);
185 
186  if (twoPi < xShifted.second) return true; // x covers [0, 2Pi)
187 
188  if ((yShifted.first <= 0) and (twoPi < yShifted.second)) return true; // y covers [0, 2Pi)
189 
190  if ((0. <= yShifted.first) and (yShifted.second < twoPi)) {
191  return intervalsCompatible(xShifted, yShifted);
192  }
193 
194  if (!(0. <= yShifted.first) and (yShifted.second < twoPi)) {
195  const Interval y1(y.first + twoPi, twoPi);
196  const Interval y2(0., y.second);
197 
198  if (intervalsCompatible(x, y1)) return true;
199  if (intervalsCompatible(x, y2)) return true;
200  return false;
201  }
202 
203  if ((0 <= yShifted.first) and !(yShifted.second < twoPi)) {
204  const Interval y1(y.first, twoPi);
205  const Interval y2(0., y.second - twoPi);
206 
207  if (intervalsCompatible(x, y1)) return true;
208  if (intervalsCompatible(x, y2)) return true;
209  return false;
210  }
211 
212  return false;
213  }
214  };
216 }
Class to compare if two angles are compatible withing a given error range.
Definition: Angle.h:24
bool intervalsCompatible(const Interval &x_interval, const Interval &y_interval) const
Checks if the intervals overlap at some point.
Definition: Angle.h:76
double getLowerIntervalBoundary(double sigma=1) const
Getter for the lower interval bound: angle-sigma*error.
Definition: Angle.h:55
double getErrorInDeg() const
Getter for the error of the angle in degrees.
Definition: Angle.h:49
BaseAngle(double angle, double error)
Constructor.
Definition: Angle.h:30
double getAngle() const
Getter for the angle.
Definition: Angle.h:37
double getUpperIntervalBoundary(double sigma=1) const
Getter for the upper interval bound: angle+sigma*error.
Definition: Angle.h:61
double getError() const
Getter for the error of the angle.
Definition: Angle.h:41
double getAngleInDeg() const
Getter for angle in degrees.
Definition: Angle.h:45
double m_error
Error in rad.
Definition: Angle.h:67
double m_angle
Angle in rad.
Definition: Angle.h:66
virtual ~BaseAngle()
Destructor.
Definition: Angle.h:33
std::pair< double, double > Interval
Shortcut for std::pair used as interval.
Definition: Angle.h:64
bool containsIn(const PhiAngle &angle, double sigma) const
Check if two angles are compatible.
Definition: Angle.h:175
PhiAngle(double angle, double error)
Constructor using radian units.
Definition: Angle.h:156
bool contains(const PhiAngle &angle) const
Check if two angles are compatible.
Definition: Angle.h:165
ThetaAngle(double angle, double error)
Constructor using radian units.
Definition: Angle.h:113
bool containsIn(const ThetaAngle &angle, double sigma) const
Check if two angles are compatible.
Definition: Angle.h:132
bool contains(const ThetaAngle &angle) const
Check if two angles are compatible.
Definition: Angle.h:122
Abstract base class for different kinds of events.