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