BlipSource.cxx
Go to the documentation of this file.
5 
6 
7 #include <iostream>
8 
11 
12 using namespace WireCell;
13 
15  : m_rng_tn("Random")
16  , m_time(0.0)
17  , m_ene(nullptr)
18  , m_tim(nullptr)
19  , m_pos(nullptr)
20  , m_blip_count(0)
21  , m_eos(false)
22 {
23 }
24 
25 Gen::BlipSource::~BlipSource()
26 {
27  delete m_ene; m_ene = nullptr;
28  delete m_tim; m_tim = nullptr;
29  delete m_pos; m_pos = nullptr;
30 }
31 
32 
33 
34 WireCell::Configuration Gen::BlipSource::default_configuration() const
35 {
37  cfg["rng"] = "Random";
38 
39  Configuration ene;
40  ene["type"] = "mono"; // future: spectrum, uniform, Ar39
41  ene["value"] = 20000.0;
42  cfg["charge"] = ene;
43  // also, in Jsonnet can support PDFs giving probability for certain number of electrons
44  // { type="pdf",
45  // edges=[(0.1+b*0.1)*wc.MeV for b in std.range(0,10)], // energy edges
46  // pdf=[my_pdf_function(self.edges)]}
47 
48 
49  Configuration tim;
50  tim["type"] = "decay";
51  tim["start"] = 0.0;
52  tim["stop"] = 10.0*units::ms;
53  tim["activity"] = 100000*units::Bq; // Ar39 in 2 DUNE drift volumes
54  cfg["time"] = tim;
55 
57  pos["type"] = "box";
58  Configuration tail, head, extent;
59  tail["x"] = -1*units::m; tail["y"] = -1*units::m; tail["z"] = -1*units::m;
60  head["x"] = +1*units::m; head["y"] = +1*units::m; head["z"] = +1*units::m;
61  extent["tail"] = tail; extent["head"] = head;
62  pos["extent"] = extent;
63 
64  cfg["position"] = pos;
65 
66  return cfg;
67 
68 }
69 
70 // Simply return the number given
71 struct ReturnValue : public Gen::BlipSource::ScalarMaker {
72  double value;
73  ReturnValue(double val) : value(val) {}
75  double operator()() { return value; }
76 };
77 // Choose scalar value from an exponential distribution
78 struct DecayTime : public Gen::BlipSource::ScalarMaker {
80  double rate;
81  DecayTime(IRandom::pointer rng, double rate) : rng(rng), rate(rate) {}
83  double operator()() { return rng->exponential(rate); }
84 };
85 // draw from a PDF
86 struct Pdf : public Gen::BlipSource::ScalarMaker {
88  std::vector<double> cumulative;
89  std::vector<double> edges;
90  double total;
91  Pdf(IRandom::pointer rng, const std::vector<double>& pdf, const std::vector<double>& edges)
92  : rng(rng), edges(edges.begin(), edges.end()) {
93  total = 0.0;
94  cumulative.push_back(0.0);
95  for (double val : pdf) {
96  total += val;
97  cumulative.push_back(total);
98  }
99  }
100  double operator()() {
101  double cp = rng->uniform(0.0, total);
102  for (size_t ind=1; ind<cumulative.size(); ++ind) { // start at 2nd element
103  if (cumulative[ind] >= cp) {
104  double rel = (cp - cumulative[ind-1]) / (cumulative[ind]-cumulative[ind-1]);
105  return edges[ind-1] + rel*(edges[ind] - edges[ind-1]);
106  }
107  }
108  return -1; // should not happen
109  }
110 };
111 
112 // return point selected uniformly from some box
113 struct UniformBox : public Gen::BlipSource::PointMaker {
116  UniformBox(IRandom::pointer rng, const Ray& extent) : rng(rng), extent(extent) {}
119  auto p = Point(
120  rng->uniform(extent.first.x(), extent.second.x()),
121  rng->uniform(extent.first.y(), extent.second.y()),
122  rng->uniform(extent.first.z(), extent.second.z()));
123  //std::cerr << "UniformBox: pt=" << p << std::endl;
124  return p;
125  }
126 };
127 
129 {
130  m_rng_tn = get(cfg, "rng", m_rng_tn);
131  m_rng = Factory::find_tn<IRandom>(m_rng_tn);
132 
133  auto ene = cfg["charge"];
134  if (ene["type"].asString() == "mono") {
135  m_ene = new ReturnValue(ene["value"].asDouble());
136  }
137  else if (ene["type"].asString() == "pdf") {
138  m_ene = new Pdf(m_rng, get< std::vector<double> >(ene, "pdf"), get< std::vector<double> >(ene, "edges"));
139  }
140  else {
141  std::cerr <<"BlipSource: no charge configuration\n";
142  THROW(ValueError() << errmsg{"BlipSource: no charge configuration"});
143  }
144 
145  auto tim = cfg["time"];
146  m_time = tim["start"].asDouble();
147  m_stop = tim["stop"].asDouble();
148  if (tim["type"].asString() == "decay") {
149  m_tim = new DecayTime(m_rng, tim["activity"].asDouble());
150  }
151  else {
152  std::cerr <<"BlipSource: no time configuration\n";
153  THROW(ValueError() << errmsg{"BlipSource: no time configuration"});
154  }
155 
156  auto pos = cfg["position"];
157  if (pos["type"].asString() == "box") {
158  Ray box = WireCell::convert<Ray>(pos["extent"]);
159  std::cerr << "Box: \n\t" << box.first/units::mm << "mm\n\t" << box.second/units::mm << "mm\n";
160  m_pos = new UniformBox(m_rng, box);
161  }
162  else {
163  std::cerr <<"BlipSource: no position configuration\n";
164  THROW(ValueError() << errmsg{"BlipSource: no position configuration"});
165  }
166 }
167 
168 bool Gen::BlipSource::operator()(IDepo::pointer& depo)
169 {
170  if (m_eos) {
171  return false;
172  }
173 
174  m_time += (*m_tim)();
175  if (m_time > m_stop) {
176  std::cerr <<"BlipSource: reached stop time: "
177  << m_time/units::ms << " > " << m_stop/units::ms << std::endl;
178  depo = nullptr;
179  m_eos = true;
180  return true;
181  }
182  ++m_blip_count;
183  depo = std::make_shared<SimpleDepo>(m_time, (*m_pos)(), (*m_ene)(),
184  nullptr, 0, 0, m_blip_count);
185  return true;
186 }
double operator()()
Definition: BlipSource.cxx:75
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:79
std::shared_ptr< const IDepo > pointer
Definition: IData.h:19
double value
Definition: BlipSource.cxx:72
UniformBox(IRandom::pointer rng, const Ray &extent)
Definition: BlipSource.cxx:116
double operator()()
Definition: BlipSource.cxx:100
double operator()()
Definition: BlipSource.cxx:83
boost::error_info< struct tag_errmsg, std::string > errmsg
Definition: Exceptions.h:54
double rate
Definition: BlipSource.cxx:80
cfg
Definition: dbjson.py:29
std::vector< double > cumulative
Definition: BlipSource.cxx:88
std::vector< double > edges
Definition: BlipSource.cxx:89
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:72
def configure(cfg)
Definition: cuda.py:34
double total
Definition: BlipSource.cxx:90
std::tuple< double, double, const reco::ClusterHit3D * > Point
Definitions used by the VoronoiDiagram algorithm.
Definition: DCEL.h:34
Pdf(IRandom::pointer rng, const std::vector< double > &pdf, const std::vector< double > &edges)
Definition: BlipSource.cxx:91
#define THROW(e)
Definition: Exceptions.h:25
IRandom::pointer rng
Definition: BlipSource.cxx:87
Point operator()()
Definition: BlipSource.cxx:118
Thrown when a wrong value has been encountered.
Definition: Exceptions.h:37
static const double mm
Definition: Units.h:73
Definition: Main.h:22
ReturnValue(double val)
Definition: BlipSource.cxx:73
p
Definition: test.py:223
DecayTime(IRandom::pointer rng, double rate)
Definition: BlipSource.cxx:81
WIRECELL_FACTORY(BlipSource, WireCell::Gen::BlipSource, WireCell::IDepoSource, WireCell::IConfigurable) using namespace WireCell
IRandom::pointer rng
Definition: BlipSource.cxx:79
static const double ms
Definition: Units.h:100
Json::Value Configuration
Definition: Configuration.h:50
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:67
IRandom::pointer rng
Definition: BlipSource.cxx:114
const GenericPointer< typename T::ValueType > & pointer
Definition: pointer.h:1124
QTextStream & endl(QTextStream &s)