11 using namespace WireCell::SigProc;
15 : m_tick(0.5*units::
us)
21 OmniChannelNoiseDB::~OmniChannelNoiseDB()
40 , decon_lf_cutoff(0.08)
43 , protection_factor(5.0)
45 , roi_min_max_ratio(0.8)
64 cfg[
"anode"] =
"AnodePlane";
65 cfg[
"field_response"] =
"FieldResponse";
68 cfg[
"groups"] = Json::arrayValue;
69 cfg[
"channel_info"] = Json::arrayValue;
101 if (jchannels.isInt()) {
102 ret.push_back(jchannels.asInt());
107 if (jchannels.isArray()) {
108 const int nch = jchannels.size();
110 for (
int ind=0; ind<nch; ++ind) {
111 ret[ind] = jchannels[ind].asInt();
119 if (jchannels.isMember(
"first") && jchannels.isMember(
"last")) {
120 const int chf = jchannels[
"first"].asInt();
121 const int chl = jchannels[
"last"].asInt();
122 const int nch = chl-chf+1;
124 for (
int ind=0; ind < nch; ++ind) {
125 ret[ind] = chf + ind;
131 if (jchannels.isMember(
"wpid")) {
133 for (
auto ch :
m_anode->channels()) {
134 if (
m_anode->resolve(ch) == wpid) {
146 return std::make_shared<filter_t>(
m_nsamples, defval);
160 auto spectrum =
make_filter(std::complex<float>(1,0));
161 for (
auto jone : jfm) {
162 double value = jone[
"value"].asDouble();
163 int lo =
std::max(jone[
"lobin"].asInt(), 0);
166 for (
int ind=lo; ind <= hi; ++ind) {
167 spectrum->at(ind) =
value;
175 if (jrcrc.isNull()) {
178 const double rcrc_val = jrcrc.asDouble();
207 auto ret = std::make_shared<filter_t>(spectrum2);
216 if (jreconfig.empty()) {
220 const double from_gain = jreconfig[
"from"][
"gain"].asDouble();
221 const double to_gain = jreconfig[
"to"][
"gain"].asDouble();
222 return to_gain/from_gain;
227 if (jreconfig.empty()) {
231 const double from_gain = jreconfig[
"from"][
"gain"].asDouble();
232 const double from_shaping = jreconfig[
"from"][
"shaping"].asDouble();
233 const double to_gain = jreconfig[
"to"][
"gain"].asDouble();
234 const double to_shaping = jreconfig[
"to"][
"shaping"].asDouble();
237 return get_reconfig(from_gain, from_shaping, to_gain, to_shaping);
240 double to_gain,
double to_shaping)
276 auto filt = std::make_shared<filter_t>(to_filt);
293 double from_gain,
double from_shaping,
294 double to_gain,
double to_shaping,
299 for (
auto& it :
m_db) {
300 it.second.config = def;
304 for (
int ch : channels) {
315 if (jfilt.isMember(
"wpid")) {
321 auto const& fr =
m_fr->field_response();
323 auto const& pr = fravg.planes[wpid.
index()];
327 for (
auto const& path : pr.paths) {
328 auto const&
current = path.current;
330 for (
size_t ind=0; ind<nsamp; ++ind) {
335 auto ret = std::make_shared<filter_t>(spectrum);
340 if (jfilt.isMember(
"waveform") && jfilt.isMember(
"waveformid")) {
341 int id = jfilt[
"waveformid"].asInt();
347 auto jwave = jfilt[
"waveform"];
352 for (
int ind=0; ind<nsamp; ++ind) {
353 waveform[ind] = jwave[ind].asFloat();
357 auto ret = std::make_shared<filter_t>(spectrum);
371 auto it =
m_db.find(chid);
372 if (it ==
m_db.end()) {
379 template<
typename Type>
382 std::sort(chans.begin(), chans.end());
390 if (cfg.isMember(
"nominal_baseline")) {
391 double val = cfg[
"nominal_baseline"].asDouble();
393 for (
int ch : chans) {
399 if (cfg.isMember(
"gain_correction")) {
400 double val = cfg[
"gain_correction"].asDouble();
402 for (
int ch : chans) {
410 auto jfilt = cfg[
"reconfig"];
411 if (!jfilt.isNull()) {
414 for (
int ch : chans) {
422 if (cfg.isMember(
"response_offset")) {
423 double val = cfg[
"response_offset"].asDouble();
425 for (
int ch : chans) {
431 if (cfg.isMember(
"min_rms_cut")) {
432 double val = cfg[
"min_rms_cut"].asDouble();
434 for (
int ch : chans) {
440 if (cfg.isMember(
"max_rms_cut")) {
441 double val = cfg[
"max_rms_cut"].asDouble();
443 for (
int ch : chans) {
449 if (cfg.isMember(
"pad_window_front")) {
450 int val = cfg[
"pad_window_front"].asDouble();
452 for (
int ch : chans) {
458 if (cfg.isMember(
"pad_window_back")) {
459 int val = cfg[
"pad_window_back"].asDouble();
461 for (
int ch : chans) {
468 if (cfg.isMember(
"decon_limit")) {
469 float val = cfg[
"decon_limit"].asDouble();
471 for (
int ch : chans) {
478 if (cfg.isMember(
"decon_lf_cutoff")) {
479 float val = cfg[
"decon_lf_cutoff"].asDouble();
480 dump_cfg(
"deconlfcutoff", chans, val);
481 for (
int ch : chans) {
488 if (cfg.isMember(
"decon_limit1")) {
489 float val = cfg[
"decon_limit1"].asDouble();
490 dump_cfg(
"deconlimit1", chans, val);
491 for (
int ch : chans) {
497 if (cfg.isMember(
"adc_limit")) {
498 float val = cfg[
"adc_limit"].asDouble();
500 for (
int ch : chans) {
506 if (cfg.isMember(
"protection_factor")) {
507 float val = cfg[
"protection_factor"].asDouble();
508 dump_cfg(
"protectionfactor", chans, val);
509 for (
int ch : chans) {
513 if (cfg.isMember(
"min_adc_limit")) {
514 float val = cfg[
"min_adc_limit"].asDouble();
515 dump_cfg(
"minadclimit", chans, val);
516 for (
int ch : chans) {
522 if (cfg.isMember(
"roi_min_max_ratio")) {
523 float val = cfg[
"roi_min_max_ratio"].asDouble();
524 dump_cfg(
"roiminmaxratio", chans, val);
525 for (
int ch : chans) {
531 auto jfilt = cfg[
"rcrc"];
532 if (!jfilt.isNull()) {
533 if (cfg.isMember(
"rc_layers")){
539 for (
int ch : chans) {
547 auto jfilt = cfg[
"reconfig"];
548 if (!jfilt.isNull()) {
551 for (
int ch : chans) {
562 auto jfilt = cfg[
"freqmasks"];
563 if (!jfilt.isNull()) {
567 for (
int ch : chans) {
575 auto jfilt = cfg[
"response"];
576 if (!jfilt.isNull()) {
579 for (
int ch : chans) {
594 std::string anode_tn = get<std::string>(
cfg,
"anode",
"AnodePlane");
595 m_anode = Factory::find_tn<IAnodePlane>(anode_tn);
596 std::string fr_tn = get<std::string>(
cfg,
"field_response",
"FieldResponse");
597 m_fr = Factory::find_tn<IFieldResponse>(fr_tn);
609 for(
auto ch: m_anode->channels()){
615 auto jgroups = cfg[
"groups"];
616 for (
auto jgroup: jgroups) {
617 std::vector<int> channel_group;
618 for (
auto jch: jgroup) {
619 channel_group.push_back(jch.asInt());
624 for (
auto jch : cfg[
"bad"]) {
629 log->debug(
"OmniChannelNoiseDB: setting {}:[{},{}] bad channels",
635 for (
auto jci : cfg[
"channel_info"]) {
std::unordered_map< int, shared_filter_t > m_rcrc_cache
int ident() const
Unit ID as integer.
virtual float coherent_nf_adc_limit(int channel) const
virtual void configure(const WireCell::Configuration &config)
Accept a configuration.
virtual const filter_t & config(int channel) const
Return the filter to correct any wrongly configured channels.
virtual const filter_t & noise(int channel) const
Return the filter to attenuate noise.
shared_filter_t get_reconfig(double from_gain, double from_shaping, double to_gain, double to_shaping)
virtual float coherent_nf_min_adc_limit(int channel) const
boost::error_info< struct tag_errmsg, std::string > errmsg
virtual float coherent_nf_decon_limit1(int channel) const
shared_filter_t parse_rcrc(Json::Value jrcrc, int nrc)
virtual double sample_time() const
FIXME: how to handle state changes?
IFieldResponse::pointer m_fr
std::unordered_map< int, shared_filter_t > m_response_cache
virtual int pad_window_back(int channel) const
std::vector< int > parse_channels(const Json::Value &jchannels)
Schema::FieldResponse wire_region_average(const Schema::FieldResponse &fr)
virtual double min_rms_cut(int channel) const
const ChannelInfo & dbget(int ch) const
A functional object caching gain and shape.
shared_filter_t default_filter()
ChannelInfo & get_ci(int chid)
virtual WireCell::Configuration default_configuration() const
Optional, override to return a hard-coded default configuration.
std::unordered_map< int, shared_filter_t > m_waveform_cache
QTextStream & reset(QTextStream &s)
double parse_gain(Json::Value jreconfig)
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
virtual float coherent_nf_roi_min_max_ratio(int channel) const
WireCell::Waveform::realseq_t generate(const WireCell::Waveform::Domain &domain, int nsamples)
FIXME: eradicate Domain in favor of Binning.
virtual float coherent_nf_protection_factor(int channel) const
virtual double nominal_baseline(int channel) const
Return a nominal baseline correction (additive offset)
virtual float coherent_nf_decon_lf_cutoff(int channel) const
virtual const filter_t & rcrc(int channel) const
Return the filter for the RC+RC coupling response function.
static int max(int a, int b)
virtual float coherent_nf_decon_limit(int channel) const
std::shared_ptr< filter_t > shared_filter_t
channel_group_t m_bad_channels
logptr_t logger(std::string name)
channel_group_t m_miscfg_channels
WireCell::Waveform::compseq_t filter_t
The data type for all frequency-space, multiplicative filters.
void dump_cfg(const std::string &name, std::vector< int > chans, Type val)
void update_channels(Json::Value cfg)
std::unordered_map< int, ChannelInfo > m_db
std::string format(const std::string &form, TYPES...objs)
void log(source_loc source, level::level_enum lvl, const char *fmt, const Args &...args)
shared_filter_t parse_reconfig(Json::Value jreconfig)
virtual const filter_t & response(int channel) const
A nominal detector response spectrum for a given channel.
std::unordered_map< int, shared_filter_t > m_reconfig_cache
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
const GenericPointer< typename T::ValueType > T2 value
IAnodePlane::pointer m_anode
virtual double max_rms_cut(int channel) const
virtual void set_misconfigured(const std::vector< int > &channels, double from_gain, double from_shaping, double to_gain, double to_shaping, bool reset=false)
shared_filter_t parse_response(Json::Value jreconfig)
Json::Value Configuration
virtual double response_offset(int channel) const
Return a time offset associated with the response().
virtual double gain_correction(int channel) const
cet::LibraryManager dummy("noplugin")
shared_filter_t parse_freqmasks(Json::Value jfm)
std::vector< channel_group_t > m_channel_groups
virtual int pad_window_front(int channel) const
shared_filter_t make_filter(std::complex< float > defval=std::complex< float >(1, 0))
WIRECELL_FACTORY(OmniChannelNoiseDB, WireCell::SigProc::OmniChannelNoiseDB, WireCell::IChannelNoiseDatabase, WireCell::IConfigurable) using namespace WireCell
Thrown when a wrong key or has been encountered.
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
int index() const
Layer as index number (0,1 or 2). -1 if unknown.