All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RawFrameSource.cxx
Go to the documentation of this file.
1 #include "RawFrameSource.h"
2 #include "art/Framework/Principal/Handle.h"
3 
4 // for tick
5 //#include "lardata/DetectorInfoServices/DetectorPropertiesService.h"
7 #include "art/Framework/Principal/Event.h"
8 #include "art/Framework/Principal/Run.h"
9 
10 #include "TTimeStamp.h"
11 
12 
13 #include "WireCellAux/SimpleFrame.h"
14 #include "WireCellAux/SimpleTrace.h"
15 #include "WireCellUtil/NamedFactory.h"
16 
17 WIRECELL_FACTORY(wclsRawFrameSource, wcls::RawFrameSource,
18  wcls::IArtEventVisitor, WireCell::IFrameSource)
19 
20 
21 using namespace wcls;
22 using namespace WireCell;
23 using WireCell::Aux::SimpleTrace;
24 using WireCell::Aux::SimpleFrame;
25 
27  : m_nticks(0)
28 {
29 }
30 
31 RawFrameSource::~RawFrameSource()
32 {
33 }
34 
35 
36 WireCell::Configuration RawFrameSource::default_configuration() const
37 {
38  Configuration cfg;
39  cfg["art_tag"] = ""; // how to look up the raw digits
40  cfg["tick"] = 0.5*WireCell::units::us;
41  cfg["frame_tags"][0] = "orig"; // the tags to apply to this frame
42  cfg["nticks"] = m_nticks; // if nonzero, truncate or baseline-pad frame to this number of ticks.
43  return cfg;
44 }
45 
46 void RawFrameSource::configure(const WireCell::Configuration& cfg)
47 {
48  const std::string art_tag = cfg["art_tag"].asString();
49  if (art_tag.empty()) {
50  THROW(ValueError() << errmsg{"WireCell::RawFrameSource requires a source_label"});
51  }
52  m_inputTag = cfg["art_tag"].asString();
53 
54  m_tick = cfg["tick"].asDouble();
55  for (auto jtag : cfg["frame_tags"]) {
56  m_frame_tags.push_back(jtag.asString());
57  }
58  m_nticks = get(cfg, "nticks", m_nticks);
59 }
60 
61 
62 
63 // is this the right way to diff an art::Timestamp?
64 static
65 double tdiff(const art::Timestamp& ts1, const art::Timestamp& ts2)
66 {
67  TTimeStamp tts1(ts1.timeHigh(), ts1.timeLow());
68  TTimeStamp tts2(ts2.timeHigh(), ts2.timeLow());
69  return tts2.AsDouble() - tts1.AsDouble();
70 }
71 
72 
73 static
74 SimpleTrace* make_trace(const raw::RawDigit& rd, unsigned int nticks_want)
75 {
76  const int chid = rd.Channel();
77  const int tbin = 0;
78  const raw::RawDigit::ADCvector_t& adcv = rd.ADCs();
79 
80  short baseline = 0;
81  unsigned int nadcs = adcv.size();
82  if (nticks_want > 0) { // don't want natural input size
83  if (nticks_want > nadcs) {
84  baseline = Waveform::most_frequent(adcv);
85  }
86  nadcs = std::min(nadcs, nticks_want);
87  }
88  else {
89  nticks_want = nadcs;
90  }
91 
92  auto strace = new SimpleTrace(chid, tbin, nticks_want);
93  for (unsigned int itick=0; itick < nadcs; ++ itick) {
94  strace->charge()[itick] = adcv[itick];
95  }
96  for (unsigned int itick = nadcs; itick < nticks_want; ++itick) {
97  strace->charge()[itick] = baseline;
98  }
99  return strace;
100 }
101 
102 void RawFrameSource::visit(art::Event & event)
103 {
104  // fixme: want to avoid depending on DetectorPropertiesService for now.
105  const double tick = m_tick;
106  art::Handle< std::vector<raw::RawDigit> > rdvh;
107  bool okay = event.getByLabel(m_inputTag, rdvh);
108  if (!okay) {
109  std::string msg = "WireCell::RawFrameSource failed to get vector<raw::RawDigit>: " + m_inputTag.encode();
110  std::cerr << msg << std::endl;
111  THROW(RuntimeError() << errmsg{msg});
112  }
113  else if (rdvh->size() == 0) return;
114 
115  const std::vector<raw::RawDigit>& rdv(*rdvh);
116  const size_t nchannels = rdv.size();
117  std::cerr << "RawFrameSource: got " << nchannels << " raw::RawDigit objects\n";
118 
119  WireCell::ITrace::vector traces(nchannels);
120  for (size_t ind=0; ind<nchannels; ++ind) {
121  auto const& rd = rdv.at(ind);
122  traces[ind] = ITrace::pointer(make_trace(rd, m_nticks));
123  if (!ind) {
124  if (m_nticks) {
125  std::cerr
126  << "\tinput nticks=" << rd.ADCs().size() << " setting to " << m_nticks
127  << std::endl;
128  }
129  else {
130  std::cerr
131  << "\tinput nticks=" << rd.ADCs().size() << " keeping as is"
132  << std::endl;
133  }
134  }
135  }
136 
137  const double time = tdiff(event.getRun().beginTime(), event.time());
138  auto sframe = new SimpleFrame(event.event(), time, traces, tick);
139  for (auto tag : m_frame_tags) {
140  //std::cerr << "\ttagged: " << tag << std::endl;
141  sframe->tag_frame(tag);
142  }
143  m_frames.push_back(WireCell::IFrame::pointer(sframe));
144  m_frames.push_back(nullptr);
145 }
146 
147 bool RawFrameSource::operator()(WireCell::IFrame::pointer& frame)
148 {
149  frame = nullptr;
150  if (m_frames.empty()) {
151  return false;
152  }
153  frame = m_frames.front();
154  m_frames.pop_front();
155  return true;
156 }
157 // Local Variables:
158 // mode: c++
159 // c-basic-offset: 4
160 // End:
const ADCvector_t & ADCs() const
Reference to the compressed ADC count vector.
Definition: RawDigit.h:210
static SimpleTrace * make_trace(const raw::RawDigit &rd, unsigned int nticks_want)
Collection of charge vs time digitized from a single readout channel.
Definition: RawDigit.h:69
BEGIN_PROLOG could also be cerr
ChannelID_t Channel() const
DAQ channel this raw data was read from.
Definition: RawDigit.h:212
std::vector< short > ADCvector_t
Type representing a (compressed) vector of ADC counts.
Definition: RawDigit.h:73
Definition of basic raw digits.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
BEGIN_PROLOG baseline
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:75
WIRECELL_FACTORY(wclsChannelNoiseDB, wcls::ChannelNoiseDB, wcls::IArtEventVisitor, WireCell::IChannelNoiseDatabase) using namespace WireCell
static double tdiff(const art::Timestamp &ts1, const art::Timestamp &ts2)