Logo coherent WaveBurst  
Library Reference Guide
Logo
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
wavearray.cc
Go to the documentation of this file.
1 /*
2 # Copyright (C) 2019 Sergey Klimenko, Gabriele Vedovato
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  * Package: Wavelet Analysis Tool
21  * generic data container to use with DMT and ROOT
22  * File name: wavearray.cc
23  *-------------------------------------------------------
24 */
25 // wavearray class is the base class for wavelet data amd methods .
26 
27 #include <time.h>
28 #include <iostream>
29 //#include <sstream>
30 //#include <strstream>
31 
32 //#include "PConfig.h"
33 #ifdef __GNU_STDC_OLD
34 #include <gnusstream.h>
35 #else
36 #include <sstream>
37 #endif
38 
39 #include "wavearray.hh"
40 #include "wavefft.hh"
41 #include "TComplex.h"
42 #include "TObjArray.h"
43 #include "TObjString.h"
44 #include "TFile.h"
45 
46 extern "C" {
47  typedef int (*qsort_func) (const void*, const void*);
48 }
49 
50 ClassImp(wavearray<double>)
51 
52 using namespace std;
53 
54 //: Default constructor
55 template<class DataType_t>
57  data(NULL),Size(0),Rate(1.),Start(0.),Stop(0.),Edge(0.),fftw(NULL), ifftw(NULL)
58 {
59  Slice = std::slice(0,0,0);
60 }
61 
62 //: allocates a data array with N=n elements.
63 template<class DataType_t>
65 Rate(1.),Start(0.),Edge(0.),fftw(NULL),ifftw(NULL)
66 {
67  if (n <= 0 ) n = 1;
68  data = (DataType_t *)malloc(n*sizeof(DataType_t));
69  Size = n;
70  Stop = double(n);
71  Slice = std::slice(0,n,1);
72  *this = 0;
73 }
74 
75 //: copy constructor
76 template<class DataType_t>
78  data(NULL),Size(0),Rate(1.),Start(0.),Stop(0.),Edge(0.),fftw(NULL), ifftw(NULL)
79 { *this = a; }
80 
81 // explicit construction from array
82 template<class DataType_t> template<class T>
84 wavearray(const T *p, unsigned int n, double r) :
85  data(NULL),Size(0),Rate(1.),Start(0.),Edge(0.),fftw(NULL), ifftw(NULL)
86 {
87  unsigned int i;
88  if(n != 0 && p != NULL){
89  data = (DataType_t *)malloc(n*sizeof(DataType_t));
90  for (i=0; i < n; i++) data[i] = p[i];
91  Size = n;
92  Rate = r;
93  Stop = n/r;
94  }
95  Slice = std::slice(0,n,1);
96 }
97 
98 //: destructor
99 template<class DataType_t>
101 {
102  if(data) free(data);
103  resetFFTW();
104 }
105 
106 //: operators =
107 
108 template<class DataType_t>
111 {
112  if (this==&a) return *this;
113 
114  unsigned int i;
115  unsigned int N = a.Slice.size();
116  unsigned int m = a.Slice.stride();
117 
118  this->Edge = a.Edge;
119  if (N>0 && a.data) {
120  register DataType_t *pm = a.data + a.Slice.start();
122 
123  for (i=0; i < N; i++) { data[i] = *pm; pm+=m; }
124 
125  if(a.rate()>0.) {
126  start(a.start() + a.Slice.start()/a.rate());
127  stop(start()+N*m/a.rate());
128  }
129  else {
130  start(a.start());
131  stop(a.stop());
132 
133  }
134 
135  rate(a.rate()/m);
136  Slice = std::slice(0, size(),1);
137  const_cast<wavearray<DataType_t>&>(a).Slice = std::slice(0,a.size(),1);
138  }
139  else if(data) {
140  free(data);
141  data = NULL;
142  Size = 0;
143  Start = a.start();
144  Stop = a.stop();
145  Rate = a.rate();
146  Slice = std::slice(0,0,0);
147  }
148  this->fftw = NULL;
149  this->ifftw = NULL;
150 
151  return *this;
152 }
153 
154 template<class DataType_t>
157 {
158  unsigned int i;
159  unsigned int N = limit(a);
160  unsigned int n = Slice.stride();
161  unsigned int m = a.Slice.stride();
162  register DataType_t *p = a.data + a.Slice.start();
163 
164  if(size())
165  for (i=Slice.start(); i<N; i+=n){ data[i] = *p; p += m; }
166 
167  Slice = std::slice(0, size(),1);
168  a.Slice = std::slice(0,a.size(),1);
169  return *this;
170 }
171 
172 template<class DataType_t>
174 operator=(const DataType_t c)
175 {
176  unsigned int i;
177  unsigned int n = Slice.stride();
178  unsigned int N = limit();
179 
180  if(size())
181  for (i=Slice.start(); i < N; i+=n) data[i] = c;
182 
183  Slice = std::slice(0, size(),1);
184  return *this;
185 }
186 
187 //: operators +=
188 
189 template<class DataType_t>
192 {
193  unsigned int i;
194  unsigned int N = limit(a);
195  unsigned int n = Slice.stride();
196  unsigned int m = a.Slice.stride();
197  register DataType_t *p = a.data + a.Slice.start();
198 
199  if(size())
200  for (i=Slice.start(); i<N; i+=n){ data[i] += *p; p += m; }
201 
202  Slice = std::slice(0, size(),1);
203  a.Slice = std::slice(0,a.size(),1);
204  return *this;
205 }
206 
207 template<class DataType_t>
209 operator+=(const DataType_t c)
210 {
211  unsigned int i;
212  unsigned int n = Slice.stride();
213  unsigned int N = limit();
214 
215  if(size())
216  for (i=Slice.start(); i < N; i+=n) data[i] += c;
217 
218  Slice = std::slice(0, size(),1);
219  return *this;
220 }
221 
222 //: operators -=
223 
224 template<class DataType_t>
227 {
228  unsigned int i;
229  unsigned int N = limit(a);
230  unsigned int n = Slice.stride();
231  unsigned int m = a.Slice.stride();
232  register DataType_t *p = a.data + a.Slice.start();
233 
234  if(size())
235  for (i=Slice.start(); i<N; i+=n){ data[i] -= *p; p += m; }
236 
237  Slice = std::slice(0, size(),1);
238  a.Slice = std::slice(0,a.size(),1);
239  return *this;
240 }
241 
242 template<class DataType_t>
244 operator-=(const DataType_t c)
245 {
246  unsigned int i;
247  unsigned int n = Slice.stride();
248  unsigned int N = limit();
249 
250  if(size())
251  for (i=Slice.start(); i < N; i+=n) data[i] -= c;
252 
253  Slice = std::slice(0, size(),1);
254  return *this;
255 }
256 
257 //: multiply all elements of data array by constant
258 template<class DataType_t>
260 operator*=(const DataType_t c)
261 {
262  unsigned int i;
263  unsigned int n = Slice.stride();
264  unsigned int N = limit();
265 
266  if(size())
267  for (i=Slice.start(); i < N; i+=n) data[i] *= c;
268 
269  Slice = std::slice(0, size(),1);
270  return *this;
271 }
272 
273 // scalar production
274 template<class DataType_t>
277 {
278  unsigned int i;
279  unsigned int N = limit(a);
280  unsigned int n = Slice.stride();
281  unsigned int m = a.Slice.stride();
282  register DataType_t *p = a.data + a.Slice.start();
283 
284  if(size())
285  for (i=Slice.start(); i<N; i+=n){ data[i] *= *p; p += m; }
286 
287  Slice = std::slice(0, size(),1);
288  a.Slice = std::slice(0,a.size(),1);
289  return *this;
290 }
291 
292 // operator[](const std::slice &)
293 template<class DataType_t>
296 {
297  Slice = s;
298  if(limit() > size()){
299  cout << "wavearray::operator[slice]: Illegal argument "<<limit()<<" "<<size()<<"\n";
300  Slice = std::slice(0,size(),1);
301  }
302  return *this;
303 }
304 
305 // operator[](const std::slice &)
306 template<class DataType_t>
307 DataType_t & wavearray<DataType_t>::
308 operator[](const unsigned int n)
309 {
310  if(n >= size()){
311  cout << "wavearray::operator[int]: Illegal argument\n";
312  return data[0];
313  }
314  return data[n];
315 }
316 
317 //: Dumps data array to file *fname in ASCII format.
318 template<class DataType_t>
319 void wavearray<DataType_t>::Dump(const char *fname, int app)
320 {
321  int n=size();
322  char mode[3] = "w";
323  if (app == 1) strcpy (mode, "a");
324 
325  FILE *fp;
326 
327  if ( (fp = fopen(fname, mode)) == NULL ) {
328  cout << " Dump() error: cannot open file " << fname <<". \n";
329  return;
330  };
331 
332  if(app == 0) {
333  fprintf( fp,"# start time: -start %lf \n", this->Start );
334  fprintf( fp,"# sampling rate: -rate %lf \n", this->Rate );
335  fprintf( fp,"# number of samples: -size %d \n", (int)this->Size );
336  }
337 
338  if(app == 2) {
339  double dt = 1./this->rate();
340  for (int i = 0; i < n; i++) {
341  double time = this->start()+i*dt;
342  fprintf( fp,"%14f %e\n", time, data[i]);
343  }
344  } else {
345  for (int i = 0; i < n; i++) fprintf( fp,"%e ", (float)data[i]);
346  }
347 
348  fclose(fp);
349 }
350 
351 //: Dumps data array to file *fname in binary format.
352 template<class DataType_t>
353 void wavearray<DataType_t>::DumpBinary(const char *fname, int app)
354 {
355  int n = size() * sizeof(DataType_t);
356  char mode[5];
357  strcpy (mode, "w");
358 
359  if (app == 1) strcpy (mode, "a");
360 
361  FILE *fp;
362 
363  if ( (fp=fopen(fname, mode)) == NULL ) {
364  cout << " DumpBinary() error : cannot open file " << fname <<" \n";
365  return ;
366  }
367 
368  fwrite(data, n, 1, fp);
369  fclose(fp);
370 }
371 
372 //: Dumps data array to file *fname in binary format as "short".
373 template<class DataType_t>
374 void wavearray<DataType_t>::DumpShort(const char *fname, int app)
375 {
376  int n = size();
377  char mode[5] = "w";
378  if (app == 1) strcpy (mode, "a");
379 
380  FILE *fp;
381  if ( (fp = fopen(fname, mode)) == NULL ) {
382  cout << " DumpShort() error : cannot open file " << fname <<". \n";
383  return;
384  }
385 
386  short *dtemp;
387  dtemp=new short[n];
388 
389  for ( int i=0; i<n; i++ ) dtemp[i]=short(data[i]) ;
390 
391  n = n * sizeof(short);
392 
393  fwrite(dtemp, n, 1, fp);
394  fclose(fp);
395  delete [] dtemp;
396 }
397 
398 //: Dumps object wavearray to file *fname in root format.
399 template<class DataType_t>
401 {
402  TFile* rfile = new TFile(fname, "RECREATE");
403  this->Write("wavearray"); // write this object
404  rfile->Close();
405  delete rfile;
406 }
407 
408 //: Read data from file in binary format.
409 template<class DataType_t>
411 {
412  int step = sizeof(DataType_t);
413  FILE *fp;
414  double d;
415 
416  if ( (fp=fopen(fname,"r")) == NULL ) {
417  cout << " ReadBinary() error : cannot open file " << fname <<". \n";
418  exit(1);
419  }
420 
421 
422  if(N == 0){ // find the data length
423  while(!feof(fp)){
424  fread(&d,step,1,fp);
425  N++;
426  }
427  N--;
428  rewind(fp);
429  }
430 
431  if(int(size()) != N) resize(N);
432  int n = size() * sizeof(DataType_t);
433 
434  fread(data, n, 1, fp); // Reading binary record
435  fclose(fp);
436 }
437 
438 //: Read data from file as short.
439 template<class DataType_t>
441 {
442  short *dtmp;
443  dtmp = new short[size()];
444  int n = size() * sizeof(short);
445  FILE *fp;
446 
447  if ( (fp=fopen(fname,"r")) == NULL ) {
448  cout << " ReadShort() error : cannot open file " << fname <<". \n";
449  return;
450  }
451 
452  cout << " Reading binary record, size="<< n <<"\n";
453 
454  fread(dtmp, n, 1, fp);
455  for (unsigned int i = 0; i < size(); i++)
456  data[i] = DataType_t(dtmp[i]);
457  fclose(fp);
458  delete [] dtmp;
459 }
460 
461 //: resizes data array to a new length n.
462 template<class DataType_t>
464 {
465  DataType_t *p = NULL;
466  if(n==0){
467  if(data) free(data);
468  data = NULL;
469  Size = 0;
470  Stop = Start;
471  Slice = std::slice(0,0,0);
472  return;
473  }
474 
475  p = (DataType_t *)realloc(data,n*sizeof(DataType_t));
476 
477  if(p){
478  data = p;
479  Size = n;
480  Stop = Start + n/Rate;
481  Slice = std::slice(0,n,1);
482  }
483  else {
484  cout<<"wavearray::resize(): memory allocation failed.\n";
485  exit(0);
486  }
487 
488  resetFFTW();
489 }
490 
491 /************************************************************************
492  * Creates new data set by resampling the original data from "a" *
493  * with new sample frequency "f". Uses polynomial interpolation scheme *
494  * (Lagrange formula) with np-points, "np" must be even number, by *
495  * default np=6 (corresponds to 5-th order polynomial interpolation). *
496  * This function calls wavearray::resize() function to adjust *
497  * current data array if it's size does not exactly match new number *
498  * of points. *
499  ************************************************************************/
500 
501 template<class DataType_t>
503 resample(wavearray<DataType_t> const &a, double f, int nF)
504 {
505  int nP = nF;
506  if(nP<=1) nP = 6;
507  if(int(a.size())<nP) nP = a.size();
508  nP = (nP>>1)<<1;
509 
510  int N;
511  int nP2 = nP/2;
512 
513  const DataType_t *p = a.data;
514 
515  register int i;
516  register int iL;
517  register double x;
518  double *temp=new double[nF];
519 
520  rate(f);
521  double ratio = a.rate() / rate();
522  N = int(a.size()/ratio + 0.5);
523 
524  if ( (int)size() != N ) resize(N);
525 
526 // left border
527 
528  int nL = int(nP2/ratio);
529 
530  for (i = 0; i < nL; i++)
531  data[i] = (DataType_t)Nevill(i*ratio, nP, p, temp);
532 
533 // in the middle of array
534 
535  int nM = int((a.size()-nP2)/ratio);
536  if(nM < nL) nM = nL;
537 
538  if(nM&1 && nM>nL) {
539  x = nL*ratio;
540  iL = int(x) - nP2 + 1 ;
541  data[i] = (DataType_t)Nevill(x-iL, nP, p+iL, temp);
542  nL++;
543  }
544  for (i = nL; i < nM; i+=2) {
545  x = i*ratio;
546  iL = int(x) - nP2 + 1 ;
547  data[i] = (DataType_t)Nevill(x-iL, nP, p+iL, temp);
548  x += ratio;
549  iL = int(x) - nP2 + 1 ;
550  data[i+1] = (DataType_t)Nevill(x-iL, nP, p+iL, temp);
551  }
552 
553 // right border
554 
555  int nR = a.size() - nP;
556  p += nR;
557  for (i = nM; i < N; i++)
558  data[i] = (DataType_t)Nevill(i*ratio-nR, nP, p, temp);
559 
560  delete [] temp;
561 }
562 
563 template<class DataType_t>
564 void wavearray<DataType_t>::resample(double f, int nF)
565 {
567  a = *this;
568  resample(a,f,nF);
569 }
570 
571 template<class DataType_t>
573 {
574  if(f<=0) {
575  cout<<"wavearray::Resample(): error - resample frequency must be >0\n";
576  exit(1);
577  }
578 
579  double rsize = f/this->rate()*this->size(); // new size
580 
581  if(fmod(rsize,2)!=0) {
582  cout<<"wavearray::Resample(): error - resample frequency (" << f << ") not allowed\n";
583  exit(1);
584  }
585 
586  int size = this->size(); // old size
587 
588  this->FFTW(1);
589  this->resize((int)rsize);
590  for(int i=size;i<rsize;i++) this->data[i]=0;
591  this->FFTW(-1);
592  this->rate(f);
593 }
594 
595 template<class DataType_t>
597 {
598  if(T==0) return;
599 
600  // search begin,end of non zero data
601  int ibeg=0; int iend=0;
602  for(int i=0;i<(int)this->size();i++) {
603  if(this->data[i]!=0 && ibeg==0) ibeg=i;
604  if(this->data[i]!=0) iend=i;
605  }
606  int ilen=iend-ibeg+1;
607  // create temporary array for FFTW & add scratch buffer + T
608  int ishift = fabs(T)*this->rate();
609  int isize = 2*ilen+2*ishift;
610  isize = isize + (isize%4 ? 4 - isize%4 : 0); // force to be multiple of 4
611  wavearray<DataType_t> w(isize);
612  w.rate(this->rate()); w=0;
613  // copy this->data !=0 in the middle of w array & set this->data=0
614  for(int i=0;i<ilen;i++) {w[i+ishift+ilen/2]=this->data[ibeg+i];this->data[ibeg+i]=0;}
615 
616  double pi = TMath::Pi();
617  // apply time shift to waveform vector
618  w.FFTW(1);
619  TComplex C;
620  double df = w.rate()/w.size();
621  //cout << "T : " << T << endl;
622  for (int ii=0;ii<(int)w.size()/2;ii++) {
623  TComplex X(w[2*ii],w[2*ii+1]);
624  X=X*C.Exp(TComplex(0.,-2*pi*ii*df*T)); // Time Shift
625  w[2*ii]=X.Re();
626  w[2*ii+1]=X.Im();
627  }
628  w.FFTW(-1);
629 
630  // copy shifted data to input this->data array
631  for(int i=0;i<(int)w.size();i++) {
632  int j=ibeg-(ishift+ilen/2)+i;
633  if((j>=0)&&(j<(int)this->size())) this->data[j]=w[i];
634  }
635 }
636 
637 
638 template<class DataType_t>
640 Resample(wavearray<DataType_t> const &a, double f, int np)
641 {
642  int i1, N, n1, n2, n, np2 = np/2;
643  double s, x, *c, *v;
644  c=new double[np];
645  v=new double[np];
646 
647  rate(f);
648  double ratio = a.rate() / rate();
649  n = a.size();
650  N = int(n/ratio + 0.5);
651 
652  if ( (int)size() != N ) resize(N);
653 
654 // calculate constant filter part c(k) = -(-1)^k/k!/(np-k-1)!
655  for (int i = 0; i < np; i++) {
656  int m = 1;
657  for (int j = 0; j < np; j++) if (j != i) m *= (i - j);
658  c[i] = 1./double(m);
659  }
660 
661  for (int i = 0; i < N; i++)
662  {
663  x = i*ratio;
664 
665  i1 = int(x);
666  x = x - i1 + np2 - 1;
667 
668 // to treat data boundaries we need to calculate critical numbers n1 and n2
669  n1 = i1 - np2 + 1;
670  n2 = i1 + np2 + 1 - n;
671 
672 // here we calculate the sum of products like h(k)*a(k), k=0..np-1,
673 // where h(k) are filter coefficients, a(k) are signal samples
674 // h(k) = c(k)*prod (x-i), i != k, c(k) = -(-1)^k/k!/(np-k-1)!
675 
676 // get signal part multiplied by constant filter coefficients
677  if ( n1 >= 0 )
678  if ( n2 <= 0 )
679 // regular case - far from boundaries
680  for (int j = 0; j < np; j++) v[j] = c[j]*a.data[i1 + j - np2 + 1];
681 
682  else {
683 // right border case
684  x = x + n2;
685  for (int j = 0; j < np; j++) v[j] = c[j]*a.data[n + j - np];
686  }
687  else {
688 // left border case
689  x = x + n1;
690  for (int j = 0; j < np; j++) v[j] = c[j]*a.data[j];
691  }
692 
693 // multiply resulted v[j] by x-dependent factors (x-k), if (k != j)
694  for (int k = 0; k < np; k++) {
695  for (int j = 0; j < np; j++) if (j != k) v[j] *= x;
696  x -= 1.; }
697 
698  s = 0.;
699  for (int j = 0; j < np; j++) s += v[j];
700 
701  data[i] = (DataType_t)s;
702  }
703 
704  delete [] c;
705  delete [] v;
706 }
707 
708 /******************************************************************************
709  * copies data from data array of the object wavearray a to *this
710  * object data array. Procedure starts from the element "a_pos" in
711  * the source array which is copied to the element "pos" in the
712  * destination array. "length" is the number of data elements to copy.
713  * By default "length"=0, which means copy all source data or if destination
714  * array is shorter, copy data until the destination is full.
715  *****************************************************************************/
716 template<class DataType_t> void wavearray<DataType_t>::
717 cpf(const wavearray<DataType_t> &a, int length, int a_pos, int pos)
718 {
719 // if (rate() != a.rate()){
720 // cout << "wavearray::cpf() warning: sample rate mismatch.\n";
721 // cout<<"rate out: "<<rate()<<" rate in: "<<a.rate()<<endl;
722 // }
723 
724  if (length == 0 )
725  length = ((size() - pos) < (a.size() - a_pos))?
726  (size() - pos) : (a.size() - a_pos);
727 
728  if( length > (int)(size() - pos) ) length = size() - pos;
729  if( length > (int)(a.size() - a_pos) ) length = a.size() - a_pos;
730 
731  for (int i = 0; i < length; i++)
732  data[i + pos] = a.data[i + a_pos];
733 
734 // rate(a.rate());
735 }
736 
737 /******************************************************************************
738  * Adds data from data array of the object wavearray a to *this
739  * object data array. Procedure starts from the element "a_pos" in
740  * the source array which is added starting from the element "pos" in the
741  * destination array. "length" is the number of data elements to add.
742  * By default "length"=0, which means add all source data or if destination
743  * array is shorter, add data up to the end of destination.
744  *****************************************************************************/
745 template<class DataType_t> void wavearray<DataType_t>::
746 add(const wavearray<DataType_t> &a, int length, int a_pos, int pos)
747 {
748 // if (rate() != a.rate())
749 // cout << "wavearray::add() warning: sample rate mismatch.\n";
750 
751  if (length == 0 )
752  length = ((size() - pos) < (a.size() - a_pos))?
753  (size() - pos) : (a.size() - a_pos);
754 
755  if( length > (int)( size()- pos) ) length = size() - pos;
756  if( length > (int)(a.size() - a_pos) ) length = a.size() - a_pos;
757 
758  for (int i = 0; i < length; i++)
759  data[i + pos] += a.data[i + a_pos];
760 }
761 
762 
763 /******************************************************************************
764  * Subtracts data array of the object wavearray a from *this
765  * object data array. Procedure starts from the element "a_pos" in
766  * the source array which is subtracted starting from the element "pos" in
767  * the destination array. "length" is number of data elements to subtract.
768  * By default "length"=0, which means subtract all source data or if the
769  * destination array is shorter, subtract data up to the end of destination.
770  ******************************************************************************/
771 template<class DataType_t> void wavearray<DataType_t>::
772 sub(const wavearray<DataType_t> &a, int length, int a_pos, int pos)
773 {
774 // if (rate() != a.rate())
775 // cout << "wavearray::sub() warning: sample rate mismatch.\n";
776 
777  if ( length == 0 )
778  length = ((size() - pos) < (a.size() - a_pos))?
779  (size() - pos) : (a.size() - a_pos);
780 
781  if( length > (int)(size() - pos) ) length = size() - pos;
782  if( length > (int)(a.size() - a_pos) ) length = a.size() - a_pos;
783 
784  for (int i = 0; i < length; i++)
785  data[i + pos] -= a.data[i + a_pos];
786 }
787 
788 /*****************************************************************
789  * append two wavearrays with the same rate ignoring start time
790  * of input array.
791  *****************************************************************/
792 template<class DataType_t> size_t wavearray<DataType_t>::
794 {
795  size_t n = this->size();
796  size_t m = a.size();
797 
798  if (this->rate() != a.rate())
799  cout << "wavearray::append() warning: sample rate mismatch.\n";
800 
801  if(m == 0 ) return this->size();
802  this->resize(n+m);
803  this->cpf(a,m,0,n);
804  this->stop(start()+(n+m/rate()));
805 
806  return n+m;
807 }
808 
809 /*****************************************************************
810  * append a data point
811  *****************************************************************/
812 template<class DataType_t> size_t wavearray<DataType_t>::
813 append(DataType_t a)
814 {
815  size_t n = this->size();
816  this->resize(n+1);
817  this->data[n] = a;
818  this->Stop += 1./rate();
819  return n+1;
820 }
821 
822 
823 /*****************************************************************
824  * Calculates Fourier Transform for real signal using
825  * Fast Fourier Transform (FFT) algorithm. Packs resulting
826  * complex data into original array of real numbers.
827  * Calls wavefft() function which is capable to deal with any
828  * number of data points. FFT(1) means forward transformation,
829  * which is default, FFT(-1) means inverse transformation.
830  *****************************************************************/
831 template<class DataType_t>
832 void wavearray<DataType_t>::FFT(int direction)
833 {
834  double *a, *b;
835  int N = size();
836  int n2 = N/2;
837 
838  a=new double[N];
839  b=new double[N];
840 
841  switch (direction)
842  { case 1:
843 
844 // direct transform
845 
846  for (int i=0; i<N; i++) { a[i] = data[i]; b[i]=0.;}
847 
848  wavefft(a, b, N, N, N, -1);
849 
850 // pack complex numbers to real array
851  for (int i=0; i<n2; i++)
852  { data[2*i] = (DataType_t)a[i]/N;
853  data[2*i+1] = (DataType_t)b[i]/N;
854  }
855 
856 // data[1] is not occupied because imag(F[0]) is always zero and we
857 // store in data[1] the value of F[N/2] which is pure real for even "N"
858  data[1] = (DataType_t)a[n2]/N;
859 
860 // in the case of odd number of data points we store imag(F[N/2])
861 // in the last element of array data[N]
862  if ((N&1) == 1) data[N-1] = (DataType_t)b[n2]/N;
863 
864  break;
865 
866  case -1:
867 // inverse transform
868 
869 // unpack complex numbers from real array
870  for (int i=1;i<n2;i++)
871  { a[i]=data[2*i];
872  b[i]=data[2*i+1];
873  a[N-i]=data[2*i];
874  b[N-i]=-data[2*i+1];
875  }
876 
877  a[0]=data[0];
878  b[0]=0.;
879 
880  if ((N&1) == 1)
881  { a[n2]=data[1]; b[n2]=data[N-1]; } // for odd n
882  else
883  { a[n2]=data[1]; b[n2]=0.; }
884 
885  wavefft(a, b, N, N, N, 1); // call FFT for inverse tranform
886 
887  for (int i=0; i<N; i++)
888  data[i] = (DataType_t)a[i]; // copy the result from array "a"
889  }
890 
891  delete [] b;
892  delete [] a;
893 }
894 
895 template<class DataType_t>
896 void wavearray<DataType_t>::FFTW(int direction)
897 {
898  double *a, *b;
899  int N = size();
900  int n2 = N/2;
901 
902  a=new double[N];
903  b=new double[N];
904 
905  int sign=0,kind=0; // fftw dummy parameters
906 
907  switch (direction)
908  { case 1:
909 
910  if(fftw==NULL) {
911  fftw = new TFFTRealComplex(1,&N,false);
912  fftw->Init("LS",sign,&kind); // EX - optimized, ES - least optimized
913  }
914 
915 // direct transform
916 
917  for (int i=0; i<N; i++) { a[i] = data[i]; b[i]=0.;}
918 
919  fftw->SetPoints(a);
920  fftw->Transform();
921  fftw->GetPointsComplex(a, b);
922 
923 // pack complex numbers to real array
924  for (int i=0; i<n2; i++)
925  { data[2*i] = (DataType_t)a[i]/N;
926  data[2*i+1] = (DataType_t)b[i]/N;
927  }
928 
929 // data[1] is not occupied because imag(F[0]) is always zero and we
930 // store in data[1] the value of F[N/2] which is pure real for even "N"
931  data[1] = (DataType_t)a[n2]/N;
932 
933 // in the case of odd number of data points we store imag(F[N/2])
934 // in the last element of array data[N]
935  if ((N&1) == 1) data[N-1] = (DataType_t)b[n2]/N;
936 
937  break;
938 
939  case -1:
940 // inverse transform
941 
942  if(ifftw==NULL) {
943  ifftw = new TFFTComplexReal(1,&N,false);
944  ifftw->Init("LS",sign,&kind); // EX - optimized, ES - least optimized
945  }
946 
947 // unpack complex numbers from real array
948  for (int i=1;i<n2;i++)
949  { a[i]=data[2*i];
950  b[i]=data[2*i+1];
951  a[N-i]=data[2*i];
952  b[N-i]=-data[2*i+1];
953  }
954 
955  a[0]=data[0];
956  b[0]=0.;
957 
958  if ((N&1) == 1)
959  { a[n2]=data[1]; b[n2]=data[N-1]; } // for odd n
960  else
961  { a[n2]=data[1]; b[n2]=0.; }
962 
963  ifftw->SetPointsComplex(a,b);
964  ifftw->Transform();
965  ifftw->GetPoints(a);
966 
967  for (int i=0; i<N; i++)
968  data[i] = (DataType_t)a[i]; // copy the result from array "a"
969  }
970 
971  delete [] b;
972  delete [] a;
973 }
974 
975 // Release FFTW memory
976 template<class DataType_t>
978 {
979  if(fftw) {delete fftw;fftw=NULL;}
980  if(ifftw) {delete ifftw;ifftw=NULL;}
981 }
982 
983 /*************************************************************************
984  * Stack generates wavearray *this by stacking data from wavearray td.
985  * Input data are devided on subsets with with samples "length"
986  * then they are added together. Average over the all subsets is saved in
987  * *this.
988  *************************************************************************/
989 template<class DataType_t>
992 {
993  double ss, s0, s2;
994  rate(td.rate());
995  int k = td.size()/length;
996  int n = k*length;
997 
998  if (k == 0) {
999  cout <<" Stack() error: data length too short to contain \n"
1000  << length << " samples\n";
1001  return 0.;
1002  }
1003 
1004  if (size() != (unsigned int)length) resize(length);
1005 
1006 // sum (stack) all k periods of frequency f to produce 1 cycle
1007  s0 = 0.;
1008  for (int i = 0; i < length; i++) {
1009  ss = 0.;
1010  for (int j = i; j < n; j += length) ss += td.data[j];
1011  data[i] = (DataType_t)ss/k;
1012  s0 += ss;
1013  }
1014  s0 /= (k*length);
1015 
1016 // remove constant displacement (zero frequency component)
1017  s2 = 0.;
1018  for (int i = 0; i < length; i++) {
1019  data[i] -= (DataType_t)s0;
1020  s2 += data[i]*data[i];
1021  }
1022  s2 /= length;
1023 
1024  return s2; // return stacked signal power (energy/N)
1025 }
1026 
1027 /*************************************************************************
1028  * Another version of Stack:
1029  * Input data (starting from sample "start") are devided on "k" subsets
1030  * with sections "length"
1031  * Average over the all sections is saved in *this.
1032  *************************************************************************/
1033 template<class DataType_t>
1036 {
1037  double avr, rms;
1038  rate(td.rate());
1039 
1040  if(start+length > (int)td.size()) length = td.size()-start;
1041 
1042  int k = (size()<1) ? 0 : length/size();
1043  if (k == 0) {
1044  cout <<" Stack() error: data length too short to contain \n"
1045  << length << " samples\n";
1046  return 0.;
1047  }
1048 
1049  *this = 0;
1050  for (int i = 0; i<k; i++) add(td, size(), start+i*size());
1051  *this *= DataType_t(1./k);
1052  getStatistics(avr,rms);
1053  *this -= DataType_t(avr);
1054 
1055  return rms*rms; // return stacked signal power
1056 }
1057 
1058 // Stack generates wavearray *this by stacking data from wavearray td.
1059 // Input data are devided on subsets with with samples "length"
1060 // then they are added together. Average over the all subsets is saved in
1061 // *this.
1062 template<class DataType_t>
1064 Stack(const wavearray<DataType_t> &td, double window)
1065 {
1066  return this->Stack(td, int(td.rate() * window));
1067 }
1068 
1069 // wavearray mean
1070 template<class DataType_t>
1072 {
1073  register size_t i;
1074  register double x = 0;
1075 
1076  if(!size()) return 0.;
1077 
1078  for(i=0; i<size(); i++) x += data[i];
1079  return x/size();
1080 }
1081 
1082 template<class DataType_t>
1084 {
1085 // return f percentile mean for data
1086 // param - f>0 positive side pecentile, f<0 - double-side percentile
1087 
1088  if(!size()) return 0;
1089  double ff = fabs(f);
1090  size_t nn = size_t(this->Edge*rate());
1091  if(ff > 1) ff = 1.;
1092  if(!nn || 2*nn>=size()-2) {return mean();}
1093  if(ff==0.) return median(nn,size()-nn-1);
1094 
1095  size_t i;
1096  size_t N = size()-2*nn;
1097  size_t mL = f<0. ? (N-int(N*ff))/2 : 0; // left boundary
1098  size_t mR = f<0. ? (N+int(N*ff))/2-1 : int(N*ff)-1; // right boundary
1099 
1100  double x = 0.;
1101 
1102  wavearray<DataType_t> wtmp = *this;
1103  if(f>0) wtmp *= wtmp;
1104  DataType_t *p = wtmp.data;
1105  DataType_t **pp = (DataType_t **)malloc(N*sizeof(DataType_t*));
1106  for(i=nn; i<N+nn; i++) pp[i-nn] = p + i;
1107 
1108  if(mL>0) waveSplit(pp,0,N-1,mL); // split on left side
1109  if(mR<N-2) waveSplit(pp,0,N-1,mR); // split on right side
1110  for(i=mL; i<=mR; i++) x += this->data[pp[i]-p];
1111 
1112  free(pp);
1113  return x/(mR-mL+1.);
1114 }
1115 
1116 template<class DataType_t>
1118 {
1119  register size_t i;
1120  register double x = 0.;
1121  register DataType_t *p = data + s.start();
1122  size_t N = s.size();
1123  size_t m = (s.stride()<=0) ? 1 : s.stride();
1124  if(size()<limit(s)) N = (limit(s) - s.start() - 1)/m;
1125  for(i=0; i<N; i++) { x += *p; p += m; }
1126  return (N==0) ? 0. : x/N;
1127 }
1128 
1129 // running mean
1130 template<class DataType_t>
1133  bool clean,
1134  size_t skip)
1135 {
1136 // calculate running mean of data (x) with window of t seconds
1137 // put result in input array *pm if specified
1138 // subtract median from x if clean=true otherwise replace x with median
1139 // move running window by skip samples
1140 
1141  DataType_t* p=NULL;
1142  DataType_t* q=NULL;
1143  DataType_t* xx;
1144  double sum = 0.;
1145 
1146  size_t i,last;
1147  size_t step = Slice.stride();
1148  size_t N = Slice.size(); // number of samples in wavearray
1149  size_t n = size_t(t*rate()/step); // # of samples in the window
1150 
1151  if(n<4) {
1152  cout<<"wavearray<DataType_t>::mean() short time window"<<endl;
1153  return;
1154  }
1155 
1156  if(n&1) n--; // # of samples in the window - 1
1157 
1158  size_t nM = n/2; // index of median sample
1159  size_t nL = N-nM-1;
1160 
1161  if(pm){
1162  pm->resize(N/skip);
1163  pm->start(start());
1164  pm->rate(rate());
1165  }
1166 
1167  xx = (DataType_t *)malloc((n+1)*sizeof(DataType_t));
1168 
1169  p = data+Slice.start();
1170  q = data+Slice.start();
1171  for(i=0; i<=n; i++) {
1172  xx[i] = *p;
1173  sum += xx[i];
1174  p += step;
1175  }
1176  last = 0;
1177 
1178  for(i=0; i<N; i++){
1179 
1180  if(pm) {
1181  pm->data[i/skip] = DataType_t(sum/(n+1.));
1182  if(clean) q[i*step] -= DataType_t(sum/(n+1.));
1183  }
1184  else {
1185  if(clean) q[i*step] -= DataType_t(sum/(n+1.));
1186  else q[i*step] = DataType_t(sum/(n+1.));
1187  }
1188 
1189  if(i>=nM && i<nL) { // copy next sample into last
1190  sum -= xx[last];
1191  sum += *p;
1192  xx[last++] = *p;
1193  p += step;
1194  }
1195 
1196  if(last>n) last = 0;
1197 
1198  }
1199 
1200  free(xx);
1201  return;
1202 }
1203 
1204 
1205 template<class DataType_t>
1207 {
1208  register size_t i;
1209  register double x = 0.;
1210  register double y = 0.;
1211  size_t N = (size()>>2)<<2;
1212  register DataType_t *p = data + size() - N;
1213 
1214  if(!size()) return 0.;
1215 
1216  for(i=0; i<size()-N; i++) { x += data[i]; y += data[i]*data[i]; }
1217  for(i=0; i<N; i+=4){
1218  x += p[i] + p[i+1] + p[i+2] + p[i+3];
1219  y += p[i]*p[i] + p[i+1]*p[i+1] + p[i+2]*p[i+2] + p[i+3]*p[i+3];
1220  }
1221  x /= size();
1222  return sqrt(y/size()-x*x);
1223 }
1224 
1225 // running 50% percentile rms
1226 template<class DataType_t>
1229  bool clean,
1230  size_t skip)
1231 {
1232 
1233  DataType_t* p=NULL;
1234  DataType_t* q=NULL;
1235  DataType_t** pp;
1236  DataType_t* xx;
1237  DataType_t rm = 1;
1238 
1239  size_t i,last;
1240  size_t step = Slice.stride();
1241  size_t N = Slice.size(); // number of samples in wavearray
1242  size_t n = size_t(t*rate()/step);
1243 
1244  if(n<4) {
1245  cout<<"wavearray<DataType_t>::median() short time window"<<endl;
1246  return;
1247  }
1248 
1249  if(n&1) n--; // # of samples - 1
1250 
1251  size_t nM = n/2; // index of median sample
1252  size_t nL = N-nM-1;
1253 
1254  if(pm){
1255  pm->resize(N/skip);
1256  pm->start(start());
1257  pm->rate(rate());
1258  }
1259 
1260  pp = (DataType_t **)malloc((n+1)*sizeof(DataType_t*));
1261  xx = (DataType_t *)malloc((n+1)*sizeof(DataType_t));
1262 
1263  p = data+Slice.start();
1264  q = data+Slice.start();
1265  for(i=0; i<=n; i++) {
1266  xx[i] = *p>0 ? *p : -(*p);
1267  pp[i] = xx+i;
1268  p += step;
1269  }
1270  last = 0;
1271 
1272  for(i=0; i<N; i++){
1273 
1274  if(i==(i/skip)*skip) {
1275  waveSplit(pp,0,n,nM); // median split
1276  rm=*pp[nM];
1277  }
1278 
1279  if(pm) {
1280  pm->data[i/skip] = DataType_t(rm/0.6745);
1281  if(clean) q[i*step] *= DataType_t(0.6745/rm);
1282  }
1283  else {
1284  if(clean) q[i*step] *= DataType_t(0.6745/rm);
1285  else q[i*step] = DataType_t(rm/0.6745);
1286  }
1287 
1288  if(i>=nM && i<nL) { // copy next sample into last
1289  xx[last++] = *p>0 ? *p : -(*p);
1290  p += step;
1291  }
1292 
1293  if(last>n) last = 0;
1294 
1295  }
1296 
1297 
1298  free(pp);
1299  free(xx);
1300  return;
1301 }
1302 
1303 
1304 template<class DataType_t>
1306 {
1307  register size_t i;
1308  register double a = 0.;
1309  register double x = 0.;
1310  register double y = 0.;
1311  register DataType_t *p = data + s.start();
1312  size_t n = s.size();
1313  size_t m = (s.stride()<=0) ? 1 : s.stride();
1314 
1315  if(size()<limit(s)) n = (limit(s) - s.start() - 1)/m;
1316  if(!n) return 0.;
1317  size_t N = (n>>2)<<2;
1318 
1319  for(i=0; i<n-N; i++) {
1320  a = *p; x += a; y += a*a; p += m;
1321  }
1322 
1323  for(i=0; i<N; i+=4) {
1324  a = *p; x += a; y += a*a; p += m;
1325  a = *p; x += a; y += a*a; p += m;
1326  a = *p; x += a; y += a*a; p += m;
1327  a = *p; x += a; y += a*a; p += m;
1328  }
1329  x /= N;
1330  return sqrt(y/N-x*x);
1331 }
1332 
1333 template<class DataType_t>
1334 DataType_t wavearray<DataType_t>::max() const
1335 {
1336  if(!size()) return 0;
1337  register unsigned int i;
1338  register DataType_t x = data[0];
1339  for(i=1; i<size(); i++) { if(x<data[i]) x=data[i]; }
1340  return x;
1341 }
1342 
1343 template<class DataType_t>
1345 {
1346  if(!size() ||
1347  Slice.size()!=x.Slice.size() ||
1348  Slice.start()!=x.Slice.start() ||
1349  Slice.stride()!=x.Slice.stride()) {
1350  cout<<"wavearray::max(): illegal imput array\n";
1351  return;
1352  }
1353 
1354  size_t n;
1355  size_t K = Slice.stride();
1356  size_t I = Slice.start();
1357  size_t N = Slice.size();
1358 
1359  DataType_t* pin = x.data+I;
1360  DataType_t* pou = this->data+I;
1361  for(n=0; n<N; n+=K) {
1362  if(pou[n]<pin[n]) pou[n]=pin[n];
1363  }
1364  return;
1365 }
1366 
1367 template<class DataType_t>
1368 DataType_t wavearray<DataType_t>::min() const
1369 {
1370  if(!size()) return 0;
1371  register size_t i;
1372  register DataType_t x = data[0];
1373  for(i=1; i<size(); i++) { if(x>data[i]) x=data[i]; }
1374  return x;
1375 }
1376 
1377 
1378 template<class DataType_t>
1379 int wavearray<DataType_t>::getSampleRank(size_t n, size_t l, size_t r) const
1380 {
1381  DataType_t v;
1382  register int i = l-1; // save left boundary
1383  register int j = r; // save right boundary
1384 
1385  v = data[n]; // pivot
1386  data[n]=data[r]; data[r]=v; // store pivot
1387 
1388  while(i<j)
1389  {
1390  while(data[++i]<v && i<j);
1391  while(data[--j]>v && i<j);
1392  }
1393  data[r]=data[n]; data[n]=v; // put pivot back
1394 
1395  return i-int(l)+1; // rank ranges from 1 to r-l+1
1396 }
1397 
1398 template<class DataType_t>
1399 int wavearray<DataType_t>::getSampleRankE(size_t n, size_t l, size_t r) const
1400 {
1401  DataType_t v,vv;
1402  register int i = l-1; // save left boundary
1403  register int j = r; // save right boundary
1404 
1405  v = data[n]; // pivot
1406  data[n]=data[r]; data[r]=v; // store pivot
1407  vv = v>0 ? v : -v; // sort absolute value
1408 
1409  while(i<j)
1410  {
1411  while((data[++i]>0 ? data[i] : -data[i])<vv && i<j);
1412  while((data[--j]>0 ? data[j] : -data[j])>vv && i<j);
1413  }
1414  data[r]=data[n]; data[n]=v; // put pivot back
1415 
1416  return i-int(l)+1; // rank ranges from 1 to r-l+1
1417 }
1418 
1419 
1420 template<class DataType_t>
1421 void wavearray<DataType_t>::waveSort(DataType_t** pin, size_t l, size_t r) const
1422 {
1423 // sort data array using quick sorting algorithm between left (l) and right (r) index
1424 // DataType_t** pin is pointer to array of data pointers
1425 // sorted from min to max: *pin[l]/*pin[r] points to min/max
1426 
1427  size_t k;
1428 
1429  register DataType_t v;
1430  register DataType_t* p;
1431  register DataType_t** pp = pin;
1432 
1433  if(pp==NULL || !this->size()) return;
1434  if(!r) r = this->size()-1;
1435  if(l>=r) return;
1436 
1437  register size_t i = (r+l)/2; // median
1438  register size_t j = r-1; // pivot storage index
1439 
1440 // sort l,i,r
1441  if(*pp[l] > *pp[i]) {p=pp[l]; pp[l]=pp[i]; pp[i]=p;}
1442  if(*pp[l] > *pp[r]) {p=pp[l]; pp[l]=pp[r]; pp[r]=p;}
1443  if(*pp[i] > *pp[r]) {p=pp[i]; pp[i]=pp[r]; pp[r]=p;}
1444  if(r-l < 3) return; // all sorted
1445 
1446  v = *pp[i]; // pivot
1447  p=pp[i]; pp[i]=pp[j]; pp[j]=p; // store pivot
1448  i = l;
1449 
1450  for(;;)
1451  {
1452  while(*pp[++i] < v);
1453  while(*pp[--j] > v);
1454  if(j<i) break;
1455  p=pp[i]; pp[i]=pp[j]; pp[j]=p; // swap i,j
1456  }
1457 
1458  p=pp[i]; pp[i++]=pp[r-1]; pp[r-1]=p; // return pivot back
1459 
1460  if(j-l > 2) waveSort(pp,l,j);
1461  else if(j>l){ // sort l,k,j
1462  k = l+1;
1463  if(*pp[l] > *pp[k]) {p=pp[l]; pp[l]=pp[k]; pp[k]=p;}
1464  if(*pp[l] > *pp[j]) {p=pp[l]; pp[l]=pp[j]; pp[j]=p;}
1465  if(*pp[k] > *pp[j]) {p=pp[k]; pp[k]=pp[j]; pp[j]=p;}
1466  }
1467 
1468  if(r-i > 2) waveSort(pp,i,r);
1469  else if(r>i){ // sort i,k,r
1470  k = i+1;
1471  if(*pp[i] > *pp[k]) {p=pp[i]; pp[i]=pp[k]; pp[k]=p;}
1472  if(*pp[i] > *pp[r]) {p=pp[i]; pp[i]=pp[r]; pp[r]=p;}
1473  if(*pp[k] > *pp[r]) {p=pp[k]; pp[k]=pp[r]; pp[r]=p;}
1474  }
1475 
1476  return;
1477 }
1478 
1479 template<class DataType_t>
1481 {
1482 // sort wavearray using quick sorting algorithm between left (l) and right (r) index
1483 // sorted from min to max: this->data[l]/this->data[r] is min/max
1484  size_t N = this->size();
1485  DataType_t *pd = (DataType_t *)malloc(N*sizeof(DataType_t));
1486  DataType_t **pp = (DataType_t **)malloc(N*sizeof(DataType_t*));
1487  for(size_t i=0; i<N; i++) {
1488  pd[i] = this->data[i];
1489  pp[i] = pd + i;
1490  }
1491  waveSort(pp,l,r);
1492  for(size_t i=0; i<N; i++) this->data[i] = *pp[i];
1493 
1494  free(pd);
1495  free(pp);
1496 }
1497 
1498 template<class DataType_t>
1499 void wavearray<DataType_t>::waveSplit(DataType_t** pp, size_t l, size_t r, size_t m) const
1500 {
1501 // split input array of pointers pp[i] between l <= i <= r so that:
1502 // *pp[i] < *pp[m] if i < m
1503 // *pp[i] > *pp[m] if i > m
1504  DataType_t v;
1505  DataType_t* p;
1506  size_t i = (r+l)/2;
1507  size_t j = r-1;
1508 
1509 // sort l,i,r
1510  if(*pp[l] > *pp[i]) {p=pp[l]; pp[l]=pp[i]; pp[i]=p;}
1511  if(*pp[l] > *pp[r]) {p=pp[l]; pp[l]=pp[r]; pp[r]=p;}
1512  if(*pp[i] > *pp[r]) {p=pp[i]; pp[i]=pp[r]; pp[r]=p;}
1513  if(r-l < 3) return; // all sorted
1514 
1515  v = *pp[i]; // pivot
1516  p=pp[i]; pp[i]=pp[j]; pp[j]=p; // store pivot
1517  i = l;
1518 
1519  for(;;)
1520  {
1521  while(*pp[++i] < v);
1522  while(*pp[--j] > v);
1523  if(j<i) break;
1524  p=pp[i]; pp[i]=pp[j]; pp[j]=p; // swap i,j
1525  }
1526  p=pp[i]; pp[i]=pp[r-1]; pp[r-1]=p; // put pivot
1527 
1528  if(i > m) waveSplit(pp,l,i,m);
1529  else if(i < m) waveSplit(pp,i,r,m);
1530 
1531  return;
1532 }
1533 
1534 template<class DataType_t>
1535 DataType_t wavearray<DataType_t>::waveSplit(size_t l, size_t r, size_t m)
1536 {
1537 // split wavearray between l and r & at index m so that:
1538 // *this->data[i] < *this->datap[m] if i < m
1539 // *this->data[i] > *this->datap[m] if i > m
1540  size_t N = this->size();
1541  DataType_t *pd = (DataType_t *)malloc(N*sizeof(DataType_t));
1542  DataType_t **pp = (DataType_t **)malloc(N*sizeof(DataType_t*));
1543  for(size_t i=0; i<N; i++) {
1544  pd[i] = this->data[i];
1545  pp[i] = pd + i;
1546  }
1547  waveSplit(pp,l,r,m);
1548  for(size_t i=0; i<N; i++) this->data[i] = *pp[i];
1549 
1550  free(pd);
1551  free(pp);
1552  return this->data[m];
1553 }
1554 
1555 template<class DataType_t>
1557 {
1558 // split wavearray at index m so that:
1559 // *this->data[i] < *this->datap[m] if i < m
1560 // *this->data[i] > *this->datap[m] if i > m
1561  size_t N = this->size();
1562  DataType_t *pd = (DataType_t *)malloc(N*sizeof(DataType_t));
1563  DataType_t **pp = (DataType_t **)malloc(N*sizeof(DataType_t*));
1564  for(size_t i=0; i<N; i++) {
1565  pd[i] = this->data[i];
1566  pp[i] = pd + i;
1567  }
1568  waveSplit(pp,0,N-1,m);
1569  for(size_t i=0; i<N; i++) this->data[i] = *pp[i];
1570 
1571  free(pd);
1572  free(pp);
1573 }
1574 
1575 template<class DataType_t>
1576 double wavearray<DataType_t>::median(size_t l, size_t r) const
1577 {
1578  if(!r) r = size()-1;
1579  if(r<=l) return 0.;
1580 
1581  size_t i;
1582  size_t N = r-l+1;
1583  size_t m = N/2+(N&1); // median
1584 
1585  double x = 0.;
1586 
1587  DataType_t **pp = (DataType_t **)malloc(N*sizeof(DataType_t*));
1588  for(i=l; i<=r; i++) pp[i-l] = data + i;
1589 
1590  waveSplit(pp,0,N-1,m);
1591  x = *pp[m];
1592 
1593  free(pp);
1594  return x;
1595 }
1596 
1597 
1598 template<class DataType_t>
1601  bool clean,
1602  size_t skip)
1603 {
1604 // calculate running mean of data (x) with window of t seconds
1605 // put result in input array pm if specified
1606 // subtract median from x if clean=true otherwise replace x with median
1607 // move running window by skip samples
1608 
1609  DataType_t* p=NULL;
1610  DataType_t* q=NULL;
1611  DataType_t** pp;
1612  DataType_t* xx;
1613  DataType_t am=0;
1614 
1615  size_t i,last;
1616  size_t step = Slice.stride();
1617  size_t N = Slice.size(); // number of samples in wavearray
1618  size_t n = size_t(t*rate()/step); // # of samples in running window
1619 
1620  if(n<4) {
1621  cout<<"wavearray<DataType_t>::median() short time window"<<endl;
1622  return;
1623  }
1624 
1625  if(n&1) n--; // # of samples - 1
1626 
1627  size_t nM = n/2; // index of median sample
1628  size_t nL = N-nM-1;
1629 
1630  if(pm){
1631  pm->resize(N/skip);
1632  pm->start(start());
1633  pm->rate(rate()/skip);
1634  }
1635 
1636  pp = (DataType_t **)malloc((n+1)*sizeof(DataType_t*));
1637  xx = (DataType_t *)malloc((n+1)*sizeof(DataType_t));
1638 
1639  p = data+Slice.start();
1640  q = data+Slice.start();
1641  for(i=0; i<=n; i++) {
1642  xx[i] = *p;
1643  pp[i] = xx+i;
1644  p += step;
1645  }
1646  last = 0;
1647 
1648  for(i=0; i<N; i++){
1649 
1650  if(i==(i/skip)*skip) {
1651  waveSplit(pp,0,n,nM); // median split
1652  am=*pp[nM];
1653  }
1654 
1655  if(pm) {
1656  pm->data[i/skip] = am;
1657  if(clean) q[i*step] -= am;
1658  }
1659  else {
1660  if(clean) q[i*step] -= am;
1661  else q[i*step] = am;
1662  }
1663 
1664  if(i>=nM && i<nL) { // copy next sample into last
1665  xx[last++] = *p;
1666  p += step;
1667  }
1668 
1669  if(last>n) last = 0;
1670 
1671  }
1672 
1673  free(pp);
1674  free(xx);
1675  return;
1676 }
1677 
1678 
1679 template<class DataType_t>
1681 {
1682 
1683  DataType_t* p=NULL;
1684  DataType_t* q=NULL;
1685 
1686  size_t i;
1687  double r;
1688  size_t last,next;
1689  size_t N = Slice.size(); // number of samples in wavearray
1690  size_t step = Slice.stride();
1691  size_t n = size_t(t*rate()/step);
1692 
1693  if(n<4) {
1694  cout<<"wavearray<DataType_t>::median() short time window"<<endl;
1695  return;
1696  }
1697 
1698  if(n&1) n--; // # of samples in running window
1699 
1700  size_t nM = n/2; // index of median sample
1701  size_t nL = N-nM-1;
1702 
1703  DataType_t** pp = (DataType_t **)malloc((n+1)*sizeof(DataType_t*));
1705 
1706  p = data+Slice.start();
1707  q = data+Slice.start();
1708  for(i=0; i<=n; i++) {
1709  xx.data[i] = *p;
1710  pp[i] = xx.data+i;
1711  p += step;
1712  }
1713  last = 0;
1714  next = 0;
1715 
1716  for(i=0; i<N; i++){
1717 
1718  r = (xx.getSampleRank(next,0,n)-double(nM)-1.)/(nM+1.);
1719  q[i*step] = DataType_t(r>0. ? -log(1.-r) : log(1.+r));
1720 
1721  if(i>=nM && i<nL) { // copy next sample into last
1722  xx.data[last++] = *p; p+=step;
1723  }
1724 
1725  next++;
1726  if(next>n) next = 0;
1727  if(last>n) last = 0;
1728 
1729  }
1730 
1731  free(pp);
1732  return;
1733 }
1734 
1735 
1736 template<class DataType_t>
1737 DataType_t wavearray<DataType_t>::rank(double f) const
1738 {
1739  int i;
1740  int n = size();
1741  DataType_t out = 0;
1742  DataType_t **pp = NULL;
1743  if(f<0.) f = 0.;
1744  if(f>1.) f = 1.;
1745 
1746  if(n)
1747  pp = (DataType_t **)malloc(n*sizeof(DataType_t*));
1748  else
1749  return out;
1750 
1751  for(i=0; i<n; i++) pp[i] = data + i;
1752  qsort(pp, n, sizeof(DataType_t *),
1754 
1755  i =int((1.-f)*n);
1756  if(i==0) out = *(pp[0]);
1757  else if(i>=n-1) out = *(pp[n-1]);
1758  else out = (*(pp[i])+*(pp[i+1]))/2;
1759 
1760  for(i=0; i<n; i++) *(pp[i]) = n-i;
1761 
1762  free(pp);
1763  return out;
1764 }
1765 
1766 
1767 // symmetric prediction error signal produced with
1768 // adaptive split lattice algoritm
1769 template<class DataType_t>
1770 void wavearray<DataType_t>::spesla(double T, double w, double oFFset)
1771 {
1772  int k,j;
1773  double p,q,xp,xm;
1774 
1775  int K = int(rate()*T+0.5); // filter duration
1776  int M = int(rate()*w+0.5); // integration window
1777  if(M&1) M++; // make M even
1778  int m = M/2;
1779 
1780  int offset = int(oFFset*rate()); // data offset
1781  int N = size(); // data size
1782  int nf = offset+m;
1783  int nl = N-nf;
1784 
1787 
1788  x0 = *this; // previous X iteration
1789  x1 = *this;
1790  x1.add(x0,x0.size()-1,0,1); // current X iteration
1791  x1 *= DataType_t(0.5);
1792 
1793 // cout<<nf<<" "<<nl<<" "<<offset<<" "<<K<<" "<<M<<" "<<x0.rms()<<" "<<x1.rms();
1794 
1795  for(k=1; k<K; k++) {
1796 
1797  p = q = 0.;
1798  for(j=offset; j<offset+M; j++) {
1799  p += x1.data[j]*x1.data[j];
1800  q += x0.data[j]*x0.data[j];
1801  }
1802 
1803  for(j=1; j<N; j++) {
1804  if(j>=nf && j<nl) { // update p & q
1805  xp = x1.data[j+m];
1806  xm = x1.data[j-m];
1807  p += (xp-xm)*(xp+xm);
1808  xp = x0.data[j+m];
1809  xm = x0.data[j-m];
1810  q += (xp-xm)*(xp+xm);
1811  }
1812  xp = k==1 ? 2*p/q : p/q;
1813  data[j] = x1.data[j]+x1.data[j-1]-DataType_t(x0.data[j-1]*xp);
1814  }
1815 
1816  x0 = x1;
1817  x1 = *this;
1818 
1819  }
1820  return;
1821 }
1822 
1823 
1824 // apply filter
1825 template<class DataType_t>
1827 {
1828  int i,j;
1829  int N = size();
1830  int m = w.size();
1832  x = *this;
1833 
1834  for(i=0; i<N; i++) {
1835  for(j=1; j<m && (i-j)>=0; j++) {
1836  data[i] += DataType_t(w.data[j]*x.data[i-j]);
1837  }
1838  }
1839  return;
1840 }
1841 
1842 
1843 
1844 // calculate and apply lpr filter
1845 template<class DataType_t>
1846 void wavearray<DataType_t>::lprFilter(double T, int mode, double stride,
1847  double oFFset, int tail)
1848 {
1849  int i,j,l,n,nf,nl;
1850  double duration = stop()-start()-2*oFFset;
1851  double a=0.;
1852  double b=1.;
1853 
1854  int N = size();
1855  int M = int(rate()*T+0.5); // filter duration
1856  int k = stride>0 ? int(duration/stride) : 1; // number of intervals
1857 
1858  if(!k) k++;
1859  int m = int((N-2.*oFFset*rate())/k);
1860  if(m&1) m--; // make m even
1861 
1862  int offset = int(oFFset*rate()+0.5); // data offset
1863  if(offset&1) offset++;
1864 
1866  wavearray<DataType_t> x = *this;
1868  w.rate(rate());
1869 
1870  for(l=0; l<k; l++) {
1871 
1872  n = l*m+(N-k*m)/2;
1873  w.cpf(x,m,n);
1874  f = w.getLPRFilter(M,0,tail);
1875 
1876  nf = l==0 ? 0 : n;
1877  nl = l==k-1 ? N : n+m;
1878  n = offset+M;
1879 
1880  if(mode == 0 || mode == 1) { // forward LP
1881  for(i=nf; i<nl; i++) {
1882  if(i < n) continue;
1883  b = (!mode && i<N-n) ? 0.5 : 1.; // symmetric LP
1884  for(j=1; j<M; j++) {
1885  a = double(f.data[j]*x.data[i-j]);
1886  data[i] += DataType_t(a*b);
1887  }
1888  }
1889  }
1890 
1891  if(mode == 0 || mode == -1) { // backward LP
1892  for(i=nf; i<nl; i++) {
1893  if(i >= N-n) continue;
1894  b = (!mode && i>=n) ? 0.5 : 1.; // symmetric LP
1895  for(j=1; j<M; j++) {
1896  a = double(f.data[j]*x.data[i+j]);
1897  data[i] += DataType_t(a*b);
1898  }
1899  }
1900  }
1901 
1902  }
1903 
1904  return;
1905 }
1906 
1907 //**************************************************************
1908 // calculate autocorrelation function and
1909 // solve symmetric Yule-Walker problem
1910 //**************************************************************
1911 template<class DataType_t>
1913 {
1914  // tail=-1 exclude left tail
1915  // tail= 0 exclude left and right tail
1916  // tail= 1 exclude right tail
1917  int i,m;
1918  double f = tail!=0 ? 0.06 : 0.03; // exclude tail
1919  int N = size()-2*offset;
1920  int LL = int(f*N+0.5); // excluded tail
1921  int nL = tail<1 ? LL : 1; // left percentile
1922  int nR = tail>-1 ? N-LL-1 : 1; // right percentile
1923  int nn = N/2; // median
1924  int n = size()-offset;
1925 
1926  if(size()<=offset) {
1927  cout<<"wavearray<DataType_t>::getLPRFilter() invalid input parameters\n";
1928  wavearray<double> a(1);
1929  return a;
1930  }
1931 
1932  wavearray<double> r(M);
1933  wavearray<double> a(M);
1934  wavearray<double> b(M);
1935 
1936  wavearray<DataType_t> x = *this;
1937 
1938  DataType_t ** pp = (DataType_t **)malloc(N*sizeof(DataType_t*));
1939 
1940  for(i=offset; i<n; i++) pp[i-offset] = x.data + i;
1941 
1942  waveSplit(pp,0,N-1,nn);
1943  waveSplit(pp,0,nn,nL);
1944  waveSplit(pp,nn,N-1,nR);
1945 
1946  x -= *pp[nn]; // subtract median
1947  for(i=0; i<nL; i++) *pp[i] = 0; // exclude tails
1948  for(i=nR; i<N; i++) *pp[i] = 0; // exclude tails
1949 
1950 // autocorrelation
1951 
1952  offset += M;
1953  n = size()-offset;
1954 
1955  for (m=0; m<M; m++) {
1956  r.data[m] = 0.;
1957  for (i=offset; i<n; i++) {
1958  r.data[m] += x.data[i]*(x.data[i-m] + x.data[i+m])/2.;
1959  }
1960  }
1961 
1962 
1963 // Levinson algorithm: P.Delsarte & Y.Genin, IEEE, ASSP-35, #5 May 1987
1964 
1965  double p,q;
1966  double s = r.data[0];
1967 
1968  a = 0.; a.data[0] = 1.;
1969 
1970  for (m=1; m<M; m++) {
1971 
1972  q = 0.;
1973  for (i=0; i<m; i++) q -= a.data[i] * r.data[m-i];
1974 
1975  p = q/s; // reflection coefficient
1976  s -= q*p;
1977 
1978  for (i=1; i<=m; i++) b.data[i] = a.data[i] + p*a.data[m-i];
1979  for (i=1; i<=m; i++) a.data[i] = b.data[i];
1980 
1981  }
1982 
1983 /*
1984  double tmp, num, den;
1985  M--;
1986 
1987  a.data[1] = - r.data[1] / r.data[0];
1988 
1989  for (m=1; m<M; m++) {
1990 
1991  num = r.data[m + 1];
1992  den = r.data[0];
1993 
1994  for (i=1; i<=m; i++) {
1995  num += a.data[i] * r.data[m+1-i];
1996  den += a.data[i] * r.data[i];
1997  }
1998 
1999  a.data[m+1] = - num / den;
2000 
2001  for (i=1; i <= ((m+1)>>1); i++) {
2002  tmp = a.data[i] + a.data[m+1] * a.data[m+1-i];
2003  a.data[m+1-i] = a.data[m+1-i] + a.data[m+1] * a.data[i];
2004  a.data[i] = tmp;
2005  }
2006 
2007  }
2008  a.data[0] = 1;
2009 */
2010 
2011  free(pp);
2012  return a;
2013 }
2014 
2015 
2016 //**************************************************************
2017 // normalize data by noise variance
2018 // offset | stride |
2019 // |*****|*X********X********X********X********X********X*|*****|
2020 // ^ ^ ^
2021 // measurement |<- interval ->|
2022 //**************************************************************
2023 template<class DataType_t>
2025 wavearray<DataType_t>::white(double t, int mode, double oFFset, double stride) const
2026 {
2027  int i,j;
2028  int N = size();
2029 
2030  double segT = size()/rate(); // segment duration
2031  if(t<=0.) t = segT-2.*oFFset;
2032  int offset = int(oFFset*rate()+0.5); // offset in samples
2033  if(offset&1) offset--; // make offset even
2034 
2035  if(stride > t || stride<=0.) stride = t;
2036  int K = int((segT-2.*oFFset)/stride); // number of noise measurement minus 1
2037  if(!K) K++; // special case
2038 
2039  int n = N-2*offset; // total number of samples used for noise estimate
2040  int k = n/K; // shift in samples
2041  if(k&1) k--; // make k even
2042 
2043  int m = int(t*rate()+0.5); // number of samples in one interval
2044  int mm = m/2; // median m
2045  int mL = int(0.15865*m+0.5); // -sigma index (CL=0.31732)
2046  int mR = m-mL-1; // +sigma index
2047  int jL = (N-k*K)/2; // array index for first measurement
2048  int jR = N-offset-m; // array index for last measurement
2049  int jj = jL-mm; // start of the first interval
2050 
2051  wavearray<double> meDIan(K+1);
2052  wavearray<double> norm50(K+1);
2053 
2054  meDIan.rate(rate()/k);
2055  meDIan.start(start()+jL/rate());
2056  meDIan.stop(start()+(N-offset)/rate());
2057 
2058  norm50.rate(rate()/k);
2059  norm50.start(start()+jL/rate());
2060  norm50.stop(start()+(N-offset)/rate());
2061 
2062  mode = abs(mode);
2063 
2064  if(m<3 || mL<2 || mR>m-2) {
2065  cout<<"wavearray::white(): too short input array."<<endl;
2066  return mode!=0 ? norm50 : meDIan;
2067  }
2068 
2069  register DataType_t *p = data;
2071  double x;
2072  double r;
2073 
2074  DataType_t ** pp = (DataType_t **)malloc(m*sizeof(DataType_t*));
2075 
2076  for(j=0; j<=K; j++) {
2077 
2078  if(jj < offset) p = data + offset; // left boundary
2079  else if(jj >= jR) p = data + jR; // right boundary
2080  else p = data + jj;
2081  jj += k; // update jj
2082 
2083  if(p+m>data+N) {cout<<"wavearray::white(): error1\n"; exit(1);}
2084 
2085  for(i=0; i<m; i++) pp[i] = p + i;
2086  waveSplit(pp,0,m-1,mm);
2087  waveSplit(pp,0,mm,mL);
2088  waveSplit(pp,mm,m-1,mR);
2089  meDIan[j] = mode ? *pp[mm] : sqrt((*pp[mm])*0.7191);
2090  norm50[j] = (*pp[mR] - *pp[mL])/2.;
2091 
2092  }
2093 
2094  p = data;
2095 
2096  if(mode) {
2097 
2098  mm = jL;
2099  for(i=0; i<mm; i++){
2100  x = double(*p)-meDIan.data[0];
2101  r = norm50.data[0];
2102  *(p++) = mode==1 ? DataType_t(x/r) : DataType_t(x/r/r);
2103  }
2104 
2105  for(j=0; j<K; j++) {
2106  for(i=0; i<k; i++) {
2107  x = double(*p)-(meDIan.data[j+1]*i + meDIan.data[j]*(k-i))/k;
2108  r = (norm50.data[j+1]*i + norm50.data[j]*(k-i))/k;
2109  *(p++) = mode==1 ? DataType_t(x/r) : DataType_t(x/r/r);
2110  }
2111  }
2112 
2113  mm = (data+N)-p;
2114  for(i=0; i<mm; i++){
2115  x = double(*p)-meDIan.data[K];
2116  r = norm50.data[K];
2117  *(p++) = mode==1 ? DataType_t(x/r) : DataType_t(x/r/r);
2118  }
2119 
2120  }
2121 
2122  free(pp);
2123  return mode!=0 ? norm50 : meDIan;
2124 }
2125 
2126 //: returns mean and root mean square of the signal.
2127 template<class DataType_t>
2128 double wavearray<DataType_t>::getStatistics(double &m, double &r) const
2129 {
2130  register size_t i;
2131  register double a;
2132  register double b;
2133  DataType_t *p = const_cast<DataType_t *>(data);
2134  double y = 0.;
2135  size_t N = size() - 1 + size_t(size()&1);
2136 
2137  if(!size()) return 0.;
2138 
2139  m = p[0];
2140  r = p[0]*p[0];
2141  if(N < size()){
2142  m += p[N];
2143  r += p[N]*p[N];
2144  y += p[N]*p[N-1];
2145  }
2146 
2147  for(i=1; i<N; i+=2) {
2148  a = p[i]; b = p[i+1];
2149  m += a + b;
2150  r += a*a + b*b;
2151  y += a*(p[i-1]+b);
2152  }
2153 
2154  N = size();
2155  m = m/double(N);
2156  r = r/double(N) - m*m;
2157 
2158  y = 4.*(y/N - m*m + m*(p[0]+p[i]-m)/N);
2159  y /= 4.*r - 2.*((p[0]-m)*(p[0]-m)+(p[i]-m)*(p[i]-m))/N;
2160  r = sqrt(r);
2161 
2162  a = (fabs(y) < 1) ? sqrt(0.5*(1.-fabs(y))) : 0.;
2163 
2164  return y>0 ? -a : a;
2165 }
2166 
2167 template <class DataType_t>
2168 void wavearray<DataType_t>::Streamer(TBuffer &R__b)
2169 {
2170  // Stream an object of class wavearray<DataType_t>.
2171  UInt_t R__s, R__c;
2172  if (R__b.IsReading()) {
2173  Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
2174  TNamed::Streamer(R__b);
2175  R__b >> Size;
2176  R__b >> Rate;
2177  R__b >> Start;
2178  R__b >> Stop;
2179  if(R__v>1) R__b >> Edge;
2180  R__b.StreamObject(&(Slice),typeid(slice));
2181  this->resize(Size);
2182  R__b.ReadFastArray((char*)data,Size*sizeof(DataType_t));
2183  R__b.CheckByteCount(R__s, R__c, wavearray<DataType_t>::IsA());
2184  } else {
2185  R__c = R__b.WriteVersion(wavearray<DataType_t>::IsA(), kTRUE);
2186  TNamed::Streamer(R__b);
2187  R__b << Size;
2188  R__b << Rate;
2189  R__b << Start;
2190  R__b << Stop;
2191  R__b << Edge;
2192  R__b.StreamObject(&(Slice),typeid(slice));
2193  R__b.WriteFastArray((char*)data,Size*sizeof(DataType_t));
2194  R__b.SetByteCount(R__c, kTRUE);
2195  }
2196 }
2197 
2198 //: save to file operator >>
2199 template <class DataType_t>
2201 {
2202  TString name = fname;
2203  name.ReplaceAll(" ","");
2204  TObjArray* token = TString(fname).Tokenize(TString("."));
2205  TObjString* ext_tok = (TObjString*)token->At(token->GetEntries()-1);
2206  TString ext = ext_tok->GetString();
2207  if(ext=="dat") {
2208  //: Dump data array to a binary file
2209  DumpBinary(fname,0);
2210  } else
2211  if(ext=="txt") {
2212  //: Dump data array to an ASCII file
2213  Dump(fname,0);
2214  } else
2215  if(ext=="root") {
2216  //: Dump object into root file
2217  DumpObject(fname);
2218  } else {
2219  cout << "wavearray operator (>>) : file type " << ext.Data() << " not supported" << endl;
2220  }
2221  return fname;
2222 }
2223 
2224 //: save to file operator >>
2225 template <class DataType_t>
2227 {
2228  cout << endl << endl;
2229  cout.precision(14);
2230  cout << "Size\t= " << this->Size << " samples" << endl;
2231  cout << "Rate\t= " << this->Rate << " Hz" << endl;
2232  cout << "Start\t= " << this->Start << " sec" << endl;
2233  cout << "Stop\t= " << this->Stop << " sec" << endl;
2234  cout << "Length\t= "<< this->Stop-this->Start << " sec" << endl;
2235  cout << "Edge\t= " << this->Edge << " sec" << endl;
2236  cout << "Mean\t= " << this->mean() << endl;
2237  cout << "RMS\t= " << this->rms() << endl;
2238  cout << endl;
2239 
2240  return;
2241 }
2242 
2243 #ifdef _USE_DMT
2244 
2245 template<class DataType_t>
2247 operator=(const TSeries &ts)
2248 {
2249  Interval ti = ts.getTStep();
2250  double Tsample = ti.GetSecs();
2251 
2252  unsigned int n=ts.getNSample();
2253  if(n != size()) resize(n);
2254 
2255  if ( Tsample > 0. )
2256  rate(double(int(1./Tsample + 0.5)));
2257  else {
2258  cout <<" Invalid sampling interval = 0 sec.\n";
2259  }
2260 
2261  start(double(ts.getStartTime().totalS()));
2262 
2263  TSeries r(ts.getStartTime(), ti, ts.getNSample());
2264  r = ts;
2265  float *vec_ref;
2266  vec_ref= (float*)(r.refData());
2267 
2268  for ( unsigned int i=0; i<n; i++ )
2269  data[i] = (DataType_t) (vec_ref[i]);
2270  return *this;
2271 }
2272 
2273 #endif
2274 
2275 // instantiations
2276 
2277 #define CLASS_INSTANTIATION(class_) template class wavearray< class_ >;
2278 
2280 CLASS_INSTANTIATION(short)
2281 CLASS_INSTANTIATION(long)
2282 CLASS_INSTANTIATION(long long)
2283 CLASS_INSTANTIATION(unsigned int)
2284 CLASS_INSTANTIATION(float)
2285 CLASS_INSTANTIATION(double)
2286 //CLASS_INSTANTIATION(std::complex<float>)
2287 //CLASS_INSTANTIATION(std::complex<double>)
2288 
2289 #undef CLASS_INSTANTIATION
2290 
2291 
2292 #if !defined (__SUNPRO_CC)
2293 template wavearray<double>::
2294 wavearray(const double *, unsigned int, double);
2295 
2296 template wavearray<double>::
2297 wavearray(const float *, unsigned int, double );
2298 
2299 template wavearray<double>::
2300 wavearray(const short *, unsigned int, double );
2301 
2302 template wavearray<float>::
2303 wavearray(const double *, unsigned int, double );
2304 
2305 template wavearray<float>::
2306 wavearray(const float *, unsigned int, double );
2307 
2308 template wavearray<float>::
2309 wavearray(const short *, unsigned int, double );
2310 
2311 #else
2312 // FAKE CALLS FOR SUN CC since above instatinations are
2313 // not recognized
2314 static void fake_instatination_SUN_CC ()
2315 {
2316  double x;
2317  float y;
2318  short s;
2319  wavearray<double> wvdd (&x, 1, 0);
2320  wavearray<double> wvdf (&y, 1, 0);
2321  wavearray<double> wvds (&s, 1, 0);
2322  wavearray<float> wvfd (&x, 1, 0);
2323  wavearray<float> wvff (&y, 1, 0);
2324  wavearray<float> wvfs (&s, 1, 0);
2325 }
2326 
2327 #endif
2328 
2329 
2330 
2331 
2332 
2333 
2334 
2335 
2336 
wavearray< double > t(hp.size())
size_t append(const wavearray< DataType_t > &)
Definition: wavearray.cc:793
static const double C
Definition: GNGen.cc:28
virtual DataType_t min() const
Definition: wavearray.cc:1368
virtual double stop() const
Definition: wavearray.hh:140
double M
Definition: DrawEBHH.C:13
virtual wavearray< double > getLPRFilter(int, int=0, int=0)
Definition: wavearray.cc:1912
double duration
int offset
Definition: TestSTFT_2.C:19
virtual void rate(double r)
Definition: wavearray.hh:141
virtual void ReadShort(const char *)
Definition: wavearray.cc:440
size_t Size
data array
Definition: wavearray.hh:323
#define np
wavearray< double > a(hp.size())
WSeries< float > v[nIFO]
Definition: cwb_net.C:80
par [0] name
int n
Definition: cwb_net.C:28
void print()
Definition: wavearray.cc:2226
TString("c")
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
wavearray< DataType_t > & operator=(const wavearray< DataType_t > &)
Definition: wavearray.cc:110
double Rate
Definition: wavearray.hh:324
void add(const wavearray< DataType_t > &, int=0, int=0, int=0)
Definition: wavearray.cc:746
virtual void ReadBinary(const char *, int=0)
Definition: wavearray.cc:410
double Stop
Definition: wavearray.hh:326
TFFTRealComplex * fftw
Definition: wavearray.hh:330
STL namespace.
virtual wavearray< DataType_t > & operator*=(wavearray< DataType_t > &)
Definition: wavearray.cc:276
virtual ~wavearray()
Definition: wavearray.cc:100
double Nevill(const double x0, int n, DataType_t *p, double *q)
Definition: watfun.hh:56
int m
Definition: cwb_net.C:28
virtual void start(double s)
Definition: wavearray.hh:137
int j
Definition: cwb_net.C:28
i drho i
int isize
double Edge
Definition: wavearray.hh:327
#define N
cout<< "SNR "<< xsnr<< endl;wavearray< double > f
Definition: ComputeSNR.C:75
double pi
Definition: TestChirp.C:18
cout<< "Selected Pixels : "<< nPix<< endl;wc.cluster(1, 1);SSeries< double > ss
fprintf(stdout,"start=%f duration=%f rate=%f\, x.start(), x.size()/x.rate(), x.rate())
size_t mode
virtual void waveSplit(DataType_t **pp, size_t l, size_t r, size_t m) const
Definition: wavearray.cc:1499
virtual double rms()
Definition: wavearray.cc:1206
wavearray< double > w
Definition: Test1.C:27
virtual size_t size() const
Definition: wavearray.hh:145
tlive_fix Write()
virtual void DumpObject(const char *)
Definition: wavearray.cc:400
void wavefft(double a[], double b[], int ntot, int n, int nspan, int isn)
Definition: wavefft.cc:41
void sub(const wavearray< DataType_t > &, int=0, int=0, int=0)
Definition: wavearray.cc:772
virtual char * operator>>(char *)
Definition: wavearray.cc:2200
size_t size() const
Definition: wslice.hh:89
wavearray< double > xx
Definition: TestFrame1.C:11
virtual double rate() const
Definition: wavearray.hh:142
size_t start() const
Definition: wslice.hh:85
i() int(T_cor *100))
TFFTComplexReal * ifftw
pointer to direct fftw object
Definition: wavearray.hh:331
size_t stride() const
Definition: wslice.hh:93
double Pi
bool log
Definition: WaveMDC.C:41
void Resample(const wavearray< DataType_t > &, double, int=6)
Definition: wavearray.cc:640
virtual int getSampleRankE(size_t n, size_t l, size_t r) const
Definition: wavearray.cc:1399
int l
TIter next(twave->GetListOfBranches())
char fname[1024]
std::slice Slice
Definition: wavearray.hh:328
virtual double start() const
Definition: wavearray.hh:138
int k
virtual void resetFFTW()
Definition: wavearray.cc:977
virtual wavearray< DataType_t > & operator+=(wavearray< DataType_t > &)
Definition: wavearray.cc:191
TObjArray * token
virtual size_t limit() const
Definition: wavearray.hh:344
int(* qsort_func)(const void *, const void *)
Definition: wavearray.cc:47
virtual wavearray< DataType_t > & operator<<(wavearray< DataType_t > &)
Definition: wavearray.cc:156
double dt
virtual void DumpBinary(const char *, int=0)
Definition: wavearray.cc:353
virtual void FFTW(int=1)
Definition: wavearray.cc:896
regression r
Definition: Regression_H1.C:44
s s
Definition: cwb_net.C:155
double T
Definition: testWDM_4.C:11
virtual void lprFilter(wavearray< double > &)
Definition: wavearray.cc:1826
wavearray< double > ts(N)
virtual double mean() const
Definition: wavearray.cc:1071
virtual void delay(double T)
Definition: wavearray.cc:596
virtual void DumpShort(const char *, int=0)
Definition: wavearray.cc:374
virtual void stop(double s)
Definition: wavearray.hh:139
virtual wavearray< DataType_t > & operator-=(wavearray< DataType_t > &)
Definition: wavearray.cc:226
double fabs(const Complex &x)
Definition: numpy.cc:55
virtual void spesla(double, double, double=0.)
Definition: wavearray.cc:1770
virtual void waveSort(DataType_t **pp, size_t l=0, size_t r=0) const
Definition: wavearray.cc:1421
void resample(const wavearray< DataType_t > &, double, int=6)
Definition: wavearray.cc:503
DataType_t rank(double=0.5) const
Definition: wavearray.cc:1737
virtual wavearray< DataType_t > & operator[](const std::slice &)
Definition: wavearray.cc:295
strcpy(RunLabel, RUN_LABEL)
virtual void Dump(const char *, int=0)
Definition: wavearray.cc:319
double df
virtual DataType_t max() const
Definition: wavearray.cc:1334
virtual void exponential(double)
Definition: wavearray.cc:1680
#define CLASS_INSTANTIATION(class_)
Definition: wavearray.cc:2277
DataType_t * data
Definition: wavearray.hh:319
double getStatistics(double &mean, double &rms) const
Definition: wavearray.cc:2128
virtual wavearray< double > white(double, int=0, double=0., double=0.) const
Definition: wavearray.cc:2025
double Stack(const wavearray< DataType_t > &, int)
Definition: wavearray.cc:991
fclose(ftrig)
double Start
Definition: wavearray.hh:325
for(int i=0;i< 101;++i) Cos2[2][i]=0
pointers to detectors
virtual void resize(unsigned int)
Definition: wavearray.cc:463
virtual double median(size_t=0, size_t=0) const
Definition: wavearray.cc:1576
double length
Definition: TestBandPass.C:18
wavearray< double > y
Definition: Test10.C:31
char pm[8]
Double_t x0
virtual void FFT(int=1)
Definition: wavearray.cc:832
virtual int getSampleRank(size_t n, size_t l, size_t r) const
Definition: wavearray.cc:1379
exit(0)
void cpf(const wavearray< DataType_t > &, int=0, int=0, int=0)
Definition: wavearray.cc:717
double avr