test_raygrid.cxx
Go to the documentation of this file.
1 #include "WireCellUtil/RayGrid.h"
2 #include "WireCellUtil/Logging.h"
3 #include "WireCellUtil/Testing.h"
4 
5 #include "TCanvas.h"
6 #include "TMarker.h"
7 #include "TText.h"
8 #include "TLine.h"
9 #include "TH1F.h"
10 
11 
12 #include <string>
13 #include <sstream>
14 
15 using namespace WireCell;
16 using namespace WireCell::RayGrid;
17 using namespace std;
18 
19 using spdlog::info;
20 
21 void draw_ray(const Ray& ray, int color=1)
22 {
23  TLine l;
24  l.SetLineColor(color);
25  l.DrawLine(ray.first.z(), ray.first.y(),
26  ray.second.z(), ray.second.y());
27 }
28 
29 void draw_point(const Point& p, float size=1, int style=20, int color=1);
30 void draw_point(const Point& p, float size, int style, int color)
31 {
32  TMarker m;
33  m.SetMarkerColor(color);
34  m.SetMarkerSize(size);
35  m.SetMarkerStyle(style);
36  m.DrawMarker(p.z(), p.y());
37 }
38 void draw_text(const Point&p, std::string text)
39 {
40  TText t;
41  t.SetTextFont(82);
42  t.SetTextSize(0.03);
43  t.DrawText(p.z(), p.y(), text.c_str());
44 }
46 {
47  auto p = rg.zero_crossing(il, im);
48  draw_point(p, 1, 24);
49 
50  const auto& cs = rg.centers();
51  const auto& c1 = cs[il];
52  const auto& c2 = cs[im];
53  draw_point(c1, 0.5, 20, 2);
54  draw_point(c2, 0.5, 20, 4);
55 
56  const auto& rjs = rg.ray_jumps();
57  const auto& j1 = rjs(il,im);
58  const auto& j2 = rjs(im,il);
59 
60  draw_ray(Ray(c1, c1+j1), 2);
61  draw_ray(Ray(c2, c2+j2), 4);
62 
63  std::stringstream ss;
64  ss << "(" << il << "," << im << ")";
65  draw_text(p, ss.str());
66 }
67 
68 void draw_segments(const Coordinates& rg)
69 {
70  const auto c0 = rg.centers()[0];
71  const auto c1 = rg.centers()[1];
72  const auto p0 = rg.pitch_dirs()[0];
73  const auto p1 = rg.pitch_dirs()[1];
74  const auto pm0 = rg.pitch_mags()[0];
75  const auto pm1 = rg.pitch_mags()[1];
76 
77  const Vector ecks(1,0,0);
78 
79  for (int lind=2; lind < rg.nlayers(); ++lind) {
80  const auto& center = rg.centers()[lind];
81  const auto& pdir = rg.pitch_dirs()[lind];
82  const double pmag = rg.pitch_mags()[lind];
83  const auto rdir = pdir.cross(ecks);
84 
85  Point next_center = center;
86 
87  int pind = -1;
88  while (true) {
89  ++pind;
90 
91  const auto pc = next_center;
92  const double d0 = p0.dot(pc-c0);
93  const double d1 = p1.dot(pc-c1);
94  if (d0 < 0 or d0 > pm0) { break; }
95  if (d1 < 0 or d1 > pm1) { break; }
96  // handle anyt parallel layers special.
97 
98  Point pa, pb;
99  if (1.0-p0.dot(pdir) < 0.001) { // layer 0 is parallel
100  pa = rg.ray_crossing({1,0}, {lind,pind} );
101  pb = rg.ray_crossing({1,1}, {lind,pind} );
102  }
103  else if (1.0-p1.dot(pdir) < 0.001) {// layer 1 is parallel
104  pa = rg.ray_crossing({0,0}, {lind,pind} );
105  pb = rg.ray_crossing({0,1}, {lind,pind} );
106  }
107  else {
108  // normally, center is inside the "box" so sorting by
109  // dot product of a vector from center to crossing
110  // point and the ray direction means middle two are
111  // closest.
112  std::vector<Vector> crossings {
113  rg.ray_crossing({0,0}, {lind,pind} ),
114  rg.ray_crossing({0,1}, {lind,pind} ),
115  rg.ray_crossing({1,0}, {lind,pind} ),
116  rg.ray_crossing({1,1}, {lind,pind} )};
117 
118  sort(crossings.begin(), crossings.end(),
119  [&](const Vector&a, const Vector&b) {
120  return rdir.dot(a-pc) < rdir.dot(b-pc);
121  });
122  pa = crossings[1];
123  pb = crossings[2];
124  }
125 
126  draw_ray(Ray(pa,pb));
127 
128  // recenter and move by one pitch
129  next_center = 0.5*(pa+pb) + pmag * pdir; // this builds up errors
130 
131 
132  }
133  }
134 }
135 
136 void draw_pairs(const ray_pair_vector_t& raypairs)
137 {
138  for (const auto& rp : raypairs) {
139  draw_ray(rp.first);
140  draw_ray(rp.second);
141  }
142 }
143 
144 TH1F* draw_frame(TCanvas& canvas, std::string title,
145  double xmin=-110, double ymin=-110,
146  double xmax=+110, double ymax=+110)
147 {
148  auto* frame = canvas.DrawFrame(xmin,ymin,xmax,ymax);
149  frame->SetTitle(title.c_str());
150  return frame;
151 }
152 
153 void draw(std::string fname, const Coordinates& rg, const ray_pair_vector_t& raypairs)
154 {
155 
156  TCanvas canvas("test_raygrid","Ray Grid", 500, 500);
157  auto draw_print = [&](std::string extra="") { canvas.Print((fname + extra).c_str(), "pdf"); };
158 
159  draw_print("[");
160 
161  draw_frame(canvas, "rays", -10, -10);
162  draw_segments(rg);
163  draw_print();
164 
165  const int nbounds = raypairs.size();
166 
167 
168  for (layer_index_t il=0; il < nbounds; ++il) {
169  for (layer_index_t im=0; im < nbounds; ++im) {
170  if (il < im) {
171  draw_frame(canvas, Form("LAYER (%d,%d)", (int)il, (int)im));
172  draw_pairs(raypairs);
173  draw_zero_crossing(rg, il, im);
174 
175  for (grid_index_t ip = 0; ip < 100; ++ip) {
176  for (grid_index_t jp = 0; jp < 100; ++jp) {
177  coordinate_t one{il, ip}, two{im, jp};
178  auto p = rg.ray_crossing(one, two);
179  // cheat about knowing the bounds
180  if (p.z() < 0.0 or p.z() > 100.0) continue;
181  if (p.y() < 0.0 or p.y() > 100.0) continue;
182  draw_point(p, 1, 7);
183  }
184  }
185 
186  draw_print();
187  }
188  }
189  }
190 
191  draw_print("]");
192 }
193 
194 
195 void dump(std::string msg, const tensor_t& ar)
196 {
197  info(msg);
198 
199  auto shape = ar.shape();
200  std::stringstream ss;
201  ss << "Dimensions: " << shape[0] << " " << shape[1] << " "<< shape[2];
202  info (ss.str());
203 
204 
205  for (size_t i = 0; i < shape[0]; ++i) {
206  for (size_t j = 0; j < shape[1]; ++j) {
207  std::string line="\t";
208  for (size_t k = 0; k < shape[2]; ++k) {
209  line += Form("%.1f", ar[i][j][k]);
210  }
211  info(line);
212  }
213  info("");
214  }
215 }
216 
217 void test_012(const Coordinates& rg)
218 {
219  dump("a", rg.a());
220  dump("b", rg.b());
221 
222  std::vector<double> ps;
223  for (int a=0; a<2; ++a) {
224  for (int b=0; b<2; ++b) {
225  const double p = rg.pitch_location({0,a}, {1,b}, 2);
226  info("a={} b={} p={}", a,b,p);
227  ps.push_back(p);
228  }
229  }
230 
231  Assert(ps.front() != ps.back());
232 
233 }
234 
235 
236 #include "raygrid.h"
237 
238 
239 
240 int main(int argc, char *argv[])
241 {
242  ray_pair_vector_t raypairs = make_raypairs();
243 
244  Coordinates rg(raypairs);
245 
246  test_012(rg);
247 
248  Assert(rg.nlayers() == (int)raypairs.size());
249 
250  for (int ind=0; ind<rg.nlayers(); ++ind) {
251  info("{} r1={} r2={} p={}[{}] c={}",
252  ind,
253  raypairs[ind].first,
254  raypairs[ind].second,
255  rg.pitch_dirs().at(ind),
256  rg.pitch_mags().at(ind),
257  rg.centers().at(ind));
258  }
259 
260  std::string fname = argv[0];
261  fname += ".pdf";
262  draw(fname, rg, raypairs);
263  return 0;
264 
265 }
266 
void draw_pairs(const ray_pair_vector_t &raypairs)
std::pair< Point, Point > Ray
A line segment running from a first (tail) to a second (head) point.
Definition: Point.h:21
static const double m
Definition: Units.h:79
const vector_array2d_t & ray_jumps() const
Definition: RayGrid.h:91
void msg(const char *fmt,...)
Definition: message.cpp:107
void info(const char *fmt, const Args &...args)
Definition: spdlog.h:189
static const double ps
Definition: Units.h:103
D3Vector< double > Point
A 3D Cartesian point in double precision.
Definition: Point.h:15
std::string string
Definition: nybbler.cc:12
double pitch_location(const coordinate_t &one, const coordinate_t &two, layer_index_t other) const
Definition: RayGrid.cxx:133
void dump(std::string msg, const tensor_t &ar)
void draw_ray(const Ray &ray, int color=1)
STL namespace.
int main(int argc, char *argv[])
TH1F * draw_frame(TCanvas &canvas, std::string title, double xmin=-110, double ymin=-110, double xmax=+110, double ymax=+110)
static QStrList * l
Definition: config.cpp:1044
const vector_array1d_t & pitch_dirs() const
Definition: RayGrid.h:88
#define Assert
Definition: Testing.h:7
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:87
void draw_segments(const Coordinates &rg)
const tensor_t a() const
Definition: RayGrid.h:93
static const double pb
Definition: Units.h:90
const tensor_t b() const
Definition: RayGrid.h:94
Vector ray_crossing(const coordinate_t &one, const coordinate_t &two) const
Definition: RayGrid.cxx:122
const vector_array1d_t & centers() const
Definition: RayGrid.h:89
const std::vector< double > & pitch_mags() const
Definition: RayGrid.h:87
void draw_zero_crossing(const Coordinates &rg, layer_index_t il, layer_index_t im)
void draw_text(const Point &p, std::string text)
Vector zero_crossing(layer_index_t one, layer_index_t two) const
Definition: RayGrid.cxx:117
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124
std::vector< ray_pair_t > ray_pair_vector_t
Definition: Point.h:27
Definition: Main.h:22
p
Definition: test.py:223
std::vector< float > Vector
color
Definition: color.h:50
void draw(std::string fname, const Coordinates &rg, const ray_pair_vector_t &raypairs)
def center(depos, point)
Definition: depos.py:117
static bool * b
Definition: config.cpp:1043
void test_012(const Coordinates &rg)
void draw_point(const Point &p, float size=1, int style=20, int color=1)
const char * cs
ray_pair_vector_t make_raypairs(double width=100, double height=100, double pitch_mag=3, double angle=60.0 *M_PI/180.0)
Definition: raygrid.h:5
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:80
boost::multi_array< double, 3 > tensor_t
Definition: RayGrid.h:50