Logo coherent WaveBurst  
Library Reference Guide
Logo
cluster.cc
Go to the documentation of this file.
1 /*
2 # Copyright (C) 2019 Sergey Klimenko
3 #
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17 
18 
19 //---------------------------------------------------
20 // WAT cluster class
21 // S. Klimenko, University of Florida
22 //---------------------------------------------------
23 
24 #define WAVECLUSTER_CC
25 #include <time.h>
26 #include <iostream>
27 #include <stdexcept>
28 #include "cluster.hh"
29 
30 using namespace std;
31 
32 // sort wavepixel objects on time
33 int compare_pix(const void *x, const void *y){
34  wavepixel* p = *((wavepixel**)x);
35  wavepixel* q = *((wavepixel**)y);
36  double a = (p->time+0.5)/p->rate - (q->time+0.5)/q->rate;
37  if(a > 0) return 1;
38  if(a < 0) return -1;
39  return 0;
40 }
41 
42 // constructors
43 
45 {
46  pList.clear();
47  sCuts.clear();
48  cList.clear();
49  cRate.clear();
50  start = 0.;
51  stop = 0.;
52  shift = 0.;
53  bpp = 0.;
54  low = 0.;
55  high = 0.;
56  ifo = 0;
57  run = 0;
58 }
59 
61 {
62  *this = value;
63 }
64 
65 
67 {
68  init(w,halo);
69 }
70 
71 // destructor
72 
74 
75 //: operator =
76 
78 {
79  pList.clear();
80  sCuts.clear();
81  cList.clear();
82  cRate.clear();
83  pList = value.pList;
84  sCuts = value.sCuts;
85  cList = value.cList;
86  cRate = value.cRate;
87  nRMS = value.nRMS;
88  start = value.start;
89  stop = value.stop;
90  shift = value.shift;
91  bpp = value.bpp;
92  low = value.low;
93  high = value.high;
94  ifo = value.ifo;
95  run = value.run;
96  return *this;
97 }
98 
99 
100 
101 //**************************************************************************
102 // initialize wavecluster from WSeries (binary tree)
103 //**************************************************************************
105 {
106  pList.clear();
107  sCuts.clear();
108  cList.clear();
109  cRate.clear();
110  bpp=0.; start=0.; stop=0., ifo=0; shift=0.;
111 
112  if(!w.pWavelet->BinaryTree()) return 0;
113 
114  start = w.start(); // set start time
115  stop = start+w.size()/w.wavearray<double>::rate(); // set stop time (end of time interval)
116  bpp = w.getbpp();
117  low = w.getlow();
118  high = w.gethigh();
119 
120  size_t i,j,k;
121 
122  size_t ni = w.maxLayer()+1;
123  size_t nj = w.size()/ni;
124  size_t n = ni-1;
125  size_t m = nj-1;
126  size_t nl = size_t(2.*low*ni/w.wavearray<double>::rate()); // low frequency boundary index
127  size_t nh = size_t(2.*high*ni/w.wavearray<double>::rate()); // high frequency boundary index
128 
129  if(nh>=ni) nh = ni-1;
130 
131  int L;
132  int* TF = new int[ni*nj];
133  int* p = NULL;
134  int* q = NULL;
135 
137 
138  k = 0;
139  for(i=0; i<ni; i++){
140  p = TF+i*nj;
141  w.getLayer(a,i);
142 
143  if(nj!=a.size())
144  cout<<"wavecluster::constructor() size error: "<<nj<<endl;
145 
146  for(j=0; j<nj; j++){
147  if(a.data[j]==0. || i<nl || i>nh) p[j]=0;
148  else {p[j]=-1; k++;}
149  }
150  }
151  if(!k) { delete [] TF; return 0; }
152 
153 /**************************************/
154 /* fill in the pixel list */
155 /**************************************/
156 
157  wavepixel pix;
158  pix.amplitude.clear(); // clear link pixels amplitudes
159  pix.neighbors.clear(); // clear link vector for neighbors
160  pix.clusterID = 0; // initialize cluster ID
161  L = 1<<w.getLevel(); // number of layers
162  pix.rate = float(w.wavearray<double>::rate()/L); // pixel rate
163 
164  size_t &f = pix.frequency;
165  size_t &t = pix.time;
166  size_t F,T;
167 
168  L = 0;
169 
170  for(i=0; i<ni; i++)
171  {
172  p = TF + i*nj;
173 
174  for(j=0; j<nj; j++)
175  {
176  if(p[j] != -1) continue;
177 
178  t = j; f = i; // time index; frequency index;
179  pix.core = true; // core pixel
180  pList.push_back(pix); // save pixel
181  p[j] = ++L; // save pixel index (Fortran indexing)
182 
183  if(!halo) continue;
184 
185 // include halo
186 
187  pix.core = false; // halo pixel
188 
189  F = i<n ? i+1 : i;
190  T = j<m ? j+1 : j;
191 
192  for(f = i>0 ? i-1 : i; f<=F; f++) {
193  q = TF + f*nj;
194  for(t = j>0 ? j-1 : j; t<=T; t++) {
195  if(!q[t]) {pList.push_back(pix); q[t] = ++L;}
196  }
197  }
198  }
199  }
200 
201 // set amplitude and neighbours
202 
203  std::vector<int>* pN;
204  size_t nL = pList.size();
205  slice S;
206 
207  for(k=0; k<nL; k++)
208  {
209  i = pList[k].frequency;
210  j = pList[k].time;
211  if(int(i)>w.maxLayer()) cout<<"wavecluster::constructor() maxLayer error: "<<i<<endl;
212  S = w.getSlice(i);
213 
214 // set pixel amplitude
215 
216  pList[k].amplitude.push_back(w.data[S.start()+S.stride()*j]);
217 
218 // set neighbors
219 
220  pN = &(pList[k].neighbors);
221 
222  F = i<n ? i+1 : i;
223  T = j<m ? j+1 : j;
224 
225  for(f = i>0 ? i-1 : i; f<=F; f++) {
226  q = TF + f*nj;
227  for(t = j>0 ? j-1 : j; t<=T; t++) {
228  L = (f==i && t==j) ? 0 : q[t];
229  if(L) pN->push_back(L-1);
230  }
231  }
232  }
233 
234  delete [] TF;
235  return pList.size();
236 }
237 
238 
239 //**************************************************************************
240 // cluster analysis
241 //**************************************************************************
243 {
244  size_t volume;
245  size_t i,m;
246  vector<int> refMask;
247  size_t nCluster = 0;
248  size_t n = pList.size();
249 
250  if(!pList.size()) return 0;
251 
252  cList.clear();
253  sCuts.clear();
254  cRate.clear();
255 
256  for(i=0; i<n; i++){
257  if(pList[i].clusterID) continue;
258  pList[i].clusterID = ++nCluster;
259  volume = cluster(&pList[i]);
260  refMask.clear();
261  cRate.push_back(refMask);
262  refMask.resize(volume);
263  cList.push_back(refMask);
264  sCuts.push_back(false);
265  }
266 
267  list<vector_int>::iterator it;
268  nCluster = 0;
269  if(!cList.size()) return 0;
270 
271  for(it=cList.begin(); it != cList.end(); it++) {
272  nCluster++;
273 
274  m = 0;
275  for(i=0; i<n; i++) {
276  if(pList[i].clusterID == nCluster) (*it)[m++] = i;
277  }
278 
279  if(it->size() != m) {
280  cout<<"cluster::cluster() size mismatch error: ";
281  cout<<m<<" size="<<it->size()<<" "<<nCluster<<endl;
282  }
283  if(m==1 && !pList[(*it)[0]].core) {
284  cout<<"cluster::cluster() : empty cluster. \n";
285  cout<<pList[(*it)[0]].time<<" "<<pList[(*it)[0]].frequency<<endl;
286  }
287  }
288  return nCluster;
289 }
290 
292 {
293  size_t volume = 1;
294  int i = p->neighbors.size();
295  wavepixel* q;
296 
297  while(--i >= 0){
298  q = &pList[p->neighbors[i]];
299  if(!q->clusterID){
300  q->clusterID = p->clusterID;
301  volume += cluster(q);
302  }
303  }
304  return volume;
305 }
306 
307 
308 //**************************************************************************
309 // remove halo pixels from pixel list
310 //**************************************************************************
311 size_t wavecluster::cleanhalo(bool keepid)
312 {
313  if(!pList.size() || !cList.size()) return 0;
314 
315  size_t i;
316  size_t cid = 0; // new cluster ID
317  size_t pid = 0; // new pixel ID
318 
319  wavepixel* pix = NULL;
320  list<vector_int>::iterator it;
321  std::vector<int> id;
322 
323  wavecluster x(*this);
324 
325  pList.clear();
326  sCuts.clear();
327  cList.clear();
328 
329  for(it=x.cList.begin(); it != x.cList.end(); it++) { // loop over clusters
330 
331  pix = &(x.pList[((*it)[0])]);
332  if(x.sCuts[pix->clusterID-1]) continue; // apply selection cuts
333 
334  cid++;
335  id.clear();
336  for(i=0; i<it->size(); i++) { // loop over pixels in the cluster
337  pix = &(x.pList[((*it)[i])]);
338  if(pix->core) {
339  pix->clusterID = keepid ? cid : 0;
340  pix->neighbors.clear();
341  id.push_back(pid++);
342  pList.push_back(*pix); // fill pixel list
343  }
344  }
345 
346  i = id.size();
347  if(!i) cout<<"wavecluster::cleanhalo() error: empty cluster.";
348 
349  if(keepid) {
350  cList.push_back(id); // fill cluster list
351  sCuts.push_back(false); // fill selection cuts
352  }
353 
354  if(i<2) continue;
355 
356  while(--i > 0) { // set neighbors
357  pList[id[i-1]].neighbors.push_back(id[i]);
358  pList[id[i]].neighbors.push_back(id[i-1]);
359  }
360 
361 
362  }
363  return pList.size();
364 }
365 
366 //**************************************************************************
367 // save wavelet amplitudes in cluster structure
368 //**************************************************************************
370 {
371  size_t j,k,m;
372  slice S;
373  size_t N = w.size()-1;
374  size_t M = pList.size();
375  size_t max_layer = w.maxLayer();
376  wavepixel* p = NULL; // pointer to pixel structure
377  double a;
378  float rate;
379  size_t ofFSet;
380 
381  if(!M) return 0;
382 
383  offset = fabs(offset);
384  if(fabs(w.start()+offset-start)>1.e-12) {
385  printf("wavecluster::apush: start time mismatch: dT=%16.13f",start-w.start());
386  return 0;
387  }
388 
389  for(k=0; k<M; k++){
390  p = &(pList[k]);
391 
392  if(p->frequency > max_layer) {
393  p->amplitude.push_back(0.);
394  continue;
395  }
396 
397  S = w.getSlice(p->frequency);
398  m = S.stride();
399 
400  rate = w.wavearray<double>::rate()/m; // rate at this layer
401  ofFSet = size_t(offset*w.wavearray<double>::rate()+0.5); // number of offset samples
402 
403  if(int(p->rate+0.1) != int(rate+0.1)) {
404  p->amplitude.push_back(0.);
405  continue;
406  }
407 
408  if((ofFSet/m)*m != ofFSet)
409  cout<<"wavecluster::apush(): illegal offset "<<ofFSet<<" m="<<m<<"\n";
410 
411  j = S.start()+ofFSet+S.stride()*p->time; // pixel index in cluster
412  a = j>N ? 0. : w.data[j];
413  p->amplitude.push_back(a);
414  }
415 
416  return pList[0].amplitude.size();
417 }
418 
419 //**************************************************************************
420 // append input cluster list
421 //**************************************************************************
423 {
424  size_t i,k,n;
425  size_t in = w.pList.size();
426  size_t on = pList.size();
427  size_t im = w.cList.size();
428  size_t om = cList.size();
429 
430  if(!in) { return on; }
431  if(!on) { *this = w; return in; }
432 
433  wavepixel* p = NULL; // pointer to pixel structure
434  std::vector<int>* v;
435 
436  if((w.start!=start) || (w.ifo!=ifo) || (w.shift!=shift)) {
437  printf("\n wavecluster::append(): cluster type mismatch");
438  printf("%f / %f, %f / %f, %d / %d\n",w.start,start,w.shift,shift,w.ifo,ifo);
439 
440  return on;
441  }
442 
443  if(im && !om) { // clear in clusters
444  w.sCuts.clear(); w.cList.clear(); im=0;
445  for(i=0; i<in; i++) w.pList[i].clusterID=0;
446  }
447  if(!im && om) { // clear out clusters
448  sCuts.clear(); cList.clear(); om=0;
449  for(i=0; i<on; i++) pList[i].clusterID=0;
450  }
451 
452 
453  for(i=0; i<in; i++){
454  p = &(w.pList[i]);
455  v = &(p->neighbors);
456  n = v->size();
457  for(k=0; k<n; k++) (*v)[k] += on; // new neighbors pointers
458  p->clusterID += om; // update cluster ID
459  pList.push_back(*p);
460  }
461 
462  if(!im) return pList.size();
463 
464  list<vector_int>::iterator it;
465  n = 0;
466 
467  for(it=w.cList.begin(); it != w.cList.end(); it++) {
468 
469  for(i=0; i<it->size(); i++) { // loop over pixels in the cluster
470  (*it)[i] += on; // update pixel index
471  }
472 
473  cList.push_back(*it);
474  sCuts.push_back(w.sCuts[n++]);
475  }
476 
477  return pList.size();
478 }
479 
480 //**************************************************************************
481 // merge clusters in the lists
482 //**************************************************************************
483 size_t wavecluster::merge(double S)
484 {
485  size_t i,j,k,m;
486  size_t n = pList.size();
487  int l;
488 
489  if(!n) return 0;
490 
491  wavepixel* p = NULL; // pointer to pixel structure
492  wavepixel* q = NULL; // pointer to pixel structure
493  std::vector<int>* v;
494  float eps;
495  double E;
496  bool insert;
497  double ptime, pfreq;
498  double qtime, qfreq;
499 
500  cRate.clear();
501  wavepixel** pp = (wavepixel**)malloc(n*sizeof(wavepixel*));
502 
503 // sort pixels
504 
505  for(i=0; i<n; i++) { pp[i] = &(pList[i]); pp[i]->index = i; }
506  qsort(pp, n, sizeof(wavepixel*), &compare_pix); // sorted time
507 
508 
509 // update neighbors
510 
511  for(i=0; i<n; i++) {
512  p = pp[i];
513  if(!p->core) continue;
514  ptime = (p->time+0.5)/p->rate;
515  pfreq = (p->frequency+0.5)*p->rate;
516 
517  for(j=i+1; j<n; j++){
518  q = pp[j];
519 
520  eps = 0.55/p->rate + 0.55/q->rate;
521  qtime = (q->time+0.5)/q->rate;
522 
523  if(qtime<ptime) cout<<"wavecluster::merge() error"<<endl;
524 
525  if(qtime-ptime > 1.) break;
526  if(qtime-ptime > eps) continue;
527  if(!q->core || p->rate==q->rate) continue;
528  if(!(p->rate==2*q->rate || q->rate==2*p->rate)) continue;
529 
530  eps = 0.55*(p->rate+q->rate);
531  qfreq = (q->frequency+0.5)*q->rate;
532  if(fabs(pfreq-qfreq) > eps) continue;
533 
534 // insert in p
535 
536  l = q->index;
537  insert = true;
538  v = &(p->neighbors);
539  m = v->size();
540  for(k=0; k<m; k++) {
541  if((*v)[k] == l) {insert=false; break;}
542  }
543  if(insert) v->push_back(l);
544 
545 // insert in q
546 
547  l = p->index;
548  insert = true;
549  v = &(q->neighbors);
550  m = v->size();
551  for(k=0; k<m; k++) {
552  if((*v)[k] == l) {insert=false; break;}
553  }
554  if(insert) v->push_back(l);
555 
556  }
557  }
558  free(pp);
559 
560 //***************
561  cluster();
562 //***************
563 
564  std::list<vector_int>::iterator it;
565  wavepixel* pix = NULL;
566  std::vector<int> rate;
567  std::vector<int> temp;
568  std::vector<int> sIZe;
569  std::vector<bool> cuts;
570  std::vector<double> ampl;
571  std::vector<double> amax;
572  std::vector<double> sigf;
573  std::vector<double>* pa;
574  double a;
575  bool cut;
576  size_t ID;
577  size_t max = 0;
578  size_t min = 0;
579  size_t count=0;
580 
581  for(it=cList.begin(); it != cList.end(); it++) {
582  k = it->size();
583  if(!k) cout<<"wavecluster::merge() error: empty cluster.\n";
584 
585 // fill cluster statistics
586 
587  m = 0; E = 0;
588  rate.clear();
589  ampl.clear();
590  amax.clear();
591  sigf.clear();
592  cuts.clear();
593  sIZe.clear();
594  temp.clear();
595 
596  ID = pList[((*it)[0])].clusterID;
597 
598  for(i=0; i<k; i++) {
599  pix = &(pList[((*it)[i])]);
600  if(!pix->core) continue;
601  pa = &(pix->amplitude);
602  a = pa->size()>1 ? pow((*pa)[1],2) : (*pa)[0];
603 
604  insert = true;
605  for(j=0; j<rate.size(); j++) {
606  if(rate[j] == int(pix->rate+0.1)) {
607  insert=false;
608  ampl[j] += a;
609  sIZe[j] += 1;
610  sigf[j] += (*pa)[0];
611  if(a>amax[j]) amax[j] = a;
612  }
613  }
614 
615  if(insert) {
616  rate.push_back(int(pix->rate+0.1));
617  ampl.push_back(a);
618  amax.push_back(a);
619  sIZe.push_back(1);
620  cuts.push_back(true);
621  sigf.push_back((*pa)[0]);
622  }
623 
624  m++; E += (*pa)[0];
625 
626  if(ID != pix->clusterID)
627  cout<<"wavecluster::merge() error: cluster ID mismatch.\n";
628  }
629 
630 // cut off single level clusters
631 
632  if(!rate.size()) { cout<<"k="<<k<<" id="<<ID<<endl; continue; }
633  if(rate.size()<2 || m<=2){ sCuts[ID-1] = true; continue; }
634 // sCuts[ID-1] = (gammaCL(E,m) > S-log(m-1.)) ? false : true;
635  sCuts[ID-1] = (gammaCL(E,m) > S) ? false : true;
636 
637 // coincidence between levels
638  cut = true;
639  for(i=0; i<rate.size(); i++) {
640  for(j=0; j<rate.size(); j++) {
641  if(rate[i]/2==rate[j] || rate[j]/2==rate[i]) {
642  cuts[i] = cuts[j] = cut = false;
643  }
644  }
645  }
646  if(cut || sCuts[ID-1]) { sCuts[ID-1] = true; continue; }
647 
648 // select optimal resolution
649 
650  a = -1.e99;
651  for(j=0; j<rate.size(); j++) { // select max excess power
652  if(ampl[j]-sIZe[j]>a && !cuts[j]) {max=j; a=ampl[j]-sIZe[j];}
653  }
654 
655  a = -1.e99;
656  for(j=0; j<rate.size(); j++) {
657  if(max==j) continue;
658  if(ampl[j]-sIZe[j]>a && !cuts[j]) {min=j; a=ampl[j]-sIZe[j];}
659  }
660 
661  temp.push_back(rate[max]);
662  temp.push_back(rate[min]);
663  cRate[ID-1] = temp;
664  count++;
665 
666  }
667 
668  return count;
669 }
670 
671 
672 //**************************************************************************
673 // coincidence between two clusters lists
674 //**************************************************************************
676 {
677  size_t i,j,k;
678  size_t ik = w.asize();
679  size_t ok = asize();
680 
681  if(!ik || !ok) return 0;
682 
683  k = ok>1 ? ik : 1;
684  k = k>1 ? 2 : 1;
685 
686  wavearray<float> tin = w.get((char*)"time",k); // get in time
687  wavearray<float> tou = get((char*)"time",k); // get out time
688  wavearray<float> rin = w.get((char*)"rate",0); // get in rate
689  wavearray<float> rou = get((char*)"rate",0); // get out rate
690  wavearray<float> cid = get((char*)"ID",0); // get out cluster ID
691 
692  size_t in = tin.size();
693  size_t on = tou.size();
694  double window;
695  bool cut;
696 
697  k = 0;
698 
699  for(i=0; i<on; i++){
700  cut = true;
701  for(j=0; j<in; j++){
702  window = 0.5/rou[i]+0.5/rin[j];
703  if(window<T) window = T;
704  if(fabs(tou.data[i]-tin.data[j])<window) { cut=false; break; }
705  }
706  if(cut) sCuts[int(cid[i]-0.5)] = true;
707  else k++;
708  }
709  return k;
710 }
711 
712 //**************************************************************************
713 // save noise rms in amplitude array in cluster structure
714 // input fl is used for low pass filter correction
715 //**************************************************************************
716 void wavecluster::setrms(WSeries<double>& w, double fl, double fh)
717 {
718  size_t i,j,n,m;
719  slice S;
720  size_t M = pList.size();
721  size_t max_layer = w.maxLayer()+1;
722  wavepixel* p = NULL; // pointer to pixel structure
723 
724  int k;
725  int wsize = w.size()/max_layer;
726  double wstart = w.start();
727  double wrate = w.wavearray<double>::rate();
728  double deltaF = w.gethigh()/max_layer;
729  double x,f,t,r;
730  bool C; // low pass filter correction flag
731 
732  if(fl<0.) fl = low;
733  if(fh<0.) fh = w.gethigh();
734 
735  if(!M || !w.size()) return;
736 
737  for(i=0; i<M; i++){
738  p = &(pList[i]);
739 
740  if(p->frequency >= max_layer) continue;
741 
742  f = p->frequency*p->rate/2.;
743  C = f<fl ? true : false;
744  f = C ? fl : f;
745  n = size_t(f/deltaF); // first layer in w
746  f = (p->frequency+1)*p->rate/2.;
747  m = size_t(f/deltaF); // last layer in w
748  t = start+(p->time+0.5)/p->rate;
749  k = int((t-wstart)*wrate); // time index in noise array
750 
751  if(k>=wsize) k -= k ? 1 : 0;
752  if(k<0 || n>=m || k>=wsize) {
753  cout<<"wavecluster::setrms() - invalid input\n";
754  continue;
755  }
756 
757  r = 0.;
758  for(j=n; j<m; j++) { // get noise rms for specified pixel
759  S = w.getSlice(j);
760  x = w.data[S.start()+k*S.stride()];
761  r += 1./x/x;
762  // r += C && (j<2*n) ? 2./x/x : 1./x/x;
763  }
764  r /= double(m)-double(n);
765  p->noiserms = sqrt(1./r);
766 
767  }
768  return;
769 }
770 
771 //**************************************************************************
772 // save noise variance in amplitude array in cluster structure
773 //**************************************************************************
774 void wavecluster::setvar(wavearray<float>& w, double fl, double fh)
775 {
776  size_t i;
777  size_t M = pList.size();
778  wavepixel* p = NULL; // pointer to pixel structure
779 
780  int k;
781  int wsize = w.size();
782  double wstart = w.start();
783  double f,t;
784 
785  if(!M || !w.size()) return;
786  if(fl<0.) fl = low;
787  if(fh<0.) fh = high;
788 
789  for(i=0; i<M; i++){
790  p = &(pList[i]);
791 
792  f = p->frequency*p->rate/2.;
793  if(f>=fh && f+p->rate/2. >fh) continue;
794  if(f <fl && f+p->rate/2.<=fl) continue;
795 
796  t = start+(p->time+0.5)/p->rate;
797  k = int((t-wstart)*w.rate()); // time index in variability array
798 
799  if(k>=wsize) k -= k ? 1 : 0;
800  if(k<0 || k>=wsize) {
801  cout<<"wavecluster::setvar() - invalid input\n";
802  continue;
803  }
804 
805  p->variability = w.data[k];
806  }
807  return;
808 }
809 
810 
811 double wavecluster::getNoiseRMS(double t, double fl, double fh)
812 {
813  if(!nRMS.size()) return 1.;
814 
815  size_t i;
816  size_t M = nRMS.maxLayer()+1; // number of layers in nRMS
817  size_t n = size_t(fl/(nRMS.gethigh()/M)); // first layer to get in nRMS
818  size_t m = size_t(fh/(nRMS.gethigh()/M)); // last layer to get in nRMS
819 
820  double rms = 0.;
821  double x;
822  slice S;
823 
824  int inRMS = int((t-nRMS.start())*nRMS.rate());
825  int inVAR = nVAR.size() ? int((t-nVAR.start())*nVAR.rate()) : 0;
826 
827  if(inRMS>=int(nRMS.size()/M)) inRMS -= inRMS ? 1 : 0;
828  if(inVAR>=int(nVAR.size())) inVAR -= inVAR ? 1 : 0;
829 
830  if(inRMS<0 || inVAR<0 || n>=m ||
831  inRMS >= int(nRMS.size()/M) ||
832  inVAR >= int(nVAR.size()))
833  {
834  cout<<"wavecluster::getNoiseRMS() - invalid pixel time\n";
835  return 0.;
836  }
837 
838  for(i=n; i<m; i++) { // get noise vector for specified fl-fh
839  S = nRMS.getSlice(i);
840  x = nRMS.data[S.start()+inRMS*S.stride()];
841  rms += 1./x/x;
842  }
843  rms /= double(m)-double(n);
844  rms = sqrt(1./rms);
845 
846  if(!nVAR.size() || fh<low || fl>high) return rms;
847 
848  return rms*double(nVAR.data[inVAR]);
849 }
850 
851 //**************************************************************************
852 // return cluster parameters.
853 //**************************************************************************
854 wavearray<float> wavecluster::get(char* name, int index, size_t type)
855 {
857  if(!cList.size()) return out;
858 
859  size_t k;
860  size_t mp,mm;
861  size_t it_size;
862  size_t it_core;
863  size_t out_size = 0;
864  double x,y;
865  double a,b;
866  double t,r;
867  double sum = 0.;
868  int ID, rate;
869 
870  wavearray<int> skip;
871  list<vector_int>::iterator it;
872  vector_int* pv = NULL;
873  size_t M = pList.size();
874  size_t m = abs(index);
875  if(m==0) m++;
876 
877  out.resize(cList.size());
878  out.start(start);
879  out.rate(1.);
880  out = 0.;
881 
882  char c = '0';
883 
884  if(strstr(name,"ID")) c = 'i'; // clusterID
885  if(strstr(name,"size")) c = 'k'; // size
886  if(strstr(name,"volume")) c = 'v'; // volume
887  if(strstr(name,"start")) c = 's'; // start time
888  if(strstr(name,"stop")) c = 'd'; // stop time
889  if(strstr(name,"low")) c = 'l'; // low frequency
890  if(strstr(name,"high")) c = 'h'; // high frequency
891  if(strstr(name,"time")) c = 't'; // time averaged over SNR, index>=0 - Gauss
892  if(strstr(name,"TIME")) c = 'T'; // time averaged over hrss, index>=0 - Gauss
893  if(strstr(name,"freq")) c = 'f'; // frequency averaged over SNR, index>=0 - Gauss
894  if(strstr(name,"FREQ")) c = 'F'; // frequency averaged over hrss, index>=0 - Gauss
895  if(strstr(name,"energy")) c = 'e'; // energy; index<0 - rank, index>0 - Gauss
896  if(strstr(name,"like")) c = 'Y'; // likelihood; index<0 - rank, index>0 - Gauss
897  if(strstr(name,"sign")) c = 'z'; // significance; index<0 - rank, index>0 - Gauss
898  if(strstr(name,"corr")) c = 'x'; // xcorrelation
899  if(strstr(name,"asym")) c = 'a'; // asymmetry
900  if(strstr(name,"grand")) c = 'g'; // grandAmplitude
901  if(strstr(name,"rate")) c = 'r'; // cluster rate
902  if(strstr(name,"SNR")) c = 'S'; // cluster SNR: index<0 - rank, index>0 - Gauss
903  if(strstr(name,"hrss")) c = 'H'; // log10(calibrated cluster hrss)
904  if(strstr(name,"noise")) c = 'n'; // log10(average calibrated noise)
905 
906  if(c=='0') return out;
907 
908  k = 0;
909 
910  for(it=cList.begin(); it!=cList.end(); it++){
911 
912  ID = pList[((*it)[0])].clusterID;
913  if(sCuts[ID-1]) continue; // apply selection cuts
914 
915  it_size = it->size();
916  it_core = 0;
917  skip.resize(it_size);
918 
919  pv =&(cRate[ID-1]);
920  rate = type && type<=pv->size()? (*pv)[type-1] : 0;
921 
922 // cout<<(*pv)[0]<<" "<<(*pv)[1]<<" "<<pv->size()<<endl;
923 
924  for(k=0; k<it_size; k++) { // fill skip array
925  M = (*it)[k];
926  skip.data[k] = 1;
927  if(!pList[M].core) continue;
928  if(rate && int(pList[M].rate+0.1)!=rate) continue;
929  skip.data[k] = 0;
930  it_core++;
931  }
932 
933  if(!it_core) continue; // skip cluster
934 
935  switch (c) {
936 
937  case 'i': // get cluster ID
938  M = (*it)[0];
939  out.data[out_size++] = pList[M].clusterID;
940  break;
941 
942  case 'k': // get cluster core size
943  out.data[out_size++] = float(it_core);
944  break;
945 
946  case 'r': // get cluster rate
947  for(k=0; k<it_size; k++){
948  M = (*it)[k];
949  if(!skip.data[k]) break;
950  }
951  out.data[out_size++] = pList[M].rate;
952  break;
953 
954  case 'a': // get cluster asymmetry
955  case 'x': // get cluster x-correlation parameter
956  mp = 0; mm = 0;
957  for(k=0; k<it_size; k++){
958  M = (*it)[k];
959 
960  if(skip.data[k]) continue;
961  if(pList[M].amplitude.size()<m) continue;
962 
963  x = pList[M].amplitude[m-1];
964  if(x>0.) mp++;
965  else mm++;
966  }
967  if(c == 'a') out.data[out_size++] = (float(mp)-float(mm))/(mp+mm);
968  else out.data[out_size++] = signPDF(mp,mm);
969  break;
970 
971  case 'e': // get cluster energy
972  case 'S': // get cluster SNR
973  case 'Y': // get cluster likelihood
974  case 'z': // get cluster significance
975  y = 0.;
976  for(k=0; k<it_size; k++){
977  M = (*it)[k];
978 
979  if(skip.data[k]) continue;
980  if(pList[M].amplitude.size()<m) continue;
981 
982  x = pList[M].amplitude[m-1];
983  if(index>0){ // get Gaussian statistics
984  if(c=='Y' || c=='z') y += pow(fabs(x)+1.11/2,2)/2./1.07 + log(bpp);
985  else if(c=='S') y += x*x-1.;
986  else if(c=='e') y += x*x;
987  }
988  else { // get rank statistics
989  if(c=='Y' || c=='z') y += fabs(x);
990  else if(c=='S') y += pow(sqrt(2*1.07*(fabs(x)-log(bpp)))-1.11/2.,2)-1.;
991  else if(c=='e') y += pow(sqrt(2*1.07*(fabs(x)-log(bpp)))-1.11/2.,2);
992  }
993  }
994  out.data[out_size++] = c=='z' ? gammaCL(y,it_core) : y;
995  break;
996 
997  case 'g': // get cluster grand amplitude
998  y = 0.;
999  for(k=0; k<it_size; k++){
1000  M = (*it)[k];
1001 
1002  if(skip.data[k]) continue;
1003  if(pList[M].amplitude.size()<m) continue;
1004 
1005  x = fabs(pList[M].amplitude[m-1]);
1006  if(x>y) y = x;
1007  }
1008  out.data[out_size++] = y;
1009  break;
1010 
1011  case 's': // get cluster start time
1012  case 'd': // get cluster stop time
1013  a = 1.e99;
1014  b = 0.;
1015  for(k=0; k<it_size; k++){
1016  M = (*it)[k];
1017  if(skip.data[k]) continue;
1018  y = 1./pList[M].rate; // time resolution
1019  x = y * pList[M].time; // pixel time relative to start
1020  if(x <a) a = x;
1021  if(x+y>b) b = x+y;
1022  }
1023  out.data[out_size++] = (c=='s') ? a : b;
1024  break;
1025 
1026  case 'l': // get low frequency
1027  case 'h': // get high frequency
1028  a = 1.e99;
1029  b = 0.;
1030  for(k=0; k<it_size; k++){
1031  M = (*it)[k];
1032  if(skip.data[k]) continue;
1033  y = pList[M].rate/2.; // frequency resolution
1034  x = y * pList[M].frequency; // pixel frequency
1035  if(x <a) a = x;
1036  if(x+y>b) b = x+y;
1037  }
1038  out.data[out_size++] = (c=='l') ? a : b;
1039  break;
1040 
1041  case 't': // get central time (SNR)
1042  case 'f': // get central frequency (SNR)
1043  case 'T': // get central time (hrss)
1044  case 'F': // get central frequency (hrss)
1045  a = 0.;
1046  b = 0.;
1047  for(k=0; k<it_size; k++) {
1048  M = (*it)[k];
1049 
1050  if(skip.data[k]) continue;
1051  if(pList[M].amplitude.size()<m) continue;
1052 
1053  r = pList[M].variability;
1054  if(c =='T' || c =='F') {
1055 // f = pList[M].frequency*pList[M].rate/2.; // low frequency
1056 // t = start+(pList[M].time+0.5)/pList[M].rate; // pixel time
1057 // r = getNoiseRMS(t,f,f+pList[M].rate/2.); // noise rms for this pixel
1058  r *= pList[M].noiserms;
1059  }
1060 
1061  x = pList[M].amplitude[m-1];
1062  t = 1./pList[M].rate;
1063  if(index>=0) { // get Gaussian statistics
1064  x = (x*x-1.)*r*r;
1065  }
1066  else { // get rank statistics
1067  x = pow(sqrt(2*1.07*(fabs(x)-log(bpp)))-1.11/2.,2)-1.;
1068  }
1069  if(x<0.) x = 0.;
1070 
1071  if(c =='t' || c =='T'){
1072 // y = 1./pList[M].rate; // time resolution
1073  a += (pList[M].time+0.5)*x; // pixel time sum
1074  b += x*pList[M].rate;
1075  }
1076  else {
1077 // y = pList[M].rate/2.; // frequency resolution
1078  a += (pList[M].frequency+0.5)*x; // pixel frequency sum
1079  b += x*2./pList[M].rate;
1080  }
1081 // b += x;
1082  }
1083  out.data[out_size++] = b>0. ? a/b : -1.;
1084  break;
1085 
1086  case 'H': // get calibrated hrss
1087  case 'n': // get calibrated noise
1088 
1089  mp = 0;
1090  sum = 0.;
1091  out.data[out_size] = 0.;
1092 // if(!nRMS.size()) { out_size++; break; } // no calibration constants
1093 
1094  for(k=0; k<it_size; k++) {
1095  M = (*it)[k];
1096 
1097  if(skip.data[k]) continue;
1098  if(pList[M].amplitude.size()<m) continue;
1099 
1100 // calculate noise RMS for pixel
1101 
1102 // f = pList[M].frequency*pList[M].rate/2.; // low frequency
1103 // t = start+(pList[M].time+0.5)/pList[M].rate; // pixel time
1104 // r = getNoiseRMS(t,f,f+pList[M].rate/2.); // noise rms for this pixel
1105 
1106  r = pList[M].variability*pList[M].noiserms;
1107  mp++;
1108 
1109  if(c == 'H'){
1110  a = pow(pList[M].amplitude[m-1],2)-1.;
1111  sum += a<0. ? 0. : a*r*r;
1112  }
1113  else {
1114  sum += 1./r/r;
1115  }
1116 
1117  }
1118 
1119  if(c == 'n') { sum = double(mp)/sum; } // noise hrss
1120  out.data[out_size++] = float(log(sum)/2./log(10.));
1121  break;
1122 
1123  case 'v':
1124  default:
1125  out.data[out_size++] = it_size;
1126  break;
1127  }
1128  }
1129  out.resize(out_size);
1130  return out;
1131 }
1132 
1133 // initialize from binary WSeries
1134 
1135 double wavecluster::setMask(WSeries<double>& w, int nc, bool halo)
1136 {
1137 #if !defined (__SUNPRO_CC)
1138  register int i;
1139  register int j;
1140  int x, y, L, k;
1141  register int* q = NULL;
1142  register int* p = NULL;
1143  int* pp;
1144  int* pm;
1145  wavepixel pix;
1146 
1148 
1149  if(!w.pWavelet->BinaryTree()) return 1.;
1150 
1151  start = w.start(); // set start time
1152  bpp = w.getbpp();
1153 
1154  int ni = w.maxLayer()+1;
1155  int nj = w.size()/ni;
1156  int n = ni-1;
1157  int m = nj-1;
1158  int nPixel = 0;
1159 
1160  int FT[ni][nj];
1161  int XY[ni][nj];
1162 
1163  for(i=0; i<ni; i++){
1164  p = FT[i];
1165  q = XY[i];
1166 
1167  w.getLayer(a,i);
1168 
1169  for(j=0; j<nj; j++){
1170  p[j] = (a.data[j]!=0) ? 1 : 0;
1171  if(p[j]) nPixel++;
1172  q[j] = 0;
1173  }
1174  }
1175 
1176  pList.clear();
1177  sCuts.clear();
1178  cList.clear();
1179 
1180  if(!nc || ni<3 || nPixel<2) return double(nPixel)/double(size());
1181 
1182 // calculate number of neighbors and ignore 1 pixel clusters
1183 
1184 // corners
1185  if(FT[0][0]) XY[0][0] = FT[0][1] + FT[1][0] + FT[1][1];
1186  if(FT[0][m]) XY[0][m] = FT[1][m] + FT[1][m-1] + FT[0][m-1];
1187  if(FT[n][0]) XY[n][0] = FT[n-1][0] + FT[n-1][1] + FT[n][1];
1188  if(FT[n][m]) XY[n][m] = FT[n][m-1] + FT[n-1][m] + FT[n-1][m-1];
1189 
1190 // up/down raws
1191  for(j=1; j<m; j++){
1192  p = FT[0];
1193  q = FT[n];
1194 
1195  if(p[j]){
1196  pp = FT[1];
1197  XY[0][j] = p[j-1]+p[j+1] + pp[j-1]+pp[j]+pp[j+1];
1198  }
1199  if(q[j]){
1200  pm = FT[n-1];
1201  XY[n][j] = q[j-1]+q[j+1] + pm[j-1]+pm[j]+pm[j+1];
1202  }
1203  }
1204 
1205  for(i=1; i<n; i++){
1206  pm = FT[i-1]; p = FT[i]; pp = FT[i+1]; q = XY[i];
1207 
1208  if(p[0]) // left side
1209  q[0] = p[1] + pm[0]+pm[1] + pp[0]+pp[1];
1210 
1211  if(p[m]) // right side
1212  q[m] = p[m-1] + pm[m]+pm[m-1] + pp[m]+pp[m-1];
1213 
1214  for(j=1; j<m; j++){
1215  if(p[j])
1216  q[j] = pm[j-1]+pm[j]+pm[j+1] + pp[j-1]+pp[j]+pp[j+1] + p[j-1]+p[j+1];
1217  }
1218  }
1219 
1220 /**************************************/
1221 /* remove clusters with 2,3 pixels */
1222 /**************************************/
1223 
1224  if(nc>1){
1225 
1226 // corners
1227  if(XY[0][0]){
1228  x = XY[0][1] + XY[1][0] + XY[1][1];
1229  if(x==1 || x==4) XY[0][0]=XY[0][1]=XY[1][0]=XY[1][1]=0;
1230  }
1231  if(XY[0][m]){
1232  x = XY[1][m] + XY[1][m-1] + XY[0][m-1];
1233  if(x==1 || x==4) XY[0][m]=XY[1][m]=XY[1][m-1]=XY[0][m-1]=0;
1234  }
1235  if(XY[n][0]){
1236  x = XY[n-1][0] + XY[n-1][1] + XY[n][1];
1237  if(x==1 || x==4) XY[n][0]=XY[n-1][0]=XY[n-1][1]=XY[n][1]=0;
1238  }
1239  if(XY[n][m]){
1240  x = XY[n-1][m] + XY[n][m-1] + XY[n-1][m-1];
1241  if(x==1 || x==4) XY[n][m]=XY[n-1][m]=XY[n][m-1]=XY[n-1][m-1]=0;
1242  }
1243 
1244 // up/down raws
1245  for(j=1; j<m; j++){
1246  p = XY[0];
1247  q = XY[n];
1248 
1249  if(p[j]==1 || p[j]==2){
1250  if(p[j-1]+p[j+1] < 4){
1251  pp = XY[1];
1252  L = p[j-1]+p[j+1] + pp[j];
1253  x = pp[j-1] + pp[j+1] + L;
1254 
1255  if(x==1 || (p[j]==2 && nc>2 && (x==2 || (x==4 && L==4))))
1256  p[j]=p[j-1]=p[j+1]=pp[j-1]=pp[j]=pp[j+1]=0;
1257  }
1258  }
1259 
1260  if(q[j]==1 || q[j]==2){
1261  if(q[j-1]+q[j+1] < 4){
1262  pm = XY[n-1];
1263  L = q[j-1]+q[j+1] + pm[j];
1264  x = pm[j-1] + pm[j+1] + L;
1265 
1266  if(x==1 || (q[j]==2 && nc>2 && (x==2 || (x==4 && L==4))))
1267  q[j]=q[j-1]=q[j+1]=pm[j-1]=pm[j]=pm[j+1]=0;
1268  }
1269  }
1270  }
1271 
1272 // regular case
1273  for(i=1; i<n; i++){
1274  pm = XY[i-1];
1275  p = XY[i];
1276  pp = XY[i+1];
1277 
1278 
1279  if(p[0]==1 || p[0]==2){ // left side
1280  if(pm[0]+pp[0] < 4){
1281  L = p[1] + pm[0] + pp[0];
1282  x = pm[1] + pp[1] + L;
1283 
1284  if(x==1 || (p[0]==2 && nc>2 && (x==2 || (x==4 && L==4))))
1285  p[0]=pm[0]=pp[0]=pm[1]=pp[1]=p[1]=0;;
1286  }
1287  }
1288 
1289  if(p[m]==1 || p[m]==2){ // right side
1290  if(pm[m]+pp[m] < 4){
1291  L = p[m-1] + pm[m] + pp[m];
1292  x = pm[m-1] + pp[m-1] + L;
1293 
1294  if(x==1 || (p[m]==2 && nc>2 && (x==2 || (x==4 && L==4))))
1295  p[m]=pm[m]=pp[m]=pm[m-1]=pp[m-1]=p[m-1]=0;
1296  }
1297  }
1298 
1299  for(j=1; j<m; j++){
1300  y = p[j];
1301  if(y == 1 || y == 2){
1302  if(pm[j]+pp[j] >3) continue;
1303  if(p[j-1]+p[j+1] >3) continue;
1304 
1305  L = pm[j]+pp[j] + p[j-1]+p[j+1];
1306  x = pm[j-1]+pm[j+1] + pp[j-1]+pp[j+1] + L;
1307 
1308  if(x==1 || (y==2 && nc>2 && (x==2 || (x==4 && L==4))))
1309  p[j]=p[j-1]=p[j+1]=pm[j-1]=pm[j]=pm[j+1]=pp[j-1]=pp[j]=pp[j+1]=0;
1310  }
1311  }
1312  }
1313  }
1314 
1315 /**************************************/
1316 /* fill in the pixel mask */
1317 /**************************************/
1318 
1319  pix.amplitude.clear(); // clear link pixels amplitudes
1320  pix.neighbors.clear(); // clear link vector for neighbors
1321  pix.clusterID = 0; // initialize cluster ID
1322  L = 1<<w.getLevel(); // number of layers
1323  pix.rate = float(w.wavearray<double>::rate()/L); // pixel bandwidth
1324 
1325  size_t &f = pix.frequency;
1326  size_t &t = pix.time;
1327 
1328  L = 0;
1329 
1330  for(i=0; i<ni; i++){
1331  p = FT[i]; q = XY[i];
1332  for(j=0; j<nj; j++)
1333  p[j] = q[j];
1334  }
1335 
1336  for(i=0; i<ni; i++){
1337  q = XY[i];
1338  p = FT[i];
1339  for(j=0; j<nj; j++){
1340  if(q[j]) {
1341  t = j; f = i; // time index; frequency index;
1342  pix.core = true; // core pixel
1343  pList.push_back(pix); // save pixel
1344  p[j] = ++L; // save pixel mask index (Fortran indexing)
1345 
1346  if(halo){ // include halo
1347  pix.core = false; // halo pixel
1348 
1349  if(i>0 && j>0) {
1350  t=j-1; f=i-1; if(!FT[f][t]) {pList.push_back(pix); FT[f][t] = ++L;}
1351  }
1352  if(i>0) {
1353  t=j; f=i-1; if(!FT[f][t]) {pList.push_back(pix); FT[f][t] = ++L;}
1354  }
1355  if(i>0 && j<m) {
1356  t=j+1; f=i-1; if(!FT[f][t]) {pList.push_back(pix); FT[f][t] = ++L;}
1357  }
1358  if(j>0) {
1359  t=j-1; f=i; if(!FT[f][t]) {pList.push_back(pix); FT[f][t] = ++L;}
1360  }
1361  if(j<m) {
1362  t=j+1; f=i; if(!FT[f][t]) {pList.push_back(pix); FT[f][t] = ++L;}
1363  }
1364  if(i<n && j>0) {
1365  t=j-1; f=i+1; if(!FT[f][t]) {pList.push_back(pix); FT[f][t] = ++L;}
1366  }
1367  if(i<n) {
1368  t=j; f=i+1; if(!FT[f][t]) {pList.push_back(pix); FT[f][t] = ++L;}
1369  }
1370  if(i<n && j<m) {
1371  t=j+1; f=i+1; if(!FT[f][t]) {pList.push_back(pix); FT[f][t] = ++L;}
1372  }
1373 
1374  }
1375  }
1376  }
1377  }
1378 
1379  register std::vector<int>* pN;
1380  int nM = pList.size();
1381  slice S;
1382 
1383  for(k=0; k<nM; k++){
1384 
1385 // set pixel amplitude
1386  i = pList[k].frequency;
1387  j = pList[k].time;
1388  if(int(i)>w.maxLayer()) cout<<"cluster::setMask() maxLayer error: "<<i<<endl;
1389  S = w.getSlice(i);
1390  pList[k].amplitude.clear();
1391  pList[k].amplitude.push_back(w.data[S.start()+S.stride()*j]);
1392 
1393 // set neighbors
1394  pN = &(pList[k].neighbors);
1395  L = 0;
1396 
1397  if(i==0 || i==n){ // first or last layer
1398  if(i==0){ p = FT[0]; q = FT[1];}
1399  if(i==n){ p = FT[n]; q = FT[n-1];}
1400 
1401  if(j==0){ // first sample
1402  if(p[1]) pN->push_back(p[1]-1);
1403  if(q[1]) pN->push_back(q[1]-1);
1404  if(q[0]) pN->push_back(q[0]-1);
1405  }
1406  else if(j==m){ // last sample
1407  if(p[m-1]) pN->push_back(p[m-1]-1);
1408  if(q[m-1]) pN->push_back(q[m-1]-1);
1409  if(q[m]<0) pN->push_back(q[m]-1);
1410  }
1411  else{ // samples in the middle
1412  if(p[j-1]) pN->push_back(p[j-1]-1);
1413  if(p[j+1]) pN->push_back(p[j+1]-1);
1414  if(q[j-1]) pN->push_back(q[j-1]-1);
1415  if(q[j]) pN->push_back(q[j]-1);
1416  if(q[j+1]) pN->push_back(q[j+1]-1);
1417  }
1418  }
1419 
1420  else{
1421  pp = FT[i+1];
1422  p = FT[i];
1423  pm = FT[i-1];
1424 
1425  if(j==0){ // first sample
1426  if(pm[0]) pN->push_back(pm[0]-1);
1427  if(pp[0]) pN->push_back(pp[0]-1);
1428  if( p[1]) pN->push_back(p[1]-1);
1429  if(pm[1]) pN->push_back(pm[1]-1);
1430  if(pp[1]) pN->push_back(pp[1]-1);
1431  }
1432  else if(j==m){
1433  if(pm[m]) pN->push_back(pm[m]-1); // last sample
1434  if(pp[m]) pN->push_back(pp[m]-1);
1435  if( p[m-1]) pN->push_back(p[m-1]-1);
1436  if(pm[m-1]) pN->push_back(pm[m-1]-1);
1437  if(pp[m-1]) pN->push_back(pp[m-1]-1);
1438  }
1439  else{
1440  if(pm[j-1]) pN->push_back(pm[j-1]-1);
1441  if(pm[j]) pN->push_back(pm[j]-1);
1442  if(pm[j+1]) pN->push_back(pm[j+1]-1);
1443  if( p[j-1]) pN->push_back(p[j-1]-1);
1444  if( p[j+1]) pN->push_back(p[j+1]-1);
1445  if(pp[j-1]) pN->push_back(pp[j-1]-1);
1446  if(pp[j]) pN->push_back(pp[j]-1);
1447  if(pp[j+1]) pN->push_back(pp[j+1]-1);
1448  }
1449  }
1450 
1451  L = pList[k].neighbors.size();
1452  x = pList[k].core ? XY[i][j] : L;
1453  if((x != L && !halo) || L>8){
1454  cout<<"cluster::getMask() vector size error: "<<L<<" reserved: "<<x<<endl;
1455  cout<<"k="<<k<<" i="<<i<<" j="<<j<<endl;
1456  }
1457  }
1458 #endif
1459  return double(pList.size())/double(size());
1460 }
1461 
1462 
1463 
1464 
1465 
1466 
1467 
1468 
1469 
1470 
1471 
1472 
1473 
wavearray< double > t(hp.size())
std::vector< vector_int > cRate
Definition: cluster.hh:227
std::vector< int > vector_int
Definition: cluster.hh:35
static const double C
Definition: GNGen.cc:28
virtual size_t append(wavecluster &)
param: input cluster list return size of appended list
Definition: cluster.cc:422
virtual ~wavecluster()
Definition: cluster.cc:73
double gammaCL(double x, double n)
Definition: watfun.hh:131
double getlow() const
Definition: wseries.hh:129
size_t time
Definition: cluster.hh:57
double M
Definition: DrawEBHH.C:13
double bpp
Definition: cluster.hh:215
par [0] value
virtual size_t cluster()
return number of clusters
Definition: cluster.cc:242
double min(double x, double y)
Definition: eBBH.cc:31
int offset
Definition: TestSTFT_2.C:19
virtual void rate(double r)
Definition: wavearray.hh:141
std::vector< pixel > cluster
Definition: wavepath.hh:61
CWB run(runID)
wavearray< double > a(hp.size())
wavearray< float > get(char *, int=0, size_t=0)
param: string with parameter name param: amplitude field index param: rate index, if 0 ignore rate fo...
Definition: cluster.cc:854
WSeries< float > v[nIFO]
Definition: cwb_net.C:80
par [0] name
int n
Definition: cwb_net.C:28
float variability
Definition: cluster.hh:61
std::vector< wavepixel > pList
Definition: cluster.hh:221
int ID
Definition: TestMDC.C:70
wavecluster & operator=(const wavecluster &)
Definition: cluster.cc:77
ofstream out
Definition: cwb_merge.C:214
cout<< endl;cout<< "ts size = "<< ts.size()<< " ts rate = "<< ts.rate()<< endl;tf.Forward(ts, wdm);int levels=tf.getLevel();cout<< "tf size = "<< tf.size()<< endl;double dF=tf.resolution();double dT=1./(2 *dF);cout<< "rate(hz) : "<< RATE<< "\ layers : "<< nLAYERS<< "\ dF(hz) : "<< dF<< "\ dT(ms) : "<< dT *1000.<< endl;int itime=TIME_PIXEL_INDEX;int ifreq=FREQ_PIXEL_INDEX;int index=(levels+1) *itime+ifreq;double time=itime *dT;double freq=(ifreq >0) ? ifreq *dF :dF/4;cout<< endl;cout<< "PIXEL TIME = "<< time<< " sec "<< endl;cout<< "PIXEL FREQ = "<< freq<< " Hz "<< endl;cout<< endl;wavearray< double > x
double bpp
Definition: test_config1.C:22
size_t index
Definition: cluster.hh:59
double amplitude
virtual double setMask(WSeries< double > &, int=1, bool=false)
param: max number of pixels in clusters to be cleaned (<4); param: false - core only, true - core + halo return pixel occupancy
Definition: cluster.cc:1135
netpixel pix(nifo)
STL namespace.
std::slice getSlice(double n)
Definition: wseries.hh:152
virtual size_t init(WSeries< double > &, bool=false)
param: false - core only, true - core + halo return cluster list size
Definition: cluster.cc:104
Long_t size
int m
Definition: cwb_net.C:28
virtual void start(double s)
Definition: wavearray.hh:137
int j
Definition: cwb_net.C:28
i drho i
double gethigh() const
Definition: wseries.hh:136
#define N
cout<< "SNR "<< xsnr<< endl;wavearray< double > f
Definition: ComputeSNR.C:75
char ifo[NIFO_MAX][8]
double stop
Definition: cluster.hh:212
double low
Definition: cluster.hh:213
wavearray< double > w
Definition: Test1.C:27
virtual size_t size() const
Definition: wavearray.hh:145
wavecluster()
Definition: cluster.cc:44
int getLevel()
Definition: wseries.hh:109
double signPDF(const size_t m, const size_t k)
Definition: watfun.hh:97
virtual size_t coincidence(wavecluster &, double=1.)
param: input cluster list return size of the coincidence list
Definition: cluster.cc:675
void setvar(wavearray< float > &, double=-1., double=-1.)
Definition: cluster.cc:774
int asize()
Definition: cluster.hh:238
size_t start() const
Definition: wslice.hh:85
i() int(T_cor *100))
size_t stride() const
Definition: wslice.hh:93
double start
Definition: cluster.hh:211
bool log
Definition: WaveMDC.C:41
int compare_pix(const void *x, const void *y)
Definition: cluster.cc:33
char cut[512]
int getLayer(wavearray< DataType_t > &w, double n)
param: n - layer number
Definition: wseries.cc:193
printf("total live time: non-zero lags = %10.1f \, liveTot)
int l
double high
Definition: cluster.hh:214
virtual size_t merge(double=0.)
param: non return size of merged list
Definition: cluster.cc:483
void setrms(WSeries< double > &, double=-1., double=-1.)
Definition: cluster.cc:716
float rate
Definition: cluster.hh:60
int k
double F
double e
double shift
Definition: cluster.hh:216
double getbpp() const
Definition: wseries.hh:117
regression r
Definition: Regression_H1.C:44
virtual size_t apush(WSeries< double > &a, double=0.)
param: this and WSeries objects should have the same tree type and the approximation level size param...
Definition: cluster.cc:369
size_t clusterID
Definition: cluster.hh:56
bool BinaryTree()
Definition: Wavelet.hh:97
virtual size_t cleanhalo(bool=false)
param: if true - de-cluster pixels return size of the list
Definition: cluster.cc:311
double T
Definition: testWDM_4.C:11
ifstream in
wavearray< int > index
WSeries< double > nRMS
Definition: cluster.hh:229
double fabs(const Complex &x)
Definition: numpy.cc:55
Meyer< double > S(1024, 2)
DataType_t * data
Definition: wavearray.hh:319
Long_t id
WaveDWT< DataType_t > * pWavelet
Definition: wseries.hh:456
std::vector< double > amplitude
Definition: cluster.hh:65
double noiserms
Definition: cluster.hh:62
double getNoiseRMS(double, double, double)
param: pixel time, sec param: pixel low frequency param: pixel high frequency
Definition: cluster.cc:811
bool core
Definition: cluster.hh:63
double shift[NIFO_MAX]
virtual void resize(unsigned int)
Definition: wavearray.cc:463
wavearray< double > y
Definition: Test10.C:31
std::vector< int > neighbors
Definition: cluster.hh:64
char pm[8]
std::list< vector_int > cList
Definition: cluster.hh:225
int maxLayer()
Definition: wseries.hh:139
init()
Definition: revMonster.cc:12
size_t frequency
Definition: cluster.hh:58
std::vector< bool > sCuts
Definition: cluster.hh:223