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

#include <Diffuser.h>

Inheritance diagram for WireCell::Diffuser:
WireCell::IDiffuser WireCell::IConfigurable WireCell::IQueuedoutNode< IDepo, IDiffusion > WireCell::IComponent< IConfigurable > WireCell::IQueuedoutNodeBase WireCell::Interface WireCell::INode WireCell::IComponent< INode > WireCell::Interface

Public Types

typedef std::pair< double, double > bounds_type
 
- Public Types inherited from WireCell::IQueuedoutNode< IDepo, IDiffusion >
typedef std::shared_ptr< IQueuedoutNodeBasepointer
 
typedef IDepo input_type
 
typedef IDiffusion output_type
 
typedef std::shared_ptr< const IDepoinput_pointer
 
typedef std::shared_ptr< const IDiffusionoutput_pointer
 
typedef std::deque< output_pointeroutput_queue
 
- Public Types inherited from WireCell::IQueuedoutNodeBase
typedef std::shared_ptr< IQueuedoutNodeBasepointer
 
typedef std::deque< boost::any > queuedany
 
- Public Types inherited from WireCell::INode
enum  NodeCategory {
  unknown, sourceNode, sinkNode, functionNode,
  queuedoutNode, joinNode, splitNode, faninNode,
  fanoutNode, multioutNode, hydraNode
}
 
- Public Types inherited from WireCell::IComponent< INode >
typedef std::shared_ptr< INodepointer
 Access subclass facet by pointer. More...
 
typedef std::vector< pointervector
 Vector of shared pointers. More...
 
- Public Types inherited from WireCell::Interface
typedef std::shared_ptr< Interfacepointer
 
- Public Types inherited from WireCell::IComponent< IConfigurable >
typedef std::shared_ptr< IConfigurablepointer
 Access subclass facet by pointer. More...
 
typedef std::vector< pointervector
 Vector of shared pointers. More...
 

Public Member Functions

 Diffuser (const Ray &pitch=Ray(Point(0.0, 0.0, 0.0), Point(0.0, 0.0, 5 *units::millimeter)), double binsize_l=2.0 *units::millimeter, double time_offset=0.0 *units::microsecond, double origin_l=0.0 *units::microsecond, double DL=5.3 *units::centimeter2/units::second, double DT=12.8 *units::centimeter2/units::second, double drift_velocity=1.6 *units::millimeter/units::microsecond, double max_sigma_l=5 *units::microsecond, double nsigma=3.0)
 
virtual ~Diffuser ()
 
virtual void configure (const WireCell::Configuration &config)
 Accept a configuration. More...
 
virtual WireCell::Configuration default_configuration () const
 Optional, override to return a hard-coded default configuration. More...
 
virtual void reset ()
 
virtual bool operator() (const input_pointer &depo, output_queue &outq)
 The calling signature: More...
 
IDiffusion::pointer diffuse (double mean_l, double mean_t, double sigma_l, double sigma_t, double weight=1.0, IDepo::pointer depo=nullptr)
 
bounds_type bounds (double mean, double sigma, double binsize, double origin=0.0)
 
std::vector< double > oned (double mean, double sigma, double binsize, const Diffuser::bounds_type &bounds)
 
- Public Member Functions inherited from WireCell::IDiffuser
virtual ~IDiffuser ()
 
virtual std::string signature ()
 
- Public Member Functions inherited from WireCell::IQueuedoutNode< IDepo, IDiffusion >
virtual ~IQueuedoutNode ()
 
virtual bool operator() (const boost::any &anyin, queuedany &outanyq)
 The calling signature: More...
 
virtual std::vector< std::stringinput_types ()
 
virtual std::vector< std::stringoutput_types ()
 
- Public Member Functions inherited from WireCell::IQueuedoutNodeBase
virtual ~IQueuedoutNodeBase ()
 
virtual NodeCategory category ()
 Return the behavior category type. More...
 
virtual int concurrency ()
 By default assume all subclasses maintain state. More...
 
- Public Member Functions inherited from WireCell::INode
virtual ~INode ()
 
- Public Member Functions inherited from WireCell::IComponent< INode >
virtual ~IComponent ()
 
- Public Member Functions inherited from WireCell::Interface
virtual ~Interface ()
 
- Public Member Functions inherited from WireCell::IConfigurable
virtual ~IConfigurable ()
 
- Public Member Functions inherited from WireCell::IComponent< IConfigurable >
virtual ~IComponent ()
 

Private Member Functions

void dump (const std::string &msg)
 

