Public Types | Public Member Functions | Private Attributes | List of all members
WireCell::Gen::GaussianDiffusion Class Reference

#include <GaussianDiffusion.h>

Public Types

typedef std::shared_ptr< GaussianDiffusionpointer
 
typedef Array::array_xxf patch_t
 

Public Member Functions

 GaussianDiffusion (const IDepo::pointer &depo, const GausDesc &time_desc, const GausDesc &pitch_desc)
 GaussianDiffusion. More...
 
void set_sampling (const Binning &tbin, const Binning &pbin, double nsigma=3.0, IRandom::pointer fluctuate=nullptr, unsigned int weightstrat=1)
 
void clear_sampling ()
 
const patch_tpatch () const
 
const std::vector< double > weights () const
 
int toffset_bin () const
 Return the absolute time bin in the binning corresponding to column 0 of the patch. More...
 
int poffset_bin () const
 Return the absolute impact bin in the binning corresponding to column 0 of the patch. More...
 
IDepo::pointer depo () const
 Access deposition. More...
 
double depo_time () const
 
double depo_x () const
 
const GausDesc pitch_desc ()
 
const GausDesc time_desc ()
 

Private Attributes

IDepo::pointer m_deposition
 
GausDesc m_time_desc
 
GausDesc m_pitch_desc
 
patch_t m_patch
 
std::vector< double > m_qweights
 
int m_toffset_bin
 
int m_poffset_bin
 

Detailed Description

Definition at line 68 of file GaussianDiffusion.h.

Member Typedef Documentation

A patch is a 2D array of diffuse charge in (nimpacts X nticks) bins. patch[0] is drifted/diffused charge waveform at impact position 0 (relative to min pitch for the patch). patch[0][0] is charge at this impact position at time = 0 (relative to min time for the patch). See bin().

Definition at line 80 of file GaussianDiffusion.h.

Definition at line 71 of file GaussianDiffusion.h.

Constructor & Destructor Documentation

Gen::GaussianDiffusion::GaussianDiffusion ( const IDepo::pointer depo,
const GausDesc time_desc,
const GausDesc pitch_desc 
)

Member Function Documentation

void Gen::GaussianDiffusion::clear_sampling ( )

Definition at line 238 of file GaussianDiffusion.cxx.

238  {
239  m_patch.resize(0,0);
240  m_qweights.clear();
241  m_qweights.shrink_to_fit();
242 }
IDepo::pointer WireCell::Gen::GaussianDiffusion::depo ( ) const
inline

Access deposition.

Definition at line 119 of file GaussianDiffusion.h.

119 { return m_deposition; }
double WireCell::Gen::GaussianDiffusion::depo_time ( ) const
inline

Definition at line 121 of file GaussianDiffusion.h.

121 { return m_deposition->time();}
double WireCell::Gen::GaussianDiffusion::depo_x ( ) const
inline

Definition at line 122 of file GaussianDiffusion.h.

122 { return m_deposition->pos().x();}
const Gen::GaussianDiffusion::patch_t & Gen::GaussianDiffusion::patch ( ) const

Get the diffusion patch as an array of N_pitch rows X N_time columns. Index as patch(i_pitch, i_time). Call set_sampling() first.

Definition at line 246 of file GaussianDiffusion.cxx.

247 {
248  return m_patch;
249 }
const GausDesc WireCell::Gen::GaussianDiffusion::pitch_desc ( )
inline

Definition at line 124 of file GaussianDiffusion.h.

int WireCell::Gen::GaussianDiffusion::poffset_bin ( ) const
inline

Return the absolute impact bin in the binning corresponding to column 0 of the patch.

Definition at line 116 of file GaussianDiffusion.h.

void Gen::GaussianDiffusion::set_sampling ( const Binning tbin,
const Binning pbin,
double  nsigma = 3.0,
IRandom::pointer  fluctuate = nullptr,
unsigned int  weightstrat = 1 
)

This fills the patch once matching the given time and pitch binning. The patch is limited to the 2D sample points that cover the subdomain determined by the number of sigma. If there should be Poisson fluctuations applied pass in an IRandom. Total charge is charge is preserved. Each cell of the patch represents the 2D bin-centered sampling of the Gaussian.

Sample time dimension

Sample pitch dimension.

fixme: for hanyu.

Definition at line 124 of file GaussianDiffusion.cxx.

