LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
geo.h
Go to the documentation of this file.
1 #ifndef GEO_GEO_H
5 #define GEO_GEO_H
6 
7 #include "cetlib_except/exception.h"
8 
9 #include "stdexcept"
10 
12 namespace geo {
13  void ProjectToBoxEdge(const double xyz[],
14  const double dxyz[],
15  double xlo,
16  double xhi,
17  double ylo,
18  double yhi,
19  double zlo,
20  double zhi,
21  double xyzout[]);
22  double ClosestApproach(const double point[],
23  const double intercept[],
24  const double slopes[],
25  double closest[]);
26  bool CrossesBoundary(double x0[],
27  double gradient[],
28  double x_lo,
29  double x_hi,
30  double y_lo,
31  double y_hi,
32  double z_lo,
33  double z_hi,
34  double point[]);
35 }
36 
54 inline void geo::ProjectToBoxEdge(const double xyz[],
55  const double dxyz[],
56  double xlo,
57  double xhi,
58  double ylo,
59  double yhi,
60  double zlo,
61  double zhi,
62  double xyzout[])
63 {
64  // Make sure we're inside the box!
65  if (!(xyz[0] >= xlo && xyz[0] <= xhi) || !(xyz[1] >= ylo && xyz[1] <= yhi) ||
66  !(xyz[2] >= zlo && xyz[2] <= zhi))
67  throw cet::exception("ProjectToBoxEdge") << "desired point is not"
68  << " in the specififed box\n";
69 
70  // Compute the distances to the x/y/z walls
71  double dx = 99.E99;
72  double dy = 99.E99;
73  double dz = 99.E99;
74  if (dxyz[0] > 0.0) { dx = (xhi - xyz[0]) / dxyz[0]; }
75  else if (dxyz[0] < 0.0) {
76  dx = (xlo - xyz[0]) / dxyz[0];
77  }
78  if (dxyz[1] > 0.0) { dy = (yhi - xyz[1]) / dxyz[1]; }
79  else if (dxyz[1] < 0.0) {
80  dy = (ylo - xyz[1]) / dxyz[1];
81  }
82  if (dxyz[2] > 0.0) { dz = (zhi - xyz[2]) / dxyz[2]; }
83  else if (dxyz[2] < 0.0) {
84  dz = (zlo - xyz[2]) / dxyz[2];
85  }
86 
87  // Choose the shortest distance
88  double d = 0.0;
89  if (dx < dy && dx < dz)
90  d = dx;
91  else if (dy < dz && dy < dx)
92  d = dy;
93  else if (dz < dx && dz < dy)
94  d = dz;
95 
96  // Make the step
97  for (int i = 0; i < 3; ++i) {
98  xyzout[i] = xyz[i] + dxyz[i] * d;
99  }
100 }
101 
112 inline double geo::ClosestApproach(const double point[],
113  const double intercept[],
114  const double slopes[],
115  double closest[])
116 {
117  double s = (slopes[0] * (point[0] - intercept[0]) + slopes[1] * (point[1] - intercept[1]) +
118  slopes[2] * (point[2] - intercept[2]));
119  double sd = (slopes[0] * slopes[0] + slopes[1] * slopes[1] + slopes[2] * slopes[2]);
120  if (sd > 0.0) {
121  s /= sd;
122  closest[0] = intercept[0] + s * slopes[0];
123  closest[1] = intercept[1] + s * slopes[1];
124  closest[2] = intercept[2] + s * slopes[2];
125  }
126  else {
127  // How to handle this zero gracefully? Assume that the intercept
128  // is a particle vertex and "slopes" are momenta. In that case,
129  // the particle goes nowhere and the closest approach is the
130  // distance from the intercept to point
131  closest[0] = intercept[0];
132  closest[1] = intercept[1];
133  closest[2] = intercept[2];
134  }
135  return std::sqrt(pow((point[0] - closest[0]), 2) + pow((point[1] - closest[1]), 2) +
136  pow((point[2] - closest[2]), 2));
137 }
138 
157 inline bool geo::CrossesBoundary(double x0[], // initial particle position
158  double gradient[], // initial particle gradient
159  double x_lo, // -
160  double x_hi, // |
161  double y_lo, // |- box coordinates
162  double y_hi, // | (make into vectors?)
163  double z_lo, // |
164  double z_hi, // -
165  double point[])
166 {
167 
168  double distance[3]; // distance to plane
169 
170  // puts box coordinates into more useful vectors (for loop later)
171  double lo[3] = {x_lo, y_lo, z_lo};
172  double hi[3] = {x_hi, y_hi, z_hi};
173 
174  // puts box coordinates into more useful vector (for loop later)
175  double facecoord[6] = {lo[0], hi[0], lo[1], hi[1], lo[2], hi[2]};
176 
177  int intersect[6] = {0, 0, 0, 0, 0, 0}; // initialize intersection tally vector
178  int count = 0;
179  // iterates through spatial axes (0,1,2) = (x,y,z)
180  for (int i = 0; i < 3; i++) {
181  // try both planes with normal parallel to axis
182  for (int p = 0; p < 2; p++) {
183 
184  point[i] = facecoord[count]; // point on face
185  distance[i] = point[i] - x0[i]; // calculate x-coordinate of track distance
186 
187  double C_dg = distance[i] / gradient[i]; // calculate correlation b/w gradient and distance
188 
189  for (int m = 0; m < 3; m++) {
190  distance[m] = C_dg * gradient[m];
191  }
192  for (int n = 0; n < 3; n++) {
193  point[n] = x0[n] + distance[n];
194  }
195 
196  int j, k;
197  switch (i) {
198  case 0:
199  j = 1;
200  k = 2;
201  break;
202  case 1:
203  j = 2;
204  k = 0;
205  break;
206  case 2:
207  j = 0;
208  k = 1;
209  break;
210  default: throw std::logic_error("Big trouble");
211  } // switch
212 
213  // now want to check to see if the point is in the right plane
214  if (lo[j] < point[j] && point[j] < hi[j] && lo[k] < point[k] && point[k] < hi[k]) {
215 
216  // double length = std::sqrt( distance[0]*distance[0]
217  // + distance[1]*distance[1]
218  // + distance[2]*distance[2] );
219 
220  // direction of motion w.r.t. start point
221  int direction = distance[i] * gradient[i] /
222  std::sqrt((distance[i] * distance[i]) * (gradient[i] * gradient[i]));
223  bool directed = (direction + 1) / 2;
224 
225  // checks if particle passes through face
226  // and also checks to see whether it passes inward or outward
227  //if ( track_length > length && directed ) {
228  if (directed) {
229  int normal = pow(-1, count + 1);
230  int thru = normal * gradient[i] / std::sqrt(gradient[i] * gradient[i]);
231  intersect[count] = thru;
232  }
233  }
234  count++;
235  }
236  }
237 
238  // count faces it passes through,
239  // ... not necessary now, but maybe useful in the future
240  int passes = 0;
241  for (int face = 0; face < 6; ++face) {
242  passes += (intersect[face] * intersect[face]);
243  }
244 
245  if (passes == 0) { return 0; }
246  else {
247  return 1;
248  }
249 }
250 
251 #endif
bool CrossesBoundary(double x0[], double gradient[], double x_lo, double x_hi, double y_lo, double y_hi, double z_lo, double z_hi, double point[])
Definition: geo.h:157
Float_t d
Definition: plot.C:235
double ClosestApproach(const double point[], const double intercept[], const double slopes[], double closest[])
Definition: geo.h:112
Char_t n[5]
void ProjectToBoxEdge(const double xyz[], const double dxyz[], double xlo, double xhi, double ylo, double yhi, double zlo, double zhi, double xyzout[])
Definition: geo.h:54
Namespace collecting geometry-related classes utilities.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33