Private Attributes

Point m_pitch_origin
 
Vector m_pitch_direction
 
double m_time_offset
 
double m_origin_l
 
double m_origin_t
 
double m_binsize_l
 
double m_binsize_t
 
double m_DL
 
double m_DT
 
double m_drift_velocity
 
double m_max_sigma_l
 
double m_nsigma
 
IDiffusionSet m_input
 
bool m_eos
 

Detailed Description

Model longitudinal and transverse diffusion of drifted charge.

WireCell::IDepo objects are inserted and WireCell::IDiffusion objects are extracted. An internal buffer is kept in order to assure the output is time ordered by the leading edge of the diffusion "patch". Depositions are diffused in place so are assumed to be drifted to whatever location they are wanted. The IDepo::prior() method is used to find the total drift distance.

FIXME: this action is really a compound as it does three things:

1) Projects a deposition position onto wire pitch. 2) Applies arbitrary time offset. 3) Diffuses the deposition.

Definition at line 31 of file Diffuser.h.

Member Typedef Documentation

typedef std::pair<double,double> WireCell::Diffuser::bounds_type

Definition at line 34 of file Diffuser.h.

Constructor & Destructor Documentation

Diffuser::Diffuser ( const Ray pitch = Ray(Point(0.0,0.0,0.0),Point(0.0,0.0,5*units::millimeter)),
double  binsize_l = 2.0*units::millimeter,
double  time_offset = 0.0*units::microsecond,
double  origin_l = 0.0*units::microsecond,
double  DL = 5.3*units::centimeter2/units::second,
double  DT = 12.8*units::centimeter2/units::second,
double  drift_velocity = 1.6*units::millimeter/units::microsecond,
double  max_sigma_l = 5*units::microsecond,
double  nsigma = 3.0 
)

Create a diffuser.

Parameters
pitchgives the wire coordinate system.
lbinsizedefines the grid spacing in the longitudinal direction.
tbinsizedefines the grid spacing in the transverse direction.
lorigindefines a grid line in the longitudinal direction.
torigindefines a grid line in the transverse direction.
DLis the longitudinal diffusion coefficient.
DTis the transverse diffusion coefficient.
drift_velocityis what it sounds like.
max_sigma_lis the largest possible longitudinal diffusion.
nsigmadefines the number of sigma at which to truncate the Gaussian.

Definition at line 20 of file Diffuser.cxx.

29  : m_pitch_origin(pitch.first)
30  , m_pitch_direction(ray_unit(pitch))
31  , m_time_offset(time_offset)
32  , m_origin_l(origin_l)
33  , m_origin_t(0.0) // measure pitch direction from pitch_origin
34  , m_binsize_l(binsize_l)
35  , m_binsize_t(ray_length(pitch))
36  , m_DL(DL)
37  , m_DT(DT)
38  , m_drift_velocity(drift_velocity)
39  , m_max_sigma_l(max_sigma_l)
40  , m_nsigma(nsigma)
41  , m_eos(false)
42 {
43  //dump("Diffuser created");
44 }
Point m_pitch_origin
Definition: Diffuser.h:104
Vector m_pitch_direction
Definition: Diffuser.h:105
double m_time_offset
Definition: Diffuser.h:106
double m_binsize_t
Definition: Diffuser.h:110
double ray_length(const Ray &ray)
Definition: Point.cxx:62
Vector ray_unit(const Ray &ray)
Definition: Point.cxx:71
double m_max_sigma_l
Definition: Diffuser.h:113
double m_drift_velocity
Definition: Diffuser.h:112
double m_binsize_l
Definition: Diffuser.h:109
Diffuser::~Diffuser ( )
virtual

Definition at line 46 of file Diffuser.cxx.

47 {
48 }

Member Function Documentation

Diffuser::bounds_type Diffuser::bounds ( double  mean,
double  sigma,
double  binsize,
double  origin = 0.0 
)

Definition at line 195 of file Diffuser.cxx.

196 {
197  double low = floor( (mean - m_nsigma*sigma - origin) / binsize ) * binsize + origin;
198  double high = ceil( (mean + m_nsigma*sigma - origin) / binsize ) * binsize + origin;
199 
200  return std::make_pair(low, high);
201 }
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:15
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:227
void Diffuser::configure ( const WireCell::Configuration config)
virtual

Accept a configuration.

Implements WireCell::IConfigurable.

Definition at line 70 of file Diffuser.cxx.