129 {
130  if (m_patch.size() > 0) {
131  return;
132  }
133 
134  /// Sample time dimension
135  auto tval_range = m_time_desc.sigma_range(nsigma);
136  auto tbin_range = tbin.sample_bin_range(tval_range.first, tval_range.second);
137  const size_t ntss = tbin_range.second - tbin_range.first;
138  m_toffset_bin = tbin_range.first;
139  //auto tvec = m_time_desc.sample(tbin.center(m_toffset_bin), tbin.binsize(), ntss);
140  auto tvec = m_time_desc.binint(tbin.edge(m_toffset_bin), tbin.binsize(), ntss);
141 
142  if (!ntss) {
143  cerr << "Gen::GaussianDiffusion: no time bins for [" << tval_range.first/units::us << "," << tval_range.second/units::us << "] us\n";
144  return;
145  }
146 
147  /// Sample pitch dimension.
148  auto pval_range = m_pitch_desc.sigma_range(nsigma);
149  auto pbin_range = pbin.sample_bin_range(pval_range.first, pval_range.second);
150  const size_t npss = pbin_range.second - pbin_range.first;
151  m_poffset_bin = pbin_range.first;
152  //auto pvec = m_pitch_desc.sample(pbin.center(m_poffset_bin), pbin.binsize(), npss);
153  auto pvec = m_pitch_desc.binint(pbin.edge(m_poffset_bin), pbin.binsize(), npss);
154 
155 
156  if (!npss) {
157  cerr << "No impact bins [" << pval_range.first/units::mm << "," << pval_range.second/units::mm << "] mm\n";
158  return;
159  }
160 
161  // weightstrat = 1;
162 
163  // make charge weights for later interpolation.
164  /// fixme: for hanyu.
165  if(weightstrat == 2){
166  auto wvec = m_pitch_desc.weight(pbin.edge(m_poffset_bin), pbin.binsize(), npss, pvec);
167  m_qweights = wvec;
168  }
169  if(weightstrat == 1){
170  m_qweights.resize(npss, 0.5);
171  }
172 
173  // start making the time vs impact patch of charge.
174  patch_t ret = patch_t::Zero(npss, ntss);
175  double raw_sum=0.0;
176 
177  // Convolve the two independent Gaussians
178  for (size_t ip = 0; ip < npss; ++ip) {
179  for (size_t it = 0; it < ntss; ++it) {
180  const double val = pvec[ip]*tvec[it];
181  raw_sum += val;
182  ret(ip,it) = (float)val;
183  }
184  }
185 
186  // normalize to total charge
187  ret *= m_deposition->charge() / raw_sum;
188 
189  const double charge_sign = m_deposition->charge() < 0 ? -1 : 1;
190 
191  double fluc_sum = 0;
192  if (fluctuate) {
193  double unfluc_sum = 0;
194 
195  for (size_t ip = 0; ip < npss; ++ip) {
196  for (size_t it = 0; it < ntss; ++it) {
197  const float oldval = ret(ip,it);
198  unfluc_sum += oldval;
199  // should be a multinomial distribution, n_i follows binomial distribution
200  // but n_i, n_j has covariance -n_tot * p_i * p_j
201  // normalize later to approximate this multinomial distribution (how precise?)
202  // how precise? better than poisson and 10000 total charge corresponds to a <1% level error.
203  float number = fluctuate->binomial((int)(std::abs(m_deposition->charge())), oldval/m_deposition->charge());
204  //the charge should be netagive -- ionization electrons
205  fluc_sum += charge_sign*number;
206  ret(ip,it) = charge_sign*number;
207  }
208  }
209  if (fluc_sum == 0) {
210  // cerr << "No net charge after fluctuation. Total unfluctuated = "
211  // << unfluc_sum
212  // << " Qdepo = " << m_deposition->charge()
213  // << endl;
214  return;
215  }
216  else {
217  ret *= m_deposition->charge() / fluc_sum;
218  }
219  }
220 
221 
222  { // debugging
223  //double retsum=0.0;
224  //for (size_t ip = 0; ip < npss; ++ip) {
225  // for (size_t it = 0; it < ntss; ++it) {
226  // retsum += ret(ip,it);
227  // }
228  //}
229  // cerr << "GaussianDiffusion: Q in electrons: depo=" << m_deposition->charge()/units::eplus
230  // << " rawsum=" << raw_sum/units::eplus << " flucsum=" << fluc_sum/units::eplus
231  // << " returned=" << retsum/units::eplus << endl;
232  }
233 
234 
235  m_patch = ret;
236 }
std::vector< double > binint(double start, double step, int nbins) const
double binsize() const
Definition: Binning.h:73
std::vector< double > weight(double start, double step, int nbins, std::vector< double > pvec) const
T abs(T value)
std::pair< double, double > sigma_range(double nsigma=3.0)
std::pair< int, int > tbin_range(const ITrace::vector &traces)
Definition: FrameTools.cxx:143
static const double mm
Definition: Units.h:55
static const double us
Definition: Units.h:105
double edge(int ind) const
Definition: Binning.h:99
std::pair< int, int > sample_bin_range(double minval, double maxval) const
Definition: Binning.h:116
const GausDesc WireCell::Gen::GaussianDiffusion::time_desc ( )
inline

Definition at line 125 of file GaussianDiffusion.h.

int WireCell::Gen::GaussianDiffusion::toffset_bin ( ) const
inline

Return the absolute time bin in the binning corresponding to column 0 of the patch.

Definition at line 113 of file GaussianDiffusion.h.

const std::vector< double > Gen::GaussianDiffusion::weights ( ) const

Definition at line 251 of file GaussianDiffusion.cxx.

252 {
253  return m_qweights;
254 }

Member Data Documentation

IDepo::pointer WireCell::Gen::GaussianDiffusion::m_deposition
private

Definition at line 129 of file GaussianDiffusion.h.

patch_t WireCell::Gen::GaussianDiffusion::m_patch
private

Definition at line 133 of file GaussianDiffusion.h.

GausDesc WireCell::Gen::GaussianDiffusion::m_pitch_desc
private

Definition at line 131 of file GaussianDiffusion.h.

int WireCell::Gen::GaussianDiffusion::m_poffset_bin
private

Definition at line 137 of file GaussianDiffusion.h.

std::vector<double> WireCell::Gen::GaussianDiffusion::m_qweights
private

Definition at line 134 of file GaussianDiffusion.h.

GausDesc WireCell::Gen::GaussianDiffusion::m_time_desc
private

Definition at line 131 of file GaussianDiffusion.h.

int WireCell::Gen::GaussianDiffusion::m_toffset_bin
private

Definition at line 136 of file GaussianDiffusion.h.


The documentation for this class was generated from the following files: