FrameMerger.cxx
Go to the documentation of this file.
5 #include "WireCellIface/ITrace.h"
6 
7 #include <string>
8 
11 
12 using namespace WireCell;
13 
14 
15 Configuration SigProc::FrameMerger::default_configuration() const
16 {
18 
19  // The merge map specifies a list of triples of tags. The first
20  // tag in the pair corresponds to a trace tag on the first frame,
21  // and likewise the second. The third is a tag that will be
22  // placed on the merged set of traces in the output frame. The
23  // merge is performed considering only traces in the two input
24  // frames that respectively match their tags. As tags may have
25  // overlapping sets of traces, it is important to recognize that
26  // the merge is progressive and in order of the merge map. If the
27  // merge map is empty then all traces in frame 1 are merged with
28  // all traces in frame 2 irrespective of any tags.
29  cfg["mergemap"] = Json::arrayValue;
30 
31  // The rule determins the algorithm employed in the merge.
32  //
33  // - replace :: the last trace encountered for a given channel is output.
34  // The traces from frame 1 will take precedence over any from frame 2.
35  //
36  // - include :: all traces encountered with a given channel are output.
37  //
38  // - tbd :: more may be added (eg, sum all traces on a given channel)
39  cfg["rule"] = "replace";
40 
41  return cfg;
42 }
43 
45 {
46  m_cfg = cfg;
47 }
48 
49 bool SigProc::FrameMerger::operator()(const input_tuple_type& intup,
50  output_pointer& out)
51 {
52  out = nullptr;
53 
54  auto one = std::get<0>(intup);
55  auto two = std::get<1>(intup);
56  if (!one or !two) {
57  std::cerr << "FrameMerger: EOS\n";
58  return true;
59  }
60 
61 
62  auto jmergemap = m_cfg["mergemap"];
63  const int nsets = jmergemap.size();
64 
65  // collect traces into a vector of vector whether we are dealling
66  // with all traces or honoring tags.
67  std::vector<ITrace::vector> tracesv1, tracesv2;
68  if (!nsets) {
69  tracesv1.push_back(FrameTools::untagged_traces(one));
70  tracesv2.push_back(FrameTools::untagged_traces(two));
71  std::cerr << "FrameMerger: see frame: "<<one->ident()<<" no tags, whole frame\n";
72  }
73  else {
74  std::cerr << "FrameMerger: see frame: "<<one->ident()<<" with tags:\n";
75  for (int ind=0; ind<nsets; ++ind) {
76  auto jtags = jmergemap[ind];
77  std::string tag1 = jtags[0].asString();
78  std::string tag2 = jtags[1].asString();
79  std::string tag3 = jtags[2].asString();
80  tracesv1.push_back(FrameTools::tagged_traces(one, tag1));
81  tracesv2.push_back(FrameTools::tagged_traces(two, tag2));
82  std::cerr << "\ttags: "
83  << tag1 << "[" << tracesv1.back().size() << "]"
84  << " + "
85  << tag2 << "[" << tracesv2.back().size() << "]"
86  << " -> " << tag3
87  << "\n";
88  }
89  }
90 
91  ITrace::vector out_traces;
92  std::vector<IFrame::trace_list_t> tagged_trace_indices;
93 
94  // apply rule, collect info for tags even if we may not be
95  // configured to honor them.
96 
97  auto rule = get<std::string>(m_cfg, "rule");
98  if (rule == "replace") {
99 
100  for (size_t ind=0; ind<tracesv1.size(); ++ind) {
101  auto& traces1 = tracesv1[ind];
102  auto& traces2 = tracesv2[ind];
103 
104  std::unordered_map<int, ITrace::pointer> ch2tr;
105  for (auto trace : traces2) {
106  ch2tr[trace->channel()] = trace;
107  }
108  for (auto trace : traces1) { // now replace any from frame 1
109  ch2tr[trace->channel()] = trace;
110  }
111 
113  for (auto chtr : ch2tr) {
114  tl.push_back(out_traces.size());
115  out_traces.push_back(chtr.second);
116  }
117  tagged_trace_indices.push_back(tl);
118  }
119  }
120  if (rule == "include") {
121  for (size_t ind=0; ind<tracesv1.size(); ++ind) {
122  auto& traces1 = tracesv1[ind];
123  auto& traces2 = tracesv2[ind];
124 
126  for (size_t trind=0; trind < traces1.size(); ++trind) {
127  tl.push_back(out_traces.size());
128  out_traces.push_back(traces1[trind]);
129  }
130  for (size_t trind=0; trind < traces2.size(); ++trind) {
131  tl.push_back(out_traces.size());
132  out_traces.push_back(traces2[trind]);
133  }
134  tagged_trace_indices.push_back(tl);
135  }
136  }
137 
138  auto sf = new SimpleFrame(two->ident(), two->time(), out_traces, two->tick());
139  if (nsets) {
140  for (int ind=0; ind<nsets; ++ind) {
141  std::string otag = jmergemap[ind][2].asString();
142  sf->tag_traces(otag, tagged_trace_indices[ind]);
143  }
144  }
145  out = IFrame::pointer(sf);
146  return true;
147 }
148 
149 
150 SigProc::FrameMerger::FrameMerger()
151 {
152 }
153 
154 SigProc::FrameMerger::~FrameMerger()
155 {
156 }
std::string string
Definition: nybbler.cc:12
port_helper_type::template WrappedConst< std::shared_ptr >::type input_tuple_type
Definition: IJoinNode.h:46
cfg
Definition: dbjson.py:29
std::vector< pointer > vector
Definition: IData.h:21
WIRECELL_FACTORY(FrameMerger, WireCell::SigProc::FrameMerger, WireCell::IFrameJoiner, WireCell::IConfigurable) using namespace WireCell
static ITrace::vector tagged_traces(IFrame::pointer frame, IFrame::tag_t tag)
def configure(cfg)
Definition: cuda.py:34
ITrace::vector untagged_traces(IFrame::pointer frame)
Definition: FrameTools.cxx:90
Definition: Main.h:22
Json::Value Configuration
Definition: Configuration.h:50
const GenericPointer< typename T::ValueType > & pointer
Definition: pointer.h:1124
std::vector< size_t > trace_list_t
Definition: IFrame.h:36