All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CookedFrameSource.cxx
Go to the documentation of this file.
1 #include "CookedFrameSource.h"
2 #include "art/Framework/Principal/Handle.h"
3 
4 #include "art/Framework/Principal/Event.h"
5 #include "art/Framework/Principal/Run.h"
7 
8 #include "TTimeStamp.h"
9 
10 #include "WireCellAux/SimpleFrame.h"
11 #include "WireCellAux/SimpleTrace.h"
12 #include "WireCellUtil/NamedFactory.h"
13 
14 WIRECELL_FACTORY(wclsCookedFrameSource,
17  WireCell::IFrameSource)
18 
19 using namespace wcls;
20 using namespace WireCell;
21 using WireCell::Aux::SimpleTrace;
22 using WireCell::Aux::SimpleFrame;
23 
25 
26 CookedFrameSource::~CookedFrameSource() {}
27 
28 WireCell::Configuration
29 CookedFrameSource::default_configuration() const
30 {
31  Configuration cfg;
32  cfg["art_tag"] = ""; // how to look up the cooked digits
33  cfg["tick"] = 0.5 * WireCell::units::us;
34  cfg["frame_tags"][0] = "orig"; // the tags to apply to this frame
35  cfg["nticks"] = m_nticks; // if nonzero, truncate or zero-pad frame to this number of ticks.
36  return cfg;
37 }
38 
39 void
40 CookedFrameSource::configure(const WireCell::Configuration& cfg)
41 {
42  const std::string art_tag = cfg["art_tag"].asString();
43  if (art_tag.empty()) {
44  THROW(ValueError() << errmsg{"WireCell::CookedFrameSource requires a source_label"});
45  }
46  m_inputTag = cfg["art_tag"].asString();
47 
48  m_tick = cfg["tick"].asDouble();
49  for (auto jtag : cfg["frame_tags"]) {
50  m_frame_tags.push_back(jtag.asString());
51  }
52  m_nticks = get(cfg, "nticks", m_nticks);
53 }
54 
55 // this code assumes that the high part of timestamp represents number of seconds from Jan 1st, 1970 and the low part
56 // represents the number of nanoseconds.
57 static double
58 tdiff(const art::Timestamp& ts1, const art::Timestamp& ts2)
59 {
60  TTimeStamp tts1(ts1.timeHigh(), ts1.timeLow());
61  TTimeStamp tts2(ts2.timeHigh(), ts2.timeLow());
62  return tts2.AsDouble() - tts1.AsDouble();
63 }
64 
65 static SimpleTrace*
66 make_trace(const recob::Wire& rw, unsigned int nticks_want)
67 {
68  // uint
69  const raw::ChannelID_t chid = rw.Channel();
70  const int tbin = 0;
71  const std::vector<float> sig = rw.Signal();
72 
73  const float baseline = 0.0;
74  unsigned int nsamp = sig.size();
75  if (nticks_want > 0) { nsamp = std::min(nsamp, nticks_want); }
76  else {
77  nticks_want = nsamp;
78  }
79 
80  auto strace = new SimpleTrace(chid, tbin, nticks_want);
81  auto& q = strace->charge();
82  for (unsigned int itick = 0; itick < nsamp; ++itick) {
83  q[itick] = sig[itick];
84  }
85  for (unsigned int itick = nsamp; itick < nticks_want; ++itick) {
86  q[itick] = baseline;
87  }
88  return strace;
89 }
90 
91 void
92 CookedFrameSource::visit(art::Event& e)
93 {
94  auto const& event = e;
95  // fixme: want to avoid depending on DetectorPropertiesService for now.
96  const double tick = m_tick;
97  art::Handle<std::vector<recob::Wire>> rwvh;
98  bool okay = event.getByLabel(m_inputTag, rwvh);
99  if (!okay) {
100  std::string msg =
101  "WireCell::CookedFrameSource failed to get vector<recob::Wire>: " + m_inputTag.encode();
102  std::cerr << msg << std::endl;
103  THROW(RuntimeError() << errmsg{msg});
104  }
105  else if (rwvh->size() == 0)
106  return;
107 
108  const std::vector<recob::Wire>& rwv(*rwvh);
109  const size_t nchannels = rwv.size();
110  std::cerr << "CookedFrameSource: got " << nchannels << " recob::Wire objects\n";
111 
112  WireCell::ITrace::vector traces(nchannels);
113  for (size_t ind = 0; ind < nchannels; ++ind) {
114  auto const& rw = rwv.at(ind);
115  traces[ind] = ITrace::pointer(make_trace(rw, m_nticks));
116  if (!ind) { // first time through
117  if (m_nticks) {
118  std::cerr << "\tinput nticks=" << rw.NSignal() << " setting to " << m_nticks << std::endl;
119  }
120  else {
121  std::cerr << "\tinput nticks=" << rw.NSignal() << " keeping as is" << std::endl;
122  }
123  }
124  }
125 
126  const double time = tdiff(event.getRun().beginTime(), event.time());
127  auto sframe = new SimpleFrame(event.event(), time, traces, tick);
128  for (auto tag : m_frame_tags) {
129  //std::cerr << "\ttagged: " << tag << std::endl;
130  sframe->tag_frame(tag);
131  }
132  m_frames.push_back(WireCell::IFrame::pointer(sframe));
133  m_frames.push_back(nullptr);
134 }
135 
136 bool
137 CookedFrameSource::operator()(WireCell::IFrame::pointer& frame)
138 {
139  frame = nullptr;
140  if (m_frames.empty()) { return false; }
141  frame = m_frames.front();
142  m_frames.pop_front();
143  return true;
144 }
145 // Local Variables:
146 // mode: c++
147 // c-basic-offset: 4
148 // End:
BEGIN_PROLOG could also be cerr
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
raw::ChannelID_t Channel() const
Returns the ID of the channel (or InvalidChannelID)
Definition: Wire.h:231
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
std::vector< float > Signal() const
Return a zero-padded full length vector filled with RoI signal.
Definition: Wire.cxx:47
static SimpleTrace * make_trace(const recob::Wire &rw, unsigned int nticks_want)
do i e
static double tdiff(const art::Timestamp &ts1, const art::Timestamp &ts2)
Class holding the regions of interest of signal from a channel.
Definition: Wire.h:118
Declaration of basic channel signal object.
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28