RayGrid.cxx
Go to the documentation of this file.
1 #include "WireCellUtil/RayGrid.h"
2 
3 using namespace WireCell;
4 using namespace WireCell::RayGrid;
5 
6 
8  int normal_axis, double normal_location)
9  : m_nlayers(rays.size())
10  , m_pitch_mag(m_nlayers, 0.0)
11  , m_pitch_dir(m_nlayers)
12  , m_center(m_nlayers)
13  , m_zero_crossing(m_nlayers, m_nlayers)
14  , m_ray_jump(m_nlayers, m_nlayers)
15  , m_a(boost::extents[m_nlayers][m_nlayers][m_nlayers])
16  , m_b(boost::extents[m_nlayers][m_nlayers][m_nlayers])
17 {
18 
19  // really we are working in 2D space, so project all vectors into the plane.
20  auto project = [&](Vector v) { v[normal_axis]=normal_location; return v; };
21 
22  // must go through 1, 2 and 3 combonations
23 
24  // First, find the per-layer things
25  for (layer_index_t ilayer=0; ilayer<m_nlayers; ++ilayer) {
26  const auto& rpair = rays[ilayer];
27  const auto& r0 = rpair.first;
28  const auto& r1 = rpair.second;
29 
30  // vector of closest approach between the two parallel rays
31  const auto rpitch = ray_pitch(r0, r1);
32 
33  // relative pitch vector
34  auto rpv = project(rpitch.second - rpitch.first);
35 
36  m_pitch_mag[ilayer] = rpv.magnitude();
37  m_pitch_dir[ilayer] = rpv.norm();
38 
39  // center point of ray 0
40  m_center[ilayer] = 0.5*(project(r0.first + r0.second));
41  }
42 
43  // Next find cross-layer things
44  for (layer_index_t il=0; il<m_nlayers; ++il) {
45  for (layer_index_t im=0; im<m_nlayers; ++im) {
46 
47  // ray pairs for layer l and m
48  const auto& rpl = rays[il];
49  const auto& rpm = rays[im];
50 
51  const auto& rl0 = rpl.first;
52  const auto& rl1 = rpl.second;
53  const auto& rm0 = rpm.first;
54  const auto& rm1 = rpm.second;
55 
56  // Iterate only over triangle of indices to avoid extra work.
57  if (il < im) {
58  const auto r00 = ray_pitch(rl0, rm0);
59  const auto& pl0 = r00.first;
60  const auto& pm0 = r00.second;
61 
62  // These really should be the same after projection.
63  m_zero_crossing(il,im) = project(pl0);
64  m_zero_crossing(im,il) = project(pm0);
65 
66  // along l-layer ray 0, crossing of m-layer ray 1.
67  {
68  const auto ray = ray_pitch(rl0, rm1);
69  const auto jump = project(ray.first - pl0);
70  m_ray_jump(il, im) = jump;
71  }
72  // along m-layer ray 0, crossing of l-layer ray 1.
73  {
74  const auto ray = ray_pitch(rm0, rl1);
75  const auto jump = project(ray.first - pm0);
76  m_ray_jump(im, il) = jump;
77  }
78 
79  }
80  if (il == im) {
81  m_zero_crossing(il,im).invalidate();
82  m_ray_jump(il,im).invalidate();
83  }
84  }
85  }
86 
87  // Finally, find triple-layer things (coefficients for
88  // P^{lmn}_{ij}). Needs some of the above completed.
89  for (layer_index_t in=0; in<m_nlayers; ++in) {
90  const auto& pn = m_pitch_dir[in];
91  const double cp = m_center[in].dot(pn);
92 
93  for (layer_index_t il=0; il<m_nlayers; ++il) {
94  if (il == in) { continue; }
95 
96  // triangle iteration
97  for (layer_index_t im=0; im<il; ++im) {
98  if (im == in) { continue; }
99 
100  const double rlmpn = m_zero_crossing(il,im).dot(pn);
101 
102  const double wlmpn = m_ray_jump(il,im).dot(pn);
103  const double wmlpn = m_ray_jump(im,il).dot(pn);
104 
105  m_a[il][im][in] = wlmpn;
106  m_a[im][il][in] = wmlpn;
107  // b is symmetric.
108  m_b[il][im][in] = rlmpn - cp;
109  m_b[im][il][in] = rlmpn - cp;
110 
111  // j*a{lmn} + i*a{mln} + b{lmn}
112  }
113  }
114  }
115 }
116 
118 {
119  return m_zero_crossing(one, two);
120 }
121 
123 {
124  const layer_index_t l = one.layer, m = two.layer;
125  const auto r00 = m_zero_crossing(l,m);
126  const auto& wlm = m_ray_jump(l,m);
127  const auto& wml = m_ray_jump(m,l);
128  const double i = one.grid, j = two.grid;
129  Vector res = r00 + j*wlm + i*wml;
130  return res;
131 }
132 
134 {
135  const tensor_t::index il=one.layer, im=two.layer, in=other;
136  const tensor_t::index i=one.grid, j=two.grid;
137  return j*m_a[il][im][in] + i*m_a[im][il][in] + m_b[il][im][in];
138 }
static const double m
Definition: Units.h:79
vector_array2d_t m_ray_jump
Definition: RayGrid.h:116
double pitch_location(const coordinate_t &one, const coordinate_t &two, layer_index_t other) const
Definition: RayGrid.cxx:133
vector_array2d_t m_zero_crossing
Definition: RayGrid.h:111
vector_array1d_t m_pitch_dir
Definition: RayGrid.h:104
static QStrList * l
Definition: config.cpp:1044
std::vector< double > m_pitch_mag
Definition: RayGrid.h:101
Coordinates(const ray_pair_vector_t &rays, int normal_axis=0, double normal_location=0.0)
Definition: RayGrid.cxx:7
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:87
Vector ray_crossing(const coordinate_t &one, const coordinate_t &two) const
Definition: RayGrid.cxx:122
vector_array1d_t m_center
Definition: RayGrid.h:107
Vector zero_crossing(layer_index_t one, layer_index_t two) const
Definition: RayGrid.cxx:117
std::vector< ray_pair_t > ray_pair_vector_t
Definition: Point.h:27
Definition: Main.h:22
Ray ray_pitch(const Ray &ray1, const Ray &ray2)
Definition: Point.cxx:76