OmnibusNoiseFilter.cxx
Go to the documentation of this file.
2 
4 
6 
9 
11 // #include "WireCellUtil/ExecMon.h" // debugging
12 
13 #include "FrameUtils.h" // fixme: needs to move to somewhere more useful.
14 
15 #include <unordered_map>
16 
19 
20 using namespace WireCell;
21 
22 using namespace WireCell::SigProc;
23 
24 OmnibusNoiseFilter::OmnibusNoiseFilter(std::string intag, std::string outtag)
25  : m_nticks(0)
26  , m_intag(intag) // orig
27  , m_outtag(outtag) // raw
28  , log(Log::logger("sigproc"))
29 {
30 }
31 OmnibusNoiseFilter::~OmnibusNoiseFilter()
32 {
33 }
34 
36 {
37  //std::cerr << "OmnibusNoiseFilter: configuring with:\n" << cfg << std::endl;
38  m_nticks = (size_t)get(cfg, "nticks", (int)m_nticks);
39  if (! cfg["nsamples"].isNull()) {
40  log->warn("OmnibusNoiseFilter: \"nsamples\" is an obsolete parameter, use \"nticks\"");
41  }
42 
43  auto jmm = cfg["maskmap"];
44  for (auto name : jmm.getMemberNames()) {
45  m_maskmap[name] = jmm[name].asString();
46  // std::cerr << name << " " << m_maskmap[name] << std::endl;
47  }
48 
49  for (auto jf : cfg["channel_filters"]) {
50  auto filt = Factory::find_tn<IChannelFilter>(jf.asString());
51  log->debug("OmnibusNoiseFilter: adding channel filter: {} \"{}\"",
52  m_perchan.size(), jf.asString());
53  m_perchan.push_back(filt);
54  }
55  for (auto jf : cfg["channel_status_filters"]) {
56  auto filt = Factory::find_tn<IChannelFilter>(jf.asString());
57  log->debug("OmnibusNoiseFilter: adding channel status filter: {} \"{}\"",
58  m_perchan_status.size(), jf.asString());
59  m_perchan_status.push_back(filt);
60  }
61  for (auto jf : cfg["grouped_filters"]) {
62  auto filt = Factory::find_tn<IChannelFilter>(jf.asString());
63  log->debug("OmnibusNoiseFilter: adding grouped filter: {} \"{}\"",
64  m_grouped.size(), jf.asString());
65  m_grouped.push_back(filt);
66  }
67 
68 
69  auto jcndb = cfg["noisedb"];
70  m_noisedb = Factory::find_tn<IChannelNoiseDatabase>(jcndb.asString());
71  log->debug("OmnibusNoiseFilter: using channel noise DB object: \"{}\"",
72  jcndb.asString());
73 
74  m_intag = get(cfg, "intraces", m_intag);
75  m_outtag = get(cfg, "outtraces", m_outtag);
76 }
77 
79 {
81  cfg["nticks"] = (int)m_nticks;
82  cfg["maskmap"]["chirp"] = "bad";
83  cfg["maskmap"]["noisy"] = "bad";
84 
85  cfg["channel_filters"][0] = "mbOneChannelNoise";
86  cfg["channel_status_filters"][0] = "mbOneChannelStatus";
87  cfg["grouped_filters"][0] = "mbCoherentNoiseSub";
88 
89  // user must supply. "OmniChannelNoiseDB" is a likely choice.
90  // Avoid SimpleChannelNoiseDB.
91  cfg["noisedb"] = "";
92 
93  // The tags for input and output traces
94  cfg["intraces"] = m_intag;
95  cfg["outtraces"] = m_outtag;
96  return cfg;
97 }
98 
99 
101 {
102  if (!inframe) { // eos
103  outframe = nullptr;
104  return true;
105  }
106 
107  auto traces = wct::sigproc::tagged_traces(inframe, m_intag);
108  if (traces.empty()) {
109  log->warn("OmnibusNoiseFilter: no traces for tag \"{}\", sending empty frame", m_intag);
110  outframe = std::make_shared<SimpleFrame>(inframe->ident(), inframe->time(),
111  std::make_shared<ITrace::vector>(),
112  inframe->tick());
113 
114  return true;
115  }
116 
117  if (m_nticks) {
118  log->debug("OmnibusNoiseFilter: will resize working waveforms from {} to {}",
119  traces.at(0)->charge().size(), m_nticks);
120  }
121  else {
122  // Warning: this implicitly assumes a dense frame (ie, all tbin=0 and all waveforms same size).
123  // It also won't stop triggering a warning inside OneChannelNoise if there is a mismatch.
124  m_nticks = traces.at(0)->charge().size();
125  log->debug("OmnibusNoiseFilter: nticks based on first waveform: {}", m_nticks);
126  }
127 
128  // For now, just collect any and all masks and interpret them as "bad".
129  Waveform::ChannelMaskMap input_cmm = inframe->masks();
131  Waveform::merge(cmm,input_cmm,m_maskmap);
132 
133  // Get the ones from database and then merge
134  std::vector<int> bad_channels = m_noisedb->bad_channels();
135  {
136  Waveform::BinRange bad_bins;
137  bad_bins.first = 0;
138  bad_bins.second = (int) m_nticks;
140  for (size_t i = 0; i< bad_channels.size();i++){
141  temp[bad_channels.at(i)].push_back(bad_bins);
142  //std::cout << temp.size() << " " << temp[bad_channels.at(i)].size() << std::endl;
143  }
144  Waveform::ChannelMaskMap temp_map;
145  temp_map["bad"] = temp;
146  Waveform::merge(cmm,temp_map,m_maskmap);
147  }
148 
149 
150  int nchanged_samples = 0;
151 
152  // Collect our working area indexed by channel.
153  std::unordered_map<int, SimpleTrace*> bychan;
154  for (auto trace : traces) {
155  int ch = trace->channel();
156 
157  // make working area directly in simple trace to avoid memory fragmentation
158  SimpleTrace* signal = new SimpleTrace(ch, 0, m_nticks);
159  bychan[ch] = signal;
160 
161  // if good
162  if (find(bad_channels.begin(), bad_channels.end(),ch) == bad_channels.end()) {
163 
164  auto const& charge = trace->charge();
165  const size_t ncharges = charge.size();
166 
167  signal->charge().assign(charge.begin(), charge.begin() + std::min(m_nticks, ncharges));
168  signal->charge().resize(m_nticks, 0.0);
169 
170  if (ncharges != m_nticks) {
171  nchanged_samples += std::abs((int)m_nticks - (int)ncharges);
172  }
173 
174  }
175 
176  int filt_count=0;
177  for (auto filter : m_perchan) {
178  auto masks = filter->apply(ch, signal->charge());
179 
180  // fixme: probably should assure these masks do not lead to out-of-bounds...
181 
182  Waveform::merge(cmm,masks,m_maskmap);
183  ++filt_count;
184  }
185  }
186  traces.clear(); // done with our copy of vector of shared pointers
187 
188  if (nchanged_samples) {
189  log->warn("OmnibusNoiseFilter: warning, truncated or extended {} samples", nchanged_samples);
190  }
191 
192  int group_counter = 0;
193  int nunknownchans=0;
194  for (auto group : m_noisedb->coherent_channels()) {
195  ++group_counter;
196 
197  int flag = 1;
198 
200  for (auto ch : group) { // fix me: check if we don't actually have this channel
201  // std::cout << group_counter << " " << ch << " " << std::endl;
202  if (bychan.find(ch)==bychan.end()) {
203  ++nunknownchans;
204  flag = 0;
205  }
206  else{
207  chgrp[ch] = bychan[ch]->charge(); // copy...
208  }
209  }
210 
211  if (flag == 0) continue;
212 
213  for (auto filter : m_grouped) {
214  auto masks = filter->apply(chgrp);
215 
216  Waveform::merge(cmm,masks,m_maskmap);
217  }
218 
219  for (auto cs : chgrp) {
220  // cs.second; // copy
221  bychan[cs.first]->charge().assign(cs.second.begin(), cs.second.end());
222  }
223  }
224 
225  if (nunknownchans) {
226  log->debug("OmnibusNoiseFilter: {} unknown channels (probably the channel selector is in use)", nunknownchans);
227  }
228 
229  // run status
230  for (auto& it : bychan) {
231  const int ch = it.first;
232  IChannelFilter::signal_t& signal = it.second->charge();
233  for (auto filter : m_perchan_status) {
234  auto masks = filter->apply(ch, signal);
235 
236  Waveform::merge(cmm,masks,m_maskmap);
237  }
238  }
239 
240  ITrace::vector itraces;
241  for (auto& cs : bychan) { // fixme: that tbin though
242  itraces.push_back(ITrace::pointer(cs.second));
243  }
244 
245  bychan.clear();
246 
247  auto sframe = new SimpleFrame(inframe->ident(), inframe->time(), itraces, inframe->tick(), cmm);
248  IFrame::trace_list_t indices(itraces.size());
249  for (size_t ind=0; ind<itraces.size(); ++ind) {
250  indices[ind] = ind;
251  }
252  sframe->tag_traces(m_outtag, indices);
253  sframe->tag_frame("noisefilter");
254  outframe = IFrame::pointer(sframe);
255 
256  return true;
257 }
258 
259 
260 // Local Variables:
261 // mode: c++
262 // c-basic-offset: 4
263 // End:
static QCString name
Definition: declinfo.cpp:673
std::shared_ptr< const ITrace > pointer
Definition: IData.h:19
std::vector< WireCell::IChannelFilter::pointer > m_perchan
virtual void configure(const WireCell::Configuration &config)
IConfigurable interface.
std::pair< int, int > BinRange
A half-open range of bins (from first bin to one past last bin)
Definition: Waveform.h:38
Waveform::realseq_t signal_t
STL namespace.
std::map< std::string, std::string > m_maskmap
cfg
Definition: dbjson.py:29
std::vector< pointer > vector
Definition: IData.h:21
std::map< int, BinRangeList > ChannelMasks
Map channel number to a vector of BinRanges.
Definition: Waveform.h:50
virtual bool operator()(const input_pointer &in, output_pointer &out)
IFrameFilter interface.
BinRangeList merge(const BinRangeList &br)
Return a new list with any overlaps formed into unions.
Definition: Waveform.cxx:222
std::vector< WireCell::IChannelFilter::pointer > m_grouped
T abs(T value)
std::shared_ptr< const IFrame > input_pointer
Definition: IFunctionNode.h:39
virtual WireCell::Configuration default_configuration() const
Optional, override to return a hard-coded default configuration.
Configuration find(Configuration &lst, const std::string &dotpath, const T &val)
Return dictionary in given list if it value at dotpath matches.
std::map< std::string, ChannelMasks > ChannelMaskMap
Collect channel masks by some label.
Definition: Waveform.h:59
constexpr std::array< std::size_t, geo::vect::dimension< Vector >)> indices()
Returns a sequence of indices valid for a vector of the specified type.
std::shared_ptr< const IFrame > output_pointer
Definition: IFunctionNode.h:40
logptr_t logger(std::string name)
Definition: Logging.cxx:71
void log(source_loc source, level::level_enum lvl, const char *fmt, const Args &...args)
Definition: spdlog.h:165
std::vector< WireCell::IChannelFilter::pointer > m_perchan_status
Definition: Main.h:22
std::map< int, signal_t > channel_signals_t
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
ChargeSequence & charge()
Definition: SimpleTrace.h:26
WireCell::ITrace::vector tagged_traces(WireCell::IFrame::pointer frame, WireCell::IFrame::tag_t tag)
Json::Value Configuration
Definition: Configuration.h:50
WireCell::IChannelNoiseDatabase::pointer m_noisedb
WIRECELL_FACTORY(OmnibusNoiseFilter, WireCell::SigProc::OmnibusNoiseFilter, WireCell::IFrameFilter, WireCell::IConfigurable) using namespace WireCell
const char * cs
std::vector< size_t > trace_list_t
Definition: IFrame.h:36