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