test_interpolation.cxx
Go to the documentation of this file.
1 /** Simple testing of field response interpolation
2  * Linear weighting/re-distributing charge instead
3  * Implementation in GaussianDiffusion for each charge depo
4  */
10 #include "WireCellUtil/ExecMon.h"
11 #include "WireCellUtil/Point.h"
12 #include "WireCellUtil/Binning.h"
13 #include "WireCellUtil/Testing.h"
14 
15 #include "WireCellIface/IRandom.h"
16 
17 #include "TCanvas.h"
18 #include "TFile.h"
19 #include "TLine.h"
20 #include "TStyle.h"
21 #include "TH2F.h"
22 #include "TMath.h"
23 #include "TGraph.h"
24 #include "TBox.h"
25 #include "TF1.h"
26 
27 #include <iostream>
28 #include <string>
29 
30 using namespace WireCell;
31 using namespace std;
32 
33 // linear weighting for the charge in each bin hornoring a Gaussian distribution
34 // cross check on WireCell::Gen::GaussianDiffusion
35 double WeightGaus(double x1, double x2, double mean, double sigma)
36 {
37  double val=0;
38  if(!sigma){
39  val = mean - x2;
40  }
41  else{
42  Double_t sqrt2 = TMath::Sqrt(2);
43  val = TMath::Gaus(x2, mean, sigma, 1) - TMath::Gaus(x1, mean, sigma, 1);
44  val *= -2.*sigma*sigma/(TMath::Erf((x2-mean)/sqrt2/sigma)-TMath::Erf((x1-mean)/sqrt2/sigma));
45  val += (mean-x2);
46  }
47  return val/(x1-x2);
48 }
49 
50 
51 int main(const int argc, char *argv[])
52 {
53  string out_basename = argv[0];
54  if (argc > 3) {
55  out_basename = argv[3];
56  }
57 
58  WireCell::ExecMon em(out_basename);
59 
60  //Generate trivial track of points
61  const double stepsize = 0.01*units::mm;
62  Gen::TrackDepos tracks(stepsize);
63 
64  const double t0 = 0.0*units::s;
65  const double event_time = t0 + 1*units::ms;
66  const Point start_vertex(1*units::m, 0*units::m, 0.1*units::mm);
67 
68  // 6 points inbetween an impact pitch
69  for(int i=0; i<6; i++){
70  const Point vertex = start_vertex + Vector(0, 0, i*0.06*units::mm);
71  tracks.add_track(event_time+i*1*units::us,
72  Ray(vertex,
73  vertex + Vector(0, 0, 0.1*stepsize)),
74  -1.0*units::eplus);
75  }
76 
77  em("made tracks");
78 
79  Point field_origin(100*units::mm, 0, 0);
80  const double drift_speed = 1.0*units::mm/units::us;
81  const double nsigma = 3.0;
82  IRandom::pointer fluctuate = nullptr;
83  /// Time/Pitch Gaussian
84  const double sigma_time = 0.0*units::us;
85  const double sigma_pitch = 0.3*units::mm;
86 
87  /// Time bins
88  const double t_sample = 0.5*units::us;
89  const double t_min = event_time - 1*units::s;
90  const double t_max = event_time + 1*units::s;
91  const int nt = (t_max-t_min)/t_sample;
92  const Binning tbins(nt, t_min, t_max);
93 
94  /// Pitch bins
95  const double p_sample = 0.3*units::mm;
96  const double p_min = -10*p_sample;
97  const double p_max = 10*p_sample;
98  const int np = (p_max-p_min)/p_sample;
99  const Binning pbins(np, p_min, p_max);
100 
101 
102  /// output file
103  //TFile* rootfile = TFile::Open(Form("%s.root", out_basename.c_str()), "recreate");
104  TCanvas* canvas = new TCanvas("c","canvas",1000,1000);
105  gStyle->SetOptStat(0);
106  Double_t x[6];
107  Double_t y[6];
108  Double_t xc[6]; // cross check
109  Double_t yc[6];
110 
111  // point charge case, if at right boundary of the bin, in next impact pitch, not shown in the following. Other cases will overwrite.
112  x[5] = 0.3;
113  y[5] = 0;
114  xc[5] = 0.3;
115  yc[5] = 0;
116 
117  // charge distribution
118  TF1 *charge[6];
119 
120  int pcount = 0;
121  int wcount = 0;
122 
123  auto depos = tracks.depos();
124  for(auto depo : depos)
125  {
126  auto drifted = std::make_shared<Gen::TransportedDepo>(depo, field_origin.x(), drift_speed);
127  double center_time = drifted->time();
128  double center_pitch = drifted->pos().z();
129  std::cerr << "depo:"
130  << " q=" << drifted->charge()/units::eplus << "ele"
131  << " time-T0=" << (drifted->time()-t0)/units::us<< "us"
132  << " pt=" << drifted->pos() / units::mm << " mm\n";
133 
134  Gen::GausDesc tdesc(center_time, sigma_time);
135  Gen::GausDesc pdesc(center_pitch, sigma_pitch);
136  if(!sigma_pitch){
137  charge[5 - pcount] = new TF1(Form("charge%d",5-pcount), "1", center_pitch-0.01, center_pitch+0.01);
138  cout<<"hahha"<<endl;
139  }
140  else{
141  charge[5 - pcount] = new TF1(Form("charge%d",5-pcount),"[0]*TMath::Gaus(x, [1], [2], 0)", -0.3, 0.9);
142  charge[5 - pcount]->SetParameters(1, center_pitch, sigma_pitch);
143  charge[5 - pcount]->SetNpx(1000);
144  }
145 
146 
147  Gen::GaussianDiffusion gd(drifted, tdesc, pdesc);
148  gd.set_sampling(tbins, pbins, nsigma, fluctuate);
149 
150  int offsetbin = gd.poffset_bin();
151  cout<<"Offset bin: "<<offsetbin<<std::endl;
152  auto weight = gd.weights();
153  for(unsigned int i=0; i<weight.size(); i++)
154  {
155  if(10-offsetbin-i==0){
156  cout<<"weight "<<i<<" : "<<weight[i]<<endl;
157  double check = WeightGaus(pbins.edge(10), pbins.edge(10)+p_sample, center_pitch, sigma_pitch);
158  cout<<"weight "<<check<<endl;
159  y[5 - pcount] = weight[i];
160  x[5 - pcount] = center_pitch;
161  yc[5 - pcount] = check;
162  xc[5 - pcount] = center_pitch;
163  wcount ++;
164  }
165  }
166  pcount ++;
167  }
168  cout<<"Points: "<<pcount<<endl;
169  cout<<"Weights: "<<wcount<<endl;
170  for(int i=0; i<pcount; i++)
171  {
172  cout<<x[i]<<", "<<y[i]<<endl;
173  }
174 
175  /// Plot
176  TGraph *graph = new TGraph(6, x, y);
177  graph->SetTitle("Gaussian");
178  TGraph *graphc = new TGraph(6, xc, yc);
179  graph->Draw("A*");
180  graph->GetXaxis()->SetLimits(-0.3, 0.9);
181  graph->GetYaxis()->SetRangeUser(0, 1.1);
182  graphc->Fit("pol1");
183  graphc->Draw("* same");
184  graphc->SetMarkerColor(kRed);
185  graphc->SetMarkerStyle(24);
186  graphc->SetMarkerSize(2);
187  TBox bb(0, 0, 0.3, 1.1);
188  bb.SetLineColor(kRed);
189  bb.SetFillColorAlpha(7, 0.4);
190  bb.Draw("same");
191 
192  Int_t color[6] = {2, 4, 6, 8, 9, 1};
193  for(int i=0; i<pcount; i++)
194  {
195  charge[i]->Draw("same");
196  charge[i]->SetLineColor(color[i]);
197  charge[i]->SetLineStyle(kDashed);
198  }
199 
200  canvas->Print(Form("%s-Gaus7.pdf", out_basename.c_str()), "pdf");
201 
202  return 0;
203 
204 }
double WeightGaus(double x1, double x2, double mean, double sigma)
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
static const double m
Definition: Units.h:63
static const double eplus
Definition: Units.h:110
std::shared_ptr< IRandom > pointer
Access subclass facet by pointer.
Definition: IComponent.h:33
void add_track(double time, const WireCell::Ray &ray, double dedx=-1.0)
Definition: TrackDepos.cxx:85
D3Vector< double > Point
A 3D Cartesian point in double precision.
Definition: Point.h:15
const std::vector< double > weights() const
def graph(desc, maker=maker)
Definition: apa.py:294
STL namespace.
void set_sampling(const Binning &tbin, const Binning &pbin, double nsigma=3.0, IRandom::pointer fluctuate=nullptr, unsigned int weightstrat=1)
static const double ms
Definition: Units.h:104
bool check(const std::vector< std::vector< float > > &outputs)
Binning tbins(nticks, t0, t0+readout_time)
A producer of depositions created from some number of simple, linear tracks.
Definition: TrackDepos.h:17
double y
const double t0
int main(const int argc, char *argv[])
int poffset_bin() const
Return the absolute impact bin in the binning corresponding to column 0 of the patch.
WireCell::IDepo::vector depos()
Definition: TrackDepos.cxx:137
const double drift_speed
Point Vector
An alias for Point.
Definition: Point.h:18
static const double mm
Definition: Units.h:55
Definition: Main.h:22
color
Definition: color.h:50
static const double s
Definition: Units.h:103
static const double us
Definition: Units.h:105
list x
Definition: train.py:276
double edge(int ind) const
Definition: Binning.h:99
weight
Definition: test.py:257
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:15
QTextStream & endl(QTextStream &s)
vertex reconstruction