Digitizer.cxx
Go to the documentation of this file.
2 
7 
8 #include "WireCellUtil/Testing.h"
10 #include <sstream>
11 
14 
15 using namespace std;
16 using namespace WireCell;
17 
18 
19 Gen::Digitizer::Digitizer(const std::string& anode,
20  int resolution, double gain,
21  std::vector<double> fullscale, std::vector<double> baselines)
22  : m_anode_tn(anode)
23  , m_resolution(resolution)
24  , m_gain(gain)
25  , m_fullscale(fullscale)
26  , m_baselines(baselines)
27  , m_frame_tag("")
28  , log(Log::logger("sim"))
29 {
30 }
31 
32 Gen::Digitizer::~Digitizer()
33 {
34 }
35 
37 {
39  put(cfg, "anode", m_anode_tn);
40 
41  put(cfg, "resolution", m_resolution);
42  put(cfg, "gain", m_gain);
43  Configuration fs(Json::arrayValue); // fixme: sure would be nice if we had some templated sugar for this
44  for (int ind=0; ind<2; ++ind) {
45  fs[ind] = m_fullscale[ind];
46  }
47  cfg["fullscale"] = fs;
48 
49  Configuration bl(Json::arrayValue);
50  for (int ind=0; ind<3; ++ind) {
51  bl[ind] = m_baselines[ind];
52  }
53  cfg["baselines"] = bl;
54 
55  cfg["frame_tag"] = m_frame_tag;
56  return cfg;
57 }
58 
60 {
61  m_anode_tn = get<string>(cfg, "anode", m_anode_tn);
62  m_anode = Factory::find_tn<IAnodePlane>(m_anode_tn);
63 
64  m_resolution = get(cfg, "resolution", m_resolution);
65  m_gain = get(cfg, "gain", m_gain);
66  m_fullscale = get(cfg, "fullscale", m_fullscale);
67  m_baselines = get(cfg, "baselines", m_baselines);
68  m_frame_tag = get(cfg, "frame_tag", m_frame_tag);
69 
70  std::stringstream ss;
71  ss << "Gen::Digitizer: "
72  << "tag=\""<<m_frame_tag << "\", "
73  << "resolution="<<m_resolution<<" bits, "
74  << "maxvalue=" << (1<<m_resolution) << " counts, "
75  << "gain=" << m_gain << ", "
76  << "fullscale=[" << m_fullscale[0]/units::mV << "," << m_fullscale[1]/units::mV << "] mV, "
77  << "baselines=[" << m_baselines[0]/units::mV << "," << m_baselines[1]/units::mV << "," << m_baselines[2]/units::mV << "] mV";
78  log->debug(ss.str());
79 
80 }
81 
82 
83 double Gen::Digitizer::digitize(double voltage)
84 {
85  const int adcmaxval = (1<<m_resolution)-1;
86 
87  if (voltage <= m_fullscale[0]) {
88  return 0;
89  }
90  if (voltage >= m_fullscale[1]) {
91  return adcmaxval;
92  }
93  const double relvoltage = (voltage - m_fullscale[0])/(m_fullscale[1] - m_fullscale[0]);
94  return relvoltage*adcmaxval;
95 }
96 
98 {
99  if (!vframe) { // EOS
100  log->debug("Gen::Digitizer: EOS");
101  adcframe = nullptr;
102  return true;
103  }
104 
105 
106  // fixme: maybe make this honor a tag
107  auto vtraces = FrameTools::untagged_traces(vframe);
108  if (vtraces.empty()) {
109  log->error("Gen::Digitizer: no traces in input frame {}", vframe->ident());
110  return false;
111  }
112 
113  // Get extent in channel and tbin
114  auto channels = FrameTools::channels(vtraces);
115  std::sort(channels.begin(), channels.end());
116  auto chbeg = channels.begin();
117  auto chend = std::unique(chbeg, channels.end());
118  auto tbinmm = FrameTools::tbin_range(vtraces);
119 
120  const size_t ncols = tbinmm.second-tbinmm.first;
121  const size_t nrows = std::distance(chbeg, chend);
122 
123  // make a dense array working space. a row is one trace. a
124  // column is one tick.
125  Array::array_xxf arr = Array::array_xxf::Zero(nrows, ncols);
126  FrameTools::fill(arr, vtraces, channels.begin(), chend, tbinmm.first);
127 
128  ITrace::vector adctraces(nrows);
129 
130  for (size_t irow=0; irow < nrows; ++irow) {
131  int ch = channels[irow];
132  WirePlaneId wpid = m_anode->resolve(ch);
133  if (!wpid.valid()) {
134  log->warn("Gen::Digitizer, got invalid WPID for channel {}: {}, skipping", ch, wpid);
135  continue;
136  }
137  const float baseline = m_baselines[wpid.index()];
138 
139  ITrace::ChargeSequence adcwave(ncols);
140  for (size_t icol=0; icol < ncols; ++icol) {
141  double voltage = m_gain*arr(irow, icol) + baseline;
142  const float adcf = digitize(voltage);
143  adcwave[icol] = adcf;
144  }
145  adctraces[irow] = make_shared<SimpleTrace>(ch, tbinmm.first, adcwave);
146  }
147  auto sframe = make_shared<SimpleFrame>(vframe->ident(), vframe->time(), adctraces,
148  vframe->tick(), vframe->masks());
149  if (!m_frame_tag.empty()) {
150  sframe->tag_frame(m_frame_tag);
151  }
152  adcframe = sframe;
153 
154  return true;
155 }
virtual bool operator()(const input_pointer &inframe, output_pointer &outframe)
The calling signature:
Definition: Digitizer.cxx:97
std::string m_anode_tn
Definition: Digitizer.h:45
void fill(Array::array_xxf &array, const ITrace::vector &traces, channel_list::iterator ch_begin, channel_list::iterator ch_end, int tbin=0)
Definition: FrameTools.cxx:158
STL namespace.
void put(Configuration &cfg, const std::string &dotpath, const T &val)
Put value in configuration at the dotted path.
static const double mV
Definition: Units.h:180
cfg
Definition: dbjson.py:29
std::vector< pointer > vector
Definition: IData.h:21
double digitize(double voltage)
Definition: Digitizer.cxx:83
std::vector< pointer > vector
Vector of shared pointers.
Definition: IComponent.h:36
std::shared_ptr< const IFrame > input_pointer
Definition: IFunctionNode.h:39
std::vector< double > m_fullscale
Definition: Digitizer.h:48
virtual void configure(const WireCell::Configuration &config)
Accept a configuration.
Definition: Digitizer.cxx:59
WIRECELL_FACTORY(Digitizer, WireCell::Gen::Digitizer, WireCell::IFrameFilter, WireCell::IConfigurable) using namespace std
ITrace::vector untagged_traces(IFrame::pointer frame)
Definition: FrameTools.cxx:90
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
channel_list channels(const ITrace::vector &traces)
Definition: FrameTools.cxx:132
virtual WireCell::Configuration default_configuration() const
Optional, override to return a hard-coded default configuration.
Definition: Digitizer.cxx:36
Monte Carlo Simulation.
std::shared_ptr< const IFrame > output_pointer
Definition: IFunctionNode.h:40
std::pair< int, int > tbin_range(const ITrace::vector &traces)
Definition: FrameTools.cxx:143
std::string m_frame_tag
Definition: Digitizer.h:49
logptr_t logger(std::string name)
Definition: Logging.cxx:71
bool valid() const
return true if valid
Definition: WirePlaneId.cxx:53
void log(source_loc source, level::level_enum lvl, const char *fmt, const Args &...args)
Definition: spdlog.h:165
Definition: Main.h:22
Json::Value Configuration
Definition: Configuration.h:50
unsigned nrows(sqlite3 *db, std::string const &tablename)
Definition: helpers.cc:84
IAnodePlane::pointer m_anode
Definition: Digitizer.h:44
std::vector< double > m_baselines
Definition: Digitizer.h:48
std::vector< float > ChargeSequence
Sequential collection of charge.
Definition: ITrace.h:21
Log::logptr_t log
Definition: Digitizer.h:50
int index() const
Layer as index number (0,1 or 2). -1 if unknown.
Definition: WirePlaneId.cxx:34
Eigen::ArrayXXf array_xxf
A real, 2D array.
Definition: Array.h:54