Belle II Software  release-05-02-19
LineHelper.h
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2012 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Jake Bennett
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #pragma once
12 
13 #include <cmath>
14 #include <vector>
15 
16 namespace Belle2 {
31  class DedxPoint {
32 
33  public:
34 
36  DedxPoint() : m_x(0), m_y(0), m_valid(true) {}
37 
39  DedxPoint(double x, double y) : m_x(x), m_y(y), m_valid(true) {}
40 
42  double getX() const { return m_x; }
43 
45  double getY() const { return m_y; }
46 
48  void setPoint(double x, double y)
49  {
50  m_x = x;
51  m_y = y;
52  }
53 
55  double length(const DedxPoint& p)
56  {
57  // horizontal line
58  if (m_y == p.getY()) return std::abs(m_x - p.getX());
59  // vertical line
60  else if (m_x == p.getX()) return std::abs(m_y - p.getY());
61  // else use Pythagorean Theorem
62  else return std::sqrt((m_x - p.getX()) * (m_x - p.getX()) +
63  (m_y - p.getY()) * (m_y - p.getY()));
64  }
65 
67  bool isValid() const { return m_valid; }
68 
70  void setInvalid() { m_valid = false; }
71 
72  private:
73 
74  double m_x;
75  double m_y;
76  bool m_valid;
78  };
79 
85  class DedxLine {
86 
87  public:
88 
94  DedxLine(): m_m(0), m_vertical(false) {}
95 
97  DedxLine(const DedxPoint& p, const double slope) : m_p1(p), m_p2(p), m_m(slope), m_vertical(false) {}
98 
100  DedxLine(const DedxPoint& p1, const DedxPoint& p2) : m_p1(p1), m_p2(p2), m_vertical(false)
101  {
102  //check if the line is vertical (set vertical flag if it is)
103  if (p1.getX() == p2.getX()) {
104  m_m = -10000.0;
105  m_vertical = true;
106  } else
107  m_m = (p1.getY() - p2.getY()) / (p1.getX() - p2.getX());
108  }
109 
111  double getSlope() const { return m_m; }
112 
114  DedxPoint intersection(const DedxLine& l)
115  {
116  double x, y;
117  DedxPoint intP;
118 
119  // First check if the lines will intersect.
120  // Also check for special cases of horizontal or
121  // vertical lines.
122  if (m_m == l.m_m) {
123  B2WARNING("Lines are parallel, will not intersect...");
124  intP.setInvalid();
125  intP.setPoint(0, 0);
126  return intP;
127  } else if (m_m == 0.0) {
128  y = m_p1.getY();
129  x = (y - l.m_p1.getY()) / l.m_m + l.m_p1.getX();
130  } else if (l.m_m == 0.0) {
131  y = l.m_p1.getY();
132  x = (y - m_p1.getY()) / m_m + m_p1.getX();
133  } else if (m_vertical) {
134  x = m_p1.getX();
135  y = l.m_p1.getY() + l.m_m * (x - l.m_p1.getX());
136  } else if (l.isVertical()) {
137  x = l.m_p1.getX();
138  y = m_p1.getY() + m_m * (x - m_p1.getX());
139  } else {
140  x = ((l.m_p1.getY() - l.m_m * l.m_p1.getX()) - (m_p1.getY() - m_m * m_p1.getX())) / (m_m - l.m_m);
141  y = m_p1.getY() + m_m * (x - m_p1.getX());
142  }
143 
144  // This is the point of intersection
145  intP.setPoint(x, y);
146 
147  // Check if the point falls outside the endpoints of the line.
148  // This is useful for calculating the track length (dx).
149  if ((x > m_p1.getX() && x > m_p2.getX()) ||
150  (x < m_p1.getX() && x < m_p2.getX()))
151  intP.setInvalid();
152  if ((y > m_p1.getY() && y > m_p2.getY()) ||
153  (y < m_p1.getY() && y < m_p2.getY()))
154  intP.setInvalid();
155 
156  // Check if the DedxLine was made from a point and make sure the
157  // point is not outside the cell
158  if (l.m_p1.getX() == l.m_p2.getX() && l.m_p1.getY() == l.m_p2.getY() &&
159  ((l.m_p1.getX() > m_p1.getX() && l.m_p1.getX() > m_p2.getX()) ||
160  (l.m_p1.getX() < m_p1.getX() && l.m_p1.getX() < m_p2.getX())) &&
161  ((l.m_p1.getY() > m_p1.getY() && l.m_p1.getY() > m_p2.getY()) ||
162  (l.m_p1.getY() < m_p1.getY() && l.m_p1.getY() < m_p2.getY())))
163  intP.setInvalid();
164 
165  return intP;
166  }
167 
169  bool isVertical() const { return m_vertical; }
170 
172  void setVertical() { m_vertical = true; }
173 
174  private:
175 
176  DedxPoint m_p1 ;
178  double m_m;
179  int m_vertical;
181  };
182 
188  class DedxDriftCell {
189 
190  public:
191 
193  DedxDriftCell(const DedxLine& left, const DedxLine& top, const DedxLine& right, const DedxLine& bot) : m_Left(left), m_Top(top),
194  m_Right(right), m_Bot(bot), m_isValid(true) {}
195 
197  DedxDriftCell(const DedxPoint& tl, const DedxPoint& tr, const DedxPoint& br, const DedxPoint& bl) : m_Left(bl, tl), m_Top(tl, tr),
198  m_Right(tr, br), m_Bot(br, bl), m_isValid(true) {}
199 
201  bool isValid() { return m_isValid; }
202 
205  double dx(const DedxPoint& poca, double entAng)
206  {
207  // The path length (dx) is the length of the track in this cell.
208  double Dx = 0;
209 
210  // The DedxPoint Of Closest Approach (poca) is useful for a reference point
211  // to construct a line that represents the track.
212  DedxLine track = DedxLine(poca, std::tan(M_PI_2 - entAng));
213 
214  // Find the points of intersection with each cell boundary
215  DedxPoint intLeft = m_Left.intersection(track);
216  DedxPoint intTop = m_Top.intersection(track);
217  DedxPoint intRight = m_Right.intersection(track);
218  DedxPoint intBot = m_Bot.intersection(track);
219 
220  std::vector<DedxPoint> endpoints;
221  if (intLeft.isValid())
222  endpoints.push_back(intLeft);
223  if (intTop.isValid())
224  endpoints.push_back(intTop);
225  if (intRight.isValid())
226  endpoints.push_back(intRight);
227  if (intBot.isValid())
228  endpoints.push_back(intBot);
229 
230  // Make sure we only get two intersections!
231  if (endpoints.size() == 2) {
232  Dx = endpoints[0].length(endpoints[1]);
233  if (Dx == 0)
234  m_isValid = false;
235  } else
236  m_isValid = false;
237 
238  return Dx;
239  }
240 
243  double dx(double doca, double entAng)
244  {
245  // The path length (dx) is the length of the track in this cell.
246  double Dx = 0;
247 
248  // The DedxPoint Of Closest Approach (poca) is useful for a reference point
249  // to construct a line that represents the track.
250  const DedxPoint poca = DedxPoint(doca * std::abs(std::cos(entAng)), -1.0 * doca * std::sin(entAng));
251  DedxLine track = DedxLine(poca, std::tan(M_PI_2 - entAng));
252 
253  // Find the points of intersection with each cell boundary
254  DedxPoint intLeft = m_Left.intersection(track);
255  DedxPoint intTop = m_Top.intersection(track);
256  DedxPoint intRight = m_Right.intersection(track);
257  DedxPoint intBot = m_Bot.intersection(track);
258 
259  std::vector< DedxPoint > endpoints;
260  if (intLeft.isValid())
261  endpoints.push_back(intLeft);
262  if (intTop.isValid())
263  endpoints.push_back(intTop);
264  if (intRight.isValid())
265  endpoints.push_back(intRight);
266  if (intBot.isValid())
267  endpoints.push_back(intBot);
268 
269  // Make sure we only get two intersections!
270  if (endpoints.size() == 2) {
271  Dx = endpoints[0].length(endpoints[1]);
272  if (Dx == 0)
273  m_isValid = false;
274  } else
275  m_isValid = false;
276 
277  return Dx;
278  }
279 
280  private:
281 
282  DedxLine m_Left;
283  DedxLine m_Top;
284  DedxLine m_Right;
285  DedxLine m_Bot;
286  bool m_isValid;
287  };
289 } // Belle2 namespace
Belle2::DedxLine::m_m
double m_m
Slope of the line.
Definition: LineHelper.h:186
Belle2::DedxPoint::length
double length(const DedxPoint &p)
Calculate the distance between this and another point.
Definition: LineHelper.h:63
Belle2::DedxLine::m_p2
DedxPoint m_p2
Second endpoint.
Definition: LineHelper.h:185
Belle2::DedxDriftCell::DedxDriftCell
DedxDriftCell(const DedxLine &left, const DedxLine &top, const DedxLine &right, const DedxLine &bot)
Construct a DedxDriftCell from four different DedxLines (sides)
Definition: LineHelper.h:201
Belle2::DedxLine::DedxLine
DedxLine()
A line is definied either by a point and a slope, or by endpoints.
Definition: LineHelper.h:102
Belle2::DedxPoint::getX
double getX() const
Helper function to return the x-coordinates of a DedxPoint.
Definition: LineHelper.h:50
Belle2::DedxLine::m_p1
DedxPoint m_p1
First endpoint.
Definition: LineHelper.h:184
Belle2::DedxLine::intersection
DedxPoint intersection(const DedxLine &l)
Find the intersection of this and another line.
Definition: LineHelper.h:122
Belle2::DedxLine
A class to hold the endpoints and slope of a line.
Definition: LineHelper.h:93
Belle2::DedxLine::isVertical
bool isVertical() const
The m_vertical flag is used for the special case of a vertical line.
Definition: LineHelper.h:177
Belle2::DedxPoint::setPoint
void setPoint(double x, double y)
Set the x and y coordinates of a DedxPoint.
Definition: LineHelper.h:56
Belle2::DedxDriftCell::m_Right
DedxLine m_Right
the left boundary of the cell
Definition: LineHelper.h:292
Belle2::DedxPoint::setInvalid
void setInvalid()
Mark this point as invalid (exists outside a DedxDriftCell)
Definition: LineHelper.h:78
Belle2::DedxDriftCell::m_Top
DedxLine m_Top
the left boundary of the cell
Definition: LineHelper.h:291
Belle2::DedxPoint
A collection of classes that are useful for making a simple path length correction to the dE/dx measu...
Definition: LineHelper.h:39
Belle2::DedxPoint::m_x
double m_x
the x-coordinate of the DedxPoint
Definition: LineHelper.h:82
Belle2::DedxDriftCell::isValid
bool isValid()
Check if this is a valid calculation (number of intersections = 2)
Definition: LineHelper.h:209
Belle2::DedxDriftCell::m_Left
DedxLine m_Left
the left boundary of the cell
Definition: LineHelper.h:290
Belle2::DedxPoint::getY
double getY() const
Helper function to return the y-coordinates of a DedxPoint.
Definition: LineHelper.h:53
Belle2::DedxDriftCell::m_Bot
DedxLine m_Bot
the left boundary of the cell
Definition: LineHelper.h:293
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::DedxPoint::m_y
double m_y
the y-coordinate of the DedxPoint
Definition: LineHelper.h:83
Belle2::DedxDriftCell
A class to hold the geometry of a cell.
Definition: LineHelper.h:196
Belle2::DedxPoint::DedxPoint
DedxPoint()
The default constructor sets the coordinates to zero.
Definition: LineHelper.h:44
Belle2::DedxLine::m_vertical
int m_vertical
If the line is vertical, this is set to true.
Definition: LineHelper.h:187
Belle2::DedxPoint::m_valid
bool m_valid
used to check if the point lies inside a boundary
Definition: LineHelper.h:84
Belle2::DedxPoint::isValid
bool isValid() const
Check whether this point lies within the endpoints of a line.
Definition: LineHelper.h:75
Belle2::DedxLine::setVertical
void setVertical()
Mark this DedxLine as being vertical.
Definition: LineHelper.h:180
Belle2::DedxLine::getSlope
double getSlope() const
Helper function to return the slope.
Definition: LineHelper.h:119
Belle2::DedxDriftCell::dx
double dx(const DedxPoint &poca, double entAng)
Calculate the path length through this cell for a track with a given DedxPoint Of Closest Approach (p...
Definition: LineHelper.h:213
Belle2::DedxDriftCell::m_isValid
bool m_isValid
does the hit land in this cell
Definition: LineHelper.h:294