Logo coherent WaveBurst  
Library Reference Guide
Logo
gwavearray.cc
Go to the documentation of this file.
1 /*
2 # Copyright (C) 2019 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 #include "gwavearray.hh"
20 
21 ClassImp(gwavearray<double>)
22 
23 //______________________________________________________________________________
24 /* Begin_Html
25 <center><h2>gwavearray class</h2></center>
26 This class gwavearray is derived from the wavearray class
27 It is used to produce time,freq and time-freq plots of a signal stored in a wavearray structure.
28 
29 <p>
30 <h3><a name="example">Example</a></h3>
31 <p>
32 The macro <a href="./tutorials/gwat/DrawGWaveArray.C.html">DrawGWaveArray.C</a> is an example which shown how to use the gWaveArray class.<br>
33 The pictures below gives the macro output plots.<br>
34 <p>
35 
36 End_Html
37 
38 Begin_Macro
39 DrawGWaveArray.C
40 End_Macro */
41 
42 using namespace std;
43 
44 
45 //______________________________________________________________________________
46 // destructor
47 template<class DataType_t>
49 {
50  if(wextern) this->data = NULL;
51 
52  if(stft!=NULL) delete stft;
53  if(pts!=NULL) delete pts;
54 }
55 
56 //______________________________________________________________________________
57 template<class DataType_t>
59 wavearray<DataType_t>(w) {Init();wextern=false;}
60 
61 //______________________________________________________________________________
62 template<class DataType_t>
64 {
65  Init();
66  wextern = true;
67 
68  this->data = w->data;
69  this->Rate = w->rate();
70  this->Size = w->size();
71  this->Start = w->start();
72  this->Stop = w->start() + w->size()/w->rate();
73  this->Slice = std::slice(0,w->size(),1);
74 }
75 
76 //______________________________________________________________________________
77 template<class DataType_t>
79 
80  gRandom->SetSeed(0);
81  tMin=0;
82  tMax=0;
83 
84  stft=NULL;pts=NULL;
85 }
86 
87 //______________________________________________________________________________
88 template<class DataType_t>
90 //
91 // Draw waveform in time/frequency domain
92 //
93 // Input:
94 // type - GWAT_TIME, GWAT_FFT, GWAT_TF
95 // options - graphic options
96 // color - option for GWAT_TIME, GWAT_FFT
97 //
98 
99  return Draw(NULL,type,options,color);
100 }
101 
102 //______________________________________________________________________________
103 template<class DataType_t>
105 //
106 // Draw waveform in time/frequency domain
107 //
108 // Input:
109 // wavearray - data array
110 // type - GWAT_TIME, GWAT_FFT, GWAT_TF
111 // options - graphic options
112 // color - option for GWAT_TIME, GWAT_FFT
113 //
114 
115  if(type==GWAT_TIME) DrawTime(x,options,color);
116  if(type==GWAT_FFT) DrawFFT(x,options,color);
117  if(type==GWAT_TF) DrawTF(x,options);
118  if(type==GWAT_SG) cout << "gwavearray<DataType_t>::Draw - Error : draw type "
119  << "GWAT_SG" << " not allowed" << endl;
120 }
121 
122 //______________________________________________________________________________
123 template<class DataType_t>
125 //
126 // Draw waveform in time domain
127 //
128 // Input:
129 // options - draw options (same as TGraph)
130 // if contains FULL the full interval is showed
131 //
132 // return pointer to watplot object
133 //
134 
135  return DrawTime(NULL,options,color);
136 }
137 
138 //______________________________________________________________________________
139 template<class DataType_t>
141 //
142 // Draw waveform in time domain
143 //
144 // Input:
145 // wavearray - data array
146 // options - draw options (same as TGraph)
147 // if contains FULL the full interval is showed
148 //
149 // return pointer to watplot object
150 //
151 
152  if(this->rate()<=0) {
153  cout << "gwavearray::DrawTime : Error - rate must be >0" << endl;
154  exit(1);
155  }
156 
157  options.ToUpper();
158  if(stft!=NULL) delete stft;
159  if(options.Contains("SAME")&&(pts!=NULL)) {
160  } else {
161  if(pts!=NULL) delete pts;
162  char name[32];sprintf(name,"TIME-gID:%d",int(gRandom->Rndm(13)*1.e9));
163  pts = new watplot(const_cast<char*>(name),200,20,800,500);
164  }
165  double tStart,tStop;
166  if(options.Contains("FULL")) {
167  options.ReplaceAll("FULL","");
168  tStart=this->start();
169  tStop=this->start()+this->size()/this->rate();
170  tStop-=this->start();tStart-=this->start();
171  } else if(options.Contains("CUSTOM")) {
172  options.ReplaceAll("CUSTOM","");
173  tStart=this->start();
174  tStop=this->start()+this->size()/this->rate();
175  tStart = tMin>tStart&&tMin<tStop ? tMin : tStart;
176  tStop = tMax>tStart&&tMax<tStop ? tMax : tStop;
177  tStop-=this->start();tStart-=this->start();
178  } else {
179  GetTimeRange(tStart, tStop);
180  }
182  if(x!=NULL) waveAssign(tf,*x);
183  else waveAssign(tf,*this);
184  char title[256];
185  sprintf(title,"START : %10.3f (gps) - LENGHT : %g (sec) - RATE : %g (hz)",
186  tf.start()+tStart,tStop-tStart,tf.rate());
187  if(!options.Contains("SAME")) {
188  tSave=tf.start(); // save start time of first plot
189  tf.start(0);
190  } else {
191  tf.start(tf.start()-tSave);
192  }
193  if(!options.Contains("SAME")) options=options+TString(" ALP");
194  options.ReplaceAll(" ","");
195  pts->plot(tf, const_cast<char*>(options.Data()), color, tStart, tStop);
196  pts->graph[pts->graph.size()-1]->SetTitle(title);
197 
198  return pts;
199 }
200 
201 //______________________________________________________________________________
202 template<class DataType_t>
204 //
205 // Draw waveform spectrum
206 //
207 // Input:
208 // wavearray - data array
209 // options - draw options (same as TGraph)
210 // if contains FULL the full interval is showed
211 // if contains NOLOGX/NOLOGY X/Y axis are linear
212 //
213 // return pointer to watplot object
214 //
215 
216  return DrawFFT(NULL,options,color);
217 }
218 
219 //______________________________________________________________________________
220 template<class DataType_t>
222 //
223 // Draw waveform spectrum
224 //
225 // Input:
226 // wavearray - data array
227 // options - draw options (same as TGraph)
228 // if contains FULL the full interval is showed
229 // if contains NOLOGX/NOLOGY X/Y axis are linear
230 //
231 // return pointer to watplot object
232 //
233 
234  options.ToUpper();
235  if(stft!=NULL) delete stft;
236  if(options.Contains("SAME")&&(pts!=NULL)) {
237  } else {
238  if(pts!=NULL) delete pts;
239  char name[32];sprintf(name,"FFT-gID:%d",int(gRandom->Rndm(13)*1.e9));
240  pts = new watplot(const_cast<char*>(name),200,20,800,500);
241  }
242 
243  double fLow = 4.;
244  double fHigh = this->rate()/2.;
245  double tStart,tStop;
246  bool psd = options.Contains("PSD") ? true : false;
247  options.ReplaceAll("PSD","");
248  if(options.Contains("FULL")) {
249  options.ReplaceAll("FULL","");
250  tStart=this->start();
251  tStop=this->start()+this->size()/this->rate();
252  tStop-=this->start();tStart-=this->start();
253  } else if(options.Contains("CUSTOM")) {
254  options.ReplaceAll("CUSTOM","");
255  tStart=this->start();
256  tStop=this->start()+this->size()/this->rate();
257  tStart = tMin>tStart&&tMin<tStop ? tMin : tStart;
258  tStop = tMax>tStart&&tMax<tStop ? tMax : tStop;
259  tStop-=this->start();tStart-=this->start();
260  } else {
261  GetTimeRange(tStart, tStop);
262  }
263  bool logx = true;
264  if(options.Contains("NOLOGX")) {logx=false;options.ReplaceAll("NOLOGX","");}
265  bool logy = true;
266  if(options.Contains("NOLOGY")) {logy=false;options.ReplaceAll("NOLOGY","");}
268  if(x!=NULL) waveAssign(tf,*x);
269  else waveAssign(tf,*this);
270  // use only the selected range
271  int nb=tStart*tf.rate();
272  int ne=tStop*tf.rate();
273  for(int i=nb;i<ne;i++) tf[i-nb] = tf[i];
274  tf.resize(ne-nb);
275  char title[256];
276  sprintf(title,"START : %10.3f (gps) - LENGHT : %g (sec) - RATE : %g (hz)",
277  tf.start()+tStart,tStop-tStart,tf.rate());
278  tf.start(0);
279  if(!options.Contains("SAME")) options=options+TString(" ALP");
280  options.ReplaceAll(" ","");
281  pts->plot(tf, const_cast<char*>(options.Data()), color, 0, tStop-tStart, true, fLow, fHigh, psd, 8);
282  pts->graph[pts->graph.size()-1]->SetTitle(title);
283  if(logx) pts->canvas->SetLogx();
284  if(logy) pts->canvas->SetLogy();
285 
286  return pts;
287 }
288 
289 //______________________________________________________________________________
290 template<class DataType_t>
292 //
293 // Draw waveform spectrogram
294 //
295 // Input:
296 // wavearray - data array
297 // options - draw options (same as TH2D)
298 //
299 // return pointer to CWB::STFT object
300 //
301 
302  return DrawTF(NULL,options);
303 }
304 
305 //______________________________________________________________________________
306 template<class DataType_t>
308 //
309 // Draw waveform spectrogram
310 //
311 // Input:
312 // options - draw options (same as TH2D)
313 //
314 // return pointer to CWB::STFT object
315 //
316 
317  int nfact=4;
318  int nfft=nfact*512;
319  int noverlap=nfft-10;
320  double fparm=nfact*6;
321 
322  double tStart,tStop;
323  if(options.Contains("FULL")) {
324  options.ReplaceAll("FULL","");
325  tStart=this->start();
326  tStop=this->start()+this->size()/this->rate();
327  tStop-=this->start();tStart-=this->start();
328  } else if(options.Contains("CUSTOM")) {
329  options.ReplaceAll("CUSTOM","");
330  tStart=this->start();
331  tStop=this->start()+this->size()/this->rate();
332  tStart = tMin>tStart&&tMin<tStop ? tMin : tStart;
333  tStop = tMax>tStart&&tMax<tStop ? tMax : tStop;
334  tStop-=this->start();tStart-=this->start();
335  } else {
336  GetTimeRange(tStart, tStop);
337  }
338 
339  if(stft!=NULL) delete stft;
340  if(pts!=NULL) delete pts;
341 
343  if(x!=NULL) waveAssign(tf,*x);
344  else waveAssign(tf,*this);
345  tf.start(0);
346  char name[32];sprintf(name,"TF-gID:%d",int(gRandom->Rndm(13)*1.e9));
347  stft = new CWB::STFT(tf,nfft,noverlap,"amplitude","gauss",fparm,name);
348 
349  double fLow = 4.;
350  double fHigh = this->rate()/2.;
351  stft->Draw(tStart,tStop,fLow,fHigh,0,0,1);
352  stft->GetCanvas()->SetLogy(true);
353 
354  return stft;
355 }
356 
357 //______________________________________________________________________________
358 template<class DataType_t>
359 double gwavearray<DataType_t>::GetTimeRange(double& tMin, double& tMax, double efraction) {
360 //
361 // Get mdc time interval
362 //
363 // Input: efraction - energy fraction used to evaluate the range which contains efraction
364 // default = 0.9999999
365 //
366 // Output: tMin - start time interval
367 // tMax - stop time interval
368 //
369 
370  double a,b;
371 
372  double T = GetCentralTime();
373 
374  double E=0.;
375  int size=(int)this->size();
376  double rate=this->rate();
377  for(int j=0;j<size;j++) E += this->data[j]*this->data[j];
378 
379  int OS = int(T*rate);
380  int M = OS<size/2 ? OS : size-OS;
381 
382  int I=0;
383  double sum = this->data[OS]*this->data[OS];
384  for(int j=1; j<int(M); j++) {
385  a = this->data[OS-j];
386  b = this->data[OS+j];
387  sum += a*a+b*b;
388  if(sum/E > efraction) break;
389  I=j;
390  }
391  I++;
392  tMin = tMin>=0 ? double((OS-I)/rate) : 0.;
393  tMax = tMax<size/rate ? double((OS+I)/rate) : size/rate;
394 
395  if(sum/E<efraction) {tMin=0.;tMax=size/rate;}
396 
397  return T;
398 }
399 
400 //______________________________________________________________________________
401 template<class DataType_t>
403 //
404 // Get mdc central time
405 //
406 // Input:
407 //
408 // Retun central time
409 //
410 
411  double a;
412  double E=0.,T=0.;
413  int size=(int)this->size();
414  double rate=this->rate();
415  for(int j=0;j<size;j++) {
416  a = this->data[j];
417  T += a*a*j/rate; // central time
418  E += a*a; // energy
419  }
420  T = E>0 ? T/E : 0.5*size/rate;
421 
422  return T;
423 }
424 
425 //______________________________________________________________________________
426 template<class DataType_t>
428 //
429 // apply time shift
430 //
431 //
432 // Input:
433 // time - time shift (sec)
434 //
435 
436  if(tShift==0) return;
437 
438  // search begin,end of non zero data
439  int ibeg=0; int iend=0;
440  for(int i=0;i<(int)this->size();i++) {
441  if(this->data[i]!=0 && ibeg==0) ibeg=i;
442  if(this->data[i]!=0) iend=i;
443  }
444  int ilen=iend-ibeg+1;
445  // create temporary array for FFTW & add scratch buffer + tShift
446  int isize = 2*ilen+2*fabs(tShift)*this->rate();
447  isize = isize + (isize%4 ? 4 - isize%4 : 0); // force to be multiple of 4
448  wavearray<double> w(isize);
449  w.rate(this->rate()); w=0;
450  // copy this->data data !=0 in the middle of w array & set this->data=0
451  for(int i=0;i<ilen;i++) {w[i+isize/4]=this->data[ibeg+i];this->data[ibeg+i]=0;}
452 
453  double pi = TMath::Pi();
454  // apply time shift to waveform vector
455  w.FFTW(1);
456  TComplex C;
457  double df = w.rate()/w.size();
458  //cout << "tShift : " << tShift << endl;
459  for (int ii=0;ii<(int)w.size()/2;ii++) {
460  TComplex X(w[2*ii],w[2*ii+1]);
461  X=X*C.Exp(TComplex(0.,-2*pi*ii*df*tShift)); // Time Shift
462  w[2*ii]=X.Re();
463  w[2*ii+1]=X.Im();
464  }
465  w.FFTW(-1);
466 
467  // copy shifted data to input this->data array
468  for(int i=0;i<(int)w.size();i++) {
469  int j=ibeg-isize/4+i;
470  if((j>=0)&&(j<(int)this->size())) this->data[j]=w[i];
471  }
472 
473  return;
474 }
475 
476 //______________________________________________________________________________
477 template<class DataType_t>
479 //
480 // apply phase shift
481 //
482 // Input:
483 // pShift - phase shift (degrees)
484 //
485 
486  if(pShift==0) return;
487 
488  // search begin,end of non zero data
489  int ibeg=0; int iend=0;
490  for(int i=0;i<(int)this->size();i++) {
491  if(this->data[i]!=0 && ibeg==0) ibeg=i;
492  if(this->data[i]!=0) iend=i;
493  }
494  int ilen=iend-ibeg+1;
495  // create temporary array for FFTW & add scratch buffer + tShift
496  int isize = 2*ilen;
497  isize = isize + (isize%4 ? 4 - isize%4 : 0); // force to be multiple of 4
498  wavearray<double> w(isize);
499  w.rate(this->rate()); w=0;
500  // copy this->data data !=0 in the middle of w array & set this->data=0
501  for(int i=0;i<ilen;i++) {w[i+isize/4]=this->data[ibeg+i];this->data[ibeg+i]=0;}
502 
503  // apply phase shift to waveform vector
504  w.FFTW(1);
505  TComplex C;
506  //cout << "pShift : " << pShift << endl;
507  pShift*=TMath::Pi()/180.;
508  for (int ii=0;ii<(int)w.size()/2;ii++) {
509  TComplex X(w[2*ii],w[2*ii+1]);
510  X=X*C.Exp(TComplex(0.,-pShift)); // Phase Shift
511  w[2*ii]=X.Re();
512  w[2*ii+1]=X.Im();
513  }
514  w.FFTW(-1);
515 
516  // copy shifted data to input this->data array
517  for(int i=0;i<(int)w.size();i++) {
518  int j=ibeg-isize/4+i;
519  if((j>=0)&&(j<(int)this->size())) this->data[j]=w[i];
520  }
521 
522  return;
523 }
524 
525 template <class DataType_t>
527 {
528  int n=this->size();
529 
530  FILE *fp;
531 
532  if ( (fp = fopen(fname, "w")) == NULL ) {
533  cout << " gwavearray::DumpToFile() error: cannot open file " << fname <<". \n";
534  return;
535  };
536 
537  double dt= this->rate() ? 1./this->rate() : 1.;
538  for (int i = 0; i < n; i++) fprintf( fp,"%e\t%e\n", i*dt, this->data[i]);
539  fclose(fp);
540 }
541 
542 /*
543 //______________________________________________________________________________
544 template <class DataType_t>
545 void gwavearray<DataType_t>::Streamer(TBuffer &R__b)
546 {
547  // Stream an object of class gwavearray<DataType_t>.
548 
549  UInt_t R__s, R__c;
550  if (R__b.IsReading()) {
551  Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
552  wavearray<DataType_t>::Streamer(R__b);
553  R__b >> wextern;
554  R__b.CheckByteCount(R__s, R__c, gwavearray<DataType_t>::IsA());
555  } else {
556  R__c = R__b.WriteVersion(gwavearray<DataType_t>::IsA(), kTRUE);
557  wavearray<DataType_t>::Streamer(R__b);
558  R__b << wextern;
559  R__b.SetByteCount(R__c, kTRUE);
560  }
561 }
562 */
563 
564 // instantiations
565 
566 #define CLASS_INSTANTIATION(class_) template class gwavearray< class_ >;
567 
568 CLASS_INSTANTIATION(short)
570 CLASS_INSTANTIATION(unsigned int)
572 CLASS_INSTANTIATION(long long)
573 CLASS_INSTANTIATION(float)
574 CLASS_INSTANTIATION(double)
575 
static const double C
Definition: GNGen.cc:28
int noverlap
Definition: TestDelta.C:20
void PhaseShift(double pShift=0.)
Definition: gwavearray.cc:478
double M
Definition: DrawEBHH.C:13
void DumpToFile(char *fname)
Definition: gwavearray.cc:526
double fHigh
virtual void rate(double r)
Definition: wavearray.hh:141
size_t Size
data array
Definition: wavearray.hh:323
double tSave
Definition: gwavearray.hh:114
wavearray< double > a(hp.size())
par [0] name
int n
Definition: cwb_net.C:28
TString("c")
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
int nfact
Definition: TestDelta.C:18
double Rate
Definition: wavearray.hh:324
wavearray< double > psd(33)
int nfft
Definition: TestDelta.C:19
std::vector< TGraph * > graph
Definition: watplot.hh:194
double Stop
Definition: wavearray.hh:326
STL namespace.
virtual void start(double s)
Definition: wavearray.hh:137
int j
Definition: cwb_net.C:28
i drho i
void plot(wavearray< double > &, char *=NULL, int=1, double=0., double=0., bool=false, float=0., float=0., bool=false, float=0., bool=false)
Definition: watplot.cc:150
int isize
void waveAssign(wavearray< Tout > &aout, wavearray< Tin > &ain)
Definition: wavearray.hh:360
double GetCentralTime()
Definition: gwavearray.cc:402
double pi
Definition: TestChirp.C:18
CWB::STFT * stft
Definition: gwavearray.hh:103
void Draw(double t1=0.0, double t2=0.0, double f1=0.0, double f2=0.0, double z1=0.0, double z2=0.0, int dpaletteId=DUMMY_PALETTE_ID, Option_t *option="colfz")
Definition: STFT.cc:94
fprintf(stdout,"start=%f duration=%f rate=%f\, x.start(), x.size()/x.rate(), x.rate())
wavearray< double > w
Definition: Test1.C:27
virtual size_t size() const
Definition: wavearray.hh:145
TCanvas * canvas
Definition: watplot.hh:192
bool wextern
Definition: gwavearray.hh:108
virtual double rate() const
Definition: wavearray.hh:142
i() int(T_cor *100))
double Pi
double tMin
Definition: gwavearray.hh:112
watplot * pts
Definition: gwavearray.hh:104
char fname[1024]
GWAT_DRAW
Definition: gwat.hh:28
std::slice Slice
Definition: wavearray.hh:328
void TimeShift(double tShift=0.)
Definition: gwavearray.cc:427
virtual double start() const
Definition: wavearray.hh:138
double GetTimeRange(double &tMin, double &tMax, double efraction=0.9999999)
Definition: gwavearray.cc:359
virtual ~gwavearray()
Definition: gwavearray.cc:48
Definition: gwat.hh:32
void Init()
Definition: gwavearray.cc:78
double dt
char options[256]
CWB::STFT * DrawTF(TString options="")
Definition: gwavearray.cc:291
char title[256]
Definition: SSeriesExample.C:1
double T
Definition: testWDM_4.C:11
Definition: gwat.hh:30
Definition: gwat.hh:31
WSeries< double > tf
double fLow
double fabs(const Complex &x)
Definition: numpy.cc:55
TCanvas * GetCanvas()
Definition: STFT.hh:70
TString OS
Definition: cwb_rootlogon.C:25
double df
sprintf(tfres,"(1/%g)x(%g) (sec)x(Hz)", 2 *df, df)
DataType_t * data
Definition: wavearray.hh:319
#define CLASS_INSTANTIATION(class_)
Definition: gwavearray.cc:566
fclose(ftrig)
double Start
Definition: wavearray.hh:325
virtual void resize(unsigned int)
Definition: wavearray.cc:463
watplot * DrawTime(TString options="ALP", Color_t color=kBlack)
Definition: gwavearray.cc:124
double fparm
Definition: TestDelta.C:22
double tMax
Definition: gwavearray.hh:113
void Draw(GWAT_DRAW type=GWAT_TIME, TString options="ALP", Color_t color=kBlack)
Definition: gwavearray.cc:89
watplot * DrawFFT(TString options="ALP", Color_t color=kBlack)
Definition: gwavearray.cc:203
CWB::STFT * stft
Definition: ChirpMass.C:121
exit(0)