27 WireCell::SigProc::Protodune::OneChannelNoise,
30 WireCell::SigProc::Protodune::RelGainCalib,
43 std::vector<int> averaged;
44 int up = signal.size()/UNIT;
45 int nticks = signal.size();
47 for(
int i=0;i<up;i++){
49 for(
int j=0;j<UNIT;j++){
50 temp += signal.at(i*UNIT+j);
52 averaged.push_back(temp);
55 auto imax = std::min_element(signal.begin(), signal.end());
56 double max_value = *imax;
57 if(max_value-baseline>1000) { CONTIN /=1.25; JUMPS *= 1.2; }
59 int NumberOfLedge = 0 ;
60 int StartOfLastLedgeCandidate = 0;
61 for(
int LE = 0; LE < 3; LE++){
62 if(LE>0 && StartOfLastLedgeCandidate == 0 )
break;
63 if(StartOfLastLedgeCandidate>nticks-200)
break;
64 if(NumberOfLedge>0 && (LedgeEnd[NumberOfLedge-1]+200)>
nticks)
break;
66 int decreaseD = 0, tolerence=0;
69 if(StartOfLastLedgeCandidate==0) {
73 if(NumberOfLedge == 0)
74 StartWindow = (StartOfLastLedgeCandidate+200)/UNIT;
76 if(StartOfLastLedgeCandidate>LedgeEnd[NumberOfLedge-1])
78 StartWindow = (StartOfLastLedgeCandidate+50)/UNIT;
80 StartWindow = (LedgeEnd[NumberOfLedge-1]+30)/UNIT;
83 for(
int i=StartWindow+1;i<up-1;i++){
84 if(averaged.at(i)<averaged.at(i-1)) {
85 if(decreaseD==0) start = i;
89 if(averaged.at(i+1)<averaged.at(i-1)&&tolerence<JUMPS&&decreaseD>0){
97 StartOfLastLedgeCandidate = start*UNIT;
125 int tempLedgeEnd = 0;
127 for(
int i = StartOfLastLedgeCandidate/UNIT; i<up-1; i++){
128 if(averaged.at(i+1)-averaged.at(i)>5*UNIT) {
129 tempLedgeEnd = i*UNIT+5;
130 if(tempLedgeEnd>nticks) tempLedgeEnd = nticks-1;
135 if(tempLedgeEnd == 0) {
137 for(
int i = StartOfLastLedgeCandidate+80;i<nticks-20;i+=20){
138 for(
int j=i;j<20+i;j++){
139 tempA.at(j-i) = signal.at(j);
142 if(
stat.first-baseline<2&&stat.second>3){
148 if(tempLedgeEnd == 0) tempLedgeEnd = nticks-1;
153 double height = signal.at(StartOfLastLedgeCandidate+1)- signal.at(tempLedgeEnd);
154 if(height<0) ledge = 0;
155 if((tempLedgeEnd-StartOfLastLedgeCandidate) > 80){
157 height50 = signal.at(StartOfLastLedgeCandidate+51);
158 double height50Pre = signal.at(StartOfLastLedgeCandidate+1)- height*(1-exp(-50/100.));
160 if(height50-height50Pre<-12) ledge = 0;
183 if(averaged.at(tempLedgeEnd/UNIT)-baseline*UNIT>5.*UNIT) ledge = 0;
185 if(averaged.at(StartOfLastLedgeCandidate/UNIT)-baseline*UNIT>100*UNIT) ledge = 0;
188 if(ledge==1 && StartOfLastLedgeCandidate>1000){
191 for(
int i=StartOfLastLedgeCandidate-1000; i<StartOfLastLedgeCandidate-100; i++){
192 if(signal.at(i)>hmax) hmax= signal.at(i);
194 if(hmax-baseline<200) ledge=0;
200 LedgeStart[NumberOfLedge] =
std::max(StartOfLastLedgeCandidate-20, 0);
201 LedgeEnd[NumberOfLedge] =
std::min(tempLedgeEnd+10, (
int)signal.size());
206 return NumberOfLedge;
218 std::vector<int> averaged;
219 int up = signal.size()/UNIT;
220 int nticks = signal.size();
222 for(
int i=0;i<up;i++){
224 for(
int j=0;j<UNIT;j++){
225 temp += signal.at(i*UNIT+j);
227 averaged.push_back(temp);
230 auto imax = std::min_element(signal.begin(), signal.end());
231 double max_value = *imax;
234 if(max_value-baseline>1000) { CONTIN = 16; JUMPS = 5; }
236 int decreaseD = 0, tolerence=0;
239 for(
int i=1;i<up-1;i++){
240 if(averaged.at(i)<averaged.at(i-1)) {
241 if(decreaseD==0) start = i;
245 if(averaged.at(i+1)<averaged.at(i-1)&&tolerence<JUMPS&&decreaseD>0){
251 if(decreaseD>CONTIN){
253 LedgeStart = start*UNIT;
266 if(ledge &&LedgeStart>30){
275 if(averaged.at(LedgeStart/UNIT)-baseline*UNIT>150*UNIT) ledge =
false;
278 if(ledge &&LedgeStart>20){
280 if(LedgeStart<5750) {
283 double tempHeight = signal.at(LedgeStart+200) + signal.at(LedgeStart+220) + signal.at(LedgeStart+180) + signal.at(LedgeStart+240);
284 height = signal.at(LedgeStart) - tempHeight/4;
288 else height = signal.at(LedgeStart) - signal.back();
289 if(height<0) height = 80;
290 if(height>30&&LedgeStart<5900){
291 double height50 = 0, height100 = 0;
297 height50 = signal.at(LedgeStart+50);
298 height100 = signal.at(LedgeStart+100);
299 double height50Pre = signal.at(LedgeStart)- height*(1-std::exp(-50/100.));
300 double height100Pre = signal.at(LedgeStart) - height*(1-std::exp(-100./100));
302 if(height50-height50Pre<-8) ledge =
false;
303 if(height100-height100Pre<-8) ledge =
false;
313 for(
int i = LedgeStart/UNIT; i<up-1; i++){
314 if(averaged.at(i+1)-averaged.at(i)>50) {
322 for(
int i = LedgeStart+80;i<nticks-20;i+=20){
323 for(
int j=i;j<20+i;j++){
325 tempA.at(j-i) = signal.at(j);
329 if(wfinfo.first - baseline < 2 && wfinfo.second > 3){
335 if(LedgeEnd == 0) LedgeEnd = 6000;
381 float stky_sig_like_val,
382 float stky_sig_like_rms){
384 const int nsiglen = signal.size();
386 for(
auto const&
rng: rng_list){
387 int start =
rng.first -1;
389 if (start >=0 && end <nsiglen){
390 std::vector<float> digits;
391 for(
int i=start+1; i<
end; i++){
392 digits.push_back(signal.at(i));
395 auto min = std::max_element(digits.begin(), digits.end());
396 auto max = std::min_element(digits.begin(), digits.end());
397 double max_value = *
max;
398 double min_value = *
min;
400 double start_content = signal.at(start);
401 double end_content = signal.at(end);
402 bool isSignalLike =
false;
403 if(
rng.second ==
rng.first) isSignalLike =
true;
407 if(max_value - temp.first > stky_sig_like_val){
408 if( (start_content - temp.first > stky_sig_like_rms*temp.second)
409 && (end_content - temp.first > stky_sig_like_rms*temp.second) ){
413 else if(temp.first - min_value > stky_sig_like_val){
414 if( (temp.first - start_content > stky_sig_like_rms*temp.second)
415 && (temp.first - end_content > stky_sig_like_rms*temp.second) ){
422 if (! isSignalLike) {
423 for (
int i = start+1; i<
end; i++){
424 double content = start_content + (end_content - start_content) /(end-start) *(i-start);
425 signal.at(i) = content;
429 else if(start<0 && end <nsiglen){
430 for(
int i=0; i<
end; i++){
431 signal.at(i) = signal.at(end);
435 else if(start>=0 && end==nsiglen){
436 for(
int i=start+1; i<
end; i++){
437 signal.at(i) = signal.at(start);
446 const int nsiglen = signal.size();
448 int nsublen = nsiglen/2;
449 int nsublen2 = nsiglen - nsublen;
452 for(
int j=0; j<nsiglen; j++){
453 if(j%2==0) signal_even.at(j/2) = signal.at(j);
454 else signal_odd.at((j-1)/2) = signal.at(j);
459 tran_even.resize(nsublen*2);
461 std::rotate(tran_even.begin()+nsublen/2, tran_even.begin()+nsublen, tran_even.end());
464 std::rotate(tran_even.begin()+(nsublen+1)/2, tran_even.begin()+nsublen, tran_even.end());
468 float scale = tran_even.size() / nsublen;
473 tran_odd.resize(nsublen2*2);
475 std::rotate(tran_odd.begin()+nsublen2/2, tran_odd.begin()+nsublen2, tran_odd.end());
478 std::rotate(tran_odd.begin()+(nsublen2+1)/2, tran_odd.begin()+nsublen2, tran_odd.end());
481 float scale2 = tran_odd.size() / nsublen2;
485 for (
size_t j = 0; j<rng_list.size();j++){
486 int start = rng_list.at(j).first -1 ;
487 int end = rng_list.at(j).second + 1 ;
488 if (start >=0 && end <=nsiglen){
489 for (
int i = start+1; i<
end; i++){
491 signal.at(i) = signal_odd_fc.at(i-1);
494 signal.at(i) = signal_even_fc.at(i);
507 const int nsiglen = signal.size();
509 int nsublen = nsiglen/2;
510 int nsublen2 = nsiglen - nsublen;
513 for(
int j=0; j<nsiglen; j++){
514 if(j%2==0) signal_even.at(j/2) = signal.at(j);
515 else signal_odd.at((j-1)/2) = signal.at(j);
520 double f0 = 1./nsublen;
521 const double PI = std::atan(1.0)*4;
522 for(
size_t i=0; i<tran_even.size(); i++){
524 double omega = 2*PI*fi;
525 auto z = tran_even.at(i);
526 std::complex<float> z1(0, omega*toffset);
528 tran_even.at(i) =
z * std::exp(z1);
538 for(
size_t i=0; i<tran_odd.size(); i++){
540 double omega = 2*PI*fi;
541 auto z = tran_odd.at(i);
542 std::complex<float> z1(0, omega*toffset);
544 tran_odd.at(i) =
z * std::exp(z1);
552 for (
size_t j = 0; j<st_ranges.size();j++){
553 int start = st_ranges.at(j).first -1 ;
554 int end = st_ranges.at(j).second + 1 ;
555 if (start >=0 && end <=nsiglen){
556 for (
int i = start+1; i<
end; i++){
558 int ind = (i-1)/2. - toffset;
559 if(ind>=0 && ind<nsublen2) signal.at(i) = signal_odd_fc.at(ind);
563 int ind = i/2. - toffset;
564 if(ind>=0 && ind<nsublen) signal.at(i) = signal_even_fc.at(ind);
574 const int nsiglen = signal.size();
576 tran.resize(nsamples);
578 std::rotate(tran.begin()+nsiglen/2, tran.begin()+nsiglen, tran.end());
581 std::rotate(tran.begin()+(nsiglen+1)/2, tran.begin()+nsiglen, tran.end());
601 , m_noisedb_tn(noisedb) {}
622 float stky_sig_like_val,
float stky_sig_like_rms,
int stky_max_len)
625 , m_stky_sig_like_val(stky_sig_like_val)
626 , m_stky_sig_like_rms(stky_sig_like_rms)
627 , m_stky_max_len(stky_max_len)
647 auto jext = cfg[
"extra_stky"];
649 for(
auto jone: jext) {
650 auto jchans = jone[
"channels"];
651 for (
auto jchan: jchans){
654 for(
auto bit: jone[
"bits"]){
663 if (cfg.isMember(
"stky_sig_like_val")){
667 if (cfg.isMember(
"stky_sig_like_rms")){
671 if (cfg.isMember(
"stky_max_len")){
690 const int nsiglen = signal.size();
694 std::vector<short int> extra;
699 for(
int i=0; i<nsiglen; i++){
700 int val = signal.at(i);
702 auto it =
std::find(extra.begin(), extra.end(), mod);
704 if( it != extra.end()) {
705 if (sticky_rng_list.empty()){
706 sticky_rng_list.push_back(std::make_pair(i,i));
707 }
else if ( (sticky_rng_list.back().second + 1) == i){
708 sticky_rng_list.back().second = i;
710 sticky_rng_list.push_back(std::make_pair(i,i));
722 for(
auto rng: sticky_rng_list){
723 int stkylen=
rng.second-
rng.first;
725 ret[
"sticky"][ch].push_back(
rng);
726 ent_stkylen += stkylen;
733 auto temp_signal = signal;
734 for (
size_t i=0;i!=temp_signal.size();i++){
735 if (fabs(temp_signal.at(i)-temp.first)>6*temp.second){
736 temp_signal.at(i) = temp.first;
742 auto wpid =
m_anode->resolve(ch);
743 const int iplane = wpid.index();
745 int ledge_start[3], ledge_end[3];
746 int nledge =
LedgeIdentify1(signal, baseline, ledge_start, ledge_end);
747 for(
int LE=0; LE<nledge; LE++){
750 for(
auto rng: sticky_rng_list){
753 if(redge>=ledge) overlap += (redge-ledge+1);
755 if( overlap < 0.5 * (ledge_end[LE]-ledge_start[LE]) ){
757 ledge_bins.first = ledge_start[LE];
758 ledge_bins.second = ledge_end[LE];
759 ret[
"ledge"][ch].push_back(ledge_bins);
798 auto jext = cfg[
"resmp"];
800 for(
auto jone: jext) {
801 int smpin = jone[
"sample_from"].asInt();
802 for(
auto jch: jone[
"channels"]){
829 int smpout = signal.size();
830 signal.resize(smpin);
853 auto wpid =
m_anode->resolve(ch);
854 const int iplane = wpid.index();
870 std::vector< std::pair<int,int> > freqBins;
871 for(
int i=0; i<(
int)spec.size(); i++){
872 float flag_re = spec.at(i).real();
875 if (freqBins.empty()){
876 freqBins.push_back(std::make_pair(i,i));
878 else if (i == freqBins.back().second +1) {
879 freqBins.back().second = i;
882 freqBins.push_back(std::make_pair(i,i));
894 for(
int iter=0; iter<5; iter++){
897 for(
auto bin: freqBins) {
898 int istart =
bin.first;
899 int iend =
bin.second +1;
900 int nslice = iend - istart;
912 std::copy(
mag.begin() + istart,
mag.begin() + iend, mag_slice.begin());
915 double cut = stat.first + 2.7*stat.second;
917 cut = stat.first + 3*stat.second;
922 for(
int j=istart; j<iend; j++){
923 float content =
mag.at(j);
925 spectrum.at(j).real(0);
926 spectrum.at(j).imag(0);
927 spectrum.at(
mag.size()+1-j).
real(0);
928 spectrum.at(
mag.size()+1-j).
imag(0);
930 mag.at(
mag.size()+1-j) = 0;
960 temp_harmonic_bins.first = 0;
961 temp_harmonic_bins.second = signal.size();
962 ret[
"harmonic"][ch].push_back(temp_harmonic_bins);
969 spectrum.front() = 0;
974 auto temp_signal = signal;
975 for (
size_t i=0;i!=temp_signal.size();i++){
976 if (fabs(temp_signal.at(i)-temp.first)>6*temp.second){
977 temp_signal.at(i) = temp.first;
989 temp_chirped_bins.first = 0;
990 temp_chirped_bins.second = signal.size();
993 ret[
"lf_noisy"][ch].push_back(temp_chirped_bins);
1001 const float min_rms =
m_noisedb->min_rms_cut(ch);
1002 const float max_rms =
m_noisedb->max_rms_cut(ch);
1018 temp_chirped_bins.first = 0;
1019 temp_chirped_bins.second = signal.size();
1020 ret[
"noisy"][ch].push_back(temp_chirped_bins);
1035 float gain_def,
float gain_min_cut,
float gain_max_cut)
1038 , m_gain_def(gain_def)
1039 , m_gain_min_cut(gain_min_cut)
1040 , m_gain_max_cut(gain_max_cut)
1058 if (cfg.isMember(
"gain_def")) {
1062 if (cfg.isMember(
"gain_min_cut")){
1066 if (cfg.isMember(
"gain_max_cut")){
1071 for (
auto jch : cfg[
"rel_gain"]) {
1091 size_t nsiglen = signal.size();
1101 float baseline = 0.;
1105 bool isDefVal =
false;
1114 for (
size_t ind=0; ind<nsiglen; ind++) {
1115 float sigout = gain_fac * (signal.at(ind) - baseline);
1117 signal.at(ind) = sigout;
WireCell::IConfigurable WIRECELL_FACTORY(pdRelGainCalib, WireCell::SigProc::Protodune::RelGainCalib, WireCell::IChannelFilter, WireCell::IConfigurable) using namespace WireCell int LedgeIdentify1(WireCell::Waveform::realseq_t &signal, double baseline, int LedgeStart[3], int LedgeEnd[3])
bool SignalFilter(WireCell::Waveform::realseq_t &sig)
bool FftInterpSticky(WireCell::Waveform::realseq_t &signal, std::vector< std::pair< int, int > > &st_ranges)
float m_stky_sig_like_val
Waveform::realseq_t signal_t
bool LedgeIdentify(WireCell::Waveform::realseq_t &signal, double baseline, int &LedgeStart, int &LedgeEnd)
boost::error_info< struct tag_errmsg, std::string > errmsg
virtual WireCell::Waveform::ChannelMaskMap apply(int channel, signal_t &sig) const
float m_stky_sig_like_rms
bool FftShiftSticky(WireCell::Waveform::realseq_t &signal, double toffset, std::vector< std::pair< int, int > > &st_ranges)
IAnodePlane::pointer m_anode
virtual ~OneChannelNoise()
virtual WireCell::Configuration default_configuration() const
Optional, override to return a hard-coded default configuration.
bool LinearInterpSticky(WireCell::Waveform::realseq_t &signal, std::vector< std::pair< int, int > > &st_ranges, float stky_sig_like_val, float stky_sig_like_rms)
IChannelNoiseDatabase::pointer m_noisedb
virtual WireCell::Configuration default_configuration() const
Optional, override to return a hard-coded default configuration.
IAnodePlane::pointer m_anode
virtual void configure(const WireCell::Configuration &config)
Accept a configuration.
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
IChannelNoiseDatabase::pointer m_noisedb
std::map< int, std::vector< short int > > m_extra_stky
std::vector< float > m_rel_gain
WIRECELL_FACTORY(pdStickyCodeMitig, WireCell::SigProc::Protodune::StickyCodeMitig, WireCell::IChannelFilter, WireCell::IConfigurable) WIRECELL_FACTORY(pdOneChannelNoise
OneChannelNoise(const std::string &anode_tn="AnodePlane", const std::string &noisedb="OmniChannelNoiseDB")
static int max(int a, int b)
bool NoisyFilterAlg(WireCell::Waveform::realseq_t &spec, float min_rms, float max_rms)
IAnodePlane::pointer m_anode
bool RawAdapativeBaselineAlg(WireCell::Waveform::realseq_t &sig)
bool RemoveFilterFlags(WireCell::Waveform::realseq_t &sig)
virtual void configure(const WireCell::Configuration &config)
Accept a configuration.
Diagnostics::Partial m_check_partial
virtual WireCell::Waveform::ChannelMaskMap apply(int channel, signal_t &sig) const
IChannelNoiseDatabase::pointer m_noisedb
virtual WireCell::Configuration default_configuration() const
Optional, override to return a hard-coded default configuration.
std::map< int, signal_t > channel_signals_t
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
virtual void configure(const WireCell::Configuration &config)
Accept a configuration.
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out)
StickyCodeMitig(const std::string &anode_tn="AnodePlane", const std::string &noisedb="OmniChannelNoiseDB", float stky_sig_like_val=15.0, float stky_sig_like_rms=2.0, int stky_max_len=5)
blobvec_t overlap(const blobref_t &blob, const blobproj_t &proj, layer_index_t layer)
virtual ~StickyCodeMitig()
Json::Value Configuration
QTextStream & bin(QTextStream &s)
void configure(const WireCell::Configuration &config)
Accept a configuration.
RelGainCalib(const std::string &anode_tn="AnodePlane", const std::string &noisedb="OmniChannelNoiseDB", float gain_def=1.0, float gain_min_cut=0.8, float gain_max_cut=1.25)
virtual WireCell::Waveform::ChannelMaskMap apply(int channel, signal_t &sig) const
WireCell::Configuration default_configuration() const
Optional, override to return a hard-coded default configuration.
bool FftScaling(WireCell::Waveform::realseq_t &signal, int nsamples)
Thrown when a wrong key or has been encountered.
virtual ~ConfigFilterBase()
std::map< int, int > m_resmp