71 {
72  m_pitch_origin = get<Point>(cfg, "pitch_origin", m_pitch_origin);
73  m_pitch_direction = get<Point>(cfg, "pitch_direction", m_pitch_direction).norm();
74  m_time_offset = get<double>(cfg, "timeoffset", m_time_offset);
75 
76  m_origin_l = get<double>(cfg, "starttime", m_origin_l);
77  m_origin_t = get<double>(cfg, "origin", m_origin_t);
78 
79  m_binsize_l = get<double>(cfg, "timeslice", m_binsize_l);
80  m_binsize_t = get<double>(cfg, "pitch_distance", m_binsize_t);
81 
82  m_DL = get<double>(cfg, "DL", m_DL);
83  m_DT = get<double>(cfg, "DT", m_DT);
84 
85  m_drift_velocity = get<double>(cfg, "drift_velocity", m_drift_velocity);
86 
87  m_max_sigma_l = get<double>(cfg, "max_sigma_l", m_max_sigma_l);
88  m_nsigma = get<double>(cfg, "nsigma", m_nsigma);
89 
90  //dump("Diffuser configured");
91 }
Point m_pitch_origin
Definition: Diffuser.h:104
cfg
Definition: dbjson.py:29
Vector m_pitch_direction
Definition: Diffuser.h:105
double m_time_offset
Definition: Diffuser.h:106
double m_binsize_t
Definition: Diffuser.h:110
double m_max_sigma_l
Definition: Diffuser.h:113
double m_drift_velocity
Definition: Diffuser.h:112
auto norm(Vector const &v)
Return norm of the specified vector.
double m_binsize_l
Definition: Diffuser.h:109
Configuration Diffuser::default_configuration ( ) const
virtual

Optional, override to return a hard-coded default configuration.

Reimplemented from WireCell::IConfigurable.

Definition at line 50 of file Diffuser.cxx.

51 {
52  stringstream ss;
53  ss << "{\n"
54  << "\"pitch_origin\":{\"x\":0.0,\"y\":0.0,\"z\":0.0},\n"
55  << "\"pitch_direction\":{\"x\":0.0,\"y\":0.0,\"z\":1.0},\n"
56  << "\"pitch_distance\":" << 5.0*units::mm << ",\n"
57  << "\"timeslice\":" << 2.0 * units::us << ",\n"
58  << "\"timeoffset\":0.0,\n"
59  << "\"starttime\":0.0,\n"
60  << "\"origin\":0.0,\n"
61  << "\"DL\":" << 5.3*units::centimeter2/units::second << ",\n"
62  << "\"DT\":"<<12.8*units::centimeter2/units::second <<",\n"
63  << "\"drift_velocity\":" << 1.6 * units::mm/units::us << ",\n"
64  << "\"max_sigma_l\":" << 5.0 * units::us << ",\n"
65  << "\"nsigma\":3.0\n"
66  << "}\n";
67  return Persist::loads(ss.str());
68 }
static const double centimeter2
Definition: Units.h:27
static const double mm
Definition: Units.h:55
static const double second
Definition: Units.h:92
Json::Value loads(const std::string &text, const externalvars_t &extvar=externalvars_t(), const externalvars_t &extcode=externalvars_t())
Definition: Persist.cxx:152
static const double us
Definition: Units.h:105
IDiffusion::pointer Diffuser::diffuse ( double  mean_l,
double  mean_t,
double  sigma_l,
double  sigma_t,
double  weight = 1.0,
IDepo::pointer  depo = nullptr 
)

Diffuse a point charge.

Parameters
mean_lis the position in the longitudinal direction.
mean_tis the position in the transverse direction.
sigma_lis the Gaussian sigma in the longitudinal direction.
sigma_tis the Gaussian sigma in the transverse direction.
weightis the normalization (eg, amount of charge)

This is a mostly internal method. It does not directly fill or drain any internal buffers so can be used to test diffusion directly.

Definition at line 204 of file Diffuser.cxx.

