test_binneddiffusion.cxx
Go to the documentation of this file.
3 #include "WireCellUtil/ExecMon.h"
4 #include "WireCellUtil/Testing.h"
5 #include "WireCellUtil/Point.h"
6 #include "WireCellUtil/Units.h"
7 
10 #include "WireCellIface/IRandom.h"
12 
13 #include "TApplication.h"
14 #include "TCanvas.h"
15 #include "TStyle.h"
16 #include "TFile.h"
17 #include "TH2F.h"
18 #include "TH1F.h"
19 #include "TPolyMarker.h"
20 
21 #include <iostream>
22 
23 using namespace WireCell;
24 using namespace std;
25 
26 struct Meta {
27  //TApplication* theApp = 0;
28 
29  TCanvas* canvas;
31  const char* name;
32 
33  Meta(const char* name)
34  //: theApp(new TApplication (name,0,0))
35  : canvas(new TCanvas("canvas","canvas", 500,500))
36  , em(name)
37  , name(name) {
38  print("[");
39  }
40 
41  void print(const char* extra = "") {
42  string fname = Form("%s.pdf%s", name, extra);
43  //cerr << "Printing: " << fname << endl;
44  canvas->Print(fname.c_str(), "pdf");
45  }
46 };
47 
48 const double t0 = 1*units::s; // put it way out in left field to catch any offset errors
49 //const double t0 = 0*units::s;
50 const int nticks = 9600;
51 const double tick = 0.5*units::us;
52 const double readout_time = nticks*tick;
53 const double drift_speed = 1.6*units::mm/units::us;
54 
55 const int nwires = 2001;
56 const double wire_pitch = 3*units::mm;
57 const double min_wire_pitch = -0.5*(nwires-1)*wire_pitch;
58 const double max_wire_pitch = +0.5*(nwires-1)*wire_pitch;
59 
62 
63 // +/- this number of wire regions around wire of interest to assume
64 // we have field responses calculated.
65 const int npmwires = 10;
66 
67 
68 void test_track(Meta& meta, double charge, double track_time,
69  const Ray& track_ray, double stepsize,
70  IRandom::pointer fluctuate)
71 {
72  const int ndiffision_sigma = 3.0;
73 
74  const auto rbins = pimpos.region_binning();
75  const auto ibins = pimpos.impact_binning();
76 
77  Gen::BinnedDiffusion bd(pimpos, tbins, ndiffision_sigma, fluctuate);
78 
79  auto track_start = track_ray.first;
80  auto track_dir = ray_unit(track_ray);
81  auto track_length = ray_length(track_ray);
82 
83  const double DL=5.3*units::centimeter2/units::second;
84  const double DT=12.8*units::centimeter2/units::second;
85 
86  const double xstop = pimpos.origin()[0];
87 
88  meta.em("begin adding Depp's");
89  for (double dist=0.0; dist < track_length; dist += stepsize) {
90  auto pt = track_start + dist*track_dir;
91  const double delta_x = pt.x() - xstop;
92  const double drift_time = delta_x / drift_speed;
93  pt.x(xstop); // insta-drift
94  const double time = track_time+drift_time;
95 
96  const double pitch = pimpos.distance(pt);
97  Assert(rbins.inside(pitch));
98  Assert(ibins.inside(pitch)); // should be identical
99  Assert(tbins.inside(time));
100 
101  const double tmpcm2 = 2*DL*drift_time/units::centimeter2;
102  const double sigmaL = sqrt(tmpcm2)*units::centimeter / drift_speed;
103  const double sigmaT = sqrt(2*DT*drift_time/units::centimeter2)*units::centimeter2;
104 
105  auto depo = std::make_shared<SimpleDepo>(time, pt, charge);
106  bd.add(depo, sigmaL, sigmaT);
107  //cerr << "dist: " <<dist/units::mm << "mm, drift: " << drift_time/units::us << "us depo:" << depo->pos() << " @ " << depo->time()/units::us << "us\n";
108  }
109 
110 
111  meta.em("begin swiping wires");
112 
113 
114  for (int iwire = 0; iwire < nwires; ++iwire) {
115 
116  const int min_wire = std::max(iwire-npmwires, 0);
117  const int max_wire = std::min(iwire+npmwires, nwires-1);
118 
119  const int min_impact = std::max(pimpos.wire_impacts(min_wire).first, 0);
120  const int max_impact = std::min(pimpos.wire_impacts(max_wire).second, ibins.nbins());
121 
122  std::pair<double,double> time_span(0,0);
123  std::vector<Gen::ImpactData::pointer> collect;
124 
125  std::set<int> seen;
126  for (int imp = min_impact; imp <= max_impact; ++imp) {
127  auto impact_data = bd.impact_data(imp);
128  if (!impact_data) {
129  continue;
130  }
131 
132  const int impnum = impact_data->impact_number();
133  if (seen.find(impnum) != seen.end()) {
134  cerr << "Got duplicate impact number: " << impnum << " in wire " << iwire << endl;
135  }
136  seen.insert(impnum);
137  if (iwire==974) {
138  cerr << "collecting: " << iwire << " " << impnum << endl;
139  }
140 
141  auto ts = impact_data->span(ndiffision_sigma);
142  if (collect.empty()) {
143  time_span = ts;
144  }
145  else {
146  time_span.first = std::min(time_span.first, ts.first);
147  time_span.second = std::max(time_span.second, ts.second);
148  }
149  collect.push_back(impact_data);
150  }
151 
152  if (collect.empty()) {
153  continue;
154  }
155 
156  //bd.erase(0, min_impact);
157 
158  if (false) {
159  cerr << "Not histogramming\n";
160  continue;
161  }
162 
163  const int min_tedge = tbins.edge_index(time_span.first);
164  const int max_tedge = tbins.edge_index(time_span.second);
165 
166  const double min_time = tbins.edge(min_tedge);
167  const double max_time = tbins.edge(max_tedge);
168  const int ntbins = max_tedge - min_tedge;
169 
170  const double min_pitch = ibins.edge(min_impact);
171  const double max_pitch = ibins.edge(max_impact);
172  const int npbins = (max_pitch-min_pitch)/ibins.binsize();
173 
174  // cerr << "t:"<<ntbins<<"["<<min_time/units::us<<","<<max_time/units::us<<"]us ("<<max_time-min_time<<")\n";
175  // cerr << "p:"<<npbins<<"["<<min_pitch/units::mm<<","<<max_pitch/units::mm<<"]mm\n";
176 
177  Assert(max_time > min_time);
178  Assert(ntbins>1);
179  Assert(max_pitch > min_pitch);
180  Assert(npbins>1);
181 
182  TH2F hist(Form("hwire%04d", iwire),Form("Diffused charge for wire %d", iwire),
183  ntbins, (min_time-t0)/units::us, (max_time-t0)/units::us,
184  npbins, min_pitch/units::mm, max_pitch/units::mm);
185  hist.SetXTitle("time (us)");
186  hist.SetYTitle("pitch (mm)");
187 
188  TH1F hp(Form("pwire%04d", iwire),Form("Pitches for wire %d", iwire),
189  npbins, min_pitch/units::mm, max_pitch/units::mm);
190  TH1F ht(Form("twire%04d", iwire),Form("Times for wire %d", iwire),
191  ntbins, (min_time-t0)/units::us, (max_time-t0)/units::us);
192 
193  for (auto idptr : collect) {
194  auto wave = idptr->waveform();
195  Assert (wave.size() == nticks);
196  const int impact = idptr->impact_number();
197  const double pitch_dist = ibins.center(impact);
198  if (iwire == 974) {
199  cerr << iwire << " impact=" << impact << " pitch=" << pitch_dist << endl;
200  }
201  auto mm = idptr->span(ndiffision_sigma);
202  const int min_tick = tbins.bin(mm.first);
203  const int max_tick = tbins.bin(mm.second);
204  //cerr << "impact:" << impact << " pitch="<<pitch_dist/units::mm << " ticks:["<<min_tick<<","<<max_tick<<"]\n";
205  for (int itick=min_tick; itick<=max_tick; ++itick) {
206  const double time = tbins.center(itick);
207  if (!tbins.inside(time)) {
208  cerr << "OOB time: " << time/units::us << "us tick:"<<itick
209  << " impact:" << idptr->impact_number()
210  << " pitch:" << pitch_dist/units::mm << "mm\n";
211  }
212 
213  Assert(tbins.inside(time));
214  Assert(rbins.inside(pitch_dist));
215  const double t_us = (time-t0)/units::us;
216  const double p_mm = pitch_dist/units::mm;
217  hist.Fill(t_us, p_mm, wave[itick]);
218  ht.Fill(t_us);
219  hp.Fill(p_mm);
220  }
221  }
222  hist.Draw("colz");
223  //hp.Draw();
224  hist.Write();
225  ht.Write();
226  hp.Write();
227  meta.print();
228  }
229  meta.em("done");
230 }
231 
232 int main(int argc, char* argv[])
233 {
235  pm.add("WireCellGen");
236  {
237  auto rngcfg = Factory::lookup<IConfigurable>("Random");
238  auto cfg = rngcfg->default_configuration();
239  rngcfg->configure(cfg);
240  }
241  auto rng = Factory::lookup<IRandom>("Random");
242 
243  const char* me = argv[0];
244 
245  TFile* rootfile = TFile::Open(Form("%s.root", me), "RECREATE");
246 
247  Meta meta(me);
248  gStyle->SetOptStat(0);
249 
250  const double track_time = t0+10*units::ns;
251  const double delta = 100*units::mm;
252  Ray track_ray(Point(1*units::m-delta, 0, -delta),
253  Point(1*units::m+delta, 0, +delta));
254  const double stepsize = 1*units::mm;
255  const double charge = 1e5;
256 
257 
258 
259  test_track(meta, charge, track_time, track_ray, stepsize, rng);
260 
261  meta.print("]");
262  rootfile->Close();
263  cerr << meta.em.summary() << endl;
264  return 0;
265 }
code to link reconstructed objects back to the MC truth information
std::pair< Point, Point > Ray
A line segment running from a first (tail) to a second (head) point.
Definition: Point.h:21
const int nwires
static const double m
Definition: Units.h:63
int edge_index(double val) const
Definition: Binning.h:93
const double max_wire_pitch
std::shared_ptr< IRandom > pointer
Access subclass facet by pointer.
Definition: IComponent.h:33
double center(int ind) const
Definition: Binning.h:86
D3Vector< double > Point
A 3D Cartesian point in double precision.
Definition: Point.h:15
TCanvas * canvas
bool add(IDepo::pointer deposition, double sigma_time, double sigma_pitch)
const Point & origin() const
Return given 3-point origin for plane pitch.
Definition: Pimpos.h:85
const Binning & region_binning() const
Definition: Pimpos.h:109
double distance(const Point &pt, int axis=2) const
Definition: Pimpos.cxx:71
STL namespace.
int main(int argc, char *argv[])
cfg
Definition: dbjson.py:29
static const double centimeter
Definition: Units.h:26
static PluginManager & instance()
const double tick
const double min_wire_pitch
const int nticks
Binning tbins(nticks, t0, t0+readout_time)
#define Assert
Definition: Testing.h:7
const Binning & impact_binning() const
Definition: Pimpos.h:113
const double t0
std::enable_if< internal::is_string< String >::value >::type print(std::FILE *f, const text_style &ts, const String &format_str, const Args &...args)
Definition: color.h:549
int bin(double val) const
Definition: Binning.h:80
double ray_length(const Ray &ray)
Definition: Point.cxx:62
void test_track(Meta &meta, double charge, double track_time, const Ray &track_ray, double stepsize, IRandom::pointer fluctuate)
const char * name
static const double centimeter2
Definition: Units.h:27
Vector ray_unit(const Ray &ray)
Definition: Point.cxx:71
static int max(int a, int b)
const double drift_speed
static const double ns
Definition: Units.h:102
static const double mm
Definition: Units.h:55
static const double mm
Definition: Units.h:73
ImpactData::pointer impact_data(int bin) const
Definition: Main.h:22
bool inside(double val) const
Definition: Binning.h:105
static const double second
Definition: Units.h:92
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
Pimpos pimpos(nwires, min_wire_pitch, max_wire_pitch)
std::pair< int, int > wire_impacts(int wireind) const
Definition: Pimpos.cxx:48
Pitch-Impact-Position.
Definition: Pimpos.h:36
static const double s
Definition: Units.h:103
const int npmwires
Meta(const char *name)
static const double us
Definition: Units.h:105
double edge(int ind) const
Definition: Binning.h:99
Plugin * add(const std::string &plugin_name, const std::string &libname="")
Add a plugin. If libname is not given, try to derive it.
const double wire_pitch
void print(const char *extra="")
std::string summary() const
Return summary up to now.
Definition: ExecMon.cxx:21
QTextStream & endl(QTextStream &s)
const double readout_time