20 WireCell::SigProc::Microboone::OneChannelNoise,
23 WireCell::SigProc::Microboone::OneChannelStatus,
26 WireCell::SigProc::Microboone::ADCBitShift,
33 double filter_low(
double freq,
double cut_off = 0.08);
38 return (freq>0)*exp(-0.5*
pow(freq/a,b));
42 if ( (freq>0.177 && freq<0.18) || (freq > 0.2143 && freq < 0.215) ||
43 (freq >=0.106 && freq<=0.109) || (freq >0.25 && freq<0.251)){
46 return 1-exp(-
pow(freq/cut_off,8));
51 return 1-exp(-
pow(freq/0.005,2));
61 float roi_min_max_ratio)
64 double_t ave_coef1 = 0;
65 std::map<int,double> coef_all;
67 const int nbin = medians.size();
69 for (
auto it: chansig) {
84 for (
int j=0;j!=nbin;j++){
85 if (fabs(signal.at(j)) < 4 * temp.second){
86 sum2 += signal.at(j) * medians.at(j);
87 sum3 += medians.at(j) * medians.at(j);
104 ave_coef = ave_coef / ave_coef1;
107 for (
auto it: chansig) {
112 scaling = coef_all[ch]/ave_coef;
114 if (scaling < 0) scaling = 0;
116 if (scaling > 1.5) scaling = 1.5;
125 if (respec.size() > 0 && (respec.at(0).real()!=1 || respec.at(0).imag()!=0) && res_offset!=0){
126 int nbin = signal.size();
128 for (
auto roi: rois){
129 const int bin0 =
std::max(roi.front()-1, 0);
130 const int binf =
std::min(roi.back()+1, nbin-1);
131 const double m0 = signal[bin0];
132 const double mf = signal[binf];
133 const double roi_run = binf - bin0;
134 const double roi_rise = mf - m0;
135 for (
auto bin : roi) {
136 const double m = m0 + (
bin - bin0)/roi_run*roi_rise;
137 signal_roi.at(
bin) = signal.at(
bin) -
m;
144 for (
size_t i=0;i!=signal_roi_freq.size();i++){
147 if (i <signal_roi_freq.size()/2.){
148 freq = i/(1.*signal_roi_freq.size())*2.;
150 freq = (signal_roi_freq.size() - i)/(1.*signal_roi_freq.size())*2.;
153 signal_roi_freq.at(i) = signal_roi_freq.at(i) * factor;
157 std::map<int, bool> flag_replace;
158 for (
auto roi: rois){
159 flag_replace[roi.front()] =
false;
163 for (
auto roi: rois){
164 const int bin0 =
std::max(roi.front()-1, 0);
165 const int binf =
std::min(roi.back()+1, nbin-1);
168 for (
int i=bin0; i<=binf; i++){
169 int time_bin = i-res_offset;
170 if (time_bin <0) time_bin += nbin;
171 if (time_bin >=nbin) time_bin -= nbin;
173 max_val = signal_roi_decon.at(time_bin);
174 min_val = signal_roi_decon.at(time_bin);
176 if (signal_roi_decon.at(time_bin) > max_val) max_val = signal_roi_decon.at(time_bin);
177 if (signal_roi_decon.at(time_bin) < min_val) min_val = signal_roi_decon.at(time_bin);
184 if ( max_val > decon_limit1 && fabs(min_val) < max_val * roi_min_max_ratio)
185 flag_replace[roi.front()] =
true;
190 for (
auto roi : rois) {
192 const int bin0 =
std::max(roi.front()-1, 0);
193 const int binf =
std::min(roi.back()+1, nbin-1);
194 if (flag_replace[roi.front()]){
195 const double m0 = temp_medians[bin0];
196 const double mf = temp_medians[binf];
197 const double roi_run = binf - bin0;
198 const double roi_rise = mf - m0;
199 for (
auto bin : roi) {
200 const double m = m0 + (
bin - bin0)/roi_run*roi_rise;
201 temp_medians.at(
bin) =
m;
207 for (
int i=0;i!=nbin;i++){
208 if (fabs(signal.at(i)) > 0.001) {
209 signal.at(i) = signal.at(i) - temp_medians.at(i) * scaling;
216 for (
int i=0;i!=nbin;i++){
217 if (fabs(signal.at(i)) > 0.001) {
218 signal.at(i) = signal.at(i) - medians.at(i) * scaling;
222 chansig[ch] = signal;
246 const int nbin = medians.size();
255 std::vector<bool> signalsBool;
256 signalsBool.resize(nbin,
false);
263 double mean = temp.first;
264 double rms = temp.second;
269 if (protection_factor*rms > upper_adc_limit){
270 limit = protection_factor*
rms;
272 limit = upper_adc_limit;
274 if (min_adc_limit < limit){
275 limit = min_adc_limit;
280 for (
int j=0;j!=nbin;j++) {
281 float content = medians.at(j);
282 if (fabs(content-mean)>limit){
285 signalsBool.at(j) =
true;
287 for (
int k=0;
k!=pad_b;
k++){
289 if (bin > nbin-1) bin = nbin-1;
290 signalsBool.at(bin) =
true;
292 for (
int k=0;
k!=pad_f;
k++){
294 if (bin <0) { bin = 0; }
295 signalsBool.at(bin) =
true;
303 if (respec.size() > 0 && (respec.at(0).real()!=1 || respec.at(0).imag()!=0) && res_offset!=0){
309 for (
size_t i=0;i!=medians_freq.size();i++){
312 if (i <medians_freq.size()/2.){
313 freq = i/(1.*medians_freq.size())*2.;
315 freq = (medians_freq.size() - i)/(1.*medians_freq.size())*2.;
318 medians_freq.at(i) = medians_freq.at(i) * factor;
326 if (protection_factor*rms > upper_decon_limit){
327 limit = protection_factor*
rms;
329 limit = upper_decon_limit;
337 for (
int j=0;j!=nbin;j++) {
338 float content = medians_decon.at(j);
339 if ((content-mean)>limit){
340 int time_bin = j + res_offset;
341 if (time_bin >= nbin) time_bin -= nbin;
343 signalsBool.at(time_bin) =
true;
345 for (
int k=0;
k!=pad_b;
k++){
346 int bin = time_bin+
k+1;
347 if (bin > nbin-1) bin = nbin-1;
348 signalsBool.at(bin) =
true;
350 for (
int k=0;
k!=pad_f;
k++){
351 int bin = time_bin-
k-1;
352 if (bin <0) { bin = 0; }
353 signalsBool.at(bin) =
true;
417 std::vector< std::vector<int> > rois;
419 for (
int ind=0; ind<nbin; ++ind) {
421 if (signalsBool[ind]) {
422 rois.back().push_back(ind);
428 if (signalsBool[ind]) {
429 std::vector<int> roi;
439 std::map<int, bool> flag_replace;
440 for (
auto roi: rois){
441 flag_replace[roi.front()] =
true;
444 if (respec.size() > 0 && (respec.at(0).real()!=1 || respec.at(0).imag()!=0) && res_offset!=0){
445 for (
auto roi: rois){
446 flag_replace[roi.front()] =
false;
522 for (
auto roi : rois) {
524 const int bin0 =
std::max(roi.front()-1, 0);
525 const int binf =
std::min(roi.back()+1, nbin-1);
526 if (flag_replace[roi.front()]){
527 const double m0 = medians[bin0];
528 const double mf = medians[binf];
529 const double roi_run = binf - bin0;
530 const double roi_rise = mf - m0;
531 for (
auto bin : roi) {
532 const double m = m0 + (
bin - bin0)/roi_run*roi_rise;
601 if(rmsVal > max_rms || rmsVal < min_rms) {
602 int numBins = sig.size();
603 for(
int i = 0; i < numBins; i++) {
617 if (bin1 < 0 ) bin1 = 0;
618 if (bin2 > (
int)sig.size()) bin2 = sig.size();
619 for (
int i=bin1; i<bin2;i++) {
631 for (
size_t i=0;i!=sig.size();i++){
632 if (sig.at(i) < 4096) temp.push_back(sig.at(i));
642 theRMS = sqrt((
pow(par[2]-par[1],2)+
pow(par[1]-par[0],2))/2.);
650 const double sigFactor = 4.0;
651 const int padBins = 8;
654 float sigThreshold = sigFactor*rmsVal;
657 std::vector<bool> signalRegions;
658 int numBins = sig.size();
660 for (
int i = 0; i < numBins; i++) {
662 if (((ADCval > sigThreshold) || (ADCval < -1.0*sigThreshold)) && (ADCval < 4096.0)) {
663 signalRegions.push_back(
true);
666 signalRegions.push_back(
false);
670 for(
int i = 0; i < numBins; i++) {
671 if(signalRegions[i] ==
true) {
672 int bin1 = i - padBins;
676 int bin2 = i + padBins;
677 if (bin2 > numBins) {
681 for(
int j = bin1; j < bin2; j++) {
683 if(ADCval < 4096.0) {
684 sig.at(j) = sig.at(j)+20000.0;
695 const int windowSize = 20;
696 const int numBins = sig.size();
697 int minWindowBins = windowSize/2;
699 std::vector<double> baselineVec(numBins, 0.0);
700 std::vector<bool> isFilledVec(numBins,
false);
702 int numFlaggedBins = 0;
704 for(
int j = 0; j < numBins; j++) {
705 if(sig.at(j) == 10000.0) {
709 if(numFlaggedBins == numBins) {
713 double baselineVal = 0.0;
717 for(
int j = 0; j <= windowSize/2; j++) {
719 if(ADCval < 4096.0) {
720 baselineVal += ADCval;
725 if(windowBins == 0) {
726 baselineVec[0] = 0.0;
729 baselineVec[0] = baselineVal/((double) windowBins);
732 if(windowBins < minWindowBins) {
733 isFilledVec[0] =
false;
736 isFilledVec[0] =
true;
739 for(
int j = 1; j < numBins; j++) {
740 int oldIndex = j-windowSize/2-1;
741 int newIndex = j+windowSize/2;
744 ADCval = sig.at(oldIndex);
745 if(ADCval < 4096.0) {
746 baselineVal -= sig.at(oldIndex);
750 if(newIndex < numBins) {
751 ADCval = sig.at(newIndex);
753 baselineVal += sig.at(newIndex);
758 if(windowBins == 0) {
759 baselineVec[j] = 0.0;
762 baselineVec[j] = baselineVal/windowBins;
765 if(windowBins < minWindowBins) {
766 isFilledVec[j] =
false;
769 isFilledVec[j] =
true;
773 for(
int j = 0; j < numBins; j++) {
774 bool downFlag =
false;
778 if(ADCval != 10000.0) {
779 if(isFilledVec[j] ==
false) {
781 while((isFilledVec[downIndex] ==
false) && (downIndex > 0) && (sig.at(downIndex) != 10000.0)) {
785 if(isFilledVec[downIndex] ==
false) {
790 while((isFilledVec[upIndex] ==
false) && (upIndex < numBins-1) && (sig.at(upIndex) != 10000.0)) {
794 if(isFilledVec[upIndex] ==
false) {
798 if((downFlag ==
false) && (upFlag ==
false)) {
799 baselineVec[j] = ((j-downIndex)*baselineVec[downIndex]+(upIndex-j)*baselineVec[upIndex])/((
double) upIndex-downIndex);
801 else if((downFlag ==
true) && (upFlag ==
false)) {
802 baselineVec[j] = baselineVec[upIndex];
804 else if((downFlag ==
false) && (upFlag ==
true)) {
805 baselineVec[j] = baselineVec[downIndex];
808 baselineVec[j] = 0.0;
812 sig.at(j) = ADCval -baselineVec[j];
823 int numBins = sig.size();
824 for(
int i = 0; i < numBins; i++) {
825 double ADCval = sig.at(i);
826 if (ADCval > 4096.0) {
827 if(ADCval > 10000.0) {
828 sig.at(i) = ADCval-20000.0;
851 , m_noisedb_tn(noisedb) {}
886 const int achannel = chansig.begin()->first;
891 const int res_offset =
m_noisedb->response_offset(achannel);
892 const int pad_f =
m_noisedb->pad_window_front(achannel);
893 const int pad_b =
m_noisedb->pad_window_back(achannel);
897 const float decon_limit =
m_noisedb->coherent_nf_decon_limit(achannel);
898 const float decon_lf_cutoff =
m_noisedb->coherent_nf_decon_lf_cutoff(achannel);
899 const float adc_limit =
m_noisedb->coherent_nf_adc_limit(achannel);
900 const float decon_limit1 =
m_noisedb->coherent_nf_decon_limit1(achannel);
901 const float roi_min_max_ratio =
m_noisedb->coherent_nf_roi_min_max_ratio(achannel);
903 const float protection_factor =
m_noisedb->coherent_nf_protection_factor(achannel);
904 const float min_adc_limit =
m_noisedb->coherent_nf_min_adc_limit(achannel);
917 std::vector< std::vector<int> > rois =
Microboone::SignalProtection(medians,respec,res_offset,pad_f,pad_b,decon_limit, decon_lf_cutoff, adc_limit, protection_factor, min_adc_limit);
971 const size_t nsiglen = signal.size();
972 int nmismatchlen = 0;
977 float baseline =
m_noisedb->nominal_baseline(ch);
980 float gc =
m_noisedb->gain_correction(ch);
983 auto signal_gc = signal;
993 bool is_chirp =
m_check_chirp(signal_gc, chirped_bins.first, chirped_bins.second);
995 ret[
"chirp"][ch].push_back(chirped_bins);
997 auto wpid =
m_anode->resolve(ch);
998 const int iplane = wpid.index();
1001 if (chirped_bins.first>0 || chirped_bins.second<
int(signal.size())){
1002 ret[
"lf_noisy"][ch].push_back(chirped_bins);
1018 if (nsiglen != spec.size()) {
1025 auto const& spec =
m_noisedb->config(ch);
1028 if (nsiglen != spec.size()) {
1035 auto const& spec =
m_noisedb->noise(ch);
1038 if (nsiglen != spec.size()) {
1045 std::cerr <<
"OneChannelNoise: WARNING: "<<nmismatchlen <<
" config/data mismatches. " 1046 <<
"#spec="<<nspec <<
", #wave=" << nsiglen <<
".\n" 1047 <<
"\tResults may be suspect." 1052 spectrum.front() = 0;
1059 auto temp_signal = signal;
1060 for (
size_t i=0;i!=temp_signal.size();i++){
1061 if (fabs(temp_signal.at(i)-temp.first)>6*temp.second){
1062 temp_signal.at(i) = temp.first;
1084 temp_chirped_bins.first = 0;
1085 temp_chirped_bins.second = signal.size();
1087 auto wpid =
m_anode->resolve(ch);
1088 const int iplane = wpid.index();
1090 ret[
"lf_noisy"][ch].push_back(temp_chirped_bins);
1103 const float min_rms =
m_noisedb->min_rms_cut(ch);
1104 const float max_rms =
m_noisedb->max_rms_cut(ch);
1118 chirped_bins.first = 0;
1119 chirped_bins.second = signal.size();
1120 ret[
"noisy"][ch].push_back(chirped_bins);
1122 if (ret.find(
"lf_noisy") != ret.end()) {
1123 if(ret[
"lf_noisy"].
find(ch)!=ret[
"lf_noisy"].end())
1124 ret[
"lf_noisy"].erase(ch);
1146 , m_exam_nticks(exam_nticks)
1147 , m_threshold_sigma(threshold_sigma)
1148 , m_threshold_fix(threshold_fix)
1166 cfg[
"Number_of_ADC_bits"] =
m_nbits;
1189 for (
int i=0;i!=nbin;i++){
1190 int x = signal.at(i);
1194 s.push_back( (x & 1));
1199 counter.at(j) +=
abs(s.at(j) - s1.at(j));
1214 if (nshift!=0 && nshift < 11){
1216 ADC_bit_shifts.first = nshift;
1217 ADC_bit_shifts.second = nshift;
1219 ret[
"ADCBitShift"][ch].push_back(ADC_bit_shifts);
1222 const int nl = signal.size();
1223 std::vector<int>
x(nl,0), x_orig(nl,0);
1224 for (
int i=0;i!=
nl;i++){
1225 x_orig[i] = signal.at(i);
1226 x[i] = signal.at(i);
1229 std::set<int> fillings;
1232 for (
int i=0;i!=
nl;i++){
1235 fillings.insert(filling);
1247 int prev1_bin_content =
mean;
1248 int prev_bin_content =
mean;
1249 int next_bin_content =
mean;
1250 int next1_bin_content =
mean;
1251 int curr_bin_content;
1253 for (
int i=0;i<
nl;i=i+1){
1254 curr_bin_content =
x[i];
1256 if (
abs(curr_bin_content-mean)>exp_diff &&
1257 (
abs(curr_bin_content - prev_bin_content) > exp_diff ||
1258 abs(curr_bin_content - next_bin_content) > exp_diff)
1260 int exp_value = ( (2*prev_bin_content - prev1_bin_content) +
1261 (prev_bin_content + next_bin_content)/2. +
1262 (prev_bin_content * 2./3. + next1_bin_content/3.))/3.;
1263 for (
auto it = fillings.begin(); it!=fillings.end(); it++){
1266 if (fabs(y-exp_value) < fabs(
x[i] - exp_value)){
1272 prev1_bin_content = prev_bin_content;
1273 prev_bin_content =
x[i];
1275 next_bin_content =
x[i+2];
1277 next_bin_content =
mean;
1280 next1_bin_content =
x[i+3];
1282 next1_bin_content =
mean;
1287 for (
int i=0;i!=
nl;i++){
1288 signal.at(i) =
x[i];
1298 : m_anode_tn(anode_tn)
1299 , m_threshold(threshold)
1345 auto wpid =
m_anode->resolve(ch);
1346 const int iplane = wpid.index();
1351 temp_chirped_bins.first = 0;
1352 temp_chirped_bins.second = signal.size();
1353 ret[
"lf_noisy"][ch].push_back(temp_chirped_bins);
1372 double rms = sqrt((
pow(val1-mean,2)+
pow(val2-mean,2))/2.);
1375 for (
int i=0;i<
int(sig.size());i++){
1387 for (
int i=0;i<
int(sig.size());i++){
1390 if (
k+i>=0&&
k+i <
int(sig.size()))
1391 temp_sig.at(
k+i) =
mean;
1403 content +=
abs(sig_freq.at(i+1));
1409 if (content/valid>
m_cut) {
CoherentNoiseSub(const std::string &anode="AnodePlane", const std::string &noisedb="OmniChannelNoiseDB")
std::vector< std::vector< int > > SignalProtection(WireCell::Waveform::realseq_t &sig, const WireCell::Waveform::compseq_t &respec, int res_offset, int pad_f, int pad_b, float upper_decon_limit=0.02, float decon_lf_cutoff=0.08, float upper_adc_limit=15, float protection_factor=5.0, float min_adc_limit=50)
virtual WireCell::Waveform::ChannelMaskMap apply(int channel, signal_t &sig) const
virtual ~ConfigFilterBase()
bool SignalFilter(WireCell::Waveform::realseq_t &sig)
double rms(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Waveform::realseq_t signal_t
double filter_low_loose(double freq)
bool Subtract_WScaling(WireCell::IChannelFilter::channel_signals_t &chansig, const WireCell::Waveform::realseq_t &medians, const WireCell::Waveform::compseq_t &respec, int res_offset, std::vector< std::vector< int > > &rois, float upper_decon_limit1=0.08, float roi_min_max_ratio=0.8)
boost::error_info< struct tag_errmsg, std::string > errmsg
std::pair< double, double > CalcRMS(const WireCell::Waveform::realseq_t &signal)
bool Chirp_raise_baseline(WireCell::Waveform::realseq_t &sig, int bin1, int bin2)
virtual ~OneChannelStatus()
IAnodePlane::pointer m_anode
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
Configuration find(Configuration &lst, const std::string &dotpath, const T &val)
Return dictionary in given list if it value at dotpath matches.
OneChannelStatus(const std::string anode_tn="AnodePlane", double threshold=3.5, int window=5, int nbins=250, double cut=14)
virtual void configure(const WireCell::Configuration &config)
Accept a configuration.
virtual void configure(const WireCell::Configuration &config)
IConfigurable configuration interface.
virtual ~CoherentNoiseSub()
static int max(int a, int b)
virtual WireCell::Configuration default_configuration() const
Optional, override to return a hard-coded default configuration.
virtual void configure(const WireCell::Configuration &config)
Accept a configuration.
WireCell::Waveform::realseq_t CalcMedian(const WireCell::IChannelFilter::channel_signals_t &chansig)
bool NoisyFilterAlg(WireCell::Waveform::realseq_t &spec, float min_rms, float max_rms)
bool RawAdapativeBaselineAlg(WireCell::Waveform::realseq_t &sig)
bool RemoveFilterFlags(WireCell::Waveform::realseq_t &sig)
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
OneChannelNoise(const std::string &anode_tn="AnodePlane", const std::string &noisedb="OmniChannelNoiseDB")
IAnodePlane::pointer m_anode
Diagnostics::Chirp m_check_chirp
std::map< int, signal_t > channel_signals_t
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
virtual WireCell::Waveform::ChannelMaskMap apply(int channel, signal_t &sig) const
virtual WireCell::Configuration default_configuration() const
Optional, override to return a hard-coded default configuration.
Json::Value Configuration
QTextStream & bin(QTextStream &s)
IChannelNoiseDatabase::pointer m_noisedb
virtual WireCell::Waveform::ChannelMaskMap apply(int channel, signal_t &sig) const
virtual WireCell::Waveform::ChannelMaskMap apply(int channel, signal_t &sig) const
bool ID_lf_noisy(signal_t &sig) const
virtual WireCell::Configuration default_configuration() const
Optional, override to return a hard-coded default configuration.
double filter_low(double freq, double cut_off=0.08)
Diagnostics::Partial m_check_partial
int lowest_bits(int value, int n)
float CalcRMSWithFlags(const WireCell::Waveform::realseq_t &sig)
WIRECELL_FACTORY(mbCoherentNoiseSub, WireCell::SigProc::Microboone::CoherentNoiseSub, WireCell::IChannelFilter) WIRECELL_FACTORY(mbOneChannelNoise
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
std::string nl(std::size_t i=1)
Thrown when a wrong key or has been encountered.
int shift_right(int value, int n, int filling, int totalBit)
QTextStream & endl(QTextStream &s)
ADCBitShift(int nbits=12, int exam_nticks=500, double threshold_sigma=7.5, double threshold_fix=0.8)
double filter_time(double freq)
virtual ~OneChannelNoise()