EventUtilities.cxx
Go to the documentation of this file.
1 /**
2  * @file Event.cxx
3  *
4  * @brief Producer module to create 3D clusters from input hits
5  *
6  */
7 
8 // LArSoft includes
11 
12 // std includes
13 #include <algorithm>
14 #include <cmath>
15 #include <limits>
16 
17 //------------------------------------------------------------------------------------------------------------------------------------------
18 // implementation follows
19 
20 namespace voronoi2d {
21 
22 double EventUtilities::computeArcVal(double beachPos, double yPos, const IEvent* arc) const
23 {
24  // Note that if the input arc site point lies on the beach line then the arc position is infinite
25  double arcVal = std::numeric_limits<double>::max();
26  double deltaxLx = arc->xPos() - beachPos;
27 
28  if (std::abs(deltaxLx) > std::numeric_limits<double>::epsilon())
29  {
30  double deltayPy = yPos - arc->yPos();
31  double sumPxLx = arc->xPos() + beachPos;
32 
33  arcVal = 0.5 * (deltayPy * deltayPy / deltaxLx + sumPxLx);
34  }
35 
36  return arcVal;
37 }
38 
39 double EventUtilities::computeBreak(const double beachLinePos, const IEvent* leftArc, const IEvent* rightArc, RootsPair& roots) const
40 {
41  // Given arcs to the left and right of this node (meaning we are a breakpoint), compute the
42  // current coordinates of the breakpoint based on the input beachline position
43  double lx = beachLinePos;
44  double deltaX1 = leftArc->xPos() - lx;
45  double deltaX2 = rightArc->xPos() - lx;
46  double breakPoint = -std::numeric_limits<double>::max();
47 
48  // if the two are the same then the arcs are side-by-side and intersection is right in the middle
49  if (std::abs(deltaX1 - deltaX2) < std::numeric_limits<double>::epsilon()) breakPoint = 0.5 * (rightArc->yPos() + leftArc->yPos());
50 
51  // otherwise, we do the full calculation
52  else
53  {
54  // set up for quadratic equation
55  double p1x = leftArc->xPos();
56  double p1y = leftArc->yPos();
57  double p2x = rightArc->xPos();
58  double p2y = rightArc->yPos();
59  double a = p2x - p1x;
60  double b = 2. * (p2y * deltaX1 - p1y * deltaX2);
61  double c = deltaX2 * (p1y * p1y + deltaX1 * (p1x + lx)) - deltaX1 * (p2y * p2y + deltaX2 * (p2x + lx));
62  double radical = std::max(0.,b * b - 4. * a * c);
63 
64  if (radical > 0.) radical = sqrt(radical);
65 
66  double rootPos = 0.5 * (-b + radical) / a;
67  double rootNeg = 0.5 * (-b - radical) / a;
68 
69  roots.first = std::min(rootPos, rootNeg);
70  roots.second = std::max(rootPos, rootNeg);
71 
72  // Ah yes, the eternal question... which solution?
73  // Generally, we think we want the solution which is "between" the left and the right
74  // However, it can be that the right arc is the remnant of an arc whose center lies to the
75  // left of the center of the left arc, and vice versa.
76  if (p1x < p2x) breakPoint = roots.second;
77  else breakPoint = roots.first;
78  }
79 
80  return breakPoint;
81 }
82 
83 bool EventUtilities::newSiteToLeft(const IEvent* newSite, const IEvent* leftArc, const IEvent* rightArc) const
84 {
85  // Note that the input site is used to give us the position of the sweep line
86  // Using the coordinates of the beach line then recover the current breakpoint between the two
87  // input arcs
88  RootsPair roots;
89 
90  double breakPoint = computeBreak(newSite->xPos()-0.000001, leftArc, rightArc, roots);
91 
92  return newSite->yPos() < breakPoint;
93 }
94 
95 } // namespace lar_cluster3d
Provides some basic functions operating in IEvent class objects.
bool newSiteToLeft(const IEvent *, const IEvent *, const IEvent *) const
double computeArcVal(const double, const double, const IEvent *) const
T abs(T value)
const double a
virtual double yPos() const =0
static int max(int a, int b)
virtual double xPos() const =0
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
double computeBreak(const double, const IEvent *, const IEvent *, RootsPair &) const
static bool * b
Definition: config.cpp:1043
std::pair< double, double > RootsPair