Logo Coherent WaveBurst  
Reference Guide
Logo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
wseries.cc
Go to the documentation of this file.
1 // $Id: wseries.cc,v 1.5 2005/07/01 02:25:58 klimenko Exp $
2 
3 #define WSeries_CC
4 #include <time.h>
5 #include <iostream>
6 #include <stdexcept>
7 #include "wseries.hh"
8 
9 #include "Haar.hh"
10 #include "Biorthogonal.hh"
11 #include "Daubechies.hh"
12 #include "Symlet.hh"
13 #include "Meyer.hh"
14 #include "WDM.hh"
15 
16 ClassImp(WSeries<double>)
17 
18 using namespace std;
19 
20 // constructors
21 
22 template<class DataType_t>
23 WSeries<DataType_t>::WSeries() : wavearray<DataType_t>()
24 {
25  this->pWavelet = new WaveDWT<DataType_t>();
26  this->pWavelet->allocate(this->size(),this->data);
27  this->bpp = 1.;
28  this->wRate = 0.;
29  this->f_low = 0.;
30  this->f_high = 0.;
31  this->w_mode = 0;
32 }
33 
34 template<class DataType_t>
36 wavearray<DataType_t>()
37 {
38  this->pWavelet = NULL;
39  this->setWavelet(w);
40  this->bpp = 1.;
41  this->wRate = 0.;
42  this->f_low = 0.;
43  this->f_high = 0.;
44  this->w_mode = 0;
45 }
46 
47 template<class DataType_t>
49 wavearray<DataType_t>(value)
50 {
51  this->pWavelet = NULL;
52  this->setWavelet(w);
53  this->bpp = 1.;
54  this->wRate = value.rate();
55  this->f_low = 0.;
56  this->f_high = value.rate()/2.;
57  this->w_mode = 0;
58 }
59 
60 template<class DataType_t>
62 wavearray<DataType_t>(value)
63 {
64  this->pWavelet = NULL;
65  this->setWavelet(*(value.pWavelet));
66  this->bpp = value.getbpp();
67  this->wRate = value.wRate;
68  this->f_low = value.getlow();
69  this->f_high = value.gethigh();
70  this->w_mode = value.w_mode;
71 }
72 
73 // destructor
74 
75 template<class DataType_t>
77 {
78  if(this->pWavelet) this->pWavelet->release();
79  if(this->pWavelet) delete this->pWavelet;
80 }
81 
82 // metadata methods
83 
84 template<class DataType_t>
86 {
87  int maxlevel = 0;
88 
89  if(pWavelet->allocate())
90  maxlevel = pWavelet->getMaxLevel();
91 
92  return maxlevel;
93 }
94 
95 // Accessors
96 
97 //: Get central frequency of a layer
98 template<class DataType_t>
100 // Get central frequency of a layer
101 // l - layer number.
102 // TF map binary dyadic WDM
103 // zero layer Fc dF/2 Fo 0
104 // non-zero Fc +n*dF Fn +n*dF
105  int I = maxLayer()+1;
106  double df = this->rate()/I/4.;
107  if(I==1) return this->rate()/2.;
108  if(pWavelet->m_WaveType==WDMT) return i*this->rate()/(I-1)/2.;
109  if(pWavelet->BinaryTree()) return 2*df*(i+0.5);
110  df = this->rate()/(1<<I);
111  double f = df;
112  while(i--){ f += 2*df; df*=2; }
113  return f;
114 }
115 
116 template<class DataType_t>
118 // multiply this and w layaer by layer
119 // requires the same number of layer samples in this and w
120  int I = this->maxLayer()+1; // layers in this
121  int J = w.maxLayer(); // layers-1 in w
122  int i = 0;
123  int j = 0;
124  double df = (w.frequency(1)-w.frequency(0))/2.;
125  double f,F;
127  bool error = false;
128  w.getLayer(x,j); // get x array
129  while(i<I) {
130  f = w.frequency(j)+df;
131  F = this->frequency(i);
132  if(f<F){
133  if(j==J) {error = true; break;}
134  w.getLayer(x,++j); // update x array
135  }
136  this->getLayer(y,i); // extract layer from this
137  if(x.size()!=y.size()) {
138  cout<<"wseries::mul(): "<<x.size()<<" "<<y.size()<<endl;
139  error=true; break; // error!
140  }
141  y *= x;
142  this->putLayer(y,i++); // replace layer in this
143  }
144  if(error) {cout<<"wseries::mul() error!\n"; exit(1);}
145  return;
146 }
147 
148 template<class DataType_t>
150 //: Get layer index for input frequency
151 // f - frequency Hz
152 // TF map binary dyadic WDM
153 // zero layer Fc dF/2 Fo 0
154 // non-zero Fc +n*dF Fn +n*dF
155 
156  int I = int(maxLayer()+1);
157  if(I<2 || f>=this->rate()/2.) return I;
158  double df = this->rate()/(I-1)/2.;
159  if(pWavelet->m_WaveType==WDMT) return int((f+df/2.)/df);
160  df = this->rate()/I/2.;
161  if(pWavelet->BinaryTree()) return int(f/df);
162  df = this->rate()/(1<<I);
163  double ff = df;
164  int i = 0;
165  while(ff<f){ ff += 2*df; df*=2; i++; }
166  return i;
167 
168 }
169 
170 // access to data in wavelet domain
171 // get wavelet coefficients from a layer with specified frequency index
172 // if index>0 - get coefficients from the layer = |index| and 0 phase
173 // if index<0 - get coefficients from the layer = |index| and 90 phase
174 template<class DataType_t>
176 {
177  int n = int(fabs(index)+0.001);
178  if(n > maxLayer()) index = maxLayer();
179  slice s = pWavelet->getSlice(index);
180 
181  if(this->limit(s) <= this->size()){
182  value.resize(s.size());
183  value.rate(this->wrate());
184  value.start(this->start());
185  value.stop(this->start()+s.size()/value.rate());
186  value.edge(this->edge());
187  value.Slice = slice(0,s.size(),1);
188  value << (*this)[s]; // get slice of wavelet valarray
189  return n;
190  }
191  else{
192  cout<<"WSeries::getLayer(): data length mismatch: "<<this->limit(s)<<" "<<this->size()<<"\n";
193  return -1;
194  }
195 }
196 
197 // access to data in wavelet domain
198 // put wavelet coefficients into layer with specified frequency index
199 // if index<0 - put coefficients into layer = |index|
200 template<class DataType_t>
202 {
203  slice s = this->pWavelet->getSlice(index);
204 
205  if( (s.size() < value.size()) || (this->limit(s) > this->size()) ){
206  cout<<"WSeries::putLayer(): invalid array size.\n";
207  }
208  else{
209  (*this)[s] << value; // put slice into wavelet valarray
210  }
211 }
212 
213 // mutators
214 
215 template<class DataType_t>
217 {
218  if(pWavelet){ // delete old wavelet object
219  pWavelet->release();
220  delete pWavelet;
221  }
222 
223  pWavelet = (WaveDWT<DataType_t> *)w.Clone();
224  pWavelet->allocate(this->size(), this->data);
225 }
226 
227 template<class DataType_t>
229 {
230  if(pWavelet->allocate()){
231  pWavelet->nSTS = pWavelet->nWWS;
232  pWavelet->t2w(k);
233  if(pWavelet->pWWS != this->data || pWavelet->nWWS != this->Size){
234  this->data = pWavelet->pWWS;
235  this->Size = pWavelet->nWWS;
236  this->Slice = std::slice(0,pWavelet->nWWS,1);
237  }
238  std::slice s = this->getSlice(0);
239  this->wrate(s.size()/(this->stop()-this->start()));
240  }
241  else{
242  throw std::invalid_argument
243  ("WSeries::Forward(): data is not allocated");
244  }
245 }
246 
247 template<class DataType_t>
249 {
250  wavearray<DataType_t>* p = this;
251  if(pWavelet->allocate()) pWavelet->release();
252  *p = x;
253  this->wrate(x.rate());
254  f_high = x.rate()/2.;
255  pWavelet->allocate(this->size(), this->data);
256  pWavelet->reset();
257  Forward(k);
258 }
259 
260 template<class DataType_t>
262 {
263  wavearray<DataType_t>* p = this;
264  if(pWavelet->allocate()) pWavelet->release();
265  *p = x;
266  this->wrate(x.rate());
267  f_high = x.rate()/2.;
268  setWavelet(w);
269  Forward(k);
270 }
271 
272 template<class DataType_t>
274 {
275  if(pWavelet->allocate()){
276  pWavelet->w2t(k);
277  if(pWavelet->pWWS != this->data || pWavelet->nWWS != this->Size) {
278  this->data = pWavelet->pWWS;
279  this->Size = pWavelet->nWWS;
280  this->Slice = std::slice(0,pWavelet->nWWS,1);
281  this->wrate(this->rate());
282  }
283  else {
284  std::slice s = this->getSlice(0);
285  this->wrate(s.size()/(this->stop()-this->start()));
286  }
287  }
288  else{
289  throw std::invalid_argument
290  ("WSeries::Inverse(): data is not allocated");
291  }
292 }
293 
294 template<class DataType_t>
296 {
297 // bandpass data and store in TF domain, do not use for WDM
298 // ts - input time series
299 // flow - low frequence boundary
300 // fhigh - high frequency boundary
301 // n - decomposition level
302  if(!this->pWavelet) {
303  cout<<"WSeries::bandpass ERROR: no transformation is specified"<<endl;
304  exit(1);
305  }
306 
307  this->Forward(ts,n);
308 
309  double freq;
311  size_t I = this->maxLayer()+1;
312  for(size_t i=0; i<I; i++) {
313  freq = this->frequency(i);
314  if(freq<flow || freq>fhigh) {
315  this->getLayer(wa,i); wa = 0;
316  this->putLayer(wa,i);
317  }
318  }
319 }
320 
321 template<class DataType_t>
322 void WSeries<DataType_t>::bandpass(double f1, double f2, double a)
323 {
324 // set wseries coefficients to a in layers between
325 // f1 - low frequence boundary
326 // f2 - high frequency boundary
327 // f1>0, f2>0 - zzzzzz..........zzzzzz band pass
328 // f1<0, f2<0 - ......zzzzzzzzzz...... band cut
329 // f1<0, f2>0 - ......zzzzzzzzzzzzzzzz low pass
330 // f1>0, f2<0 - zzzzzzzzzzzzzzzz...... high pass
331 // a - value
332  int i;
333  double dF = this->frequency(1)-this->frequency(0); // frequency resolution
334  double fl = fabs(f1)>0. ? fabs(f1) : this->getlow();
335  double fh = fabs(f2)>0. ? fabs(f2) : this->gethigh();
336  size_t n = this->pWavelet->m_WaveType==WDMT ? size_t((fl+dF/2.)/dF+0.1) : size_t(fl/dF+0.1);
337  size_t m = this->pWavelet->m_WaveType==WDMT ? size_t((fh+dF/2.)/dF+0.1)-1 : size_t(fh/dF+0.1)-1;
338  size_t M = this->maxLayer()+1;
340 
341  if(n>m) return;
342 
343  for(i=0; i<int(M); i++) { // ......f1......f2......
344 
345  if((f1>=0 && i>n) && (f2>=0 && i<=m)) continue; // zzzzzz..........zzzzzz band pass
346  if((f1<0 && i<n) || (f2<0 && i>m)) continue; // ......zzzzzzzzzz...... band cut
347  if((f1<0 && f2>=0 && i<n)) continue; // ......zzzzzzzzzzzzzzzz low pass
348  if((f1>=0 && f2<0 && i>=m)) continue; // zzzzzzzzzzzzzzzz...... high pass
349 
350  this->getLayer(w,i+0.01); w=a; this->putLayer(w,i+0.01);
351  this->getLayer(w,-i-0.01); w=a; this->putLayer(w,-i-0.01);
352  }
353  return;
354 }
355 
356 
357 template<class DataType_t>
358 double WSeries<DataType_t>::wdmPacket(int patt, char c, TH1F* hist)
359 {
360 // wdmPacket: converts this to WDM packet series described by pattern
361 // c = 'e' / 'E' - returns pattern / packet energy
362 // c = 'l' / 'L' - returns pattern / packet likelihood
363 // c = 'a' / 'A' - returns packet amplitudes
364 // patt = pattern
365 // patterns: "/" - chirp, "\" - ringdown, "|" - delta, "*" - pixel
366 // param: pattern = 0 - "*" single pixel standard search
367 // param: pattern = 1 - "3|" packet
368 // param: pattern = 2 - "3-" packet
369 // param: pattern = 3 - "3/" packet - chirp
370 // param: pattern = 4 - "3\" packet - ringdown
371 // param: pattern = 5 - "5/" packet - chirp
372 // param: pattern = 6 - "5\" packet - ringdown
373 // param: pattern = 7 - "3+" packet
374 // param: pattern = 8 - "3x" cross packet
375 // param: pattern = 9 - "9p" 9-pixel square packet
376 // pattern = else - "*" single pixel standard search
377 // mean of the packet noise distribution is mu=2*K+1, where K is
378 // the effective number of pixels in the packet (K may not be integer)
379 //
380  int n,m;
381  double aa,ee,EE,uu,UU,dd,DD,em,ss,cc,nn;
382  double shape,mean,alp;
383  int pattern = abs(patt);
384  int J = this->size()/2; // energy map size
385  if(pattern==0) return 1.;
386  if(!this->isWDM() || (2*J)/this->xsize()==1) exit(0);
387 
388  WSeries<DataType_t> in = *this;
389  int M = in.maxLayer()+1; // number of layers
390  int jb = int(in.Edge*in.wrate()/4.)*M;
391  if(jb<4*M) jb = 4*M;
392  int je = J-jb;
393  int p[] = {0,0,0,0,0,0,0,0,0};
394  double df = in.resolution(0);
395  int mL = int(in.getlow()/df+0.1);
396  int mH = int(in.gethigh()/df+0.1);
397 
398  if(c!='a'||c!='A') this->resize(J); // convert to energy array
399 
400  if(pattern==1) { // "3|" vertical line
401  p[1]=1; p[2]=-1; // 'p': a=2.8,b=0.90
402  shape = mean = 3.; // 'e': a=3.0,b=1.00
403  mL+=1; mH-=1;
404  }
405  else if(pattern==2) { // "3-" horizontal line
406  p[1]=M; p[2]=-M; // 'p': a=2.0,b=1.41
407  shape = mean = 3.; // 'e': a=2.2,b=1.38
408  }
409  else if(pattern==3) { // "3/" chirp packet
410  p[1]=M+1; p[2]=-M-1; // 'p': a=2.7,b=0.91
411  shape = mean = 3.; // 'e': a=3.0,b=1.00
412  mL+=1; mH-=1;
413  }
414  else if(pattern==4) { // "3\" chirp packet
415  p[1]=-M+1; p[2]=M-1; // 'p': a=2.7,b=0.91
416  shape = mean = 3.; // 'e': a=3.0,b=1.00
417  mL+=1; mH-=1;
418  }
419  else if(pattern==5) { // "5/"-pattern=5
420  p[1]=M+1; p[2]=-M-1; p[3]=2*M+2; p[4]=-2*M-2; // 'e': a=5.0,b=1.00
421  shape = mean = 5.; //shape=4.8; mean=4.8*0.95; // 'p': a=4.8,b=0.95
422  mL+=2; mH-=2;
423  }
424  else if(pattern==6) { // "5\"-pattern=-5
425  p[1]=-M+1; p[2]=M-1; p[3]=-2*M+2; p[4]=2*M-2; // 'e': a=5.0,b=1.00
426  shape = mean = 5.; // 'p': a=4.8,b=0.95
427  mL+=2; mH-=2;
428  }
429  else if(pattern==7) { // "3+" packet
430  p[1]=1; p[2]=-1; p[3]=M; p[4]=-M; // 'e': a=3.9,b=1.28
431  shape = mean = 5.; // 'p': a=3.6,b=1.28
432  mL+=1; mH-=1;
433  }
434  else if(pattern==8) { // "3x" cross packet
435  p[1]=M+1; p[2]=-M+1; p[3]= M-1; p[4]=-M-1; // 'p': a=2.8,b=0.90
436  shape = mean = 5.; // 'e': a=3.0,b=1.00
437  mL+=1; mH-=1;
438  }
439  else if(pattern==9) { // "9*" 9-pixel square
440  p[1]=1; p[2]=-1; p[3]=M; p[4]=-M; // 'p': a=5.6,b=1.57
441  p[5]=M+1; p[6]=M-1; p[7]=-M+1; p[8]=-M-1; // 'e': a=5.8,b=1.55
442  shape = mean = 9.;
443  mL+=1; mH-=1;
444  } else { shape = mean = 1.; }
445 
446  DataType_t *q; // pointers to 00 phase
447  DataType_t *Q; // pointers to 90 phase
448 
449  for(int j=jb; j<je; j++) {
450  m = j%M;
451  if(m<mL || m>mH) {this->data[j]=0.; continue;}
452  q = in.data+j; Q = q+J;
453  ss = q[p[1]]*Q[p[1]]+q[p[2]]*Q[p[2]]+q[p[3]]*Q[p[3]]+q[p[4]]*Q[p[4]]
454  + q[p[5]]*Q[p[5]]+q[p[6]]*Q[p[6]]+q[p[7]]*Q[p[7]]+q[p[8]]*Q[p[8]];
455  ee = q[p[1]]*q[p[1]]+q[p[2]]*q[p[2]]+q[p[3]]*q[p[3]]+q[p[4]]*q[p[4]]
456  + q[p[5]]*q[p[5]]+q[p[6]]*q[p[6]]+q[p[7]]*q[p[7]]+q[p[8]]*q[p[8]];
457  EE = Q[p[1]]*Q[p[1]]+Q[p[2]]*Q[p[2]]+Q[p[3]]*Q[p[3]]+Q[p[4]]*Q[p[4]]
458  + Q[p[5]]*Q[p[5]]+Q[p[6]]*Q[p[6]]+Q[p[7]]*Q[p[7]]+Q[p[8]]*Q[p[8]];
459  ss+= q[p[0]]*Q[p[0]]*(mean-8);
460  ee+= q[p[0]]*q[p[0]]*(mean-8);
461  EE+= Q[p[0]]*Q[p[0]]*(mean-8);
462 
463  cc = ee-EE; ss*=2;
464  nn = sqrt(cc*cc+ss*ss);
465  if(ee+EE<nn) nn=ee+EE;
466  aa = sqrt((ee+EE+nn)/2) + sqrt((ee+EE-nn)/2);
467  em = (c=='e'||c=='l'||mean==1.) ? (ee+EE)/2. : aa*aa/4;
468  alp = shape-log(shape)/3;
469  if(c=='l'||c=='L') {
470  em*=shape/mean;
471  if(em<alp) {em=0; continue;}
472  em-= alp*(1+log(em/alp));
473  }
474  if(c=='a'||c=='A') {
475  cc/=nn; ss/=nn;
476  nn = sqrt((1+cc)*(1+cc)+ss*ss)/2;
477  this->data[j]=aa*cc/nn; this->data[j+J]=aa*ss/nn/2;
478  } else {this->data[j] = em;}
479  if(hist && em>0.01) hist->Fill(sqrt(em));
480  }
481  return shape;
482 }
483 
484 
485 template<class DataType_t>
487  double dT, int N, int pattern, TH1F* hist)
488 {
489 // maxEnergy: put maximum energy of delayed samples in this
490 // param: wavearray - input time series
491 // param: wavelet - wavelet used for the transformation
492 // param: double - range of time delays
493 // param: int - downsample factor to obtain coarse TD steps
494 // param: int - clustering pattern
497  int K = int(ts.rate()*fabs(dT)); // half number of time delays
498  double shape = 1.;
499 
500  if(w.m_WaveType != WDMT) {
501  cout<<"wseries::maxEnergy(): illegal wavelet\n";
502  exit(0);
503  }
504 
505  this->Forward(ts,w,0);
506 
507  if(abs(pattern)) {
508  *this = 0.;
509  tmp.Forward(ts,w);
510  tmp.setlow(this->getlow());
511  tmp.sethigh(this->gethigh());
512  shape=tmp.wdmPacket(pattern,'E');
513  this->max(tmp);
514  for(int k=N; k<=K; k+=N) {
515  xx.cpf(ts,ts.size()-k,k);
516  tmp.Forward(xx,w);
517  tmp.setlow(this->getlow());
518  tmp.sethigh(this->gethigh());
519  tmp.wdmPacket(pattern,'E');
520  this->max(tmp);
521  xx.cpf(ts,ts.size()-k,0,k);
522  tmp.Forward(xx,w);
523  tmp.setlow(this->getlow());
524  tmp.sethigh(this->gethigh());
525  tmp.wdmPacket(pattern,'E');
526  this->max(tmp);
527  }
528  } else { // extract single pixels
529  for(int k=N; k<=K; k+=N) {
530  xx.cpf(ts,ts.size()-k,k);
531  tmp.Forward(xx,w,0);
532  this->max(tmp);
533  xx.cpf(ts,ts.size()-k,0,k);
534  tmp.Forward(xx,w,0);
535  this->max(tmp);
536  }
537  }
538 
539  int M = tmp.maxLayer()+1;
540  this->getLayer(xx,0.1); xx=0;
541  this->putLayer(xx,0.1);
542  this->getLayer(xx,M-1); xx=0;
543  this->putLayer(xx,M-1);
544 
545  int m = abs(pattern);
546  if(m==5 || m==6 || m==9) {
547  this->getLayer(xx,1); xx=0;
548  this->putLayer(xx,1);
549  this->getLayer(xx,M-2); xx=0;
550  this->putLayer(xx,M-2);
551  }
552 
553  if(!pattern) return 1.;
554  return Gamma2Gauss(hist);
555 }
556 
557 template<class DataType_t>
559 {
560 // finds parameters shape and scale for noise Gamma statistic
561 // convert from Gamma to Gaussian statistic
562 
563  WSeries<DataType_t> tmp = *(this);
564  int M = tmp.maxLayer()+1;
565  int nL = size_t(tmp.Edge*tmp.wrate()*M);
566  int nn = tmp.size();
567  int nR = nn-nL-1; // right boundary
568  double fff = (nR-nL)*tmp.wavecount(0.001)/double(nn); // zero fraction
569  double med = tmp.waveSplit(nL,nR,nR-int(0.5*fff)); // distribution median
570  double amp, aaa, bbb, rms, alp;
571 
572  aaa = bbb = 0.; nn = 0;
573  for(int i=nL; i<nR; i++) { // get Gamma shape
574  amp = (double)this->data[i];
575  if(amp>0.01 && amp<20*med) {
576  aaa += amp; bbb += log(amp); nn++;
577  }
578  }
579  alp = log(aaa/nn)-bbb/nn;
580  alp = (3-alp+sqrt((alp-3)*(alp-3)+24*alp))/12./alp;
581  double avr = med*(3*alp+0.2)/(3*alp-0.8); // get Gamma mean
582  //cout<<"debug0: "<<fff<<" "<<avr<<" "<<med<<" "<<alp<<endl;
583 
584  double ALP = med*alp/avr;
585  for(int i=0; i<this->size(); i++) {
586  amp = (double)this->data[i]*alp/avr;
587  if(amp<ALP) {this->data[i]=0.; continue;}
588  this->data[i] = amp-ALP*(1+log(amp/ALP));
589  //if(hist && i>nL && i<nR) hist->Fill(this->data[i]);
590  }
591  tmp = *(this);
592  fff = tmp.wavecount(1.e-5,nL); // number of events excluding 0
593  rms = 1./tmp.waveSplit(nL,nR,nR-int(0.3173*fff)); // 1 over distribution rms
594  //cout<<"debug1: "<<fff<<" "<<avr<<" "<<rms<<" "<<aaa<<endl;
595  for(int i=0; i<this->size(); i++) {
596  this->data[i] *= rms;
597  if(hist && i>nL && i<nR) hist->Fill(sqrt(this->data[i]));
598  }
599  return ALP;
600 }
601 
602 
603 template<class DataType_t>
605 {
606 // create a wavescan object
607 // produce multi-resolution TF series of input time series x
608 // pws - array of pointers to input time-frequency series
609 // N - number of resolutions
610 // hist - diagnostic histogram
611 
612  std::vector<int> vM; // vector to store number of layers
613  std::vector<int> vJ; // vector to store TF map size
614  std::vector<double> vR; // vector to store number of layers
615  std::vector<double> vF; // vector to store resolutions
616  int mBand, mRate, level;
617  int nn,j,J;
618  double time, freq, a,A,ee,EE,ss,cc,gg,b,B;
619  double mean = 2.*N-1; // Gamma distribution mean
620  double shape = N-log(N)/N; // Gamma distribution shape parameter
621 
622  mBand = 0; mRate = 0;
623  for(int n=0; n<N; n++) { // get all TF data
624  vF.push_back(pws[n]->resolution()); // save frequency resolution
625  vR.push_back(pws[n]->wrate()); // save frequency resolution
626  vM.push_back(pws[n]->maxLayer()+1);
627  vJ.push_back(pws[n]->size()/2);
628  if(vM[n]>mBand) {mBand = vM[n]; nn=n;}
629  if(pws[n]->wrate()>mRate) mRate = pws[n]->wrate();
630  }
631 
632 // set super TF map
633 
634  time = pws[nn]->size()/pws[nn]->wrate()/2; // number of ticks
635  J = mRate*int(time+0.1);
636  cout<<"debug1: "<<mBand<<" "<<mRate<<" "<<J<<" "<<pws[nn]->size()<<endl;
637  level = 0;
638  *this = *pws[nn];
639  this->resize(J);
640  this->setLevel(mBand-1);
641  this->wrate(mRate);
642  //this->rate(mRate*(mBand-1));
643  this->pWavelet->nWWS = J;
644  this->pWavelet->nSTS = (J/mBand)*(mBand-1);
645 
646  int nL = int(this->Edge*mRate*mBand); // left boundary
647  int nR = this->size()-nL-1; // right boundary
648 
649  for(int i=0; i<this->size(); i++) { // loop over super-TF-map
650  time = double(i/mBand)/mRate; // discrete time in seconds
651  freq = (i%mBand)*vF[nn]; // discrete frequency
652  ss=ee=EE=0.;
653  for(int n=1; n<N; n++) { // loop over TF-maps
654  j = int(time*vR[n-1]+0.1)*vM[n-1]; // pixel tick index in TF map
655  j+= int(freq/vF[n-1]+0.1); // add pixel frequency index
656  a = pws[n]->data[j]; // 00 phase amplitude
657  A = pws[n]->data[j+vJ[n-1]]; // 90 phase amplitude
658  j = int(time*vR[n]+0.1)*vM[n]; // pixel tick index in TF map
659  j+= int(freq/vF[n]+0.1); // add pixel frequency index
660  b = pws[n]->data[j]; // 00 phase amplitude
661  B = pws[n]->data[j+vJ[n]]; // 90 phase amplitude
662  ss = 2*(a*A+b*B);
663  ee = 2*(a*a+b*b);
664  EE = 2*(a*a+b*b);
665 EE+=A*A;
666  cc = ee-EE;
667  gg = sqrt(cc*cc+4*ss*ss);
668  a = sqrt((ee+EE+gg)/2);
669  A = sqrt((ee+EE-gg)/2);
670  }
671 
672 
673  this->data[i] = (a+A)*(a+A)/mean/2.;
674  if(hist && i>nL && i<nR) hist->Fill(this->data[i]);
675  }
676  //this->Gamma2Gauss(shape,hist);
677  return;
678 }
679 
680 
681 //: operators =
682 
683 template<class DataType_t>
685 {
686  wavearray<DataType_t>* p = this;
687  if( pWavelet->allocate() ) pWavelet->release();
688  if(p->size() != a.size()) pWavelet->reset();
689  *p = a;
690  this->rate(a.rate());
691  this->wrate(0.);
692  f_high = a.rate()/2.;
693  pWavelet->allocate(this->size(), this->data);
694  return *this;
695 }
696 
697 template<class DataType_t>
699 {
700  const wavearray<DataType_t>* p = &a;
701  wavearray<DataType_t>* q = this;
702  *q = *p;
703  setWavelet(*(a.pWavelet));
704  bpp = a.getbpp();
705  wRate = a.wrate();
706  f_low = a.getlow();
707  f_high = a.gethigh();
708  w_mode = a.w_mode;
709  return *this;
710 }
711 
712 template<class DataType_t>
714 {
715  this->Slice = s;
716  if(this->limit() > this->size()){
717  cout << "WSeries::operator[]: Illegal argument: "<<this->limit()<<" "<<this->size()<<"\n";
718  this->Slice = std::slice(0,this->size(),1);
719  }
720  return *this;
721 }
722 
723 template<class DataType_t>
725 { this->wavearray<DataType_t>::operator=(a); return *this; }
726 
727 template<class DataType_t>
729 { this->wavearray<DataType_t>::operator*=(a); return *this; }
730 
731 template<class DataType_t>
733 { this->wavearray<DataType_t>::operator-=(a); return *this; }
734 
735 template<class DataType_t>
737 { this->wavearray<DataType_t>::operator+=(a); return *this; }
738 
739 //template<class DataType_t>
740 //WSeries<DataType_t>& WSeries<DataType_t>::
741 //operator*=(wavearray<DataType_t> &a)
742 //{ this->wavearray<DataType_t>::operator*=(a); return *this; }
743 
744 template<class DataType_t>
746 { this->wavearray<DataType_t>::operator-=(a); return *this; }
747 
748 template<class DataType_t>
750 { this->wavearray<DataType_t>::operator+=(a); return *this; }
751 
752 template<class DataType_t>
754 {
755  size_t i;
759  size_t max_layer = (maxLayer() > a.maxLayer()) ? a.maxLayer() : maxLayer();
760 
761  if(pWavelet->m_TreeType != a.pWavelet->m_TreeType){
762  cout<<"WSeries::operator* : wavelet tree type mismatch."<<endl;
763  return *this;
764  }
765 
766  if(this->size()==a.size()) {
768  return *this;
769  }
770 
771  for(i=0; i<= max_layer; i++)
772  (*p)[pWavelet->getSlice(i)] *= (*pa)[a.pWavelet->getSlice(i)];
773 
774  return *this;
775 }
776 
777 template<class DataType_t>
779 {
780  size_t i;
783  size_t max_layer = (maxLayer() > a.maxLayer()) ? a.maxLayer() : maxLayer();
784 
785  if(pWavelet->m_TreeType != a.pWavelet->m_TreeType){
786  cout<<"WSeries::operator+ : wavelet tree type mismatch."<<endl;
787  return *this;
788  }
789 
790  if(this->size()==a.size()) {
792  return *this;
793  }
794 
795  for(i=0; i<= max_layer; i++)
796  (*p)[pWavelet->getSlice(i)] += (*pa)[a.pWavelet->getSlice(i)];
797 
798  return *this;
799 }
800 
801 template<class DataType_t>
803 {
804  size_t i;
807  size_t max_layer = (maxLayer() > a.maxLayer()) ? a.maxLayer() : maxLayer();
808 
809  if(pWavelet->m_TreeType != a.pWavelet->m_TreeType){
810  cout<<"WSeries::operator- : wavelet tree type mismatch."<<endl;
811  return *this;
812  }
813 
814  if(this->size()==a.size()) {
816  return *this;
817  }
818 
819  for(i=0; i<= max_layer; i++)
820  (*p)[pWavelet->getSlice(i)] -= (*pa)[a.pWavelet->getSlice(i)];
821 
822  return *this;
823 }
824 
825 template<class DataType_t>
827 {
828  size_t i;
830  size_t max_layer = maxLayer()+1;
831 
832  if(max_layer == a.size()) {
833  for(i=0; i< max_layer; i++) {
834  (*p)[pWavelet->getSlice(i)] *= a.data[i];
835  }
836  }
837  else if(this->size()==a.size()) {
839  return *this;
840  }
841  else cout<<"WSeries::operator* - no operation is performed"<<endl;
842 
843  return *this;
844 }
845 
846 
847 //: Dumps data array to file *fname in ASCII format.
848 template<class DataType_t>
849 void WSeries<DataType_t>::Dump(const char *fname, int app)
850 {
852  int i,j;
853  int n = this->size();
854  int m = this->maxLayer()+1;
855  char mode[3] = "w";
856  if (app == 1) strcpy (mode, "a");
857 
858  FILE *fp;
859 
860  if ( (fp = fopen(fname, mode)) == NULL ) {
861  cout << " Dump() error: cannot open file " << fname <<". \n";
862  return;
863  };
864 
865  if(app == 0) {
866  fprintf( fp,"# start time: -start %lf \n", this->Start );
867  fprintf( fp,"# sampling rate: -rate %lf \n", this->Rate );
868  fprintf( fp,"# number of samples: -size %d \n", (int)this->Size );
869  fprintf( fp,"# number of layers: -n %d \n", m );
870  }
871 
872  for (i = 0; i < m; i++) {
873  this->getLayer(a,i);
874  n = (int)a.size();
875  for(j = 0; j < n; j++) fprintf( fp,"%e ", (float)a.data[j]);
876  fprintf( fp,"\n");
877  }
878  fclose(fp);
879 }
880 
881 
882 template<class DataType_t>
883 void WSeries<DataType_t>::resize(unsigned int n)
884 {
885  wavearray<DataType_t>* p = this;
886  if( pWavelet->allocate() ) pWavelet->release();
887  p->wavearray<DataType_t>::resize(n);
888  pWavelet->allocate(this->size(), this->data);
889  pWavelet->reset();
890  bpp = 1.;
891  f_low = 0.;
892  wRate = this->rate();
893  f_high = this->rate()/2.;
894 }
895 
896 template<class DataType_t>
897 void WSeries<DataType_t>::resample(double f, int nF)
898 {
899  wavearray<DataType_t>* p = this;
900  if( pWavelet->allocate() ) pWavelet->release();
901  p->wavearray<DataType_t>::resample(f,nF);
902  pWavelet->allocate(this->size(), this->data);
903  pWavelet->reset();
904  bpp = 1.;
905  f_low = 0.;
906  wRate = p->wavearray<DataType_t>::rate();
907  f_high = p->wavearray<DataType_t>::rate()/2.;
908 }
909 
910 template<class DataType_t>
911 double WSeries<DataType_t>::coincidence(WSeries<DataType_t>& a, int t, int f, double threshold)
912 {
913 #if !defined (__SUNPRO_CC)
914  register int i;
915  register int j;
916  register int u;
917  register int v;
918  register float* q = NULL;
919  register float* p = NULL;
920 
921  int is, ie, js, je;
922 
925 
926  float energy;
927 
928  if(!pWavelet->BinaryTree()) return 1.;
929 
930  int ni = maxLayer()+1;
931  int nj = this->size()/ni;
932  int n = ni-1;
933  int m = nj-1;
934 
935  bool CROSS = t<0 || f<0;
936 
937  t = abs(t);
938  f = abs(f);
939 
940  float A[ni][nj];
941  float B[ni][nj];
942 
943  for(i=0; i<=n; i++){
944  p = A[i];
945  q = B[i];
946  a.getLayer(x,i);
947  getLayer(y,i);
948 
949  for(j=0; j<=m; j++){
950  p[j] = (float)x.data[j];
951  q[j] = (float)y.data[j];
952  }
953  }
954 
955  for(i=0; i<=n; i++){
956  p = A[i];
957  q = B[i];
958  a.getLayer(x,i);
959  getLayer(y,i);
960 
961  for(j=0; j<=m; j++){
962 
963  if(p[j]==0. && q[j]==0.) continue;
964 
965  is = i-f<0 ? 0 : i-f;
966  js = j-t<0 ? 0 : j-t;
967  ie = i+f>n ? n : i+f;
968  je = j+t>m ? m : j+t;
969 
970  energy = 0.;
971  if(x.data[j]!=0.) {
972  for(u=is; u<=ie; u++)
973  for(v=js; v<=je; v++){
974  if(CROSS && !(i==u || j==v)) continue;
975  if(B[u][v]!=0.) energy += log(fabs(B[u][v]));
976  }
977  if(energy < threshold) x.data[j]=0;
978  }
979 
980  energy = 0.;
981  if(y.data[j]!=0.) {
982  for(u=is; u<=ie; u++)
983  for(v=js; v<=je; v++){
984  if(CROSS && !(i==u || j==v)) continue;
985  if(A[u][v]!=0.) energy += log(fabs(A[u][v]));
986  }
987  if(energy < threshold) y.data[j]=0;
988  }
989 
990  if(y.data[j]==0. && x.data[j]!=0.) y.data[j]=DataType_t(a.size());
991 
992  }
993 
994  putLayer(y,i);
995 
996  }
997 #endif
998  return 0.;
999 }
1000 
1001 template<class DataType_t>
1003 {
1004  size_t i,k,m;
1005  size_t event = 0;
1006  size_t step;
1007  size_t N = a.size();
1008  int n;
1009 
1010  double E,S;
1011  bool pass;
1012 
1013  slice x,y;
1014  DataType_t* p = NULL;
1015  DataType_t* q = NULL;
1016  DataType_t* P = NULL;
1017  DataType_t* Q = NULL;
1018 
1019  if(pWavelet->m_TreeType != a.pWavelet->m_TreeType){
1020  cout<<"WSeries::operator- : wavelet tree type mismatch."<<endl;
1021  return 0.;
1022  }
1023 
1024  size_t max_layer = (maxLayer() > a.maxLayer()) ? a.maxLayer() : maxLayer();
1025 
1026  for(k=0; k<= max_layer; k++){
1027 
1028  x = getSlice(k);
1029  y = a.getSlice(k);
1030 
1031  if(x.size() != y.size()) continue;
1032  if(x.stride() != y.stride()) continue;
1033  if(x.start() != y.start()) continue;
1034 
1035  step = x.stride();
1036  n = int(w*a.rate()/2./step); // 2*(n+1) - coincidence window in pixels
1037  if(n < 0) n = 0; // not negative n
1038  if(!n && w>=0.) n++; // min 0 vs min 3 pixels
1039  S = log(float(n)); // threshold correction
1040  S = So + 2.*S/3.; // threshold
1041 // S = So + 0.5*log(2*n+1.); // threshold
1042 // S = So + S*S/(S+1); // threshold
1043  P = a.data+x.start();
1044  Q = a.data+x.start()+step*(x.size()-1);
1045  n *= step;
1046 
1047  for(i=x.start(); i<N; i+=step)
1048  {
1049  if(this->data[i] == 0.) continue;
1050 
1051  p = a.data+i-n; // start pointer
1052  if(p<P) p = P;
1053  q = a.data+i+n; // stop pointer
1054  if(q>Q) q = Q;
1055 
1056 // calculate total likelihood and number of black pixels
1057 // and set threshold on significance
1058 
1059  pass = false;
1060  E = 0.; m = 0;
1061 
1062  while(p <= q) {
1063 // if(*p>S) { pass = true; break; }
1064  if(*p>0) { E += *p; m++; }
1065  p += step;
1066  }
1067 
1068  if(m>0 && !pass) {
1069  if(gammaCL(E,m) > S-log(double(m))) pass = true;
1070  }
1071 
1072  if(pass) event++;
1073  else this->data[i] = 0;
1074  }
1075  }
1076 
1077 // handle wavelets with different number of layers
1078 
1079  if(size_t(maxLayer())>max_layer){
1081  for(k=max_layer+1; k<= size_t(maxLayer()); k++) {
1082  (*pw)[getSlice(k)] = 0;
1083  }
1084  }
1085 
1086  return double(event)/this->size();
1087 }
1088 
1089 
1090 template<class DataType_t>
1091 void WSeries<DataType_t>::median(double t, bool r)
1092 {
1093  int i;
1094  int M = maxLayer()+1;
1095 
1096  for(i=0; i<M; i++){
1097  this->setSlice(getSlice(i));
1099  }
1100 
1101  std::slice S(0,this->size(),1);
1102  this->setSlice(S);
1103  return;
1104 }
1105 
1106 
1107 template<class DataType_t>
1108 void WSeries<DataType_t>::lprFilter(double T, int mode, double stride, double offset)
1109 {
1110  if(offset<T) offset = T;
1111  size_t i;
1112  size_t M = maxLayer()+1;
1113 
1115 
1116  for(i=0; i<M; i++){
1117  getLayer(a,i);
1118  if(mode<2) a.lprFilter(T,mode,stride,offset);
1119  else a.spesla(T,stride,offset);
1120  putLayer(a,i);
1121  }
1122  return;
1123 }
1124 
1125 
1126 
1127 template<class DataType_t>
1128 WSeries<double> WSeries<DataType_t>::white(double t, int mode, double offset, double stride)
1129 {
1130 //: tracking of noise non-stationarity and whitening.
1131 // param 1 - time window dT. if = 0 - dT=T, where T is wavearray duration - 2*offset
1132 // param 2 - mode: 0 - no whitening, 1 - single whitening, >1 - double whitening
1133 // mode < 1 - whitening of guadrature (WDM wavelet only)
1134 // param 3 - boundary offset
1135 // param 4 - noise sampling interval (window stride)
1136 // the number of measurements is k=int((T-2*offset)/stride)
1137 // if stride=0, then stride is set to dT
1138 // return: noise array if param2>0, median if param2=0
1139 // what it does: each wavelet layer is devided into k intervals.
1140 // The data for each interval is sorted and the following parameters
1141 // are calculated: median and the amplitude
1142 // corresponding to 31% percentile (wp). Wavelet amplitudes (w) are
1143 // normalized as w' = (w-median(t))/wp(t), where median(t) and wp(t)
1144 // is a linear interpolation between (median,wp) measurements for
1145 // each interval.
1146  int i;
1147  double segT = this->stop()-this->start();
1148  if(t <= 0.) t = segT-2.*offset;
1149  int M = maxLayer()+1;
1150  int m = mode<0 ? -1 : 1;
1151 
1152  this->w_mode = abs(mode);
1153  if(stride > t || stride<=0.) stride = t;
1154  size_t K = size_t((segT-2.*offset)/stride); // number of noise measurement minus 1
1155  if(!K) K++; // special case
1156 
1157  Wavelet* pw = pWavelet->Clone();
1160  wavearray<double> b(M*(K+1));
1161  WSeries<double> ws(b,*pw);
1162 
1163  for(i=0; i<M; i++){
1164  getLayer(a,(i+0.01)*m);
1165  if(!w_mode) { // use square coefficients
1166  getLayer(aa,-(i+0.01)); aa*=aa; a*=a; a+=aa;
1167  }
1168  b = a.white(t,w_mode,offset,stride);
1169  if(b.size() != K+1) cout<<"wseries::white(): array size mismatch\n";
1170  ws.putLayer(b,i);
1171  if(w_mode) putLayer(a,i*m);
1172  }
1173 
1174  ws.start(b.start());
1175  ws.stop(b.stop());
1176  ws.wrate(b.rate());
1177  ws.rate(this->rate());
1178  ws.setlow(0.);
1179  ws.sethigh(this->rate()/2.);
1180 
1181  delete pw;
1182  return ws;
1183 }
1184 
1185 template<class DataType_t>
1187 {
1188 // whiten wavelet series by using TF noise rms array
1189 // if mode <0 - access qudrature WDM data
1190 // if abs(mode) <2 - single, otherwise double whitening
1191 
1192  size_t i,j,J,K;
1193 
1194  if(!nRMS.size()) return false;
1195 
1196  slice S,N;
1197 
1198  int k;
1199  int m = mode<0 ? -1 : 1;
1200  size_t In = nRMS.maxLayer()+1;
1201  size_t I = this->maxLayer()+1;
1202  double To = nRMS.start()-this->start();
1203  double dT = 1./nRMS.wrate(); // rate in a single noise layer!
1204  double R = this->wrate(); // rate in a single data layer
1205  double r;
1206  wavearray<DataType_t> xx; // data layer
1207  wavearray<double> na; // nRMS layer
1208 
1209  this->w_mode = abs(mode);
1210 
1211  if(I!=In) {
1212  cout<<"wseries::white error: mismatch between WSeries and nRMS\n";
1213  exit(0);
1214  }
1215 
1216  for(i=(1-m)/2; i<I; i++){ // loop over layers
1217  this->getLayer(xx,(i+0.01)*m); // layer of WSeries
1218  nRMS.getLayer(na,int(i)); // layer of noise array
1219  J = xx.size(); // number of data samples
1220  K = na.size()-1; // number of noise samples - 1
1221  k = 0.;
1222 
1223  for(j=0; j<J; j++) {
1224  double t = j/R; // data sample time
1225  double T = To+k*dT;
1226 
1227  if(t >= To+K*dT) r = na.data[K]; // after last noise point
1228  else if(t <= To) r = na.data[0]; // before first noise point
1229  else {
1230  if(t > T) {k++; T+=dT;}
1231  r = (na.data[k-1]*(dT-T+t) + na.data[k]*(T-t))/dT;
1232  }
1233  xx.data[j] *= abs(mode)<=1 ? DataType_t(1./r) : DataType_t(1./r/r);
1234  }
1235  this->putLayer(xx,(i+0.01)*m); // update layer in WSeries
1236 
1237  }
1238  return true;
1239 }
1240 
1241 template<class DataType_t>
1243 {
1244  size_t i;
1245  size_t M = maxLayer()+1;
1246  size_t k = 1<<n;
1247  double x;
1248 
1251  wavearray<double> v(M); // effective variance
1252 
1253  if(!pWavelet->BinaryTree()) { v = 1.; return v; }
1254  else { v = 0.; }
1255 
1256  Forward(n); // n decomposition steps
1257 
1258  for(i=0; i<M; i++){
1259  getLayer(a,i);
1260  b = a.white(1);
1261  x = b.data[0];
1262  v.data[i/k] += x>0. ? 1./x/x : 0.;
1263  putLayer(a,i);
1264  }
1265 
1266  Inverse(n); // n reconstruction steps
1267 
1268  for(i=0; i<v.size(); i++)
1269  v.data[i] = sqrt(k/v.data[i]);
1270 
1271  v.start(this->start());
1272 
1273  return v;
1274 }
1275 
1276 
1277 template<class DataType_t>
1279 {
1280  if(fl<0.) fl = this->getlow();
1281  if(fh<0.) fh = this->gethigh();
1282  double tsRate = this->rate();
1283 
1284  size_t i,j;
1285  size_t M = maxLayer()+1; // number of layers
1286  size_t N = this->size()/M; // zero layer length
1287  size_t ml = size_t(2.*M*fl/tsRate+0.5); // low layer
1288  size_t mh = size_t(2.*M*fh/tsRate+0.5); // high layer
1289 
1290  if(mh>M) mh = M;
1291 
1292  size_t nL = ml+int((mh-int(ml))/4.+0.5); // left sample (50%)
1293  size_t nR = mh-int((mh-int(ml))/4.+0.5); // right sample (50%)
1294  size_t n = size_t(fabs(t)*tsRate/M);
1295 
1296  DataType_t* p;
1297  DataType_t* pp[M]; // sorting
1298  size_t inDex[M]; // index(layer)
1299  size_t laYer[M]; // layer(index)
1300  WSeries<float> v; // effective variance
1301  WSeries<float> V; // variance correction
1302  slice S;
1303  v.resize(N);
1304 
1305  if(!pWavelet->BinaryTree() || mh<ml+8 || nL<1)
1306  { v = 1.; return v; }
1307  else { v = 0.; }
1308 
1309 // calculate frequency order of layers
1310 
1311  for(j=0; j<M; j++){
1312  S = getSlice(j);
1313  inDex[j] = S.start(); // index in the array (layer)
1314  laYer[inDex[j]] = j; // layer (index in the array)
1315  }
1316 
1317 // calculate variability for each wavelet collumn
1318 
1319  for(i=0; i<N; i++){
1320  p = this->data + i*M;
1321  for(j=0; j<M; j++){ pp[j] = &(p[inDex[j]]); }
1322  this->waveSplit(pp,ml,mh-1,nL-1); // left split
1323  this->waveSplit(pp,nL,mh-1,nR); // right split
1324  v.data[i] = float(*pp[nR] - *pp[nL-1])/2./0.6745;
1325  }
1326 
1327  v.start(this->start());
1328  v.rate(this->wrate());
1329  v.setlow(fl);
1330  v.sethigh(fl);
1331 
1332  if(n<2) return v;
1333 
1334 // calculate variability correction
1335 
1336  V=v; V-=1.;
1337  V.lprFilter(fabs(t),0,0.,fabs(t)+1.);
1338  v -= V;
1339 
1340 // correct variability
1341 
1342  p = this->data;
1343 
1344  for(i=0; i<N; i++){
1345  for(j=0; j<M; j++){
1346  if(laYer[j]>=ml && laYer[j]<mh) *p /= (DataType_t)v.data[i];
1347  p++;
1348  }
1349  }
1350 
1351  return v;
1352 }
1353 
1354 
1355 template<class DataType_t>
1356 double WSeries<DataType_t>::fraction(double t, double f, int mode)
1357 {
1358  slice S;
1359  DataType_t* p=NULL;
1360  register DataType_t* P=NULL;
1361  register DataType_t** pp;
1362  DataType_t A, aL, aR;
1363  size_t i,j,k;
1364  size_t nS, kS, nL, nR, lS;
1365  size_t nZero = 0;
1366  size_t n0 = 1;
1367  size_t nsub = t>0. ? size_t(this->size()/this->wrate()/t+0.1) : 1;
1368  long r;
1369 
1370  if(!nsub) nsub++;
1371 
1372  f = fabs(f);
1373  if((f>1. || bpp!=1.) && mode) {
1374  cout<<"WSeries fraction(): invalid bpp: "<<bpp<<" fraction="<<f<<endl;
1375  return bpp;
1376  }
1377  if(f>0.) bpp = f;
1378 
1379  size_t M = maxLayer()+1;
1380 
1381  n0 = 1;
1382  pp = (DataType_t **)malloc(sizeof(DataType_t*));
1384 
1385 // percentile fraction
1386 
1387  if(mode && f>0.){
1388  for(i=0; i<M; i++){
1389 
1390  S = getSlice(i);
1391  nS = S.size()/nsub; // # of samles in sub-interval
1392  kS = S.stride(); // stride for this layer
1393  lS = nS*nsub<S.size() ? S.size()-nS*nsub : 0; // leftover
1394 
1395 // loop over subintervals
1396 
1397  for(k=0; k<nsub; k++) {
1398 
1399  p = this->data + nS*k*kS + S.start(); // beginning of subinterval
1400 
1401  if(k+1 == nsub) nS += lS; // add leftover to last interval
1402 
1403  nL = nS&1 ? nS/2 : nS/2-1;
1404  nL = size_t(f*nL); // set left boundary
1405  nR = nS - nL - 1; // set right boundary
1406  if(nL<1 || nR>nS-1) {
1407  cout<<"WSeries::fraction() error: too short wavelet layer"<<endl;
1408  return 0.;
1409  }
1410 
1411  if(nS!=n0) { // adjust array length
1412  pp = (DataType_t **)realloc(pp,nS*sizeof(DataType_t*));
1413  a.resize(nS);
1414  n0 = nS;
1415  }
1416 
1417  for(j=0; j<nS; j++) pp[j] = p + j*kS;
1418 
1419  this->waveSplit(pp,0,nS-1,nL); // left split
1420  this->waveSplit(pp,nL,nS-1,nR); // right split
1421  aL = *pp[nL]; aR = *pp[nR];
1422 
1423  for(j=0; j<nS; j++){
1424  P = pp[j]; A = *P;
1425 
1426  if(j<nL) *P = (DataType_t)fabs(A - aL);
1427  else if(j>nR) *P = (DataType_t)fabs(A - aR);
1428  else { *P = 0; nZero++; }
1429 
1430  if(mode > 1) { // do initialization for scrambling
1431  a.data[j] = *P; // save data
1432  *P = 0; // zero sub-interval
1433  }
1434  }
1435 
1436  if(mode == 1) continue; // all done for mode=1
1437 
1438 // scramble
1439 
1440  for(j=0; j<nS; j++){
1441  if(a.data[j] == 0.) continue;
1442  do{ r = int(nS*drand48()-0.1);}
1443  while(p[r*kS] != 0);
1444  p[r*kS] = a.data[j];
1445  }
1446  }
1447  }
1448  }
1449 
1450  else if(f>0.){ // random fraction
1451  M = this->size();
1452  for(i=0; i<M; i++)
1453  if(drand48() > f) { this->data[i] = 0; nZero++; }
1454  }
1455 
1456  else{ // calculate zero coefficients
1457  M = this->size();
1458  for(i=0; i<M; i++) {
1459  if(this->data[i]==0.) nZero++;
1460  }
1461  }
1462 
1463  free(pp);
1464  return double(this->size()-nZero)/double(this->size());
1465 }
1466 
1467 
1468 template<class DataType_t>
1469 double WSeries<DataType_t>::significance(double T, double f)
1470 {
1471  slice S;
1472  DataType_t* p=NULL;
1473  DataType_t** pp;
1474  double tsRate = this->rate();
1475  size_t i,j,k,l,m;
1476  size_t nS,nP,nB;
1477  size_t M = maxLayer()+1;
1478  size_t il = size_t(2.*M*getlow()/tsRate);
1479  size_t ih = size_t(2.*M*gethigh()/tsRate+0.5);
1480  int nZero = 0;
1481  double ratio = double(this->size());
1482 
1483  if(ih>M) ih = M;
1484  if(il>=ih) {
1485  cout<<"WSeries::significance(): invalid low and high: ";
1486  cout<<"low = "<<il<<" high = "<<ih<<endl;
1487  il = 0;
1488  ih = M;
1489  }
1490 
1491 // zero unused layers
1492 
1493  for(i=0; i<M; i++){
1494 
1495  if(i>=il && i<=ih) continue;
1496 
1497  S = getSlice(i);
1498  k = S.size();
1499  m = S.stride();
1500  p = this->data+S.start();
1501  ratio -= double(k);
1502 
1503  for(j=0; j<k; j++) p[j*m] = 0;
1504  }
1505  ratio /= this->size(); // fraction of pixels between high and low
1506 
1507 // calculate number of sub-intervals
1508 
1509  S = getSlice(0); // layer 0
1510 
1511  size_t n = size_t(fabs(T)*tsRate/S.stride()/ratio+0.1); // number of towers
1512  if(n<1) n = S.size();
1513 
1514  k = S.size()/n; // number of sub-intervals
1515  m = this->size()/S.size(); // number of samples in each tower
1516 
1517  f = fabs(f);
1518  if(f>1.) f = 1.;
1519  if(f>0. && f<bpp) bpp = f;
1520  nS = n*m; // # of samples in one sub-interval
1521  nB = size_t(bpp*nS*ratio); // expected number of black pixels
1522 
1523  if(!nS || !nB || tsRate<=0. || m*S.size()!=this->size()) {
1524  cout<<"WSeries::significance() error: invalid parameters"<<endl;
1525  return 0.;
1526  }
1527 
1528  l = (S.size()-k*n)*m; // leftover
1529  if(l) k++; // add one more subinterval
1530 
1531 // cout<<"k="<<k<<" m="<<m<<" bpp="<<bpp<<" nS="<<nS<<endl;
1532 
1533  pp = (DataType_t **)malloc(nS*sizeof(DataType_t*));
1534 
1535  p = this->data;
1536 
1537  for(i=0; i<k; i++){
1538 
1539 // fill pp and a
1540 
1541  nP = 0;
1542 
1543  for(j=0; j<nS; j++) {
1544  if(*p == 0.) {p++; continue;}
1545  *p = (DataType_t)fabs(double(*p));
1546  pp[nP++] = p++;
1547  nZero++; // count non-Zero pixels
1548  }
1549 
1550  if(nP>2) this->waveSort(pp,0,nP-1); // sort black pixels
1551 
1552  for(j=0; j<nP; j++) {
1553  if(!i && l && pp[j]>=this->data+l) continue; // handle leftover
1554  *pp[j] = nP<nB ? (DataType_t)log(double(nP)/(nP-j)) :
1555  (DataType_t)log(double(nB)/(nP-j));
1556  if(*pp[j] < 0) {
1557  *pp[j] = 0;
1558  nZero--;
1559  }
1560  }
1561 
1562  p = this->data+i*nS+l;
1563  if(!l) p += nS;
1564  }
1565 
1566  free(pp);
1567  return double(nZero)/ratio/this->size();
1568 }
1569 
1570 
1571 template<class DataType_t>
1573 {
1574  DataType_t* p=NULL;
1575  DataType_t* px=NULL;
1576  DataType_t** pp;
1577  DataType_t** qq;
1578  DataType_t* xx;
1579  DataType_t* yy;
1580 
1581  double aL, aR;
1582 
1583  size_t i,j,m;
1584  size_t last, next;
1585  size_t nS,nB,nL,nR;
1586  size_t nBlack = 0;
1587  size_t index;
1588 
1589  slice S=getSlice(0); // layer 0
1590  size_t N = S.size(); // number of towers in WSeries
1591 
1592  m = this->size()/S.size(); // number of samples in each tower
1593 
1594  f = fabs(f);
1595  if(f>1.) f = 1.;
1596  if(f>0. && f<bpp) bpp = f;
1597  nS = (2*n+1)*m; // # of samples in one sub-interval
1598  nB = size_t(bpp*nS); // expected number of black pixels
1599  if(nB&1) nB++;
1600  nL = nB/2; // left bp boundary
1601  nR = nS - nL; // right bp boundary
1602 
1603  if(!nS || !nB || this->rate()<=0. || m*S.size()!=this->size()) {
1604  cout<<"WSeries::significance() error: invalid WSeries"<<endl;
1605  return 0.;
1606  }
1607 
1608  pp = (DataType_t **)malloc(nS*sizeof(DataType_t*));
1609  xx = (DataType_t *)malloc(nS*sizeof(DataType_t));
1610  qq = (DataType_t **)malloc(nS*sizeof(DataType_t*));
1611  yy = (DataType_t *)malloc(nS*sizeof(DataType_t));
1612 
1613  p = this->data;
1614  for(j=0; j<nS; j++){
1615  xx[j] = *p;
1616  pp[j] = xx+j;
1617  qq[j] = yy+j;
1618  *p++ = 0;
1619  }
1620  last = 0;
1621  next = 0;
1622 
1623  for(i=0; i<N; i++){
1624 
1625  this->waveSplit(pp,0,nS-1,nL-1); // left split
1626  this->waveSplit(pp,nL,nS-1,nR); // right split
1627  aL = *pp[nL]; aR = *pp[nR];
1628 
1629  for(j=0; j<nL; j++) yy[j] = (DataType_t)fabs(*pp[j] - aL);
1630  for(j=nR; j<nS; j++) yy[j+nL-nR] = (DataType_t)fabs(*pp[j] - aR);
1631 
1632  this->waveSort(qq,0,nB-1); // sort black pixels
1633 
1634  for(j=0; j<nB; j++) {
1635  index = qq[j]-yy; // index in yy
1636  if(index>nL) index+=nR-nL; // index in pp
1637  index = pp[index]-xx; // index in xx
1638  if(next != index/m) continue; // compare with current tower index in xx
1639  this->data[index-next*m+i*m] = (DataType_t)log(double(nB)/(nB-j));
1640  nBlack++;
1641  }
1642 
1643  if(i>=n && i<N-n) { // copy next tower into last
1644  px = xx+last*m;
1645  for(j=0; j<m; j++) { *(px++) = *p; *p++ = 0;}
1646  last++; // update last tower index in array xx
1647  }
1648 
1649  next++; // update current tower index in array xx
1650  if(next>2*n) next = 0;
1651  if(last>2*n) last = 0;
1652 
1653  }
1654 
1655  free(pp);
1656  free(qq);
1657  free(xx);
1658  free(yy);
1659 
1660  return double(nBlack)/double(this->size());
1661 }
1662 
1663 
1664 template<class DataType_t>
1665 double WSeries<DataType_t>::rSignificance(double T, double f, double t)
1666 {
1668 
1669  DataType_t* p=NULL;
1670  DataType_t* xx; // buffer for data
1671  DataType_t* yy; // buffer for black pixels
1672  DataType_t** px; // pointers to xx
1673  DataType_t** py; // pointers to yy
1674  DataType_t** pp; // pointers to this->data, so *pp[j] == xx[j]
1675 
1676  double aL, aR;
1677  double tsRate = this->rate();
1678 
1679  size_t i,j,m,l,J;
1680  size_t last, next;
1681  size_t nS,nB,nL,nR;
1682  size_t nBlack = 0;
1683  size_t index;
1684 
1685  size_t M = maxLayer()+1; // number of samples in a tower
1686  size_t il = size_t(2.*M*getlow()/tsRate);
1687  size_t ih = size_t(2.*M*gethigh()/tsRate+0.5);
1688 
1689  if(ih>M) ih = M;
1690  if(il>=ih) {
1691  cout<<"WSeries::significance(): invalid low and high: ";
1692  cout<<"low = "<<il<<" high = "<<ih<<endl;
1693  il = 0;
1694  ih = M;
1695  }
1696 
1697  m = ih-il; // # of analysis samples in a tower
1698 
1699  for(j=0; j<il; j++){ this->getLayer(wa,j); wa=1234567891.; this->putLayer(wa,j); }
1700  for(j=ih; j<M; j++){ this->getLayer(wa,j); wa=1234567891.; this->putLayer(wa,j); }
1701 
1702  t *= double(M)/m;
1703  T *= double(M)/m;
1704 
1705  slice S=getSlice(0); // layer 0
1706  size_t N = S.size(); // number of towers in WSeries
1707  size_t k = size_t(t*this->wrate()); // sliding step in towers
1708  size_t n = size_t(T*this->wrate()/2.); // 1/2 sliding window in towers
1709 
1710  if(t<=0. || k<1) k = 1;
1711  if(T<=0. || n<1) n = 1;
1712 
1713  size_t Nnk = N-n-k;
1714  size_t nW = (2*n+k)*M; // total # of samples in the window
1715 
1716  f = fabs(f);
1717  if(f>1.) f = 1.;
1718  if(f>0. && f<bpp) bpp = f;
1719  nS = (2*n+k)*m; // # of analysis samples in the window
1720  nB = size_t(bpp*nS); // expected number of black pixels
1721  if(nB&1) nB++;
1722  nL = nB/2; // left bp boundary
1723  nR = nS - nL; // right bp boundary
1724 
1725  if(!nS || !nB || this->rate()<=0. || M*S.size()!=this->size()) {
1726  cout<<"WSeries::significance() error: invalid WSeries"<<endl;
1727  return 0.;
1728  }
1729 
1730  pp = (DataType_t **)malloc(nS*sizeof(DataType_t*));
1731  px = (DataType_t **)malloc(nS*sizeof(DataType_t*));
1732  py = (DataType_t **)malloc(nS*sizeof(DataType_t*));
1733  xx = (DataType_t *)malloc(nS*sizeof(DataType_t));
1734  yy = (DataType_t *)malloc(nS*sizeof(DataType_t));
1735 
1736  p = this->data;
1737  J = 0;
1738  for(i=0; i<nW; i++){
1739  if(*p != 1234567891.){
1740  xx[J] = *p;
1741  pp[J] = p;
1742  px[J] = xx+J;
1743  py[J] = yy+J;
1744  J++;
1745  }
1746  *p++ = 0;
1747  }
1748  last = 0;
1749  next = 0;
1750 
1751  if(J != nS) {
1752  cout<<"wseries::rSignificance() error 1 - illegal sample count"<<endl;
1753  exit(0);
1754  }
1755 
1756  for(i=0; i<N; i+=k){
1757 
1758  this->waveSplit(px,0,nS-1,nL-1); // left split
1759  this->waveSplit(px,nL,nS-1,nR); // right split
1760  aL = *px[nL]; aR = *px[nR];
1761 
1762  for(j=0; j<nL; j++) yy[j] = (DataType_t)fabs(*px[j] - aL);
1763  for(j=nR; j<nS; j++) yy[j+nL-nR] = (DataType_t)fabs(*px[j] - aR);
1764 
1765  if(nB != nS-nR+nL) {
1766  cout<<"wseries::rSignificance: nB="<<nB<<", N="<<nS-nR+nL<<endl;
1767  nB = nS-nR+nL;
1768  }
1769 
1770  this->waveSort(py,0,nB-1); // sort black pixels
1771 
1772  for(j=0; j<nB; j++) { // save rank in *this
1773  index = py[j]-yy; // index in yy
1774  if(index>nL) index+=nR-nL; // index in xx
1775  index = px[index]-xx; // index in pp
1776  index = pp[index]-this->data; // index in WS data array
1777 
1778  if(index>=i*M && index<(i+k)*M) { // update pixels in window t
1779  if(this->data[index]!=0) {
1780  cout<<"WSeries::rSignificance error: "<<this->data[index]<<endl;
1781  }
1782  this->data[index] = DataType_t(log(double(nB)/(nB-j))); // save rank
1783  nBlack++;
1784  }
1785  }
1786 
1787  for(l=i; l<i+k; l++){ // copy towers
1788  if(l>=n && l<Nnk) { // copy next tower into last
1789  J = last*m; // pointer to last tower storage at xx
1790  for(j=0; j<M; j++) {
1791  if(*p != 1234567891.) { xx[J] = *p; pp[J++]=p; }
1792  *p++ = 0;
1793  }
1794  last++; // update last tower index in array xx
1795  if(J != last*m) {
1796  cout<<"wseries::rSignificance() error 2 - illegal sample count"<<endl;
1797  exit(0);
1798  }
1799  }
1800 
1801  next++; // update current tower index in array xx
1802  if(next==2*n+k) next = 0;
1803  if(last==2*n+k) last = 0;
1804  }
1805  }
1806 
1807  free(pp);
1808  free(px);
1809  free(py);
1810  free(xx);
1811  free(yy);
1812 
1813  return double(nBlack)/double(this->size());
1814 }
1815 
1816 
1817 
1818 template<class DataType_t>
1819 double WSeries<DataType_t>::gSignificance(double T, double f, double t)
1820 {
1822 
1823  DataType_t* p=NULL;
1824  DataType_t* xx; // buffer for data
1825  DataType_t* yy; // buffer for black pixels
1826  DataType_t** px; // pointers to xx
1827  DataType_t** py; // pointers to yy
1828  DataType_t** pp; // pointers to this->data, so *pp[j] == xx[j]
1829 
1830  double aL, aR;
1831 
1832  size_t i,j,m,l,J;
1833  size_t last, next;
1834  size_t nS,nB,nL,nR;
1835  size_t nBlack = 0;
1836  size_t index;
1837 
1838  size_t M = maxLayer()+1; // number of samples in a tower
1839  size_t il = size_t(2.*getlow()/this->wrate());
1840  size_t ih = size_t(2.*gethigh()/this->wrate()+0.5);
1841 
1842  if(ih>M) ih = M;
1843  if(il>=ih) {
1844  cout<<"WSeries::significance(): invalid low and high: ";
1845  cout<<"low = "<<il<<" high = "<<ih<<endl;
1846  il = 0;
1847  ih = M;
1848  }
1849 
1850  m = ih-il; // # of analysis samples in a tower
1851 
1852  for(j=0; j<il; j++){ this->getLayer(wa,j); wa=1234567891.; this->putLayer(wa,j); }
1853  for(j=ih; j<M; j++){ this->getLayer(wa,j); wa=1234567891.; this->putLayer(wa,j); }
1854 
1855  t *= double(M)/m;
1856  T *= double(M)/m;
1857 
1858  slice S=getSlice(0); // layer 0
1859  size_t N = S.size(); // number of towers in WSeries
1860  size_t k = size_t(t*this->wrate()); // sliding step in towers
1861  size_t n = size_t(T*this->wrate()/2.); // 1/2 sliding window in towers
1862 
1863  if(t<=0. || k<1) k = 1;
1864  if(T<=0. || n<1) n = 1;
1865 
1866  size_t Nnk = N-n-k;
1867  size_t nW = (2*n+k)*M; // total # of samples in the window
1868 
1869  f = fabs(f);
1870  if(f>1.) f = 1.;
1871  if(f>0. && f<bpp) bpp = f;
1872  nS = (2*n+k)*m; // # of analysis samples in the window
1873  nB = size_t(bpp*nS); // expected number of black pixels
1874  if(nB&1) nB++;
1875  nL = nB/2; // left bp boundary
1876  nR = nS - nL; // right bp boundary
1877 
1878  if(!nS || !nB || this->rate()<=0. || M*S.size()!=this->size()) {
1879  cout<<"WSeries::gSignificance() error: invalid WSeries"<<endl;
1880  return 0.;
1881  }
1882 
1883  pp = (DataType_t **)malloc(nS*sizeof(DataType_t*));
1884  px = (DataType_t **)malloc(nS*sizeof(DataType_t*));
1885  py = (DataType_t **)malloc(nS*sizeof(DataType_t*));
1886  xx = (DataType_t *)malloc(nS*sizeof(DataType_t));
1887  yy = (DataType_t *)malloc(nS*sizeof(DataType_t));
1888 
1889  p = this->data;
1890  J = 0;
1891  for(i=0; i<nW; i++){
1892  if(*p != 1234567891.){
1893  xx[J] = *p;
1894  pp[J] = p;
1895  px[J] = xx+J;
1896  py[J] = yy+J;
1897  J++;
1898  }
1899  *p++ = 0;
1900  }
1901  last = 0;
1902  next = 0;
1903 
1904  if(J != nS) {
1905  cout<<"wseries::gSignificance() error 1 - illegal sample count"<<endl;
1906  exit(0);
1907  }
1908 
1909  for(i=0; i<N; i+=k){
1910 
1911  this->waveSplit(px,0,nS-1,nL-1); // left split
1912  this->waveSplit(px,nL,nS-1,nR); // right split
1913  aL = *px[nL]; aR = *px[nR];
1914 
1915  for(j=0; j<nL; j++) yy[j] = (DataType_t)fabs(*px[j]);
1916  for(j=nR; j<nS; j++) yy[j+nL-nR] = (DataType_t)fabs(*px[j]);
1917 
1918  if(nB != nS-nR+nL) {
1919  cout<<"wseries::gSignificance: nB="<<nB<<", N="<<nS-nR+nL<<endl;
1920  nB = nS-nR+nL;
1921  }
1922 
1923  this->waveSort(py,0,nB-1); // sort black pixels
1924 
1925  for(j=0; j<nB; j++) { // save significance in *this
1926  index = py[j]-yy; // index in yy
1927  if(index>nL) index+=nR-nL; // index in pp
1928  index = px[index]-xx; // index in xx
1929  *(pp[index]) = pow(*py[j]+1.11/2,2)/2./1.07 + log(bpp); // save significance
1930  }
1931  nBlack += nB;
1932 
1933  for(l=i; l<i+k; l++){ // copy towers
1934  if(l>=n && l<Nnk) { // copy next tower into last
1935  J = last*m; // pointer to last tower storage at xx
1936  for(j=0; j<M; j++) {
1937  if(*p != 1234567891.) { xx[J] = *p; pp[J++]=p; }
1938  *p++ = 0;
1939  }
1940  last++; // update last tower index in array xx
1941  if(J != last*m) {
1942  cout<<"wseries::gSignificance() error 2 - illegal sample count"<<endl;
1943  exit(0);
1944  }
1945  }
1946 
1947  next++; // update current tower index in array xx
1948  if(next==2*n+k) next = 0;
1949  if(last==2*n+k) last = 0;
1950  }
1951  }
1952 
1953  free(pp);
1954  free(px);
1955  free(py);
1956  free(xx);
1957  free(yy);
1958 
1959  return double(nBlack)/double(this->size());
1960 }
1961 
1962 
1963 
1964 template<class DataType_t>
1966 {
1967  size_t k;
1968  size_t event = 0;
1969  int i, j, n;
1970  int nm, np, mp, mm;
1971 
1972  bool one;
1973 
1982 
1983  size_t max_layer = maxLayer()+1;
1984 
1985  pc = &ac; pp = &ap; pm = p = NULL;
1986  mp = mm = 1;
1987  getLayer(a,0);
1988  ac = a;
1989 
1990  for(k=1; k<=max_layer; k++){
1991 
1992  if(k<max_layer) getLayer(*pp,k); // next layer
1993  else pp = NULL;
1994 
1995  if(pp!=NULL) mp = pp->size()/pc->size(); // scale for upper layer
1996  if(pm!=NULL) mm = pc->size()/pm->size(); // scale for lower layer
1997 
1998  n = pc->size()-1;
1999 
2000  for(i=0; i<=n; i++) {
2001  one = true;
2002 
2003  if(pc->data[i] == 0.) continue;
2004  if(pc->data[i] > 9.7) cout<<"pixclean: "<<pc->data[i]<<endl;
2005  event++;
2006  if(i>0 && pc->data[i-1]!=0.) continue;
2007  if(i<n && pc->data[i+1]!=0.) continue;
2008 
2009 // work on upper (+) layer
2010 
2011  if(pp!=NULL) {
2012  nm = i*mp-1; // left index for + layer
2013  np = i*mp+2; // right index for + layer
2014  if(nm < 0) nm = 0;
2015  if(np > n) np = n;
2016 
2017  for(j=nm; j<np; j++) {
2018  if(pp->data[j] != 0) {
2019  one = false;
2020  break;
2021  }
2022  }
2023  }
2024  if(!one) continue;
2025 
2026 // work on lower (-) layer
2027 
2028  if(pm!=NULL) {
2029  nm = i/mm-1; // left index for + layer
2030  np = i/mm+2; // right index for + layer
2031  if(nm < 0) nm = 0;
2032  if(np > n) np = n;
2033 
2034  for(j=nm; j<np; j++) {
2035  if(pm->data[j] != 0) {
2036  one = false;
2037  break;
2038  }
2039  }
2040  }
2041  if(!one) continue;
2042 
2043  if(pc->data[i]<S) {a.data[i]=0; event--;}
2044  }
2045 
2046  putLayer(a,k-1);
2047 
2048 // shaffle layers
2049 
2050  if(pp==NULL) break;
2051 
2052  a = *pp;
2053  p = pm==NULL ? &am : pm;
2054  pm = pc;
2055  pc = pp;
2056  pp = p;
2057  }
2058 
2059  return double(event)/this->size();
2060 }
2061 
2062 
2063 template<class DataType_t>
2065 {
2066  slice S;
2067  DataType_t* p=NULL;
2068  register DataType_t* P=NULL;
2069  register DataType_t** pp;
2070  double A, aL, aR;
2071  double x;
2072  size_t i,j;
2073  size_t nS, kS, mS, nL, nR;
2074  size_t nZero = 0;
2075  long r;
2076 
2077  f = fabs(f);
2078  if((f>=1. || bpp!=1.) && mode) {
2079  cout<<"WSeries percentile(): invalid bpp: "<<bpp<<" fraction="<<f<<endl;
2080  return bpp;
2081  }
2082  bpp = f;
2083 
2084  if(pin) *this = *pin; // copy input wavelet if specified
2085 
2086  size_t M = maxLayer()+1;
2087  WaveDWT<DataType_t>* pw = pWavelet;
2088 
2089  S=pw->getSlice(0);
2090  size_t n0 = S.size();
2091  if(n0) pp = (DataType_t **)malloc(n0*sizeof(DataType_t*));
2092  else return 0.;
2093 
2096 
2097  if(mode && f>0.){ // percentile fraction
2098  for(i=0; i<M; i++){
2099 
2100  S = pw->getSlice(i);
2101  nS = S.size();
2102  kS = S.stride();
2103  mS = S.start();
2104  p = this->data+S.start();
2105  nL = size_t(f*nS/2.+0.5);
2106  nR = nS - nL;
2107 
2108  if(nL<2 || nR>nS-2) {
2109  cout<<"WSeries::percentile() error: too short wavelet layer"<<endl;
2110  return 0.;
2111  }
2112 
2113  if(nS!=n0) {
2114  pp = (DataType_t **)realloc(pp,nS*sizeof(DataType_t*));
2115  a.resize(nS);
2116  }
2117 
2118  for(j=0; j<nS; j++) pp[j] = p + j*kS;
2119 
2120  this->waveSplit(pp,0,nS-1,nL-1); // left split
2121  this->waveSplit(pp,nL,nS-1,nR); // right split
2122  aL = double(*pp[nL-1]); aR = double(*pp[nR]);
2123 
2124  for(j=0; j<nS; j++){
2125  P = pp[j]; A = double(*P);
2126 
2127 // if(j<nL) *P = -sqrt(A*A - aL*aL);
2128 // else if(j>nR) *P = sqrt(A*A - aR*aR);
2129 
2130  if(j<nL) *P = DataType_t(fabs(A - aL));
2131  else if(j>nR) *P = DataType_t(fabs(A - aR));
2132  else { *P = 0; nZero++; }
2133 
2134  if(mode == -1) continue; // all done for mode = -1
2135  if(pin) pin->data[mS+P-p] = *P; // update pin slice
2136  if(j>nL && j<nR) continue; // skip zero amplitudes
2137  a.data[(P-p)/kS] = *P; // save data
2138  if(j<nL) *P *= -1; // absolute value
2139  if(j>=nR) pp[nL+j-nR] = P; // copy right sample
2140  }
2141 
2142  if(mode == -1) continue; // keep wavelet amplitudes
2143 
2144  nL *= 2;
2145  this->waveSort(pp,0,nL-1); // sort black pixels
2146 
2147  if(abs(mode)!=1) b = a;
2148 
2149  for(j=0; j<nL; j++){
2150  r = (pp[j]-p)/kS;
2151 // x = a.data[r]<0. ? -double(nL)/(nL-j) : double(nL)/(nL-j);
2152  x = log(double(nL)/(nL-j));
2153  *pp[j] = mode==1 ? DataType_t(x) : 0;
2154  if(mode>1) a.data[r]=DataType_t(x); // save data for random sample
2155  }
2156 
2157  if(abs(mode)==1) continue;
2158 
2159 // scramble
2160 
2161  for(j=0; j<nL; j++){
2162  P = pp[j];
2163  do{ r = int(nS*drand48()-0.1);}
2164  while(p[r*kS] != 0);
2165  p[r*kS] = a.data[(P-p)/kS];
2166  if(pin) pin->data[mS+r*kS] = b.data[(P-p)/kS];
2167  }
2168  }
2169  }
2170 
2171  else if(f>0.){ // random fraction
2172  M = this->size();
2173  for(i=0; i<M; i++)
2174  if(drand48() > f) { this->data[i] = 0; nZero++; }
2175  }
2176 
2177  else{ // calculate zero coefficients
2178  M = this->size();
2179  for(i=0; i<M; i++)
2180  if(this->data[i]==0) nZero++;
2181  }
2182 
2183  free(pp);
2184  return double(this->size()-nZero)/double(this->size());
2185 }
2186 
2187 
2188 template<class DataType_t>
2190  d_complex* R, d_complex* C,
2193  size_t channel)
2194 {
2195  size_t i,k,m,N;
2196  size_t count, step;
2197  size_t M = maxLayer()+1;
2198 
2199  double tsRate = this->rate();
2200  double left, righ;
2201  double tleft, trigh;
2202  double reH, imH;
2203  double c, t, dt;
2204  double cstep = 1./a.rate();
2205  double sTart = this->start();
2206  double sTop = this->start()+this->size()/tsRate;
2207  DataType_t* p;
2208  slice S;
2209 
2210  wavecomplex* pR=R;
2211  wavecomplex* pC=C;
2212 
2213  Wavelet* pw = pWavelet->Clone();
2214  wavearray<double> alp;
2215  wavearray<double> gam;
2216  wavearray<double> reR(M);
2217  wavearray<double> reC(M);
2218  wavearray<double> imR(M);
2219  wavearray<double> imC(M);
2220 
2221  alp = a; alp.start(0.);
2222  gam = a; gam.start(0.);
2223 
2224 // select alpha to be in WB segment
2225  count=0;
2226  for(i=0; i<a.size(); i++) {
2227  if(a.start()+i/a.rate() < sTart) continue; // skip samples in front
2228  if(a.start()+i/a.rate() > sTop) break; // skip samples in the back
2229  if(alp.start()==0.) alp.start(a.start()+i/a.rate());
2230  alp.data[count++] = a.data[i];
2231  }
2232  alp.resize(count);
2233 
2234 // select gamma to be in WB segment
2235  count=0;
2236  for(i=0; i<g.size(); i++) {
2237  if(g.start()+i/g.rate() < sTart) continue; // skip samples in front
2238  if(g.start()+i/g.rate() > sTop) break; // skip samples in the back
2239  if(gam.start()==0.) gam.start(g.start()+i/g.rate());
2240  gam.data[count++] = g.data[i];
2241  }
2242  gam.resize(count);
2243 
2244  if(gam.size()>alp.size()) gam.resize(alp.size());
2245  if(gam.size()<alp.size()) alp.resize(gam.size());
2246 
2247  wavearray<double> x(M*alp.size());
2248  WSeries<double> cal(x,*pw);
2249 
2250  if(!alp.size() || a.rate()!=g.rate()) {
2251  cout<<"WSeries<DataType_t>::calibrate() no calibration data\n";
2252  return cal;
2253  }
2254 
2255  cal = 0.;
2256  left = righ = 0.;
2257 
2258  reR = 0.; reC = 0.;
2259  imR = 0.; imC = 0.;
2260  for(k=0; k<M; k++){
2261 
2262  S = getSlice(k);
2263  left = righ; // left border
2264  righ += tsRate/2./S.stride(); // right border
2265  if(righ > n*df) break;
2266 
2267 // average R and C
2268 
2269  count = 0;
2270  while(left+count*df < righ){
2271  reR.data[k] += pR->real();
2272  imR.data[k] += pR->imag();
2273  reC.data[k] += pC->real();
2274  imC.data[k] += pC->imag();
2275  count++; pR++; pC++;
2276  }
2277  reR.data[k] /= count; reC.data[k] /= count;
2278  imR.data[k] /= count; imC.data[k] /= count;
2279 
2280 // calculate calibration constants
2281 
2282  cal.getLayer(x,k);
2283  for(i=0; i<alp.size(); i++){
2284 
2285  if(alp.data[i]<=0. || gam.data[i]<=0.) {
2286  cout<<"WSeries<DataType_t>::calibrate() zero alpha error\n";
2287  alp.data[i] = 1.;
2288  gam.data[i] = 1.;
2289  }
2290 
2291  reH = reR.data[k]*reC.data[k]-imR.data[k]*imC.data[k];
2292  imH = reR.data[k]*imC.data[k]+imR.data[k]*reC.data[k];
2293  reH = 1.+(reH-1.)*gam.data[i];
2294  imH*= gam.data[i];
2295  x.data[i] = sqrt(reH*reH+imH*imH);
2296  x.data[i] /= sqrt(reC.data[k]*reC.data[k]+imC.data[k]*imC.data[k]);
2297  x.data[i] /= channel==0 ? alp.data[i] : gam.data[i];
2298  }
2299  cal.putLayer(x,k);
2300 
2301 // apply energy calibration
2302 
2303  S = getSlice(k);
2304  step = S.stride();
2305  N = S.size();
2306  p = this->data + S.start();
2307  dt = step/tsRate; // sampling time interval
2308  t = this->start(); // time stamp
2309  sTart = alp.start(); // first calibration point
2310  sTop = alp.start()+(alp.size()-1)*cstep; // last calibration sample
2311 
2312  tleft = sTart; // left and right borders defining beginning and end
2313  trigh = sTart+cstep; // of the current calibration cycle.
2314  m = 0;
2315 
2316  for(i=0; i<N; i++){
2317  t += dt;
2318  if(t <= sTart) *p *= (DataType_t)x.data[0];
2319  else if(t >= sTop) *p *= (DataType_t)x.data[alp.size()-1];
2320  else {
2321  if(t>trigh) { tleft=trigh; trigh+=cstep; m++; }
2322  c = (t-tleft)/cstep;
2323  *p *= DataType_t(x.data[m]*(1-c) + x.data[m+1]*c);
2324  }
2325  p += step;
2326  }
2327 
2328  }
2329 
2330  return cal;
2331 }
2332 
2333 template<class DataType_t>
2335 {
2336  pWavelet->print();
2338 }
2339 
2340 //______________________________________________________________________________
2341 template <class DataType_t>
2342 void WSeries<DataType_t>::Streamer(TBuffer &R__b)
2343 {
2344  // Stream an object of class WSeries<DataType_t>.
2345 
2346  UInt_t R__s, R__c;
2347  if (R__b.IsReading()) {
2348  Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
2350  R__b >> w_mode;
2351  R__b >> bpp;
2352  R__b >> wRate;
2353  R__b >> f_low;
2354  R__b >> f_high;
2355 
2356  bool bWWS;
2357  int m_WaveType;
2358  R__b >> m_WaveType;
2359  R__b >> bWWS;
2360  if(!bWWS) m_WaveType=-1;
2361  WaveDWT<DataType_t> *pW;
2362  switch(m_WaveType) {
2363  case HAAR :
2364  pW = (WaveDWT<DataType_t>*)(new Haar<DataType_t>);
2365  break;
2366  case BIORTHOGONAL :
2368  break;
2369  case DAUBECHIES :
2371  break;
2372  case SYMLET :
2374  break;
2375  case MEYER :
2376  pW = (WaveDWT<DataType_t>*)(new Meyer<DataType_t>);
2377  break;
2378  case WDMT :
2379  pW = (WaveDWT<DataType_t>*)(new WDM<DataType_t>);
2380  break;
2381  default :
2382  pW = new WaveDWT<DataType_t>;
2383  }
2384  pW->Streamer(R__b);
2385  this->setWavelet(*pW);
2386  delete pW;
2387 
2388  R__b.CheckByteCount(R__s, R__c, WSeries<DataType_t>::IsA());
2389  } else {
2390  R__c = R__b.WriteVersion(WSeries<DataType_t>::IsA(), kTRUE);
2392  R__b << w_mode;
2393  R__b << bpp;
2394  R__b << wRate;
2395  R__b << f_low;
2396  R__b << f_high;
2397 
2398  R__b << pWavelet->m_WaveType;
2399  bool bWWS = ((pWavelet->pWWS==NULL)&&(pWavelet->m_WaveType==HAAR)) ? false : true;
2400  R__b << bWWS;
2401  pWavelet->Streamer(R__b);
2402  R__b.SetByteCount(R__c, kTRUE);
2403  }
2404 }
2405 
2406 // instantiations
2407 
2408 #define CLASS_INSTANTIATION(class_) template class WSeries< class_ >;
2409 
2410 CLASS_INSTANTIATION(float)
2411 CLASS_INSTANTIATION(double)
2412 
2413 #undef CLASS_INSTANTIATION
2414 
wavearray< double > t(hp.size())
void mul(WSeries< DataType_t > &)
Definition: wseries.cc:117
void sethigh(double f)
Definition: wseries.hh:114
double pc
Definition: DrawEBHH.C:15
tfmap Forward(ts, wdm)
virtual void resize(unsigned int)
Definition: wseries.cc:883
double f_low
Definition: wseries.hh:446
double f_high
Definition: wseries.hh:448
virtual size_t size() const
Definition: wavearray.hh:127
static const double C
Definition: GNGen.cc:10
double gammaCL(double x, double n)
Definition: watfun.hh:113
double imag() const
Definition: wavecomplex.hh:52
int layer(double f)
Definition: wseries.cc:149
static double g(double e)
Definition: GNGen.cc:98
Definition: Wavelet.hh:26
par[0] value
int getMaxLevel()
Definition: wseries.cc:85
tuple f
Definition: cwb_online.py:91
fprintf(stdout,"start=%f duration=%f rate=%f\n", x.start(), x.size()/x.rate(), x.rate())
int offset
Definition: TestSTFT_2.C:19
virtual void rate(double r)
Definition: wavearray.hh:123
#define np
wavearray< double > a(hp.size())
virtual double percentile(double=0., int=0, WSeries< DataType_t > *=NULL)
param: f - black pixel fraction param: m - mode options: f = 0 - returns black pixel occupancy m = 1 ...
Definition: wseries.cc:2064
WSeries< float > v[nIFO]
Definition: cwb_net.C:62
virtual void edge(double s)
Definition: wavearray.hh:125
virtual WSeries< float > variability(double=0., double=-1., double=-1.)
param: first - time window to calculate normalization constants second - low frequency boundary for c...
Definition: wseries.cc:1278
#define B
int n
Definition: cwb_net.C:10
virtual WSeries< DataType_t > & operator+=(WSeries< DataType_t > &)
Definition: wseries.cc:778
void print()
Definition: wavearray.cc:2203
tfmap getLayer(tmp, 0)
void bandpass(wavearray< DataType_t > &ts, double flow, double fhigh, int n=-1)
Definition: wseries.cc:295
int count
Definition: compare_bkg.C:373
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 frequency
wavearray< DataType_t > & operator=(const wavearray< DataType_t > &)
Definition: wavearray.cc:92
double bpp
Definition: test_config1.C:22
virtual double rSignificance(double, double=1., double=0.)
param: T - sliding window duration in seconds param: f - black pixel fraction param: t - sliding step...
Definition: wseries.cc:1665
void setlow(double f)
Definition: wseries.hh:107
TRandom3 P
Definition: compare_bkg.C:296
double real() const
Definition: wavecomplex.hh:51
STL namespace.
std::slice getSlice(double n)
Definition: wseries.hh:134
virtual wavearray< DataType_t > & operator*=(wavearray< DataType_t > &)
Definition: wavearray.cc:258
Long_t size
virtual double median(size_t=0, size_t=0) const
Definition: wavearray.cc:1558
bool allocate(size_t, DataType_t *)
Definition: WaveDWT.cc:185
#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
i drho i
virtual WSeries< DataType_t > & operator*=(WSeries< DataType_t > &)
Definition: wseries.cc:753
double Edge
Definition: wavearray.hh:309
S setLevel(2)
#define N
tuple ff
Definition: cwb_online.py:394
cout<< "Selected Pixels : "<< nPix<< endl;wc.cluster(1, 1);SSeries< double > ss
virtual double significance(double, double=1.)
param: n - sub-interval duration in seconds param: f - black pixel fraction options: f = 0 - returns ...
Definition: wseries.cc:1469
double wRate
Definition: wseries.hh:444
void setWavelet(const Wavelet &w)
Definition: wseries.cc:216
size_t mode
wavearray< double > w
Definition: Test1.C:27
void wrate(double r)
Definition: wseries.hh:102
size_t wavecount(double x, int n=0)
Definition: wavearray.hh:286
double time[6]
Definition: cbc_plots.C:435
double getlow() const
Definition: wseries.hh:111
wavearray< double > xx
Definition: TestFrame1.C:11
double getbpp() const
Definition: wseries.hh:99
size_t w_mode
Definition: wseries.hh:440
virtual double gSignificance(double, double=1., double=0.)
param: T - sliding window duration in seconds param: f - black pixel fraction param: t - sliding step...
Definition: wseries.cc:1819
virtual wavearray< double > filter(size_t)
param: n - number of decomposition steps algorithm: 1) do forward wavelet transform with n decomposit...
Definition: wseries.cc:1242
int pattern
size_t size() const
Definition: wslice.hh:71
wavearray< double > * px
double maxEnergy(wavearray< DataType_t > &ts, Wavelet &w, double=0, int=1, int=0, TH1F *=NULL)
Definition: wseries.cc:486
virtual WSeries< DataType_t > & operator-=(WSeries< DataType_t > &)
Definition: wseries.cc:802
i() int(T_cor *100))
TF1 * f2
Definition: cbc_plots.C:1710
virtual double fraction(double=0., double=0., int=0)
param: t - sub interval duration. If can not divide on integer
Definition: wseries.cc:1356
x resize(N)
bool log
Definition: WaveMDC.C:41
double fhigh
double * tmp
Definition: testWDM_5.C:31
int getLayer(wavearray< DataType_t > &w, double n)
param: n - layer number
Definition: wseries.cc:175
TIter next(twave->GetListOfBranches())
char fname[1024]
Definition: Wavelet.hh:31
#define CLASS_INSTANTIATION(class_)
Definition: wseries.cc:2408
std::slice Slice
Definition: wavearray.hh:310
Definition: Wavelet.hh:30
virtual double coincidence(WSeries< DataType_t > &, int=0, int=0, double=0.)
param: WSeries object used for coincidence param: coincidence window in seconds return pixel occupanc...
Definition: wseries.cc:911
int k
virtual wavearray< DataType_t > & operator+=(wavearray< DataType_t > &)
Definition: wavearray.cc:173
static double A
Definition: geodesics.cc:8
ss Inverse()
int Rate
double F
std::vector< double > vR
double e
wavearray< double > yy
Definition: TestFrame5.C:12
Definition: Haar.hh:20
double gethigh() const
Definition: wseries.hh:118
double dt
regression r
Definition: Regression_H1.C:44
s s
Definition: cwb_net.C:137
double flow
virtual ~WSeries()
Definition: wseries.cc:76
virtual WSeries< DataType_t > & operator[](const std::slice &)
Definition: wseries.cc:713
Definition: WDM.hh:24
void wavescan(WSeries< DataType_t > **, int, TH1F *=NULL)
Definition: wseries.cc:604
double T
Definition: testWDM_4.C:11
virtual Wavelet * Clone() const
return: Wavelet* - duplicate of *this, allocated on heap
Definition: Wavelet.cc:42
virtual void lprFilter(wavearray< double > &)
Definition: wavearray.cc:1808
Definition: Symlet.hh:20
ifstream in
virtual std::slice getSlice(const double)
Definition: WaveDWT.cc:111
wavearray< double > ts(N)
WSeries()
Definition: wseries.cc:23
wavearray< int > index
virtual void resample(double, int=6)
Definition: wseries.cc:897
Definition: Meyer.hh:18
virtual wavearray< double > white(double, int=0, double=0., double=0.) const
Definition: wavearray.cc:2002
virtual void stop(double s)
Definition: wavearray.hh:121
virtual wavearray< DataType_t > & operator-=(wavearray< DataType_t > &)
Definition: wavearray.cc:208
double fabs(const Complex &x)
Definition: numpy.cc:37
void print()
param: int n if n<0, zero pixels defined in mask (regression) if n>=0, zero all pixels except ones de...
Definition: wseries.cc:2334
virtual void spesla(double, double, double=0.)
Definition: wavearray.cc:1752
double resolution(int=0)
Definition: wseries.hh:137
double Gamma2Gauss(TH1F *=NULL)
Definition: wseries.cc:558
virtual double Coincidence(WSeries< DataType_t > &, double=0., double=0.)
param: WSeries object used for coincidence param: coincidence window in seconds param: threshold on s...
Definition: wseries.cc:1002
double Q
virtual void lprFilter(double, int=0, double=0., double=0.)
Definition: wseries.cc:1108
void Forward(int n=-1)
param: wavelet - n is number of steps (-1 means full decomposition)
Definition: wseries.cc:228
strcpy(RunLabel, RUN_LABEL)
Meyer< double > S(1024, 2)
double df
int l
Definition: cbc_plots.C:434
virtual void median(double t, bool norm=false)
Definition: wseries.cc:1091
WSeries< DataType_t > & operator=(const wavearray< DataType_t > &)
Definition: wseries.cc:684
virtual double pixclean(double=0.)
param: S - threshold on pixel significance return pixel occupancy.
Definition: wseries.cc:1965
DataType_t * data
Definition: wavearray.hh:301
enum WAVETYPE m_WaveType
Definition: Wavelet.hh:88
WaveDWT< DataType_t > * pWavelet
Definition: wseries.hh:438
double wdmPacket(int pattern, char opt='L', TH1F *=NULL)
Definition: wseries.cc:358
double dT
Definition: testWDM_5.C:12
fclose(ftrig)
size_t stride() const
Definition: wslice.hh:75
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
virtual void waveSplit(DataType_t **pp, size_t l, size_t r, size_t m) const
Definition: wavearray.cc:1481
wavearray< double > y
Definition: Test10.C:31
void putLayer(wavearray< DataType_t > &, double n)
param: n - layer number
Definition: wseries.cc:201
virtual void Dump(const char *, int=0)
Definition: wseries.cc:849
char pm[8]
struct overlaps * data
Definition: WDMOverlap.hh:12
double frequency(int l)
Definition: wseries.cc:99
size_t start() const
Definition: wslice.hh:67
int maxLayer()
Definition: wseries.hh:121
virtual double rsignificance(size_t=0, double=1.)
param: n - sub-interval duration in domain units param: f - black pixel fraction options: f = 0 - ret...
Definition: wseries.cc:1572
double bpp
Definition: wseries.hh:442
virtual WSeries< double > calibrate(size_t, double, d_complex *, d_complex *, wavearray< double > &, wavearray< double > &, size_t ch=0)
param: number of samples in calibration arrays R & C param: frequency resolution param: pointer to re...
Definition: wseries.cc:2189
exit(0)
void cpf(const wavearray< DataType_t > &, int=0, int=0, int=0)
Definition: wavearray.cc:699
virtual WSeries< double > white(double, int, double=0., double=0.)
what it does: each wavelet layer is devided into k intervals.
Definition: wseries.cc:1128
double avr