BinnedDiffusion.cxx
Go to the documentation of this file.
3 #include "WireCellUtil/Units.h"
4 
5 #include <iostream> // debug
6 using namespace std;
7 
8 using namespace WireCell;
9 
10 
11 Gen::BinnedDiffusion::BinnedDiffusion(const Pimpos& pimpos, const Binning& tbins,
12  double nsigma, IRandom::pointer fluctuate,
14  : m_pimpos(pimpos)
15  , m_tbins(tbins)
16  , m_nsigma(nsigma)
17  , m_fluctuate(fluctuate)
18  , m_calcstrat(calcstrat)
19  , m_window(0,0)
20  , m_outside_pitch(0)
21  , m_outside_time(0)
22 {
23 }
24 
25 bool Gen::BinnedDiffusion::add(IDepo::pointer depo, double sigma_time, double sigma_pitch)
26 {
27 
28  const double center_time = depo->time();
29  const double center_pitch = m_pimpos.distance(depo->pos());
30 
31  Gen::GausDesc time_desc(center_time, sigma_time);
32  {
33  double nmin_sigma = time_desc.distance(m_tbins.min());
34  double nmax_sigma = time_desc.distance(m_tbins.max());
35 
36  double eff_nsigma = sigma_time>0?m_nsigma:0;
37  if (nmin_sigma > eff_nsigma || nmax_sigma < -eff_nsigma) {
38  // std::cerr << "BinnedDiffusion: depo too far away in time sigma:"
39  // << " t_depo=" << center_time/units::ms << "ms not in:"
40  // << " t_bounds=[" << m_tbins.min()/units::ms << ","
41  // << m_tbins.max()/units::ms << "]ms"
42  // << " in Nsigma: [" << nmin_sigma << "," << nmax_sigma << "]\n";
44  return false;
45  }
46  }
47 
48  auto ibins = m_pimpos.impact_binning();
49 
50  Gen::GausDesc pitch_desc(center_pitch, sigma_pitch);
51  {
52  double nmin_sigma = pitch_desc.distance(ibins.min());
53  double nmax_sigma = pitch_desc.distance(ibins.max());
54 
55  double eff_nsigma = sigma_pitch>0?m_nsigma:0;
56  if (nmin_sigma > eff_nsigma || nmax_sigma < -eff_nsigma) {
57  // std::cerr << "BinnedDiffusion: depo too far away in pitch sigma: "
58  // << " p_depo=" << center_pitch/units::cm << "cm not in:"
59  // << " p_bounds=[" << ibins.min()/units::cm << ","
60  // << ibins.max()/units::cm << "]cm"
61  // << " in Nsigma:[" << nmin_sigma << "," << nmax_sigma << "]\n";
63  return false;
64  }
65  }
66 
67  // make GD and add to all covered impacts
68  int bin_beg = std::max(ibins.bin(center_pitch - sigma_pitch*m_nsigma), 0);
69  int bin_end = std::min(ibins.bin(center_pitch + sigma_pitch*m_nsigma)+1, ibins.nbins());
70  // debug
71  //int bin_center = ibins.bin(center_pitch);
72  //cerr << "DEBUG center_pitch: "<<center_pitch/units::cm<<endl;
73  //cerr << "DEBUG bin_center: "<<bin_center<<endl;
74 
75  auto gd = std::make_shared<GaussianDiffusion>(depo, time_desc, pitch_desc);
76  for (int bin = bin_beg; bin < bin_end; ++bin) {
77  // if (bin == bin_beg) m_diffs.insert(gd);
78  this->add(gd, bin);
79  }
80 
81  return true;
82 }
83 
84 void Gen::BinnedDiffusion::add(std::shared_ptr<GaussianDiffusion> gd, int bin)
85 {
86  ImpactData::mutable_pointer idptr = nullptr;
87  auto it = m_impacts.find(bin);
88  if (it == m_impacts.end()) {
89  idptr = std::make_shared<ImpactData>(bin);
90  m_impacts[bin] = idptr;
91  }
92  else {
93  idptr = it->second;
94  }
95  idptr->add(gd);
96  if (false) { // debug
97  auto mm = idptr->span();
98  cerr << "Gen::BinnedDiffusion: add: "
99  << " poffoset="<<gd->poffset_bin()
100  << " toffoset="<<gd->toffset_bin()
101  << " charge=" << gd->depo()->charge()/units::eplus << " eles"
102  <<", for bin " << bin << " t=[" << mm.first/units::us << "," << mm.second/units::us << "]us\n";
103  }
104  m_diffs.insert(gd);
105  //m_diffs.push_back(gd);
106 }
107 
108 void Gen::BinnedDiffusion::erase(int begin_impact_number, int end_impact_number)
109 {
110  for (int bin=begin_impact_number; bin<end_impact_number; ++bin) {
111  m_impacts.erase(bin);
112  }
113 }
114 
115 
117 {
118  const auto ib = m_pimpos.impact_binning();
119  if (! ib.inbounds(bin)) {
120  return nullptr;
121  }
122 
123  auto it = m_impacts.find(bin);
124  if (it == m_impacts.end()) {
125  return nullptr;
126  }
127  auto idptr = it->second;
128 
129  // make sure all diffusions have been sampled
130  for (auto diff : idptr->diffusions()) {
131  diff->set_sampling(m_tbins, ib, m_nsigma, m_fluctuate, m_calcstrat);
132  //diff->set_sampling(m_tbins, ib, m_nsigma, 0, m_calcstrat);
133  }
134 
135  idptr->calculate(m_tbins.nbins());
136  return idptr;
137 }
138 
139 
140 static
141 std::pair<double,double> gausdesc_range(const std::vector<Gen::GausDesc> gds, double nsigma)
142 {
143  int ncount = -1;
144  double vmin=0, vmax=0;
145  for (auto gd : gds) {
146  ++ncount;
147 
148  const double lvmin = gd.center - gd.sigma*nsigma;
149  const double lvmax = gd.center + gd.sigma*nsigma;
150  if (!ncount) {
151  vmin = lvmin;
152  vmax = lvmax;
153  continue;
154  }
155  vmin = std::min(vmin, lvmin);
156  vmax = std::max(vmax, lvmax);
157  }
158  return std::make_pair(vmin,vmax);
159 }
160 
161 std::pair<double,double> Gen::BinnedDiffusion::pitch_range(double nsigma) const
162 {
163  std::vector<Gen::GausDesc> gds;
164  for (auto diff : m_diffs) {
165  gds.push_back(diff->pitch_desc());
166  }
167  return gausdesc_range(gds, nsigma);
168 }
169 
170 std::pair<int,int> Gen::BinnedDiffusion::impact_bin_range(double nsigma) const
171 {
172  const auto ibins = m_pimpos.impact_binning();
173  auto mm = pitch_range(nsigma);
174  return std::make_pair(std::max(ibins.bin(mm.first), 0),
175  std::min(ibins.bin(mm.second)+1, ibins.nbins()));
176 }
177 
178 std::pair<double,double> Gen::BinnedDiffusion::time_range(double nsigma) const
179 {
180  std::vector<Gen::GausDesc> gds;
181  for (auto diff : m_diffs) {
182  gds.push_back(diff->time_desc());
183  }
184  return gausdesc_range(gds, nsigma);
185 }
186 
187 std::pair<int,int> Gen::BinnedDiffusion::time_bin_range(double nsigma) const
188 {
189  auto mm = time_range(nsigma);
190  return std::make_pair(std::max(m_tbins.bin(mm.first),0),
191  std::min(m_tbins.bin(mm.second)+1, m_tbins.nbins()));
192 }
193 
std::shared_ptr< const IDepo > pointer
Definition: IData.h:19
double distance(double x)
Return the distance in number of sigma that x is from the center.
static const double eplus
Definition: Units.h:110
ImpactDataCalculationStrategy
Useful to client code to mark a calculation strategy.
bool add(IDepo::pointer deposition, double sigma_time, double sigma_pitch)
double distance(const Point &pt, int axis=2) const
Definition: Pimpos.cxx:71
STL namespace.
std::pair< double, double > pitch_range(double nsigma=0.0) const
void erase(int begin_impact_index, int end_impact_index)
double max() const
Definition: Binning.h:52
Binning tbins(nticks, t0, t0+readout_time)
const Binning & impact_binning() const
Definition: Pimpos.h:113
int bin(double val) const
Definition: Binning.h:80
static std::pair< double, double > gausdesc_range(const std::vector< Gen::GausDesc > gds, double nsigma)
double min() const
Definition: Binning.h:47
std::shared_ptr< Interface > pointer
Definition: Interface.h:16
ImpactDataCalculationStrategy m_calcstrat
static int max(int a, int b)
static const double mm
Definition: Units.h:73
ImpactData::pointer impact_data(int bin) const
Definition: Main.h:22
std::shared_ptr< const ImpactData > pointer
Definition: ImpactData.h:30
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)
Pitch-Impact-Position.
Definition: Pimpos.h:36
QTextStream & bin(QTextStream &s)
static const double us
Definition: Units.h:105
std::set< std::shared_ptr< GaussianDiffusion > > m_diffs
std::pair< double, double > time_range(double nsigma=0.0) const
std::shared_ptr< ImpactData > mutable_pointer
Definition: ImpactData.h:29
std::map< int, ImpactData::mutable_pointer > m_impacts
std::pair< int, int > impact_bin_range(double nsigma=0.0) const
int nbins() const
Definition: Binning.h:42
std::pair< int, int > time_bin_range(double nsigma=0.0) const