207 {
208  bounds_type bounds_l = bounds(mean_l, sigma_l, m_binsize_l, m_origin_l);
209  bounds_type bounds_t = bounds(mean_t, sigma_t, m_binsize_t, m_origin_t);
210 
211  std::vector<double> l_bins = oned(mean_l, sigma_l, m_binsize_l, bounds_l);
212  std::vector<double> t_bins = oned(mean_t, sigma_t, m_binsize_t, bounds_t);
213 
214  if (l_bins.empty() || t_bins.empty()) {
215  return nullptr;
216  }
217 
218  // get normalization
219  double power = 0;
220  for (auto l : l_bins) {
221  for (auto t : t_bins) {
222  power += l*t;
223  }
224  }
225  if (power == 0.0) {
226  return nullptr;
227  }
228 
229  Diffusion* smear = new Diffusion(depo,
230  l_bins.size(), t_bins.size(),
231  bounds_l.first, bounds_t.first,
232  bounds_l.second, bounds_t.second);
233 
234  for (size_t ind_l = 0; ind_l < l_bins.size(); ++ind_l) {
235  for (size_t ind_t = 0; ind_t < t_bins.size(); ++ind_t) {
236  double value = l_bins[ind_l]*t_bins[ind_t]/power*weight;
237  smear->set(ind_l, ind_t, value);
238  }
239  }
240 
241  IDiffusion::pointer ret(smear);
242  return ret;
243 }
std::shared_ptr< const IDiffusion > pointer
Definition: IData.h:19
virtual double set(int lind, int tind, double value)
Definition: Diffusion.cxx:56
static QStrList * l
Definition: config.cpp:1044
std::vector< double > oned(double mean, double sigma, double binsize, const Diffuser::bounds_type &bounds)
Definition: Diffuser.cxx:173
double m_binsize_t
Definition: Diffuser.h:110
std::pair< double, double > bounds_type
Definition: Diffuser.h:34
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1225
bounds_type bounds(double mean, double sigma, double binsize, double origin=0.0)
Definition: Diffuser.cxx:195
weight
Definition: test.py:257
double m_binsize_l
Definition: Diffuser.h:109
void Diffuser::dump ( const std::string msg)
private

Definition at line 98 of file Diffuser.cxx.

99 {
100  stringstream ss;
101  ss << msg << endl
102  << "\tpitch origin " << m_pitch_origin << endl
103  << "\tpitch direction " << m_pitch_direction << endl
104  << "\ttime offset " << m_time_offset << endl
105  << "\torigin l " << m_origin_l << endl
106  << "\torigin t " << m_origin_t << endl
107  << "\tbinsize l " << m_binsize_l << endl
108  << "\tbinsize t " << m_binsize_t << endl
109  << "\tDL = " << m_DL << " DT = " << m_DT << endl
110  << "\tdrift velocity = " << m_drift_velocity << endl
111  << "\tmax sigma l = " << m_max_sigma_l << endl
112  << "\tnsigma = " << m_nsigma;
113  cerr << ss.str() << endl;;
114 }
void msg(const char *fmt,...)
Definition: message.cpp:107
Point m_pitch_origin
Definition: Diffuser.h:104
Vector m_pitch_direction
Definition: Diffuser.h:105
double m_time_offset
Definition: Diffuser.h:106
double m_binsize_t
Definition: Diffuser.h:110
double m_max_sigma_l
Definition: Diffuser.h:113
double m_drift_velocity
Definition: Diffuser.h:112
double m_binsize_l
Definition: Diffuser.h:109
QTextStream & endl(QTextStream &s)
std::vector< double > Diffuser::oned ( double  mean,
double  sigma,
double  binsize,
const Diffuser::bounds_type bounds 
)

fragment between bin_edge_{low,high}

Definition at line 173 of file Diffuser.cxx.

175 {
176  int nbins = round((bounds.second - bounds.first)/binsize);
177 
178  /// fragment between bin_edge_{low,high}
179  std::vector<double> integral(nbins+1, 0.0);
180  for (int ibin=0; ibin <= nbins; ++ibin) {
181  double absx = bounds.first + ibin*binsize;
182  double t = 0.5*(absx-mean)/sigma;
183  double e = 0.5*std::erf(t);
184  integral[ibin] = e;
185  }
186 
187  std::vector<double> bins;
188  for (int ibin=0; ibin<nbins; ++ibin) {
189  bins.push_back(integral[ibin+1] - integral[ibin]);
190  }
191  return bins;
192 }
const double e
bounds_type bounds(double mean, double sigma, double binsize, double origin=0.0)
Definition: Diffuser.cxx:195
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:15
bool Diffuser::operator() ( const input_pointer in,
output_queue outq 
)
virtual

The calling signature:

Implements WireCell::IQueuedoutNode< IDepo, IDiffusion >.

Definition at line 117 of file Diffuser.cxx.

