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