SimpleChannelNoiseDB.cxx
Go to the documentation of this file.
3 #include "WireCellUtil/Binning.h"
4 
6 
9 
10 
11 
12 using namespace WireCell;
13 using namespace WireCell::SigProc;
14 
16  : m_tick(-1)
17  , m_nsamples(-1)
18  , m_default_baseline(0.0)
19  , m_default_gain(1.0)
20  , m_default_offset(0.0)
21  , m_default_min_rms(0.5)
22  , m_default_max_rms(10)
23  , m_default_pad_f(0)
24  , m_default_pad_b(0)
25  , m_default_decon_limit(0.02)
26  , m_default_decon_lf_cutoff(0.08)
27  , m_default_adc_limit(15.0)
28  , m_default_decon_limit1(0.08)
29  , m_default_protection_factor(5.0)
30  , m_default_min_adc_limit(50)
31  , m_default_roi_min_max_ratio(0.8)
32 {
33  set_sampling(tick, nsamples);
34 }
35 SimpleChannelNoiseDB::~SimpleChannelNoiseDB()
36 {
37 }
38 
39 
40 
42 {
43  const int ind = chind(channel);
44  if (0 <= ind && ind < (int)m_baseline.size()) {
45  return m_baseline[ind];
46  }
47  return m_default_baseline;
48 }
49 
51 {
52  const int ind = chind(channel);
53  if (0 <= ind && ind < (int)m_gain.size()) {
54  return m_gain[ind];
55  }
56  return m_default_gain;
57 }
58 
60 {
61  const int ind = chind(channel);
62  if (0 <= ind && ind < (int)m_offset.size()) {
63  return m_offset[ind];
64  }
65  return m_default_offset;
66 
67 }
68 
70 {
71  const int ind = chind(channel);
72  if (0 <= ind && ind < (int)m_min_rms.size()) {
73  return m_min_rms[ind];
74  }
75  return m_default_min_rms;
76 }
77 
79 {
80  const int ind = chind(channel);
81  if (0 <= ind && ind < (int)m_max_rms.size()) {
82  return m_max_rms[ind];
83  }
84  return m_default_max_rms;
85 }
86 
87 
88 
90 {
91  const int ind = chind(channel);
92  if (0 <= ind && ind < (int)m_pad_f.size()) {
93  return m_pad_f[ind];
94  }
95  return m_default_pad_f;
96 
97 }
98 
100 {
101  const int ind = chind(channel);
102  if (0 <= ind && ind < (int)m_pad_b.size()) {
103  return m_pad_b[ind];
104  }
105  return m_default_pad_b;
106 
107 }
108 
110 {
111  const int ind = chind(channel);
112  if (0 <= ind && ind < (int)m_decon_limit.size()) {
113  return m_decon_limit[ind];
114  }
115  return m_default_decon_limit;
116 }
117 
119 {
120  const int ind = chind(channel);
121  if (0 <= ind && ind < (int)m_decon_lf_cutoff.size()) {
122  return m_decon_lf_cutoff[ind];
123  }
125 }
126 
128 {
129  const int ind = chind(channel);
130  if (0 <= ind && ind < (int)m_decon_limit1.size()) {
131  return m_decon_limit1[ind];
132  }
133  return m_default_decon_limit1;
134 }
135 
137 {
138  const int ind = chind(channel);
139  if (0 <= ind && ind < (int)m_adc_limit.size()) {
140  return m_adc_limit[ind];
141  }
142  return m_default_adc_limit;
143 }
144 
146 {
147  const int ind = chind(channel);
148  if (0 <= ind && ind < (int)m_protection_factor.size()) {
149  return m_protection_factor[ind];
150  }
152 }
153 
155 {
156  const int ind = chind(channel);
157  if (0 <= ind && ind < (int)m_min_adc_limit.size()) {
158  return m_min_adc_limit[ind];
159  }
161 }
162 
163 
165 {
166  const int ind = chind(channel);
167  if (0 <= ind && ind < (int)m_roi_min_max_ratio.size()) {
168  return m_roi_min_max_ratio[ind];
169  }
171 }
172 
173 
175 {
176  const int ind = chind(channel);
177  //std::cerr << "ch=" << channel << " ind=" << ind << " " << fv.size() << std::endl;
178  if (0 <= ind && ind < (int)fv.size()) {
179  const shared_filter_t sf = fv[ind];
180  if (sf == nullptr) {
181  return *(m_default_filter.get());
182  }
183 
184  const filter_t* filtp = sf.get();
185  return *filtp;
186  }
187  const filter_t* filtp = m_default_filter.get();
188  //std::cerr << "Filter: "<< (void*)filtp << std::endl;
189  return *filtp;
190 }
191 
193 {
194  return get_filter(channel, m_rcrc);
195 }
196 
198 {
199  return get_filter(channel, m_config);
200 }
201 
203 {
204  return get_filter(channel, m_masks);
205 }
206 
208 {
209  return get_filter(channel, m_response);
210 }
211 
212 
213 void SimpleChannelNoiseDB::set_sampling(double tick, int nsamples)
214 {
215 
216  if (m_nsamples == nsamples && tick == m_tick) {
217  //std::cerr << "Sampling unchanged: " << nsamples << " @ " << m_tick/units::ms << " ms" << std::endl;
218  return;
219  }
220  m_nsamples = nsamples;
221  m_tick = tick;
222 
223  m_rcrc.clear();
224  m_config.clear();
225  m_response.clear();
226 
227  Waveform::compseq_t spectrum;
228  spectrum.resize(nsamples,std::complex<float>(1,0));
229  m_default_filter = std::make_shared<filter_t>(spectrum);
231  m_default_response = std::make_shared<filter_t>(empty);
232 }
233 
234 // set one thing in a vector at the index, resizing if needed, use def
235 // to back fill in case of resizing
236 template<typename T>
237 void set_one(int ind, T val, std::vector<T>& vec, T def)
238 {
239  if (ind >= (int)vec.size()) {
240  vec.resize(ind+1, def);
241  }
242  vec[ind] = val;
243 }
244 
245 void SimpleChannelNoiseDB::set_nominal_baseline(const std::vector<int>& channels, double baseline)
246 {
247  //std::cerr << "SimpleChannelNoiseDB: set baseline to " << channels.size() << " chans: " << baseline << std::endl;
248  for (auto ch : channels) {
249  set_one(chind(ch), baseline, m_baseline, m_default_baseline);
250  }
251 }
252 void SimpleChannelNoiseDB::set_rcrc_constant(const std::vector<int>& channels, double rcrc)
253 {
254  Response::SimpleRC rcres(rcrc,m_tick);
255  //auto signal = rcres.generate(WireCell::Waveform::Domain(0, m_nsamples*m_tick), m_nsamples);
256  // auto signal = rcres.generate(WireCell::Binning(m_nsamples, 0, m_nsamples*m_tick));
258 
259  Waveform::compseq_t spectrum = Waveform::dft(signal);
260 
261  //std::cout << rcrc << " " << m_tick << " " << m_nsamples << " " << signal.front() << " " << signal.at(1) << " " << signal.at(2) << std::endl;
262 
263  // get the square of it because there are two RC filters
264  Waveform::compseq_t spectrum2 = spectrum;
265  Waveform::scale(spectrum2,spectrum);
266  // for (auto it : spectrum){
267  // float real_part = it.real();
268  // float imag_part = it.imag();
269  // std::complex<float> temp(real_part*real_part-imag_part*imag_part,2*real_part*imag_part);
270  // spectrum2.push_back(temp);
271  // }
272 
273  // std::cerr << "SimpleChannelNoiseDB:: get rcrc as: " << rcrc
274  // << " sum=" << Waveform::sum(spectrum2)
275  // << std::endl;
276 
277  auto filt = std::make_shared<filter_t>(spectrum2);
278 
279  for (auto ch : channels) {
281  }
282 }
283 
284 void SimpleChannelNoiseDB::set_response(const std::vector<int>& channels, const filter_t& spectrum)
285 {
286  //std::cerr << "SimpleChannelNoiseDB: set respnose on " << channels.size() << " chans with: " << spectrum.size() << " samples\n";
287 
288  auto filt = std::make_shared<filter_t>(spectrum);
289  for (auto ch : channels) {
291  }
292 
293 }
294 
296  double from_gain, double to_gain,
297  double from_shaping, double to_shaping)
298 {
299  const double gain_ratio = to_gain/from_gain;
300  // std::cerr << "SimpleChannelNoiseDB: set gain/shaping on " << channels.size() << " chans to: "
301  // << "g=" << from_gain << "->" << to_gain << ", "
302  // << "s=" << from_shaping << "->" << to_shaping << ", "
303  // << "rat=" << gain_ratio
304  // << "m_tick=" << m_tick/units::us << " us"
305  // << "\n";
306 
307 
308  Response::ColdElec from_ce(from_gain, from_shaping);
309  Response::ColdElec to_ce(to_gain, to_shaping);
310  // auto to_sig = to_ce.generate(WireCell::Binning(m_nsamples, 0, m_nsamples*m_tick));
311  // auto from_sig = from_ce.generate(WireCell::Binning(m_nsamples, 0, m_nsamples*m_tick));
313  auto from_sig = from_ce.generate(WireCell::Waveform::Domain(0, m_nsamples*m_tick), m_nsamples);
314 
315  auto to_filt = Waveform::dft(to_sig);
316  auto from_filt = Waveform::dft(from_sig);
317 
318  // auto from_filt_sum = Waveform::sum(from_filt);
319  // auto to_filt_sum = Waveform::sum(to_filt);
320 
321  Waveform::shrink(to_filt, from_filt); // divide
322  auto filt = std::make_shared<filter_t>(to_filt);
323 
324  //std::cout << filt->at(0) << " " << filt->at(1) << std::endl;
325  // std::cerr << "SimpleChannelNoiseDB: "
326  // << " from_sig sum=" << Waveform::sum(from_sig)
327  // << " to_sig sum=" << Waveform::sum(to_sig)
328  // << " from_filt sum=" << from_filt_sum
329  // << " to_filt sum=" << to_filt_sum
330  // << " rat_filt sum=" << Waveform::sum(to_filt)
331  // << std::endl;
332 
333 
334  for (auto ch : channels) {
335  int ind = chind(ch);
337  set_one(ind, gain_ratio, m_gain, m_default_gain);
338  }
339 }
340 
341 void SimpleChannelNoiseDB::set_response_offset(const std::vector<int>& channels, double offset)
342 {
343  //std::cerr << "SimpleChannelNoiseDB: set response offset " << channels.size() << " chans to: " << offset << std::endl;
344  for (auto ch : channels) {
345  int ind = chind(ch);
346  set_one(ind, offset, m_offset, m_default_offset);
347  }
348 }
349 
350 
351 
352 void SimpleChannelNoiseDB::set_min_rms_cut(const std::vector<int>& channels, double min_rms)
353 {
354  //std::cerr << "SimpleChannelNoiseDB: set min rms cut on "<<channels.size()<<":[" << channels.front() << "," << channels.back() << "] to: " << min_rms << std::endl;
355  for (auto ch : channels) {
356  int ind = chind(ch);
357  set_one(ind, min_rms, m_min_rms, m_default_min_rms);
358  }
359 }
360 
361 void SimpleChannelNoiseDB::set_min_rms_cut_one(int ch, double min_rms)
362 {
363  //std::cerr << "SimpleChannelNoiseDB: set min rms cut on " << ch << " to: " << min_rms << std::endl;
364  int ind = chind(ch);
365  set_one(ind, min_rms, m_min_rms, m_default_min_rms);
366 }
367 
368 
369 
370 void SimpleChannelNoiseDB::set_max_rms_cut(const std::vector<int>& channels, double max_rms)
371 {
372  //std::cerr << "SimpleChannelNoiseDB: set max rms cut on "<<channels.size()<<":[" << channels.front() << "," << channels.back() << "] to: " << max_rms << std::endl;
373  for (auto ch : channels) {
374  int ind = chind(ch);
375  set_one(ind, max_rms, m_max_rms, m_default_max_rms);
376  }
377 }
378 
379 void SimpleChannelNoiseDB::set_max_rms_cut_one(int ch, double max_rms)
380 {
381  //std::cerr << "SimpleChannelNoiseDB: set max rms cut on " << ch << " to: " << max_rms << std::endl;
382  int ind = chind(ch);
383  set_one(ind, max_rms, m_max_rms, m_default_max_rms);
384 }
385 
386 
387 void SimpleChannelNoiseDB::set_pad_window_front(const std::vector<int>& channels, int pad_f)
388 {
389  //std::cerr << "SimpleChannelNoiseDB: set pad window front on " << channels.size() << " channels: " << pad_f << std::endl;
390  for (auto ch : channels) {
391  int ind = chind(ch);
392  set_one(ind, pad_f, m_pad_f, m_default_pad_f);
393  }
394 }
395 
396 void SimpleChannelNoiseDB::set_pad_window_back(const std::vector<int>& channels, int pad_b)
397 {
398  //std::cerr << "SimpleChannelNoiseDB: set pad window back on " << channels.size() << " channels: " << pad_b << std::endl;
399  for (auto ch : channels) {
400  int ind = chind(ch);
401  set_one(ind, pad_b, m_pad_b, m_default_pad_b);
402  }
403 }
404 
405 void SimpleChannelNoiseDB::set_coherent_nf_decon_limit(const std::vector<int>& channels, float decon_limit)
406 {
407  //std::cerr << "SimpleChannelNoiseDB: set pad window back on " << channels.size() << " channels: " << pad_b << std::endl;
408  for (auto ch : channels) {
409  int ind = chind(ch);
410  set_one(ind, decon_limit, m_decon_limit, m_default_decon_limit);
411  }
412 }
413 
414 void SimpleChannelNoiseDB::set_coherent_nf_decon_lf_cutoff(const std::vector<int>& channels, float decon_lf_cutoff)
415 {
416  //std::cerr << "SimpleChannelNoiseDB: set pad window back on " << channels.size() << " channels: " << pad_b << std::endl;
417  for (auto ch : channels) {
418  int ind = chind(ch);
419  set_one(ind, decon_lf_cutoff, m_decon_lf_cutoff, m_default_decon_lf_cutoff);
420  }
421 }
422 
423 
424 void SimpleChannelNoiseDB::set_coherent_nf_decon_limit1(const std::vector<int>& channels, float decon_limit1)
425 {
426  //std::cerr << "SimpleChannelNoiseDB: set pad window back on " << channels.size() << " channels: " << pad_b << std::endl;
427  for (auto ch : channels) {
428  int ind = chind(ch);
429  set_one(ind, decon_limit1, m_decon_limit1, m_default_decon_limit1);
430  }
431 }
432 
433 void SimpleChannelNoiseDB::set_coherent_nf_adc_limit(const std::vector<int>& channels, float adc_limit)
434 {
435  //std::cerr << "SimpleChannelNoiseDB: set pad window back on " << channels.size() << " channels: " << pad_b << std::endl;
436  for (auto ch : channels) {
437  int ind = chind(ch);
438  set_one(ind, adc_limit, m_adc_limit, m_default_adc_limit);
439  }
440 }
441 
442 void SimpleChannelNoiseDB::set_coherent_nf_protection_factor(const std::vector<int>& channels, float protection_factor)
443 {
444  //std::cerr << "SimpleChannelNoiseDB: set pad window back on " << channels.size() << " channels: " << pad_b << std::endl;
445  for (auto ch : channels) {
446  int ind = chind(ch);
447  set_one(ind, protection_factor, m_protection_factor, m_default_protection_factor);
448  }
449 }
450 
451 void SimpleChannelNoiseDB::set_coherent_nf_min_adc_limit(const std::vector<int>& channels, float min_adc_limit)
452 {
453  //std::cerr << "SimpleChannelNoiseDB: set pad window back on " << channels.size() << " channels: " << pad_b << std::endl;
454  for (auto ch : channels) {
455  int ind = chind(ch);
456  set_one(ind, min_adc_limit, m_min_adc_limit, m_default_min_adc_limit);
457  }
458 }
459 
460 void SimpleChannelNoiseDB::set_coherent_nf_roi_min_max_ratio(const std::vector<int>& channels, float roi_min_max_ratio)
461 {
462  //std::cerr << "SimpleChannelNoiseDB: set pad window back on " << channels.size() << " channels: " << pad_b << std::endl;
463  for (auto ch : channels) {
464  int ind = chind(ch);
465  set_one(ind, roi_min_max_ratio, m_roi_min_max_ratio, m_default_roi_min_max_ratio);
466  }
467 }
468 
469 void SimpleChannelNoiseDB::set_filter(const std::vector<int>& channels, const multimask_t& masks)
470 {
471  Waveform::compseq_t spectrum;
472  spectrum.resize(m_nsamples,std::complex<float>(1,0));
473 
474  for (auto m : masks) {
475  for (int ind=get<1>(m); ind <= get<2>(m); ++ind) {
476  //filt->assign(ind, get<0>(m));
477  spectrum.at(ind) = get<0>(m);
478  }
479  //std::cerr << "set freqmasks: " << get<1>(m) << " " << get<2>(m) << " " << get<0>(m) << " " << spectrum.at(0) << " " << spectrum.at(169) << " " << spectrum.at(170)<< std::endl;
480  }
481  auto filt = std::make_shared<filter_t>(spectrum);
482 
483 
484  for (auto ch : channels) {
485  set_one(chind(ch), filt, m_masks, m_default_filter);
486  }
487 
488 }
489 
490 
491 
492 
493 void SimpleChannelNoiseDB::set_channel_groups(const std::vector< channel_group_t >& channel_groups)
494 {
495  //std::cerr << "SimpleChannelNoiseDB: channel groups: " << channel_groups.size() << " X " << channel_groups[0].size() << std::endl;
496  m_channel_groups = channel_groups;
497 }
498 
499 
501 {
502  //std::cerr << "SimpleChannelNoiseDB:: bad channels: " << bc.size() << std::endl;
503  m_bad_channels = bc;
504 }
505 
507 {
508  auto it = m_ch2ind.find(ch);
509  if (it == m_ch2ind.end()) {
510  int ind = m_ch2ind.size();
511  m_ch2ind[ch] = ind;
512  return ind;
513  }
514  return it->second;
515 }
516 
517 // Local Variables:
518 // mode: c++
519 // c-basic-offset: 4
520 // End:
static const double m
Definition: Units.h:79
void set_coherent_nf_decon_lf_cutoff(const std::vector< int > &channels, float decon_lf_cutoff)
void set_coherent_nf_decon_limit(const std::vector< int > &channels, float decon_limit)
virtual int pad_window_back(int channel) const
void set_one(int ind, T val, std::vector< T > &vec, T def)
void set_gains_shapings(const std::vector< int > &channels, double from_gain_mVfC=7.8, double to_gain_mVfC=14.0, double from_shaping=1.0 *units::us, double to_shaping=2.0 *units::us)
void set_coherent_nf_protection_factor(const std::vector< int > &channels, float protection_factor)
void set_max_rms_cut(const std::vector< int > &channels, double max_rms)
virtual const filter_t & config(int channel) const
Return the filter to correct any wrongly configured channels.
void set_coherent_nf_min_adc_limit(const std::vector< int > &channels, float min_adc_limit)
virtual double min_rms_cut(int channel) const
virtual int pad_window_front(int channel) const
void set_coherent_nf_roi_min_max_ratio(const std::vector< int > &channels, float roi_min_max_ratio)
void set_max_rms_cut_one(int channel, double max_rms)
void set_nominal_baseline(const std::vector< int > &channels, double baseline)
Set nominal baseline in units of ADC (eg uB is -2048 for U/V, -400 for W)
void set_rcrc_constant(const std::vector< int > &channels, double rcrc=2000.0)
A functional object caching gain and shape.
Definition: Response.h:165
const double tick
void set_filter(const std::vector< int > &channels, const multimask_t &mask)
void set_min_rms_cut(const std::vector< int > &channels, double min_rms)
virtual float coherent_nf_roi_min_max_ratio(int channel) const
compseq_t dft(realseq_t seq)
Definition: Waveform.cxx:141
std::pair< double, double > Domain
Definition: Waveform.h:75
std::unordered_map< int, int > m_ch2ind
void shrink(Sequence< Val > &seq, const Sequence< Val > &other)
Shrink (divide) seq values by values from the other sequence.
Definition: Waveform.h:162
void set_pad_window_front(const std::vector< int > &channels, int pad_f)
virtual const filter_t & response(int channel) const
A nominal detector response spectrum for a given channel.
virtual float coherent_nf_adc_limit(int channel) const
WireCell::Waveform::realseq_t generate(const WireCell::Waveform::Domain &domain, int nsamples)
FIXME: eradicate Domain in favor of Binning.
Definition: Response.cxx:303
WIRECELL_FACTORY(testChannelNoiseDB, WireCell::SigProc::SimpleChannelNoiseDB, WireCell::IChannelNoiseDatabase) using namespace WireCell
void set_min_rms_cut_one(int channel, double min_rms)
void set_response_offset(const std::vector< int > &channels, double offset)
Set a response offset for the given set of channels.
virtual float coherent_nf_decon_limit1(int channel) const
void set_coherent_nf_decon_limit1(const std::vector< int > &channels, float decon_limit)
WireCell::Waveform::compseq_t filter_t
The data type for all frequency-space, multiplicative filters.
virtual double max_rms_cut(int channel) const
Definition: Main.h:22
virtual double response_offset(int channel) const
Return a time offset associated with the response().
virtual float coherent_nf_protection_factor(int channel) const
void scale(Sequence< Val > &seq, Val scalar)
Scale (multiply) sequence values by scalar.
Definition: Waveform.h:146
virtual float coherent_nf_min_adc_limit(int channel) const
void set_response(const std::vector< int > &channels, const filter_t &spectrum)
Set a detector response spectrum for the set of channels.
virtual const filter_t & noise(int channel) const
Return the filter to attenuate noise.
std::shared_ptr< filter_t > shared_filter_t
const IChannelNoiseDatabase::filter_t & get_filter(int channel, const filter_vector_t &fv) const
void set_channel_groups(const std::vector< channel_group_t > &channel_groups)
Set the channel groups.
virtual float coherent_nf_decon_limit(int channel) const
std::vector< shared_filter_t > filter_vector_t
void set_pad_window_back(const std::vector< int > &channels, int pad_b)
std::vector< channel_group_t > m_channel_groups
virtual const filter_t & rcrc(int channel) const
Return the filter for the RC+RC coupling response function.
virtual float coherent_nf_decon_lf_cutoff(int channel) const
void set_coherent_nf_adc_limit(const std::vector< int > &channels, float adc_limit)
Sequence< complex_t > compseq_t
A complex-valued sequence, eg for discrete spectrum powers.
Definition: Waveform.h:34
void set_bad_channels(const channel_group_t &bc)
Set "bad" channels.
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:92
void set_sampling(double tick=0.5 *units::us, int nsamples=9600)
virtual double nominal_baseline(int channel) const
Return a nominal baseline correction (additive offset)
virtual double gain_correction(int channel) const