Logo coherent WaveBurst  
Library Reference Guide
Logo
LineFilter.cc
Go to the documentation of this file.
1 /*
2 # Copyright (C) 2019 Sergey Klimenko
3 #
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17 
18 
19 /************************************************************************
20  * Sergey Klimenko, University of Florida
21  *
22  * v-1.63: 08/07/01
23  * - addded flag reFine (force to do fScan if !reFine)
24  * set true by default, set false if SNR<0
25  * - corrected situation when getOmega fails to find frequency
26  * getOmega always uses FilterID=1
27  * - correct frequency band fBand if start not from the first harmonic
28  * v-2.0: 11/08/01
29  * - svitched to new class of wavelet transforms
30  * replace wavearray<double> class with wavearray class
31  ************************************************************************/
32 
33 #include "LineFilter.hh"
34 #include "DVector.hh"
35 #include "TSeries.hh"
36 #include "Biorthogonal.hh"
37 #include <iostream>
38 
39 ClassImp(linefilter) // used by THtml doc
40 
41 using namespace std;
42 
44  FilterID(1), Frequency(60.), Window(0.0), Stride(1.), nFirst(1), nLast(0),
45  nStep(1), nScan(20), nBand(5), nSubs(1), fBand(0.45), nLPF(-1), nWave(16),
46  clean(false), badData(false), noScan(false), nRIF(6), SNR(2.), reFine(true),
47  dumpStart(0), FilterState(0), SeedFrequency(60.), CurrentTime(Time(0)),
48  StartTime(Time(0)), Sample(0.0)
49 {
50  reset();
51 }
52 
53 /* LineFilter constructor
54  * f - approximate line frequency
55  * w - time interval to remove lines.
56  *fid - select filter ID (-1/0/1), -1 by default
57  * nT - number of subdivisions of time interval w
58  */
59 LineFilter::LineFilter(double f, double w, int fid, int nT) :
60  FilterID(1), Frequency(60.), Window(0.0), Stride(1.), nFirst(1), nLast(0),
61  nStep(1), nScan(20), nBand(5), nSubs(1), fBand(0.45), nLPF(-1), nWave(16),
62  clean(false), badData(false), noScan(false), nRIF(6), SNR(2.), reFine(true),
63  dumpStart(0), FilterState(0), SeedFrequency(60.), CurrentTime(Time(0)),
64  StartTime(Time(0)), Sample(0.0)
65 {
66  reset();
67  Frequency = fabs(f);
69  FilterID = fid;
70  Window = w;
71  if(f < 0.) clean = true;
72  nSubs = (nT > 0) ? nT : 1;
73 }
74 
76 
79  Stride(x.Stride), nFirst(x.nFirst), nLast(x.nLast), nStep(x.nStep),
80  nScan(x.nScan), nBand(x.nBand), nSubs(x.nSubs), fBand(x.fBand),
81  nLPF(x.nLPF), nWave(x.nWave), clean(x.clean), badData(false),
82  noScan(x.noScan), nRIF(x.nRIF), SNR(x.SNR), reFine(x.reFine),
83  dumpStart(0), FilterState(0), SeedFrequency(60.), CurrentTime(Time(0)),
84  StartTime(Time(0)), Sample(0.)
85 {}
86 
88 LineFilter::clone(void) const {
89  return new LineFilter(*this);
90 }
91 
92 void LineFilter::dataCheck(const TSeries& ts) const {
93 
94  //---------------------------------- Check data type.
95  if (!ts.refDVect()->F_data() &&
96  !ts.refDVect()->S_data() &&
97  !ts.refDVect()->S_data() )
98  throw invalid_argument("Only float or short data accepted");
99 
100  //---------------------------------- Check sampling rate.
101  if (Sample != Interval(0.0) && Sample != ts.getTStep())
102  throw invalid_argument("Wrong frequency");
103 
104  //---------------------------------- Check history data valid.
105 // if (CurrentTime != Time(0) && ts.getStartTime() != CurrentTime)
106 // throw invalid_argument("Wrong start time");
107 
108 }
109 
110 unsigned int LineFilter::maxLine(int L)
111 {
112  unsigned int imax = (nLPF>0) ? int(L/2)+1 : int(L/4)+1;
113  if(nFirst > imax) std::cout<<"LineFilter: Invalid harmonic number.\n";
114  if(imax>nLast && nLast>0) imax = nLast+1;
115  if(imax <= nFirst) imax = nFirst+1;
116  if(imax > (unsigned)L/2) imax = L/2;
117  return imax;
118 }
119 
120 bool LineFilter::isDataValid(const TSeries& ts) const
121 {
122  if(!(&ts)) return false;
123  try {
124  dataCheck(ts);
125  }
126  catch (exception& e) {
127  cerr << "Data error in LineFilter: " << e.what() << endl;
128  return false;
129  }
130  return true;
131 }
132 
133 /***setFilter*********************************************************
134  * nF - first harmonic
135  * nL - last harmonic
136  * nS - skip harmonics
137  * nD - decimation depth (resampling)
138  * nB - number of frequency bins to estimate noise spectral density
139  * nR - order of interpolating filter for resample
140  * nW - lifting wavelet order
141  *********************************************************************/
143  int nL,
144  int nS,
145  int nD,
146  int nB,
147  int nR,
148  int nW){
149 
150  reset();
151  if(nS == 0) nS++;
152  nStep = nS;
153  nFirst = nF;
154  nLast = nL;
155 
156  if(nS<0){
157  nFirst *= -nStep;
158  nLast *= -nStep;
159  Frequency /= -nStep;
161  }
162 
163  nBand = (nB>=2) ? nB : 2;
164  nWave = nW;
165  nLPF = nD;
166  nRIF = nR;
167  return;
168 }
169 
171  FilterState = 0;
172  CurrentTime = Time(0);
173  StartTime = Time(0);
174  Sample = 0.0;
175  badData = false;
176  lineList.clear();
177  dumpStart = 0;
179 }
180 
181 void LineFilter::resize(size_t dS) {
182 
183  if(dS == 0){ // clear the list
184  lineList.clear();
185  dumpStart = 0;
186  }
187 
188  else{ // pop entries from the beginnig of the list
189 
190  if(lineList.size() <= dS)
191  dumpStart = lineList.size();
192 
193  else
194  do { lineList.pop_front(); }
195  while(lineList.size() > dumpStart);
196 
197  }
198 
199  return;
200 }
201 
202 
203 void LineFilter::setFScan(double f,
204  double sN,
205  double fB,
206  int nS)
207 {
208  noScan = true;
209  fBand = fabs(fB);
210  nScan = nS;
211  SNR = fabs(sN);
212  reFine = (sN>0) ? true : false;
213  if(f != 0.) {
214  Frequency = nStep>0 ? fabs(f) : fabs(f/nStep);
215  noScan = (f < 0.) ? true : false;
216  }
217  return;
218 }
219 
220 /****************************************************************************
221  * Function estimates Power Spectral Density for input TD time series.
222  * Return WaveData object with average Spectral Density near harmonics
223  * (f,2*f,3*f,..imax*f).
224  * Spectral Density is estimated using nb Fourier bins around harmonics.
225  ****************************************************************************/
226 
228 {
229  int i,j,k;
230  double a, b, c;
231  int L = int(TD.rate()/Frequency + 0.5); // # of samples in one line cycle
232  int m = int(TD.size()/nSubs); // length of 1/nSubs TD
233  int n = int(m/(nb*L))*L; // length of 1/nb/nSubs TD
234 
235  WaveData td2(2*L); // S.K. wavefft 9/10/20002
236  WaveData tds(L);
237  WaveData tdn(L);
238  WaveData tdx(n);
239  WaveData psd(L/2);
240 
241  if(nb < 1) nb = 1;
242 
243  psd = 0.;
244  if (n/L == 0) {
245  cout <<" LineFilter::getPSD error: time series is too short to contain\n"
246  <<" one cycle of fundamental harmonic " << Frequency << "\n";
247  return psd;
248  }
249 
250  c = (nb>1) ? 1./(nb-1) : 1.;
251  c *= Window/nSubs/nb/nSubs; // before 03/24/01 was c *= double(m)/nSubs/TD.rate()/nb;
252  psd.rate(TD.rate());
253 
254 // cout<<"c="<<c<<" n="<<n<<" m="<<m<<" L="<<L<<"\n";
255 
256  for(k = 0; k < nSubs; k++){
257  psd.data[0] += tdn.Stack(TD, m, m*k);
258 
259  for(j = 0; j < nb; j++){
260  if(nb > 1) {
261  psd.data[0] -= tds.Stack(TD, n, n*j+m*k);
262  tds -= tdn;
263  }
264  else
265  tds = tdn;
266 
267  tds.hann();
268 // tds.FFTW(1); // calculate FFT for stacked signal
269 
270 // SK wavefft fix 9/10/2002
271  td2.rate(tds.rate());
272  td2.cpf(tds); td2.cpf(tds,L,0,L);
273  td2.FFTW(1);
274  tds[slice(0,L/2,2)] << td2[slice(0,L/2,4)];
275  tds[slice(1,L/2,2)] << td2[slice(1,L/2,4)];
276 // SK wavefft fix 9/10/2002: end
277 
278  for (i = 2; i < L-1; i+=2){ // always neglect last harmonic
279  a = tds.data[i]; b = tds.data[i+1];
280  psd.data[i/2] += c*(a*a+b*b); // save spectral density
281  // cout<<"nb="<<nb<<" i="<<i<<" PSD="<<psd.data[i/2]<<endl;
282  }
283  }
284  }
285 
286  return psd;
287 }
288 
289 /******************************************************************
290  * makeFilter calculates comb filter.
291  * Returns the line intensity at the filter output
292  * nFirst - "number" of the first harmonic
293  * nLast - "number" of the last harmonic
294  * nStep - skip harmonics
295  * FilterID - select the filter #, 1 by default
296  * nBand - number of frequency bins used to estimate the noise SD
297  *****************************************************************/
298 double LineFilter::makeFilter(const WaveData &TD, int FID)
299 {
300  if (badData) {
301  cout <<" LineFilter::MakeFilter() error: badData flag is on\n";
302  return 0.;
303  }
304 
305  double S, N;
306  unsigned int i;
307  int L = int(TD.rate()/Frequency+0.5); // number of samples per one cycle
308  int k = int(TD.size()/L);
309 
310  if (k == 0) {
311  cout <<" LineFilter::MakeFilter() error: data length too short to contain\n"
312  <<" at least one cycle of target frequency = " << Frequency << " Hz\n";
313  badData = true;
314  return 0.;
315  }
316 
317  unsigned int imax = maxLine(L); // max number of harmonics
318 
319  if((int)Filter.size() < L/2) Filter.resize(L/2);
320  Filter = 0.;
321  for (i = nFirst; i < imax; i += abs(nStep)) Filter.data[i] = 1.;
322 
323  LineSD = getPSD(TD); // Line energy + NSD
324 
325  if (FID == 1) {
326  NoiseSD = getPSD(TD,nBand); // Line energy + NSD*nBand
327  for (i = nFirst; i < imax; i += abs(nStep)) {
328  S = LineSD.data[i];
329  N = NoiseSD.data[i];
330  Filter.data[i] = (S>N && S>0) ? (1-N/S) : 0.;
331  // cout<<"S="<<S<<" N="<<N<<" F="<<Filter.data[i]<<endl;
332  }
333  }
334 
335  S = 0.;
336  N = 0.;
337  for (i = nFirst; i < imax; i += abs(nStep)) {
338  S += LineSD.data[i]*Filter.data[i]*Filter.data[i];
339  N += (FID == 1) ? NoiseSD.data[i]*Filter.data[i] : 0.;
340  }
341 
342  if(S < SNR*N || S <= 0.) badData = true;
343  // if(badData) cout << S << " FID=" << FID << endl;
344  return S;
345 }
346 
347 /*******************************************************************
348  * getLine() replaces the original data TD with calculated
349  * interference signal. Filter F is applied. Returns lineData object
350  * with the line summary information. Works with resampled data
351  *******************************************************************/
352 
354 {
355  double a,b;
356  int iF;
357  double F;
358  lineData v;
359 
360  v.frequency = 0.;
361  v.intensity = 0.;
363 
364  if (Frequency <= 0) {
365  cout << " getLine() error: invalid interference frequency"
366  << " : " << Frequency << " Hz\n";
367  return v;
368  }
369 
370  int L = int(TD.rate()/Frequency + 0.5); // number of samples per cycle
371  int n = int(TD.size()/nSubs); // data section length
372 
373  unsigned int imax = maxLine(L); // max number of harmonics
374 
375  if (n/L == 0 || L < 4) {
376  cout << " getLine() error: input data length too short to contain\n"
377  << " one cycle of target frequency = " << Frequency << " Hz\n";
378  return v;
379  }
380 
381  WaveData td2(2*L); // SK wavefft fix 9/10/2002
382  WaveData tds(L);
383  WaveData amp(L);
384  amp *= 0.;
385 
386  double p = axb(Frequency, n/TD.rate());
387  double phase = 0.;
388 
389  v.frequency = Frequency;
390  v.intensity = 0.;
391 
392  for (int k = 0; k < nSubs; k++) {
393  tds.Stack(TD, n, n*k); // stack signal
394 
395  if(!clean) tds.hann();
396 
397 // SK wavefft fix 9/10/2002
398  td2.rate(tds.rate());
399  td2.cpf(tds); td2.cpf(tds,L,0,L);
400  td2.FFTW(1);
401  tds[slice(0,L/2,2)]<<td2[slice(0,L/2,4)];
402  tds[slice(1,L/2,2)]<<td2[slice(1,L/2,4)];
403 // SK wavefft fix 9/10/2002: end
404 
405 //*************************************************************
406 // reconstruction of filtered interference signal
407 //*************************************************************
408  // cout<<"tds.size="<<tds.size()<<" L="<<L-1<<" imax="<<imax
409  // <<" nFirst="<<nFirst<<" nLast="<<nLast<<" Filter.size="<<Filter.size()<<endl;
410 
411 // apply the filter
412  for (unsigned int i = 0; i < (unsigned)L-1; i+=2) {
413  F = Filter.data[i/2];
414  tds.data[i] *= F;
415  tds.data[i+1] *= F;
416  if(F > 0.){
417  a = tds.data[i]; b = tds.data[i+1];
418  amp.data[i] += (a*a + b*b)/nSubs;
419 
420  if(k==0){
421  phase = arg(f_complex(a,b));
422  amp.data[i+1] = phase;
423  }
424  else{
425  b = arg(f_complex(a,b));
426  a = (b-phase)/2./PI - axb(p,double(k*(i/2)));
427  a -= (a>0.) ? long(a+0.5) : long(a-0.5);
428  amp.data[i+1] += 2*PI*a/nSubs;
429  phase = b;
430  }
431  }
432  }
433  if((L&1) == 1) tds.data[L-1] = 0.; // take care of odd L
434 
435 // for(int jj=0; jj<tds.size(); jj++) cout<<"i="<<jj<<" tds="<<tds.data[jj]<<endl;
436 
437 // SK wavefft fix 9/10/2002
438  td2=0.;
439  td2[slice(0,L/2,4)]<<tds[slice(0,L/2,2)];
440  td2[slice(1,L/2,4)]<<tds[slice(1,L/2,2)];
441  td2.FFTW(-1);
442  tds.cpf(td2,L);
443 // SK wavefft fix 9/10/2002: end
444 
445  tds.getStatistics(a,b);
446  v.intensity += b*b;
447 
448  iF = (k == nSubs-1) ? TD.size() : n*k+n;
449  if(clean) // reconstruct interference to clean data
450  for (int i = 0; i < L; i++)
451  for(int j = n*k+i; j < iF; j += L)
452  TD.data[j] = tds.data[i];
453  }
454 
455 // add amplitudes and noise spectral density into the lineData
456  iF = imax-nFirst;
457  v.amplitude.resize(iF);
458  v.line.resize(iF);
459  v.noise.resize(iF);
460  v.filter.resize(iF);
461 
462  for (unsigned int i = nFirst; i < imax; i += abs(nStep)) {
463  iF = i-nFirst;
464  v.line[iF] = LineSD.data[i];
465  v.noise[iF] = (FilterID == 0) ? 0. : NoiseSD.data[i];
466  v.filter[iF] = Filter.data[i];
467  a = amp.data[2*i];
468  b = amp.data[2*i+1];
469  v.amplitude[iF] = float(2.*float(sqrt(a)))*exp(f_complex(0.,b));
470  if(!clean) v.amplitude[iF] *= sqrt(1.5); // correct for Hann (9/3/02)
471  }
472 
473 // calculate inverse FFT to reproduce one cycle of filtered signal
474  v.intensity /= nSubs;
475  if(!clean) v.intensity *= 1.5; // correct for Hann (9/3/02)
476  v.first = nFirst;
477 
478  return v;
479 }
480 
481 /*******************************************************************
482  * heterodyne() estimates single line amplitude and phase by using
483  * straight heterodyning. It replaces the original data TD with calculated
484  * interference signal. Returns lineData object
485  * with the line summary information. Works with original data
486  *******************************************************************/
487 
489 {
490  long i,k,m;
491  double a,b,u,v;
492  register double C,S, c,s, ch,sh, x;
493  double omega;
494  long N = TD.size();
495  register double* p = TD.data;
496  size_t mode;
497  lineData Q;
498 
499  Q.frequency = 0.;
500  Q.intensity = 0.;
502 
503  if (Frequency <= 0) {
504  cout << " getLine() error: invalid interference frequency"
505  << " : " << Frequency << " Hz\n";
506  return Q;
507  }
508 
509  int L = int(TD.rate()/Frequency); // number of samples per cycle
510  int n = int(TD.size()/nSubs); // data sub-section length
511  size_t imax = L; // max number of harmonics
512  size_t M = imax-nFirst; // number of modes
513 
514  omega = 2*PI*nFirst*Frequency/TD.rate();
515 
516  // tabulate sin and cos
517 
518  if(!lineList.size()) {
519  ct.resize(n);
520  st.resize(n);
521  wt.resize(n);
522  for(i=0; i<n; i++){
523  ct.data[i] = cos(i*omega);
524  st.data[i] = sin(i*omega);
525  wt.data[i] = 1.-cos(i*2.*PI/double(n));
526  }
527  }
528 
529  WaveData amp(nSubs*M);
530  WaveData phi(nSubs*M);
531 
532  amp = 0.;
533  phi = 0.;
534 
535  Q.frequency = Frequency;
536  Q.intensity = 0.;
537 
538  for (mode = nFirst; mode < imax; mode += abs(nStep)) {
539  m = nSubs*(mode-nFirst)/abs(nStep);
540  omega = 2*PI*mode*Frequency/TD.rate();
541  c = cos(omega);
542  s = sin(omega);
543  p = TD.data;
544 
545  ch = cos(2*PI/double(n));
546  sh = sin(2*PI/double(n));
547 
548  for (k = 0; k < nSubs; k++) {
549  a = b = 0.;
550  x = omega*k*n;
551  C = cos(x);
552  S = sin(x);
553 
554  if(FilterID==-1){
555  for (i = 0; i < n; i++) {
556  a += C * *p;
557  b += S * *(p++);
558  x = c*C-s*S;
559  S = c*S+s*C;
560  C = x;
561  }
562  }
563 
564  else if(FilterID==-2 || mode>nFirst){
565  u = 1.;
566  v = 0.;
567  for (i = 0; i < n; i++) {
568  x = (1-u) * *(p++);
569  a += C*x;
570  b += S*x;
571  x = c*C-s*S;
572  S = c*S+s*C;
573  C = x;
574  x = ch*u-sh*v;
575  v = ch*v+sh*u;
576  u = x;
577  }
578  }
579 
580  else if(FilterID==-3){
581  for (i = 0; i < n; i++) {
582  x = wt.data[i] * *(p++);
583  a += ct.data[i]*x;
584  b += st.data[i]*x;
585  }
586  }
587 
588  amp.data[k+m] = 2.*sqrt(a*a + b*b)/double(n);
589  phi.data[k+m] = atan2(b,a);
590  // cout<<m<<" a="<<a<<" b="<<b<<endl;
591  // cout<<m<<" "<<amp.data[k+m]<<" "<<phi.data[k+m]<<endl;
592  }
593  }
594 
595 //*************************************************************
596 // reconstruction of filtered interference signal
597 //*************************************************************
598  Q.amplitude.resize(M);
599  Q.line.resize(M);
600  Q.noise.resize(M);
601  Q.filter.resize(M);
602 
603  if(clean) TD = 0.;
604 
605  for (mode = nFirst; mode < imax; mode += abs(nStep)) {
606  m = nSubs*(mode-nFirst)/abs(nStep);
607  omega = 2*PI*mode*Frequency/TD.rate();
608  c = cos(omega);
609  s = sin(omega);
610 
611  a = b = 0.;
612  for (k = 0; k < nSubs; k++) {
613  a += amp.data[k+m]*amp.data[k+m];
614  b += phi.data[k+m];
615  }
616 
617  b /=nSubs;
618  Q.line[mode-nFirst] = 10.;
619  Q.noise[mode-nFirst] = 1.;
620  Q.filter[mode-nFirst] = 1;
621  Q.amplitude[mode-nFirst] = float(sqrt(float(a)/nSubs))*exp(f_complex(0.,b));
622  Q.intensity += a/nSubs/2.;
623 
624  if(clean){
625  p = TD.data;
626 
627  a = amp.data[m];
628  x = phi.data[m];
629  C = cos(x);
630  S = sin(x);
631  for (i = 0; i < n/2; i++){
632  *(p++) -= a*C;
633  x = c*C-s*S;
634  S = c*S+s*C;
635  C = x;
636  }
637 
638  for (k = 0; k < nSubs-1; k++) {
639  // cout<<"k="<<k<<" m="<<m<<" "<<amp.data[k+m]<<endl;
640  x = phi.data[k+m] +omega*(k*n+n/2);
641  C = cos(x);
642  S = sin(x);
643  x = phi.data[k+m+1]+omega*(k*n+n/2);
644  u = cos(x);
645  v = sin(x);
646  for (i = 0; i < n; i++) {
647  a = amp.data[k+m] * C;
648  b = amp.data[k+1+m]* u;
649  x = c*C-s*S;
650  S = c*S+s*C;
651  C = x;
652  x = c*u-s*v;
653  v = c*v+s*u;
654  u = x;
655  *(p++) -= (a*(n-i) + b*i)/n;
656  }
657  }
658 
659  a = amp.data[nSubs-1+m];
660  x = phi.data[nSubs-1+m]+omega*(TD.size()-n/2);
661  C = cos(x);
662  S = sin(x);
663  for (i = TD.size()-n/2; i<N; i++){
664  *(p++) -= a*C;
665  x = c*C-s*S;
666  S = c*S+s*C;
667  C = x;
668  }
669 
670  }
671  }
672 
673  if(clean){
674  b = TD.rms();
675  Q.intensity = b*b;
676  }
677  Q.first = nFirst;
678 
679  // cout<<"hetero: freq="<<Frequency<<" intensity="<<Q.intensity<<endl;
680 
681  return Q;
682 }
683 
684 
685 /*******************************************************************
686  * getOmega(WaveData &TD) refines the fundamental frequency using
687  * phase difference (p2+w*s/2) - (p1+w*s/2), where pi+w*s/2 is a
688  * phase in the middle of time interval s.
689  * It works with resampled data
690  *******************************************************************/
691 
692 double LineFilter::getOmega(const WaveData &TD, int nsub)
693 {
694  double a,b;
695  double F;
696 
697  if(noScan) return Frequency;
698  if(!reFine) return -Frequency;
699 
700  if(nsub<2) nsub = 2;
701 
702  if (Frequency <= 0) {
703  cout << " getOmega() error: invalid interference frequency"
704  << " : " << Frequency << " Hz\n";
705  return 0.;
706  }
707 
708 // use Wiener filter if FID = -1 or 1;
709 // int FID = (FilterID == 0) ? 0 : 1;
710 // starting 08/07/01 getOmega always works with FilterID=1
711  int FID = 1;
712 
713  WaveData TDR(1);
714  TDR.resample(TD, newRate(TD.rate()), 6);
715  makeFilter(TDR, FID);
716  if(badData) return -Frequency;
717 
718  int L = int(TDR.rate()/Frequency + 0.5); // number of samples per cycle
719  int n = int(TDR.size()/nsub); // data section length
720 
721  unsigned int imax = maxLine(L); // max number of harmonics
722 
723  if (n/L == 0 || L < 4) {
724  cout << " getOmega() error: input data length too short to contain\n"
725  << " one cycle of target frequency = " << Frequency << " Hz\n";
726  return 0.;
727  }
728 
729  WaveData td2(2*L); // SK wavefft fix 9/10/2002
730  WaveData tds(L);
731  WaveData amp(L);
732  WaveData phi(L);
733  amp *= 0.;
734  phi *= 0.;
735 
736  double step = n/TDR.rate();
737  double wt = Frequency * step;
738  double phase = 0.;
739  double FSNR = SNR/(1.+SNR); // Filter threshold
740 
741  for (int k = 0; k < nsub; k++) {
742  tds.Stack(TDR, n, n*k); // stack signal
743 
744  tds.hann();
745 // SK wavefft fix 9/10/2002
746  td2.rate(tds.rate());
747  td2.cpf(tds); td2.cpf(tds,L,0,L);
748  td2.FFTW(1);
749  tds[slice(0,L/2,2)]<<td2[slice(0,L/2,4)];
750  tds[slice(1,L/2,2)]<<td2[slice(1,L/2,4)];
751 // SK wavefft fix 9/10/2002: end
752 
753 //*************************************************************
754 // estimate frequency from the phase difference
755 // nsub always > 1 - calculate frequency from the data TD
756 //*************************************************************
757 
758  for (unsigned int i = 2; i < (unsigned)L-1; i+=2) {
759  F = Filter.data[i/2];
760  a = tds.data[i]*F;
761  b = tds.data[i+1]*F;
762 
763  if(F > FSNR){
764  amp.data[i] += a*a+b*b;
765  phase = arg(f_complex(a,b))/2./PI;
766  phase += axb(wt/2.,double(i/2));
767  phase -= intw(phase); // phase(t)
768 
769  if(k>0){
770  F = phase - phi.data[i+1];
771  F -= intw(F); // phase(t2) - phase(t1)
772  phi.data[i] += (long(wt*(i/2)+0.5) + F)/step/(i/2);
773  }
774  else
775  phi.data[i] = 0.;
776 
777  phi.data[i+1] = phase;
778  }
779  }
780  }
781 
782 // average frequency
783 
784  double omega = 0.;
785  double weight = 0.;
786 
787  for (unsigned int i = nFirst; i < imax; i += abs(nStep)) {
788  F = Filter.data[i];
789  if(F>FSNR){
790  a = 1 - F;
791  if(a < 0.0001) a = 0.0001;
792  a = 1./a;
793  omega += a*phi.data[2*i];
794  weight += a;
795  }
796  }
797 
798 // was before 08/08/01
799 // omega += amp.data[2*i]*phi.data[2*i];
800 // weight += amp.data[2*i];
801 
802  omega = (weight>1.) ? omega/weight/(nsub-1) : -Frequency;
803  return omega;
804 }
805 
806 
807 /***********************************************************************
808  * fScan(WaveData &) finds the line fundamental frequency
809  * (saves in Frequency) and the interference amplitude.
810  * Uses:
811  * Frequency - seed value for line frequency
812  * fBand - defines frequency band (f-df,f+df), where to scan for peak
813  ***********************************************************************/
814 double LineFilter::fScan(const WaveData &TD)
815 {
816 #define np 6 // number of points in interpolation scheme in resample()
817 
818  badData = false;
819 
820  if(noScan) return Frequency;
821 
822  WaveData td2(1);
823 
824  int n = TD.size();
825 // int FID = (FilterID<0) ? abs(FilterID) : 0; // set filter ID for makeFilter()
826  int FID = 0; // starting on 03/24/01 for fScan always use FID=0
827 
828  double d, s, sp, fc;
829  double fwhm = 1.;
830  double delta = 0.;
831  double am = 1., ac = 0.;
832  double dfft = nSubs*TD.rate() / n;
833  double e1 = 1.e-3;
834 
835 // double fw = fBand*dfft; before 08/03/01
836  double fw = fBand*dfft/nFirst;
837 
838  double ff = Frequency; // seed frequency before tunning
839  double fp = Frequency; // central frequency.
840 
841 // ff - seed interference frequency;
842 // fc - central frequency
843 // fp - peak's frequency estimated via scan
844 // fnew - new sampling rate which is multiple of target frequency f
845 // ac - calculated frequency correction (relative to fc) in uints of fw
846 // am - maximum allowed deviation of frequebcy in units of fw
847 // aw - am/FWHM of the peak
848 // ic = +1, -1 stores the sign of ac at previous step
849 // dfft - Fourier frequency resolution for given sample
850 // fw - frequency band width for 3 sample points to build parabola
851 // e1 - limit iteration accuracy of the frequency deviation
852 // e2 - limit iteration accuracy for frequency window width
853 
854  if (TD.rate() <= 0.) {
855  cout << " fScan() error: invalid sampling rate = "
856  << TD.rate() << " Aborting calculation.\n";
857  badData = true;
858  return ff;
859  }
860 
861  if ( ff <= 0.) {
862  cout << " fScan() error: invalid interference frequency = "
863  << ff << " Aborting calculation.\n";
864  badData = true;
865  return ff;
866  }
867 
868 
869 //*******************************************************
870 // detailed scan of the region (ff-fband, ff+fband)
871 //*******************************************************
872 
873  int mScan = -nScan;
874  if ( mScan > 0 ) {
875  WaveData sw(mScan);
876  sp = 0.;
877 
878  cout <<" Scanning frequency from "<< ff-mScan*fw/2. << " Hz to "
879  << ff+mScan*fw/2. <<" Hz\n";
880 
881  int ip = 0;
882  for (int i=0; i < mScan && !badData; i++) {
883  Frequency = ff + (i - mScan/2)*fw;
884 
885  td2.resample(TD, newRate(TD.rate()), np);
886  s = makeFilter(td2,FID);
887 
888  sw.data[i] = s;
889  if(s > sp) {sp = s; fp = Frequency; ip = i;}
890  printf(" Frequency = %f Hz, sqrt(<E>) = %f \n", Frequency, s);
891  }
892 
893 // improve peak approximation by taking 3 points close to peak
894  if (ip > 0 && ip < (mScan-1) && !badData) {
895  d = 2.*sw.data[ip] - sw.data[ip + 1] - sw.data[ip - 1];
896  fp += (d > 0.) ? 0.5*fw*(sw.data[ip + 1] - sw.data[ip - 1])/d : 0.;
897  }
898  }
899 
900 //*******************************************************
901 // start tuning frequency
902 //*******************************************************
903  int k = 3;
904  int mode;
905  double ss[3];
906  int ks[3] = {1,1,1};
907 
908  fc = fp;
909  while (!badData) {
910 
911 // calculate energies for 3 values of frequency : fp-fw, fp, fp+fw
912  for (int m = 0; m < 3; m++) {
913  if(ks[m]){
914  Frequency = fc + fw*(m - 1);
915  td2.resample(TD, newRate(TD.rate()), np);
916  ss[m] = makeFilter(td2,FID);
917  ks[m] = 0;
918  }
919  if(badData) break;
920  }
921 
922  if(k++ > nScan){
923  badData = true; // limit number of iterations
924 // cout << "fScan hits a limit on number of iterations\n";
925  }
926  if(badData) break;
927 
928 // find minimum of parabola using three values ss[i]
929 // if d > 0 - parabola has maximum, if d < 0 - minimum
930 
931  d=2.*ss[1]-(ss[2]+ss[0]);
932 
933  if (d > 0.) {
934  ac = 0.5 * (ss[2] - ss[0]); // d * (f-fc)/fw
935  fwhm = sqrt(ac*ac+2.*ss[1]*d)/d; // FWHM/fw
936  fwhm *= fw/dfft; // FWHM/dfft
937  ac /= d; // (f-fc)/fw
938  }
939  else {
940  ac = (ss[2] > ss[0])? am : -am;
941  fwhm = 1.;
942  }
943 
944 // cout<<" fp="<<fp<<" fc="<<fc<<" fw="<<fw<<" ac="<<ac<< "\n";
945 
946  mode = 0; // fw shift
947  if(fabs(ac) < am) mode = 1; // fw/2 shift
948  if(fabs(ac)<am/4. && fw/dfft>0.1) mode = 2; // no shift
949 
950  delta = 1.;
951  if(mode){
952  delta = (fc-fp)/fw + ac; // deviation from the peak frequency
953  fp += delta*fw; // new peak frequency
954  }
955 
956  delta *= fw/dfft; // deviation in units of dfft
957 
958 // cout<<k-1<<" "<<fp<<" "<<delta<<" "<<fwhm<<" "<<ac*fw/dfft<< "\n";
959 
960  if(fabs(delta) < e1) break; // limit in units of dfft
961  if(fabs(delta*fwhm) < e1 && fw/dfft<0.1) break; // limits ac in units of FWHM
962 
963  switch (mode) {
964  case 0: // one step shift right or left
965  if(ac > 0.){ // move one fw step right
966  ss[0] = ss[1]; ss[1] = ss[2]; ks[2] = 1;
967  }
968  else{ // move one fw step left
969  ss[2] = ss[1]; ss[1] = ss[0]; ks[0] = 1;
970  }
971  fc += (ac>0.) ? fw : -fw; // new central frequency
972  fp = fc;
973  break;
974 
975  case 1: // half step shift right or left
976  if(ac > 0.){
977  ss[0] = ss[1]; ks[1] = 1;
978  }
979  else{
980  ss[2] = ss[1]; ks[1] = 1;
981  }
982  fw *= 0.5; // reduce fw by 2 if d>0
983  fc += (ac>0.) ? fw : -fw; // new central frequency
984  break;
985 
986  case 2: // no shift
987  ks[0] = 1; ks[2] = 1;
988  fw = 4*fw*fabs(ac); // reduce fw
989  if(fw/dfft<0.01) fw = 0.01*dfft; // reduce fw
990  k++;
991  break;
992 
993  }
994 
995  }
996 
997  if(badData)
998  fp = ff;
999 // else if(reFine){
1000 // Frequency = fp; // use value of frequency found by fScan
1001 // fp = fabs(getOmega(TD, nSubs)); // return refined frequency
1002 // }
1003  Frequency = ff;
1004  return (badData) ? Frequency : fp; // return refined frequency
1005 
1006 }
1007 
1008 
1009 /***********************************************************************
1010  * Function returns the interference signal for harmonics from nFirst
1011  * to nLast with fundamental frequency F
1012  * Update lineList trend data
1013  * Filter = 0 - corresponds to pure "comb" filter
1014  * Filter = 1 - corresponds to optimal Wiener filter with 1-st method of
1015  * noise estimation (default)
1016  ***********************************************************************/
1018 {
1019  WaveData td2(1);
1020  double s = 0.;
1021  lineData v;
1022  double seedF = Frequency;
1023 
1024 // use Wiener filter if FID = -1 or 1;
1025  int FID = (FilterID == 0) ? 0 : 1;
1026 
1027  if ( TD.rate() <= 0. || omega <= 0. ) {
1028  cout << " Interference() error: invalid interference frequency = "
1029  << omega << "\n Aborting calculation.\n";
1030 
1031  }
1032 
1033  v.T_current = CurrentTime;
1034  v.intensity = 0.;
1035  v.frequency = Frequency;
1036  v.first = nFirst;
1037 
1038  if (badData) { // skip bad data
1039 // lineList.insert(lineList.end(),v); // update lineList trend data
1040 // cout << "Interference(): skip bad data\n";
1041  return 0.;
1042  }
1043 
1044  if(FilterID < 0){
1045  v = getHeteroLine(TD);
1046  s = v.intensity;
1047  }
1048  else {
1049 
1050 // resample data at new sample rate "fnew" which is multiple of base
1051 // frequency of interference fLine and approximately is two times as high
1052 // as original frequency "Rate"
1053 
1054  Frequency = omega;
1055  td2.resample(TD, newRate(TD.rate()), nRIF);
1056  s = makeFilter(td2, FID);
1057  v = getLine(td2); // get interference and lineData
1058 
1059  if(clean){ // return interference
1060  if(badData){
1061  TD *= 0.;
1062  }
1063  else
1064  TD.resample(td2, TD.rate(), nRIF); // resample at original sampling rate
1065  }
1066 
1067  }
1068 
1069  if(badData){
1070  v.frequency *= -1.;
1071  Frequency = seedF; // do not update frequency;
1072  }
1073  if(v.intensity > 0.)
1074  lineList.push_back(v); // update lineList trend data
1075 
1076  // cout<<"intensity="<<sqrt(v.intensity)<<" s="<<s
1077  // <<" amplitude="<<abs(v.amplitude[0])<<endl;
1078 
1079  return s;
1080 }
1081 
1082 /************************************************************************
1083  * Function returns time series with the interference signal removed
1084  ***********************************************************************/
1085 TSeries LineFilter::apply(const TSeries& ts) {
1086 //---------------------------------- Check the input data.
1087  int n = ts.getNSample();
1088  if (!n) return ts;
1089 
1090 // dataCheck(ts); // Check the input data.
1091 
1092 // use fScan to estimate frequency after a long lockloss time
1093  if(StartTime.totalS() - CurrentTime.totalS() > 120.) badData = true;
1094 
1095  StartTime = ts.getStartTime();
1097 
1098  WaveData wts;
1099  wts = ts;
1100 
1101  apply(wts);
1102 
1103  if(clean){
1104 
1105  TSeries r(ts.getStartTime(), Sample, ts.getNSample());
1106  r = ts;
1107  float *vFloat = (float*)r.refData();
1108  for(int j = 0; j<n; j++) vFloat[j] = float(wts.data[j]);
1109  return r;
1110  }
1111  else
1112  return ts;
1113 }
1114 
1115 TSeries LineFilter::operator()(const TSeries& ts) {
1116  return apply(ts);
1117 }
1118 
1119 
1120 /************************************************************************
1121  * apply(ts) estimate interference and save trend data
1122  * if clean=true returns time series with the interference signal removed
1123  ***********************************************************************/
1125 //---------------------------------- Check the input data.
1126  if (!ts.size()) return;
1127  if (!ts.rate()) return;
1128 
1129  StartTime = Time(size_t(ts.start()));
1131 
1132  Stride = ts.size()/ts.rate();
1133  double s = Window > 0. ? Window : Stride;
1134  Interval delta(s);
1135 
1136  double rate = ts.rate();
1137  int n = ts.size();
1138 
1139  int LPF = (nLPF>0) ? nLPF : 0; // depth of the wavelet LP filter
1140 
1141  Biorthogonal<wavereal> w(nWave); // needed if LPF is applied
1142  WSeries<wavereal> *pw = 0;
1143 
1144  WaveData tw; // needed if LPF is applied
1145  double omega = Frequency;
1146 
1147  int NN = 0;
1148  int nTS = ts.size();
1149 
1150  if(LPF){ // apply wavelet low path filter
1151  pw = new WSeries<wavereal>(ts, w);
1152  NN = (nTS >> LPF) << LPF; // new number of samples
1153  if(NN != nTS){ // adjust the number of samples
1154  NN += 1<<LPF;
1155  pw->resample(NN*rate/nTS,nRIF);
1156  rate = pw->rate();
1157  }
1158 
1159  pw->Forward(LPF);
1160  pw->getLayer(tw,0);
1161  rate /= (1<<LPF); // rate of decimated data
1162  tw.rate(rate);
1163  n = tw.size();
1164  }
1165 
1166  int nn = Window > 0. ? int(Window*rate) : n; // if window = 0, take whole ts
1167 
1168 // cout<<"Window="<<Window<<" rate="<<rate<<" n="<<n<<" nn="<<nn<<endl;
1169 
1170  if (nn < int(rate/Frequency)) {
1171  cout <<" LineFilter::apply() error: invalid time window "<<Window<<" sec.\n";
1172  return;
1173  }
1174 
1175  WaveData *tx = new WaveData(nn);
1176 
1177 // printf(" Time interval (sec) | Base frequency (Hz) | Sqrt(E_int)\n");
1178 
1179  int i = 0;
1180  while(i <= n-nn && nn > 0) {
1181 
1182  if((n-i-nn) < nn) { // the last data interval is too short
1183  delta *= double(n - i)/nn; // add leftover to the last interval
1184  nn = n - i;
1185  }
1186 
1187  tx->rate(rate);
1188  if((int)tx->size() != nn) tx->resize(nn);
1189 
1190  if(LPF) tx->cpf(tw,nn,i);
1191  else tx->cpf(ts,nn,i);
1192 
1193  if(FilterID>=0){
1194  if (!reFine || badData || (lineList.size()<3))
1195  omega = fScan(*tx);
1196  else{
1197  omega = getOmega(*tx, nSubs);
1198  if(omega < 0.) omega = fScan(*tx);
1199  }
1200  }
1201 
1202  s = Interference(*tx, omega);
1203  CurrentTime += delta;
1204 
1205  if(clean && !badData){
1206  if(LPF) tw.sub(*tx,nn,0,i);
1207  else ts.sub(*tx,nn,0,i);
1208  }
1209 
1210  // if(!badData)
1211  // printf(" %8.3f - %8.3f %12.6f %20.6f\n" ,
1212  // double(i)/rate, double(i + nn)/rate, Frequency*nFirst, sqrt(s));
1213 
1214  i += nn;
1215  }
1216 
1217  if(clean && LPF){
1218  pw->putLayer(tw,0);
1219  pw->Inverse();
1220  if(NN != nTS)
1221  ts.resample((WaveData &) *pw,ts.rate(),nRIF);
1222  else
1223  ts = *pw;
1224 
1225  if(nTS != (int)ts.size()) // check if data has the same length as input data
1226  cout << "LineFilter::apply(): is "<<ts.size()<<", should be: "<<nTS<<"\n";
1227  }
1228 
1229  delete tx;
1230  if(pw) delete pw;
1231  return;
1232 }
1233 
1234 /*********************************************************************
1235  * get Trend Data from lineList object
1236  *
1237  *********************************************************************/
1239 {
1240  int l_size = lineList.size();
1241  int v_size;
1242  int n = 0;
1243  wavearray<float> out(l_size);
1244  wavearray<float> www(l_size);
1245  list<lineData>::iterator it;
1246  lineData* v;
1247  double a=0., F=0.;
1248  double step = (Window>0.) ? Window : Stride;
1249  double time = 0.;
1250  double phase = 0.;
1251  double averF = 0.;
1252 
1253  out = 0;
1254  www = 0;
1255 
1256  out.rate((step>0.) ? 1./step : 1.);
1257 
1258  if(l_size < 2) { return out; }
1259 
1260  if(m < 0) m=0;
1261  it = lineList.begin(); // set the list at the beginning
1262 
1263  v = &(*(it++));
1264  v_size = v->amplitude.size();
1265 
1266  if(m > 0 && m <= v_size)
1267  phase = arg(v->amplitude[m-1]);
1268 
1269  out.start(v->T_current.totalS());
1270 
1271  if(c=='p') // average frequency
1272  for(int i=0; i<l_size; i++) {
1273  v = &(*(it++));
1274  F = double(v->frequency);
1275  if(F<=0.) continue;
1276  F *= (m == 0) ? 1. : (v->first+m-1);
1277  averF += F; n++;
1278  }
1279 
1280  if(n) averF /= double(n);
1281 
1282  it = lineList.begin(); // set the list at the beginning
1283 
1284  for(int i=0; i<l_size; i++) {
1285  v = &(*(it++));
1286  v_size = v->amplitude.size();
1287  switch (c) {
1288 
1289  case 't': // get start time
1290  out.data[i] = v->T_current.totalS() - out.start();
1291  break;
1292 
1293  case 'a': // get harmonic's amplitude
1294  if(m == 0 || m > v_size)
1295  out.data[i] = (m==0) ? sqrt(v->intensity) : 0.;
1296  else
1297  out.data[i] = abs(v->amplitude[m-1]);
1298  break;
1299 
1300  case 'p': // get harmonic's phase
1301  case 'f': // get harmonic frequency
1302  if(m == 0 || m > v_size){
1303  if(c == 'p')
1304  out.data[i] = v_size;
1305  else
1306  out.data[i] = v->frequency;
1307  }
1308  else {
1309  F = fabs(v->frequency * (v->first+m-1));
1310  a = (arg(v->amplitude[m-1])-phase)/2./PI;
1311  a += axb(F, Stride/2.);
1312  a -= axb(averF, v->T_current.totalS()-out.start()+Stride/2.);
1313  a -= (a>0.) ? long(a+0.5) : long(a-0.5);
1314  out.data[i] = 2.*PI*a;
1315  www.data[i] = 2.*PI*a;
1316  step = v->T_current.totalS() - time;
1317  time = v->T_current.totalS();
1318  if(c == 'f') out.data[i] = F;
1319  }
1320  if(c == 'f' && step<1.1*Stride){ // calculate frequency
1321  a = (i>0) ? (www.data[i]-www.data[i-1])/2./PI : F*step;
1322  a -= (a>0.) ? long(a+0.5) : long(a-0.5);
1323  out.data[i] = (long(F*step+0.5) + a)/step;
1324  }
1325  break;
1326 
1327  case 'F': // get harmonic frequency
1328  a = double(v->frequency);
1329  out.data[i] = (m == 0) ? a : a*(v->first+m-1);
1330  break;
1331 
1332  case 'P': // get harmonic's phase
1333  if(m == 0 || m > v_size)
1334  out.data[i] = v_size;
1335  else
1336  out.data[i] = arg(v->amplitude[m-1]);
1337  break;
1338 
1339  case 's': // get signal power
1340  out.data[i] = 0.;
1341  if(m > v_size || v_size < 1) break;
1342  if(m == 0)
1343  for(int j=0; j<v_size; j++){
1344  F = v->filter[j];
1345  out.data[i] += v->line[j] * F*F;
1346  }
1347  else{
1348  F = v->filter[m-1];
1349  out.data[i] = v->line[m-1] * F*F;
1350  }
1351  out.data[i] *= out.rate();
1352  break;
1353 
1354  case 'S': // get signal spectral density
1355  out.data[i] = 0.;
1356  if(m > v_size || v_size < 1) break;
1357  if(m == 0)
1358  for(int j=0; j<v_size; j++)
1359  out.data[i] += v->line[j];
1360  else
1361  out.data[i] = v->line[m-1];
1362  break;
1363 
1364  case 'n': // get noise power
1365  out.data[i] = 0.;
1366  if(m > v_size || v_size < 1) break;
1367  if(m == 0)
1368  for(int j=0; j<v_size; j++)
1369  out.data[i] += v->noise[j] * v->filter[j];
1370  else
1371  out.data[i] = v->noise[m-1] * v->filter[m-1];
1372  out.data[i] *= out.rate();
1373  break;
1374 
1375  case 'N': // get noise spectral density
1376  out.data[i] = 0.;
1377  if(m > v_size || v_size < 1) break;
1378  if(m == 0)
1379  for(int j=0; j<v_size; j++)
1380  out.data[i] += v->noise[j];
1381  else
1382  out.data[i] = v->noise[m-1];
1383  break;
1384 
1385  case 'K': // get SNR
1386  a = 0.;
1387  out.data[i] = 0.;
1388  if(m > v_size || v_size < 1) break;
1389  if(m == 0)
1390  for(int j=0; j<v_size; j++){
1391  F = v->filter[j];
1392  a += v->noise[j]*F;
1393  out.data[i] += v->line[j] * F*F;
1394  }
1395  else{
1396  F = v->filter[m-1];
1397  a = v->noise[m-1]*F;
1398  out.data[i] = v->line[m-1] * F*F;
1399  }
1400  out.data[i] /= (a>0.) ? a : 1.;
1401  break;
1402 
1403  case 'W': //get filter (m>0)
1404  out.data[i] = 0.;
1405  if(m > v_size || v_size < 1) break;
1406  if(m > 0)
1407  out.data[i] = v->filter[m-1];
1408  break;
1409 
1410  default: // get first harmonic
1411  out.data[i] = v->first;
1412  break;
1413  }
1414  }
1415  return out;
1416 }
1417 
1418 
1419 /*********************************************************************
1420  * Dumps lineList data into file *fname in binary format and type
1421  * "double".
1422  *********************************************************************/
1423 bool LineFilter::DumpTrend(const char *fname, int app)
1424 {
1425  size_t l_size;
1426  size_t v_size;
1427  lineData* v;
1428 
1429  list<lineData>::iterator it = lineList.begin();
1430 
1431  if(dumpStart >= lineList.size()) return false;
1432  for(size_t i=0; i<dumpStart; i++) it++;
1433  l_size = lineList.size() - dumpStart;
1434 
1435 // calculate the data length
1436 
1437  size_t max_size = 0;
1438  for(size_t i=0; i<l_size; i++) {
1439  v = &(*(it++));
1440  v_size = v->amplitude.size();
1441  if(v_size > max_size) max_size = v_size;
1442  }
1443 
1444  int m = (5*max_size+4);
1445  size_t n = m*(l_size+1);
1446  if(n < 4) return false;
1447 
1448 // pack lineList into WaveData out
1449 
1451  out->data[0] = max_size; // length of the lineData amplitude vector
1452  out->data[1] = l_size; // length of the lineList
1453  out->data[2] = m; // total length of the lineData
1454  out->data[3] = n; // total lenght
1455 
1456  it = lineList.begin();
1457  for(size_t i=0; i<dumpStart; i++) it++;
1458 
1459 // cout<<"dumpStart = "<<dumpStart;
1460 // cout<<", listSize = "<<lineList.size();
1461 // cout<<", Stride = "<<Stride<<endl;
1462 
1463  double gpsTime = it->T_current.totalS();
1464 
1465  int gps = int(gpsTime)/1000;
1466  out->data[4] = float(gps); // int(gps time/1000)
1467  out->data[5] = gpsTime - 1000.*double(gps); // rest of gps time
1468  out->data[6] = (Window>0.) ? Window : Stride; // filter stride
1469 
1470  for(size_t i=1; i<=l_size; i++) {
1471  v = &(*(it++));
1472  v_size = v->amplitude.size();
1473 
1474  out->data[i*m+0]= v->T_current.totalS() - gpsTime;
1475  out->data[i*m+1]= v->frequency;
1476  out->data[i*m+2]= v->intensity;
1477  out->data[i*m+3]= v->first;
1478 
1479  for(unsigned int j=0; j<max_size; j++){
1480  if(j < v_size) {
1481  out->data[i*m+4+j*5] = abs(v->amplitude[j]);
1482  out->data[i*m+5+j*5] = arg(v->amplitude[j]);
1483  out->data[i*m+6+j*5] = v->line[j];
1484  out->data[i*m+7+j*5] = v->noise[j];
1485  out->data[i*m+8+j*5] = v->filter[j];
1486  }
1487  else {
1488  out->data[i*m+4+j*5] = 0.;
1489  out->data[i*m+5+j*5] = 0.;
1490  out->data[i*m+6+j*5] = 0.;
1491  out->data[i*m+7+j*5] = 0.;
1492  out->data[i*m+8+j*5] = 0.;
1493  }
1494  }
1495  }
1496 
1497  out->DumpBinary(fname, app);
1498 
1499  delete out;
1500  return true;
1501 }
1502 
1503 
1504 /*********************************************************************
1505  * Read trend data from file into the lineList data structure.
1506  *********************************************************************/
1507 bool LineFilter::LoadTrend(const char *fname)
1508 {
1509  lineData v;
1511  float *p = 0;
1512  double last = 0.;
1513  double step = 0.;
1514  double time = 0.;
1515  double gpsTime = 0.;
1516  unsigned int count = 0;
1517 
1518  in.ReadBinary(fname); // read file
1519  if(in.size() < 6) return false;
1520 
1521  while(count < in.size()){
1522  p = &(in.data[count]);
1523  int m = int(*(p+2) + 0.5); // total length of the lineData
1524  if(m <= 1) return false;
1525 
1526  int l_size = int(*(p+1) + 0.5); // length of the lineList
1527  if(l_size < 1) return false;
1528 
1529  int v_size = int(*p + 0.5); // length of the lineData amplitude vector
1530  count += int(*(p+3)+0.5); // add total length of the block
1531 
1532  gpsTime = double(int(*(p+4)+0.5))*1000. + *(p+5); // block start time
1533  StartTime = Time(0);
1534  CurrentTime = Time(size_t(*(p+6)));
1535  Stride = *(p+6);
1536  Window = *(p+6);
1537 
1538  v.amplitude.resize(v_size);
1539  v.line.resize(v_size);
1540  v.noise.resize(v_size);
1541  v.filter.resize(v_size);
1542 
1543  time = *(p+m);
1544  last = time;
1545  step = 0.;
1546 
1547 // pack lineList from WaveData inv->T_current.totalS();
1548 
1549  for(int i=1; i<=l_size; i++) {
1550  p += m;
1551  if(*p != 0.) step = *p - last;
1552  time += step;
1553  last = *p;
1554  v.T_current = Time(size_t(time+gpsTime));
1555  v.frequency = *(p+1);
1556  v.intensity = *(p+2);
1557  v.first = int(*(p+3)+0.5);
1558 
1559  for(int j=0; j<v_size; j++){
1560  v.amplitude[j] = *(p+4+j*5);
1561  v.amplitude[j]*= exp(f_complex(0,*(p+5+j*5)));
1562  v.line[j] = *(p+6+j*5);
1563  v.noise[j] = *(p+7+j*5);
1564  v.filter[j] = *(p+8+j*5);
1565  }
1566 
1567  lineList.insert(lineList.end(),v);
1568  }
1569  }
1570  return true;
1571 }
1572 
1573 
1574 
1575 
int FilterState
Definition: LineFilter.hh:191
static const double C
Definition: GNGen.cc:28
void reset()
Clear/release the internal History vector and reset the current time.
Definition: LineFilter.cc:170
double M
Definition: DrawEBHH.C:13
unsigned int nBand
Definition: LineFilter.hh:179
bool LoadTrend(const char *)
Definition: LineFilter.cc:1507
wavearray< double > st
Definition: LineFilter.hh:199
double delta
virtual void rate(double r)
Definition: wavearray.hh:141
The linefilter class containes methods to track and remove quasi- monochromatic lines.
#define np
double axb(double, double)
Definition: LineFilter.hh:243
wavearray< double > a(hp.size())
WSeries< float > v[nIFO]
Definition: cwb_net.C:80
LineFilter * clone(void) const
Clone a LineFilter.
Definition: LineFilter.cc:88
void dataCheck(const TSeries &ts) const
Check the data for validity.
Definition: LineFilter.cc:92
bool badData
Definition: LineFilter.hh:185
int n
Definition: cwb_net.C:28
WaveData Filter
Definition: LineFilter.hh:206
Time StartTime
Definition: LineFilter.hh:195
double Interference(WaveData &, double)
Definition: LineFilter.cc:1017
ofstream out
Definition: cwb_merge.C:214
std::vector< f_complex > amplitude
Definition: LineFilter.hh:42
cout<< endl;cout<< "ts size = "<< ts.size()<< " ts rate = "<< ts.rate()<< endl;tf.Forward(ts, wdm);int levels=tf.getLevel();cout<< "tf size = "<< tf.size()<< endl;double dF=tf.resolution();double dT=1./(2 *dF);cout<< "rate(hz) : "<< RATE<< "\ layers : "<< nLAYERS<< "\ dF(hz) : "<< dF<< "\ dT(ms) : "<< dT *1000.<< endl;int itime=TIME_PIXEL_INDEX;int ifreq=FREQ_PIXEL_INDEX;int index=(levels+1) *itime+ifreq;double time=itime *dT;double freq=(ifreq >0) ? ifreq *dF :dF/4;cout<< endl;cout<< "PIXEL TIME = "<< time<< " sec "<< endl;cout<< "PIXEL FREQ = "<< freq<< " Hz "<< endl;cout<< endl;wavearray< double > x
double phase
wavearray< double > psd(33)
virtual void ReadBinary(const char *, int=0)
Definition: wavearray.cc:410
float frequency
Definition: LineFilter.hh:39
bool DumpTrend(const char *, int=0)
Definition: LineFilter.cc:1423
STL namespace.
~LineFilter(void)
Destroy the LineFilter object and release the function storage.
Definition: LineFilter.cc:75
double Frequency
Definition: LineFilter.hh:172
wavearray< wavereal > WaveData
Definition: LineFilter.hh:35
long intw(double)
Definition: LineFilter.hh:246
int m
Definition: cwb_net.C:28
virtual void start(double s)
Definition: wavearray.hh:137
int j
Definition: cwb_net.C:28
Time T_current
Definition: LineFilter.hh:38
i drho i
double newRate(double)
Definition: LineFilter.hh:236
#define N
cout<< "SNR "<< xsnr<< endl;wavearray< double > f
Definition: ComputeSNR.C:75
cout<< "Selected Pixels : "<< nPix<< endl;wc.cluster(1, 1);SSeries< double > ss
void setFilter(int nF=1, int nL=0, int nS=1, int nD=-1, int nB=5, int nR=6, int nW=8)
Definition: LineFilter.cc:142
std::list< lineData > lineList
Definition: LineFilter.hh:202
double getOmega(const WaveData &, int=2)
Definition: LineFilter.cc:692
#define PI
Definition: watfun.hh:32
int Sample(Complex *H, double *t, int N, double totalMass, double Rate, wavearray< double > &hps, wavearray< double > &hxs)
Definition: eBBH.cc:34
size_t mode
virtual double rms()
Definition: wavearray.cc:1206
wavearray< double > w
Definition: Test1.C:27
virtual size_t size() const
Definition: wavearray.hh:145
float phi
void sub(const wavearray< DataType_t > &, int=0, int=0, int=0)
Definition: wavearray.cc:772
LineFilter(void)
Build an empty LineFilter.
Definition: LineFilter.cc:43
i() int(T_cor *100))
lineData getHeteroLine(WaveData &)
Definition: LineFilter.cc:488
wavearray< double > ct
Definition: LineFilter.hh:198
unsigned int maxLine(int)
Definition: LineFilter.cc:110
std::vector< float > filter
Definition: LineFilter.hh:45
int getLayer(wavearray< DataType_t > &w, double n)
param: n - layer number
Definition: wseries.cc:193
printf("total live time: non-zero lags = %10.1f \, liveTot)
void hann(void)
Definition: wavearray.hh:372
char fname[1024]
unsigned int nLast
Definition: LineFilter.hh:176
lineData getLine(WaveData &)
Definition: LineFilter.cc:353
TSeries operator()(const TSeries &ts)
Definition: LineFilter.cc:1115
int k
double Stride
Definition: LineFilter.hh:174
WaveData getPSD(const WaveData &, int=1)
Definition: LineFilter.cc:227
void setFScan(double f=0., double sn=2., double fS=0.45, int nS=20)
Definition: LineFilter.cc:203
double Window
Definition: LineFilter.hh:173
wavearray< float > getTrend(int, char)
Definition: LineFilter.cc:1238
double F
double e
float intensity
Definition: LineFilter.hh:40
WaveData LineSD
Definition: LineFilter.hh:205
virtual void DumpBinary(const char *, int=0)
Definition: wavearray.cc:353
virtual void FFTW(int=1)
Definition: wavearray.cc:896
regression r
Definition: Regression_H1.C:44
s s
Definition: cwb_net.C:155
double fScan(const WaveData &)
Definition: LineFilter.cc:814
double gps
double makeFilter(const WaveData &, int=0)
Definition: LineFilter.cc:298
Interval Sample
Definition: LineFilter.hh:196
ifstream in
wavearray< double > ts(N)
void resize(size_t=0)
Definition: LineFilter.cc:181
virtual void resample(double, int=6)
Definition: wseries.cc:915
double fabs(const Complex &x)
Definition: numpy.cc:55
double SNR
Definition: LineFilter.hh:188
void resample(const wavearray< DataType_t > &, double, int=6)
Definition: wavearray.cc:503
WaveData NoiseSD
Definition: LineFilter.hh:204
double Q
void Forward(int n=-1)
param: wavelet - n is number of steps (-1 means full decomposition)
Definition: wseries.cc:246
Meyer< double > S(1024, 2)
double omega
Definition: testWDM_4.C:12
unsigned int nFirst
Definition: LineFilter.hh:175
DataType_t * data
Definition: wavearray.hh:319
The LineFilter class containes methods to track and remove quasi- monochromatic lines.
Definition: LineFilter.hh:56
size_t dumpStart
Definition: LineFilter.hh:190
double Stack(const wavearray< DataType_t > &, int)
Definition: wavearray.cc:991
unsigned int first
Definition: LineFilter.hh:41
std::complex< float > f_complex
Definition: LineFilter.hh:33
double fBand
Definition: LineFilter.hh:181
Time CurrentTime
Definition: LineFilter.hh:194
std::vector< float > noise
Definition: LineFilter.hh:44
virtual void resize(unsigned int)
Definition: wavearray.cc:463
void Inverse(int n=-1)
param: n - number of steps (-1 means full reconstruction)
Definition: wseries.cc:291
std::vector< float > line
Definition: LineFilter.hh:43
void putLayer(wavearray< DataType_t > &, double n)
param: n - layer number
Definition: wseries.cc:219
bool isDataValid(const TSeries &ts) const
Check the data for validity.
Definition: LineFilter.cc:120
#define SNR
Definition: DrawNRI.C:36
TSeries apply(const TSeries &ts)
The argument time series is filtered to remove lines, and the argument TSeries ts is left unchanged...
Definition: LineFilter.cc:1085
void cpf(const wavearray< DataType_t > &, int=0, int=0, int=0)
Definition: wavearray.cc:717
wavearray< double > wt
Definition: LineFilter.hh:200
double SeedFrequency
Definition: LineFilter.hh:192