118 {
119  if (m_eos) {
120  return false;
121  }
122  if (!depo) { // EOS flush
123  for (auto diff : m_input) {
124  outq.push_back(diff);
125  }
126  outq.push_back(nullptr);
127  m_eos = true;
128  return true;
129  }
130 
131  auto first = *depo_chain(depo).rbegin();
132  const double drift_distance = first->pos().x() - depo->pos().x();
133  const double drift_time = drift_distance / m_drift_velocity;
134 
135  const double tmpcm2 = 2*m_DL*drift_time/units::centimeter2;
136  const double sigmaL = sqrt(tmpcm2)*units::centimeter / m_drift_velocity;
137  const double sigmaT = sqrt(2*m_DT*drift_time/units::centimeter2)*units::centimeter2;
138 
139  const Vector to_depo = depo->pos() - m_pitch_origin;
140  const double pitch_distance = m_pitch_direction.dot(to_depo);
141 
142  cerr << "Diffuser: "
143  << " drift distance=" << drift_distance
144  << " drift time=" << drift_time
145  << " pitch distance = " << pitch_distance
146  << endl;
147 
148  IDiffusion::pointer diff = this->diffuse(m_time_offset + depo->time(), pitch_distance,
149  sigmaL, sigmaT, depo->charge(), depo);
150  m_input.insert(diff);
151 
152  while (m_input.size() > 2) {
153  auto first = *m_input.begin();
154  auto last = *m_input.rbegin();
155  const double last_center = 0.5*(last->lend() + last->lbegin());
156  if (last_center - first->lbegin() < m_max_sigma_l*m_nsigma) {
157  break; // new input with long diffusion may still take lead
158  }
159 
160  // now we are guaranteed no newly added diffusion can have a
161  // leading edge long enough to surpass that of the current
162  // leader.
163  outq.push_back(first);
164  m_input.erase(first);
165  }
166 
167  return true;
168 }
std::shared_ptr< const IDiffusion > pointer
Definition: IData.h:19
IDepo::vector depo_chain(IDepo::pointer recent)
Definition: IDepo.cxx:4
IDiffusion::pointer diffuse(double mean_l, double mean_t, double sigma_l, double sigma_t, double weight=1.0, IDepo::pointer depo=nullptr)
Definition: Diffuser.cxx:204
Point m_pitch_origin
Definition: Diffuser.h:104
IDiffusionSet m_input
Definition: Diffuser.h:116
Vector m_pitch_direction
Definition: Diffuser.h:105
static const double centimeter
Definition: Units.h:26
double m_time_offset
Definition: Diffuser.h:106
static const double centimeter2
Definition: Units.h:27
double m_max_sigma_l
Definition: Diffuser.h:113
double m_drift_velocity
Definition: Diffuser.h:112
std::vector< float > Vector
T dot(const D3Vector &rhs) const
Return the dot product of this vector and the other.
Definition: D3Vector.h:80
QTextStream & endl(QTextStream &s)
void Diffuser::reset ( void  )
virtual

Optional hook to be implemented in order to reset after an end of stream is encountered. Fixme: this should be removed.

Reimplemented from WireCell::INode.

Definition at line 93 of file Diffuser.cxx.

94 {
95  m_input.clear();
96 }
IDiffusionSet m_input
Definition: Diffuser.h:116

Member Data Documentation

double WireCell::Diffuser::m_binsize_l
private

Definition at line 109 of file Diffuser.h.

double WireCell::Diffuser::m_binsize_t
private

Definition at line 110 of file Diffuser.h.

double WireCell::Diffuser::m_DL
private

Definition at line 111 of file Diffuser.h.

double WireCell::Diffuser::m_drift_velocity
private

Definition at line 112 of file Diffuser.h.

double WireCell::Diffuser::m_DT
private

Definition at line 111 of file Diffuser.h.

bool WireCell::Diffuser::m_eos
private

Definition at line 118 of file Diffuser.h.

IDiffusionSet WireCell::Diffuser::m_input
private

Definition at line 116 of file Diffuser.h.

double WireCell::Diffuser::m_max_sigma_l
private

Definition at line 113 of file Diffuser.h.

double WireCell::Diffuser::m_nsigma
private

Definition at line 114 of file Diffuser.h.

double WireCell::Diffuser::m_origin_l
private

Definition at line 107 of file Diffuser.h.

double WireCell::Diffuser::m_origin_t
private

Definition at line 108 of file Diffuser.h.

Vector WireCell::Diffuser::m_pitch_direction
private

Definition at line 105 of file Diffuser.h.

Point WireCell::Diffuser::m_pitch_origin
private

Definition at line 104 of file Diffuser.h.

double WireCell::Diffuser::m_time_offset
private

Definition at line 106 of file Diffuser.h.


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