geo.h
Go to the documentation of this file.
1 /// \file geo.h
2 /// \brief Collect all the geometry header files together
3 /// \author brebel@fnal.gov
4 #ifndef GEO_GEO_H
5 #define GEO_GEO_H
6 
7 #include "cetlib_except/exception.h"
8 
9 #include "stdexcept"
10 
11 
12 /// Detector geometry definition and interface
13 namespace geo {
14  void ProjectToBoxEdge(const double xyz[],
15  const double dxyz[],
16  double xlo, double xhi,
17  double ylo, double yhi,
18  double zlo, double zhi,
19  double xyzout[]);
20  double ClosestApproach(const double point[],
21  const double intercept[],
22  const double slopes[],
23  double closest[]);
24  bool CrossesBoundary ( double x0[],
25  double gradient[],
26  double x_lo, double x_hi,
27  double y_lo, double y_hi,
28  double z_lo, double z_hi,
29  double point[] );
30 }
31 
32 ///
33 /// Project along a direction from a particular starting point to the
34 /// edge of a box
35 ///
36 /// \param xyz - The starting x,y,z location. Must be inside box.
37 /// \param dxyz - Direction vector
38 /// \param xlo - Low edge of box in x
39 /// \param xhi - Low edge of box in x
40 /// \param ylo - Low edge of box in y
41 /// \param yhi - Low edge of box in y
42 /// \param zlo - Low edge of box in z
43 /// \param zhi - Low edge of box in z
44 /// \param xyzout - On output, the position at the box edge
45 ///
46 /// Note: It should be safe to use the same array for input and
47 /// output.
48 ///
49 inline void geo::ProjectToBoxEdge(const double xyz[],
50  const double dxyz[],
51  double xlo, double xhi,
52  double ylo, double yhi,
53  double zlo, double zhi,
54  double xyzout[])
55 {
56  // Make sure we're inside the box!
57  if( !(xyz[0]>=xlo && xyz[0]<=xhi) ||
58  !(xyz[1]>=ylo && xyz[1]<=yhi) ||
59  !(xyz[2]>=zlo && xyz[2]<=zhi) )
60  throw cet::exception("ProjectToBoxEdge") << "desired point is not"
61  << " in the specififed box\n";
62 
63  // Compute the distances to the x/y/z walls
64  double dx = 99.E99;
65  double dy = 99.E99;
66  double dz = 99.E99;
67  if (dxyz[0]>0.0) { dx = (xhi-xyz[0])/dxyz[0]; }
68  else if (dxyz[0]<0.0) { dx = (xlo-xyz[0])/dxyz[0]; }
69  if (dxyz[1]>0.0) { dy = (yhi-xyz[1])/dxyz[1]; }
70  else if (dxyz[1]<0.0) { dy = (ylo-xyz[1])/dxyz[1]; }
71  if (dxyz[2]>0.0) { dz = (zhi-xyz[2])/dxyz[2]; }
72  else if (dxyz[2]<0.0) { dz = (zlo-xyz[2])/dxyz[2]; }
73 
74  // Choose the shortest distance
75  double d = 0.0;
76  if (dx<dy && dx<dz) d = dx;
77  else if (dy<dz && dy<dx) d = dy;
78  else if (dz<dx && dz<dy) d = dz;
79 
80  // Make the step
81  for (int i=0; i<3; ++i) {
82  xyzout[i] = xyz[i] + dxyz[i]*d;
83  }
84 }
85 
86 ///
87 /// Find the distance of closest approach between point and line
88 ///
89 /// \param point - xyz coordinates of point
90 /// \param intercept - xyz coodinates of point on line
91 /// \param slopes - unit vector direction (need not be normalized)
92 /// \param closest - on output, point on line that is closest
93 ///
94 /// \returns distance from point to line
95 ///
96 inline double geo::ClosestApproach(const double point[],
97  const double intercept[],
98  const double slopes[],
99  double closest[])
100 {
101  double s =
102  (slopes[0]*(point[0]-intercept[0]) +
103  slopes[1]*(point[1]-intercept[1]) +
104  slopes[2]*(point[2]-intercept[2]));
105  double sd =
106  (slopes[0]*slopes[0] +
107  slopes[1]*slopes[1] +
108  slopes[2]*slopes[2]);
109  if (sd>0.0) {
110  s /= sd;
111  closest[0] = intercept[0] + s*slopes[0];
112  closest[1] = intercept[1] + s*slopes[1];
113  closest[2] = intercept[2] + s*slopes[2];
114  }
115  else {
116  // How to handle this zero gracefully? Assume that the intercept
117  // is a particle vertex and "slopes" are momenta. In that case,
118  // the particle goes nowhere and the closest approach is the
119  // distance from the intercept to point
120  closest[0] = intercept[0];
121  closest[1] = intercept[1];
122  closest[2] = intercept[2];
123  }
124  return std::sqrt(pow((point[0]-closest[0]),2)+
125  pow((point[1]-closest[1]),2)+
126  pow((point[2]-closest[2]),2));
127 }
128 
129 
130 ///
131 /// Determine whether or not track intersects box of volume:
132 /// ( x_hi - x_lo ) x ( y_hi - y_lo ) x ( z_hi - z_lo )
133 ///
134 /// \param x_hi - x box coordinates in space w.r.t. the origin
135 /// \param x_lo - x box coordinates in space w.r.t. the origin
136 /// \param y_hi - y box coordinates in space w.r.t. the origin
137 /// \param y_lo - y box coordinates in space w.r.t. the origin
138 /// \param z_hi - z box coordinates in space w.r.t. the origin
139 /// \param z_lo - z box coordinates in space w.r.t. the origin
140 /// \param x0[] - initial position of the particle
141 /// \param gradient[] - initial gradient of particle position
142 /// \param point[] (_output_) - position of the particle at intersection
143 ///
144 /// @see `geo::BoxBoundedGeo::GetIntersection()`
145 ///
146 /// *** assumes particle's track is linear
147 ///
148 inline bool geo::CrossesBoundary ( double x0[], // initial particle position
149  double gradient[], // initial particle gradient
150  double x_lo, // -
151  double x_hi, // |
152  double y_lo, // |- box coordinates
153  double y_hi, // | (make into vectors?)
154  double z_lo, // |
155  double z_hi, // -
156  double point[] )
157 {
158 
159  double distance[3]; // distance to plane
160 
161  // puts box coordinates into more useful vectors (for loop later)
162  double lo[3] = { x_lo , y_lo , z_lo };
163  double hi[3] = { x_hi , y_hi , z_hi };
164 
165  // puts box coordinates into more useful vector (for loop later)
166  double facecoord[6] = { lo[0] , hi[0] ,
167  lo[1] , hi[1] ,
168  lo[2] , hi[2] };
169 
170  int intersect[6]={0,0,0,0,0,0}; // initialize intersection tally vector
171  int count=0;
172  // iterates through spatial axes (0,1,2) = (x,y,z)
173  for(int i=0; i<3; i++) {
174  // try both planes with normal parallel to axis
175  for(int p=0; p<2; p++ ) {
176 
177  point[i] = facecoord[count]; // point on face
178  distance[i] = point[i] - x0[i]; // calculate x-coordinate of track distance
179 
180  double C_dg = distance[i] / gradient[i]; // calculate correlation b/w gradient and distance
181 
182  for(int m=0; m<3; m++){ distance[m] = C_dg * gradient[m]; }
183  for(int n=0; n<3; n++){ point[n] = x0[n] + distance[n]; }
184 
185  int j, k;
186  switch (i) {
187  case 0: j=1; k=2; break;
188  case 1: j=2; k=0; break;
189  case 2: j=0; k=1; break;
190  default:
191  throw std::logic_error("Big trouble");
192  } // switch
193 
194  // now want to check to see if the point is in the right plane
195  if ( lo[j] < point[j] && point[j] < hi[j]
196  && lo[k] < point[k] && point[k] < hi[k] ) {
197 
198  // double length = std::sqrt( distance[0]*distance[0]
199  // + distance[1]*distance[1]
200  // + distance[2]*distance[2] );
201 
202  // direction of motion w.r.t. start point
203  int direction = distance[i]*gradient[i]
204  / std::sqrt( (distance[i]*distance[i]) * (gradient[i]*gradient[i]) );
205  bool directed = ( direction + 1 ) / 2;
206 
207  // checks if particle passes through face
208  // and also checks to see whether it passes inward or outward
209  //if ( track_length > length && directed ) {
210  if ( directed ) {
211  int normal = pow( -1 , count + 1 );
212  int thru = normal * gradient[i] / std::sqrt(gradient[i]*gradient[i]) ;
213  intersect[count]=thru;
214  }
215  }
216  count++;
217  }
218  }
219 
220  // count faces it passes through,
221  // ... not necessary now, but maybe useful in the future
222  int passes=0;
223  for ( int face=0; face<6; ++face ) {
224  passes+=(intersect[face]*intersect[face]);
225  }
226 
227  if ( passes==0 ) {
228  return 0;
229  } else {
230  return 1;
231  }
232 }
233 
234 #endif
constexpr T pow(T x)
Definition: pow.h:72
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:148
std::void_t< T > n
p
Definition: test.py:223
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
double ClosestApproach(const double point[], const double intercept[], const double slopes[], double closest[])
Definition: geo.h:96
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:49
LArSoft geometry interface.
Definition: ChannelGeo.h:16
static QCString * s
Definition: config.cpp:1042
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33