CookedFrameSink.cxx
Go to the documentation of this file.
1 #include "CookedFrameSink.h"
2 //#include "art/Framework/Principal/Handle.h"
3 
6 
9 
10 #include "WireCellIface/IFrame.h"
11 #include "WireCellIface/ITrace.h"
12 #include "WireCellUtil/NamedFactory.h"
13 
14 WIRECELL_FACTORY(wclsCookedFrameSink, wcls::CookedFrameSink, wcls::IArtEventVisitor, WireCell::IFrameSink)
15 
16 
17 using namespace wcls;
18 using namespace WireCell;
19 
21  : m_frame(nullptr)
22  , m_nticks(0)
23 {
24 }
25 
26 CookedFrameSink::~CookedFrameSink()
27 {
28 }
29 
30 
32 {
33  Configuration cfg;
34  cfg["anode"] = "AnodePlane";
35  // frames to output
36  cfg["frame_tags"][0] = "gauss";
37  cfg["frame_tags"][1] = "wiener";
38  cfg["nticks"] = m_nticks; // if nonzero, force number of ticks in output waveforms.
39  return cfg;
40 }
41 
43 {
44  const std::string anode_tn = cfg["anode"].asString();
45  if (anode_tn.empty()) {
46  THROW(ValueError() << errmsg{"CookedFrameSink requires an anode plane"});
47  }
48 
49  // this throws if not found
50  m_anode = Factory::find_tn<IAnodePlane>(anode_tn);
51 
52  auto jtags = cfg["frame_tags"];
53  std::cerr << "CookedFrameSink: saving " << jtags.size() << " tags\n";
54  for (auto jtag : jtags) {
55  std::string tag = jtag.asString();
56  std::cerr << "\t" << tag << "\n";
57  m_frame_tags.push_back(tag);
58  }
59  m_nticks = get(cfg, "nticks", m_nticks);
60 }
61 
63 {
64  for (auto tag : m_frame_tags) {
65  std::cerr << "CookedFrameSink: promising to produce recob::Wires named \"" << tag << "\"\n";
66  collector.produces< std::vector<recob::Wire> >(tag);
67  }
68 }
69 
70 // fixme: this is copied from sigproc/FrameUtil but it's currently private code.
71 static
72 ITrace::vector tagged_traces(IFrame::pointer frame, IFrame::tag_t tag)
73 {
74  ITrace::vector ret;
75  auto const& all_traces = frame->traces();
76  for (size_t index : frame->tagged_traces(tag)) {
77  ret.push_back(all_traces->at(index));
78  }
79  if (!ret.empty()) {
80  return ret;
81  }
82  auto ftags = frame->frame_tags();
83  if (std::find(ftags.begin(), ftags.end(), tag) == ftags.end()) {
84  return ret;
85  }
86  return *all_traces; // must make copy of shared pointers
87 }
88 
89 
91 {
92  if (!m_frame) {
93  std::cerr << "CookedFrameSink: I have no frame to save to art::Event\n";
94  return;
95  }
96 
97  std::cerr << "CookedFrameSink: got " << m_frame->traces()->size() << " total traces\n";
98 
99  for (auto tag : m_frame_tags) {
100 
101  auto traces = tagged_traces(m_frame, tag);
102  if (traces.empty()) {
103  std::cerr << "CookedFrameSink: no traces for tag \"" << tag << "\"\n";
104  continue;
105  }
106 
107 
108  std::unique_ptr<std::vector<recob::Wire> > outwires(new std::vector<recob::Wire>);
109 
110  // what about the frame's time() and ident()?
111 
112  for (const auto& trace : traces) {
113 
114  const int tbin = trace->tbin();
115  const int chid = trace->channel();
116  const auto& charge = trace->charge();
117 
118  //std::cerr << tag << ": chid=" << chid << " tbin=" << tbin << " nq=" << charge.size() << std::endl;
119 
120  // enforce number of ticks if we are so configured.
121  size_t ncharge = charge.size();
122  int nticks = tbin + ncharge;
123  if (m_nticks) { // force output waveform size
124  if (m_nticks < nticks) {
125  ncharge = m_nticks - tbin;
126  }
127  nticks = m_nticks;
128  }
130  roi.add_range(tbin, charge.begin(), charge.begin() + ncharge);
131 
132  // FIXME: the current assumption in this code is that LS channel
133  // numbers are identified with WCT channel IDs.
134  // Fact: the plane view for the ICARUS induction-1 is "geo::kY",
135  // instead of "geo::kU"
136  auto const& gc = *lar::providerFrom<geo::Geometry>();
137  auto view = gc.View(chid);
138 
139  // what about those pesky channel map masks?
140  // they are dropped for now.
141 
142  outwires->emplace_back(recob::Wire(roi, chid, view));
143  }
144  std::cerr << "CookedFrameSink saving " << outwires->size() << " recob::Wires named \""<<tag<<"\"\n";
145  event.put(std::move(outwires), tag);
146  }
147 
148  m_frame = nullptr;
149 }
150 
151 bool CookedFrameSink::operator()(const WireCell::IFrame::pointer& frame)
152 {
153  // set an IFrame based on last visited event.
154  m_frame = frame;
155  return true;
156 }
157 
158 // Local Variables:
159 // mode: c++
160 // c-basic-offset: 4
161 // End:
std::vector< std::string > m_frame_tags
std::string string
Definition: nybbler.cc:12
virtual WireCell::Configuration default_configuration() const
IConfigurable.
struct vector vector
const datarange_t & add_range(size_type offset, ITER first, ITER last)
Adds a sequence of elements as a range with specified offset.
art framework interface to geometry description
M::value_type trace(const M &m)
virtual bool operator()(const WireCell::IFrame::pointer &frame)
IFrameSink.
void produces(std::string const &instanceName={}, Persistable const persistable=Persistable::Yes)
WireCell::IAnodePlane::pointer m_anode
static ITrace::vector tagged_traces(IFrame::pointer frame, IFrame::tag_t tag)
def move(depos, offset)
Definition: depos.py:107
virtual void configure(const WireCell::Configuration &config)
WIRECELL_FACTORY(wclsChannelNoiseDB, wcls::ChannelNoiseDB, wcls::IArtEventVisitor, WireCell::IChannelNoiseDatabase) using namespace WireCell
virtual void produces(art::ProducesCollector &collector)
IArtEventVisitor.
WireCell::IFrame::pointer m_frame
Class holding the regions of interest of signal from a channel.
Definition: Wire.h:118
Declaration of basic channel signal object.
virtual void visit(art::Event &event)
Implement to visit an Art event.
Event finding and building.