Logo Coherent WaveBurst  
Reference Guide
Logo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
netcluster.cc
Go to the documentation of this file.
1 //---------------------------------------------------
2 // WAT cluster class for network analysis
3 // S. Klimenko, University of Florida
4 //---------------------------------------------------
5 
6 #define NETCLUSTER_CC
7 #include <time.h>
8 #include <iostream>
9 #include <stdexcept>
10 #include <set>
11 #include <limits>
12 #include "netcluster.hh"
13 #include "detector.hh"
14 #include "network.hh"
15 #include "constants.hh"
16 
17 #include "TCanvas.h"
18 #include "TH2F.h"
19 #include "TMath.h"
20 #include "TRandom3.h"
21 #include "TTreeFormula.h"
22 
23 using namespace std;
24 
25 ClassImp(netcluster)
26 
27 // used to check duplicated entries in vector<int>
28 template<typename T>
29 void removeDuplicates(std::vector<T>& vec)
30 {
31  std::sort(vec.begin(), vec.end());
32  vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
33 }
34 
35 // sort netpixel objects on time
36 int compare_PIX(const void *x, const void *y){
37  netpixel* p = *((netpixel**)x);
38  netpixel* q = *((netpixel**)y);
39  double a = double(p->time)/p->rate/p->layers
40  - double(q->time)/q->rate/q->layers;
41  if(a > 0) return 1;
42  if(a < 0) return -1;
43  return 0;
44 }
45 
46 // sort netpixel objects on likelihood (decreasind)
47 int compareLIKE(const void *x, const void *y){
48  netpixel* p = *((netpixel**)x);
49  netpixel* q = *((netpixel**)y);
50  double a = double(p->likelihood - q->likelihood);
51  if(a > 0) return -1;
52  if(a < 0) return 1;
53  return 0;
54 }
55 
56 
57 // structure and comparison function needed for optimizing mchirp
58 typedef struct{ double value; int type;} EndPoint;
59 
60 int compEndP(const void* p, const void* q)
61 { EndPoint* a = (EndPoint*)p;
62  EndPoint* b = (EndPoint*)q;
63  if(a->value > b->value)return 1;
64  return -1;
65 }
66 
67 // constructors
68 
70 {
71  this->clear();
72  this->rate = 0.;
73  this->start = 0.;
74  this->stop = 0.;
75  this->shift = 0.;
76  this->bpp = 1.;
77  this->flow = 0.;
78  this->fhigh = 1.e6;
79  this->run = 0;
80  this->nPIX = 3;
81  this->pair = true;
82  this->nSUB = 0;
83 
84  SetName("netcluster");
85 }
86 
88 {
89  *this = value;
90 }
91 
92 // destructor
93 
95 
96 // copyfrom function - copy selected clusters and pixels
97 // does not copy error regions
98 
99 size_t netcluster::cpf(const netcluster& value, bool optres, int nBIG)
100 {
101 // copy function (used in operator (=) as x.cpf(y,false)
102 //: copy content of y into x.
103 // If no clusters are reconstructed - copy all pixels.
104 // If clusters are reconstructed - copy selected clusters.
105 // value: netcluster object y
106 // optres: condition to select clusters:
107 // true - copy selected clusters with core pixels
108 // false - copy all selected clusters
109 // nBIG: min size of BIG clusters
110 // =0 - copy all clusters regardles of their size
111 // >0 - ignore BIG clusters with size >= nBIG
112 // <0 - copy BIG clusters with size >= nBIG
113  size_t n,m,k,K,ID;
114  size_t nbig = abs(nBIG);
115  size_t N = 0;
116  size_t cid = 0; // new cluster ID
117  size_t pid = 0; // new pixel ID
118  int R; // resolution
119 
120  std::vector<int> id; // list of pixels IDs in a cluster
121  std::vector<int> vr; // rate array
122  std::vector<int> refI; // reference integer
123  std::vector<float> refF; // reference float
124  std::vector<vector_int>::const_iterator it;
125 
126  netpixel pix;
127 
128  this->clear();
129  this->rate = value.rate;
130  this->start = value.start;
131  this->stop = value.stop;
132  this->shift = value.shift;
133  this->bpp = value.bpp;
134  this->run = value.run;
135  this->nPIX = value.nPIX;
136  this->flow = value.flow;
137  this->fhigh = value.fhigh;
138  this->pair = value.pair;
139 
140  if(!value.cList.size()) { // not clustered value
141  this->pList = value.pList;
142  this->cluster();
143  return this->pList.size();
144  }
145 
146  for(it=value.cList.begin(); it!=value.cList.end(); it++){
147 
148  ID = value.pList[(*it)[0]].clusterID;
149  K = it->size(); // cluster size
150  if(value.sCuts[ID-1]>0) continue; // apply selection cuts
151  if(nBIG>0 && K>nbig) continue; // do not copy BIG clusters
152  if(nBIG<0 && K<nbig) continue; // copy only BIG clusters
153 
154  vr = value.cRate[ID-1]; // rate array
155  m = vr.size(); // size of rate array
156  if(m && optres) { // count only optimal resolution pixels
157  for(k=0; k<K; k++) {
158  R = int(value.pList[(*it)[k]].rate+0.1);
159  if(vr[0] == R) N++;
160  }
161  }
162  else N += K; // count all pixels
163  }
164  this->pList.reserve(N+2);
165 
166  for(it=value.cList.begin(); it!=value.cList.end(); it++){
167 
168  K = it->size();
169  ID = value.pList[(*it)[0]].clusterID;
170  if(value.sCuts[ID-1]>0) continue; // apply selection cuts
171  if(!K) continue; // skip empty cluster (e.g. after defragmentation)
172 
173  vr = value.cRate[ID-1]; // rate array
174  m = vr.size(); // size of rate array
175 
176  cid++; // increment cluster ID
177  id.clear(); // clear pixel list
178 
179  for(k=0; k<K; k++) { // loop over pixels
180  pix = value.pList[(*it)[k]];
181  R = int(value.pList[(*it)[k]].rate+0.1);
182 
183  if(m && optres) { // skip if not optimal resolution
184  if(vr[0] != R) continue;
185  }
186 
187  pix.neighbors.clear();
188  std::vector<int>().swap(pix.neighbors); // free memory
189  pix.clusterID = cid;
190  n = this->pList.size();
191  if(id.size()) {
192  pix.append(-1); // append a neighbor on the left
193  this->pList[n-1].append(1); // append a neighbor on the right
194  }
195  id.push_back(pid++); // update pixel list
196  this->append(pix); // append pixel to pList
197  }
198 
199  if(!id.size()) cout<<"netcluster::cpf() error: empty cluster.";
200 
201  cList.push_back(id); // fill cluster list
202  cData.push_back(value.cData[ID-1]); // copy cluster metadata
203  sCuts.push_back(0); // fill selection cuts
204  cRate.push_back(vr); // fill in rate array
205  p_Ind.push_back(refI); // create other arrays
206  p_Map.push_back(refF);
207  sArea.push_back(refF);
208  nTofF.push_back(refI);
209  cTime.push_back(value.cTime[ID-1]); // save supercluster central time
210  cFreq.push_back(value.cFreq[ID-1]); // save supercluster frequency
211  }
212  return this->pList.size();
213 }
214 
215 // netcluster::operator - copy only selected clusters
216 
218 {
219  this->cpf(value,false);
220  return *this;
221 }
222 
223 
224 size_t netcluster::setcore(bool core, int id)
225 {
226 // set pixel core field to be equal to the input parameter core
227 // reset cluster type to 0 except for rejecter clusters (type=1)
228  const vector_int* v;
229  size_t i,k,K;
230 
231  for(i=0; i<this->cList.size(); i++){
232 
233  v = &(this->cList[i]);
234  K = v->size();
235 
236  for(k=0; k<K; k++) {
237  if(id && this->pList[(*v)[k]].clusterID != id) continue;
238  this->pList[(*v)[k]].core = core;
239  }
240  }
241  return this->size();
242 }
243 
245 {
246 // select clusters - work with a single resolution
247 // name - parameter name
248 // thr - parameter threshold
249 
250  if(!this->pList.size()) return 0;
251 
252  if(!this->nSUB) this->nSUB=(2*iGamma(pList[0].size()-1,0.314));
253 
254  double aa,ee,mm;
255  wavearray<double> ID = this->get(const_cast<char*>("ID")); // get cluster ID
256  wavearray<double> out = ID; out=0;
257  int I = ID.size();
258 
259  if(strstr(name,"subnet")) { // subnetwork power;
260  out = this->get(const_cast<char*>("subnet"),0,'S'); // get subnetwork power
261  for(int i=0; i<I; i++){
262  aa = out.data[i];
263  if(aa<thr) this->ignore(ID.data[i]);
264  }
265  }
266 
267  if(strstr(name,"subrho")) { // subnetwork power;
268  out = this->get(const_cast<char*>("subrho"),0,'S'); // get subnetwork power
269  for(int i=0; i<I; i++){
270  aa = out.data[i];
271  if(aa<thr) this->ignore(ID.data[i]);
272  }
273  }
274 
275  if(strstr(name,"SUBCUT")) { // subnetwork
276  wavearray<double> sub = this->get(const_cast<char*>("subnrg"),0,'S'); // get subnetwork energy
277  wavearray<double> siz = this->get(const_cast<char*>("size"),0,'S'); // get cluster size
278  wavearray<double> max = this->get(const_cast<char*>("maxnrg"),0,'S'); // get maximum detector energy
279  double prl,qrl,ptime,qtime,pfreq,qfreq;
280  int N = pList.size();
281  netpixel* p; // pointer to pixel structure
282  netpixel* q; // pointer to pixel structure
283 
284  for(int i=0; i<I; i++){
285  aa = sub.data[i];
286  mm = siz.data[i];
287  aa = aa*(1+aa/max.data[i]);
288  out.data[i] = aa/(aa+mm+max.data[i]/10.);
289  if(out.data[i]>thr) continue;
290  this->ignore(ID.data[i]); // reject cluster
291 
292  const vector_int& vint = cList[ID.data[i]-1];
293  int K = vint.size();
294 
295  for(int n=0; n<N; n++) { // search for fragments
296  p = &(pList[n]);
297  if(sCuts[p->clusterID-1]>0) continue; // skip rejected pixels
298  prl = p->rate*p->layers;
299  ptime = p->time/prl; // time in seconds
300  pfreq = p->frequency*p->rate/2.; // frequency in Hz
301 
302  for(int k; k<K; k++){ // loop over rejected cluster
303  q = &pList[vint[k]];
304  qrl = q->rate*q->layers;
305  qtime = q->time/qrl; // time in seconds
306  qfreq = q->frequency*q->rate/2.; // frequency in Hz
307 
308  if(fabs(qfreq-pfreq)>128 &&
309  fabs(qtime-ptime)>0.125) continue;
310  sCuts[p->clusterID-1] = 1;
311  }
312  }
313  }
314  }
315  return out;
316 }
317 
319 {
320 //: clean input wseries ws removing rejected clusters
321 //: output number of remaining pixels
322  if(!pList.size() || !cList.size()) return 0;
323 
324  int i,ID;
325  int N = ws.pWavelet->nWWS/ws.pWavelet->nSTS;
326  int I = ws.pWavelet->nWWS/N;
327  int J = N>1? I : 0;
328  int K = pList.size();
329 
330  netpixel* pix = NULL;
331  vector<vector_int>::iterator it;
332 
333  for(it=this->cList.begin(); it != this->cList.end(); it++) { // loop over clusters
334 
335  pix = &(this->pList[((*it)[0])]);
336  ID = pix->clusterID;
337  if(this->sCuts[ID-1]==0) continue; // skip selected clusters
338 
339  for(size_t n=0; n<it->size(); n++) { // loop over pixels in the cluster
340  pix = &(this->pList[((*it)[n])]);
341  i = pix->time;
342  if(i < I) {
343  ws.data[i] = 0;
344  ws.data[i+J]=0;
345  K--;
346  }
347  }
348  }
349  return K;
350 }
351 
352 
353 // delink superclusters)
355 {
356 // delink superclusters
357 // - destroy supercluster neighbors links
358 // - preserve links for pixels with the same wavelet resolution
359 
360  size_t K = this->pList.size();
361  size_t n,k,N;
362 
363  if(!K) return 0;
364 
365  std::vector<int> v;
366  std::vector<int>* u;
367  netpixel* q;
368  netpixel* p;
369 
370  for(k=0; k<K; k++) {
371  q = &(this->pList[k]);
372  u = &(this->pList[k].neighbors);
373  v = *u;
374  u->clear();
375  N = v.size();
376  for(n=0; n<N; n++) {
377  p = q+v[n]; // pixel index in pList
378  if(p->clusterID != q->clusterID) {
379  cout<<"netcluster::delink(): cluster ID mismatch"<<endl;
380  continue;
381  }
382  // restore neighbors for the same resolution
383  if(p->rate == q->rate) q->append(v[n]);
384  }
385  }
386  return this->cluster();
387 }
388 
389 
390 size_t netcluster::cluster(int kt, int kf)
391 {
392 // produce time-frequency clusters at a single TF resolution
393 // any two pixels are associated if they are closer than both kt/kf
394 // samples in time/ftrequency
395  size_t i,j;
396  size_t n = this->pList.size();
397  if(n==0) return 0;
398  size_t M = this->pList[0].layers;
399  double R = this->pList[0].rate;
400 
401  int index;
402 
403  if(kt<=0) kt = 1;
404  if(kf<=0) kf = 1;
405  if(!n) return 0;
406  if(n==1) return this->cluster();
407 
408  netpixel** pp = (netpixel**)malloc(n*sizeof(netpixel*));
409  netpixel* p;
410  netpixel* q;
411 
412  for(i=0; i<n; i++) { pp[i] = &(pList[i]); pp[i]->neighbors.clear();}
413 
414  qsort(pp, n, sizeof(netpixel*), &compare_PIX); // sorted pixels
415 
416  for(i=0; i<n; i++) {
417  p = pp[i];
418  bool isWavelet = (size_t(this->rate/R+0.1) == pp[i]->layers) ? true : false; // wavelet : WDM
419 
420  if(R != p->rate || M != p->layers)
421  cout<<"netcluster::cluster(int,int) applied to mixed pixel list"<<endl;
422 
423  for(j=i+1; j<n; j++){
424  q = pp[j];
425  if(isWavelet) {
426  index = int(q->time) - int(p->time); // wavelet
427  } else {
428  index = int(q->time/M) - int(p->time/M); // WDM
429  }
430 
431  if(index < 0) cout<<"netcluster::cluster(int,int) sort error"<<endl;
432  if(isWavelet) {
433  if(index/M > kt) break; // wavelet
434  } else {
435  if(index > kt) break; // WDM
436  }
437 
438  if(abs(int(q->frequency) - int(p->frequency)) <= kf) { // set neighbours
439  p->append(q-p); // insert in p
440  q->append(p-q); // insert in q
441  }
442  }
443  }
444 
445  free(pp);
446  return this->cluster();
447 }
448 
449 
451 {
452 // perform cluster analysis
453 // this function initializes the netcluster data structures and
454 // call recursive cluster(netpixel) function to break pixel set into
455 // clusters.
456  size_t volume;
457  size_t i,m;
458  vector<int> refMask;
459  vector<int> refRate;
460  vector<float> refArea;
461  clusterdata refCD;
462  size_t nCluster = 0;
463  size_t n = pList.size();
464 
465  if(!pList.size()) return 0;
466 
467  // clear/initialize netcluster metadata
468 
469  cList.clear();
470  cData.clear();
471  sCuts.clear();
472  cRate.clear();
473  cTime.clear();
474  cFreq.clear();
475  sArea.clear();
476  p_Ind.clear();
477  p_Map.clear();
478  nTofF.clear();
479 
480  for(i=0; i<n; i++) pList[i].clusterID = 0;
481 
482  // loop over pixels
483 
484  for(i=0; i<n; i++){
485  if(pList[i].clusterID) continue; // pixel is clustered
486  pList[i].clusterID = ++nCluster; // new seed pixel - set ID
487  volume = cluster(&pList[i]); // cluster and return number of pixels
488  refMask.clear(); // to the end of the loop
489  cRate.push_back(refRate); // initialize cluster metadata
490  cTime.push_back(-1.);
491  cFreq.push_back(-1.);
492  p_Ind.push_back(refRate);
493  p_Map.push_back(refArea);
494  sArea.push_back(refArea);
495  nTofF.push_back(refRate);
496  refMask.resize(volume);
497  cList.push_back(refMask);
498  cData.push_back(refCD);
499  sCuts.push_back(0);
500  }
501 
502  vector<vector_int>::iterator it;
503  nCluster = 0;
504  if(!cList.size()) return 0;
505 
506  for(it=cList.begin(); it != cList.end(); it++) {
507  nCluster++;
508 
509  m = 0;
510  for(i=0; i<n; i++) {
511  if(pList[i].clusterID == nCluster) (*it)[m++] = i;
512  }
513 
514  if(it->size() != m) {
515  cout<<"cluster::cluster() size mismatch error: ";
516  cout<<m<<" size="<<it->size()<<" "<<nCluster<<endl;
517  }
518  }
519  return nCluster;
520 }
521 
523 {
524 // recursive clustering function used in cluster()
525 // it check neighbors and set the cluster ID field
526  size_t volume = 1;
527  int i = p->neighbors.size();
528  netpixel* q;
529 
530  while(--i >= 0){
531  q = p + p->neighbors[i];
532  if(!q->clusterID){
533  q->clusterID = p->clusterID;
534  volume += cluster(q);
535  }
536  }
537  return volume;
538 }
539 
540 
541 
542 size_t netcluster::cleanhalo(bool keepid)
543 {
544 // remove halo pixels from the pixel list
545 
546  if(!pList.size() || !cList.size()) return 0;
547 
548  size_t i,n,ID;
549  size_t cid = 0; // new cluster ID
550  size_t pid = 0; // new pixel ID
551 
552  netpixel* pix = NULL;
553  vector<vector_int>::iterator it;
554  std::vector<int> id; // list of pixels IDs in a cluster
555  std::vector<int>* pr; // pointer to rate array
556  std::vector<int> refI; // reference integer
557  std::vector<float> refF; // reference float
558 
559  netcluster x(*this);
560 
561  this->clear();
562 
563  for(it=x.cList.begin(); it != x.cList.end(); it++) { // loop over clusters
564 
565  pix = &(x.pList[((*it)[0])]);
566  ID = pix->clusterID;
567  if(x.sCuts[ID-1]>0) continue; // apply selection cuts
568  n = x.cRate.size();
569  pr = n ? &(x.cRate[ID-1]) : NULL; // pointer to the rate array
570 
571  cid++;
572  id.clear();
573  for(i=0; i<it->size(); i++) { // loop over pixels in the cluster
574  pix = &(x.pList[((*it)[i])]);
575  if(pix->core) {
576  pix->clusterID = keepid ? cid : 0;
577  pix->neighbors.clear();
578  std::vector<int>().swap(pix->neighbors); // free memory
579  id.push_back(pid++);
580  this->append(*pix); // fill pixel list
581  }
582  }
583 
584  i = id.size();
585  if(!i) cout<<"netcluster::cleanhalo() error: empty cluster.";
586 
587  if(keepid) {
588  cList.push_back(id); // fill cluster list
589  cData.push_back(x.cData[ID-1]); // fillin cluster metadata
590  sCuts.push_back(0); // fill selection cuts
591  if(pr) cRate.push_back(*pr); // fill in rate array
592  p_Ind.push_back(refI); // create other arrays
593  p_Map.push_back(refF);
594  sArea.push_back(refF);
595  nTofF.push_back(refI);
596  cTime.push_back(x.cTime[ID-1]); // fillin cluster central time
597  cFreq.push_back(x.cFreq[ID-1]); // fillin cluster frequency
598  }
599 
600  if(i<2) continue;
601 
602  while(--i > 0) { // set neighbors
603  pList[id[i-1]].append(id[i]-id[i-1]);
604  pList[id[i]].append(id[i-1]-id[i]);
605  }
606 
607 
608  }
609  return pList.size();
610 }
611 
613 {
614 // add halo pixels to the pixel list
615 // set pixel neighbours to match the packet pattern defined by mode
616 
617  if(!pList.size() || !cList.size()) return 0;
618  if(mode==0) return pList.size();
619 
620  size_t i,j,k,n,nIFO,ID,K,JJ;
621  int N,M,J;
622  size_t cid = 0; // new cluster ID
623  size_t pid = 0; // new pixel ID
624  bool save;
625 
626  netpixel* pix = NULL;
627  netpixel* PIX = NULL;
628  netpixel tmp;
629  vector<vector_int>::iterator it;
630  std::vector<int> id; // list of pixels IDs in a cluster
631  std::vector<int> jj; // time index array
632  std::vector<int> nid; // neighbors ID
633  std::vector<int>* pn; // pointer to neighbors array
634  std::vector<int> refI; // reference integer
635  std::vector<float> refF; // reference float
636 
637  netcluster x(*this);
638  this->clear();
639 
640  for(k=0; k<9; k++) {nid.push_back(0); jj.push_back(0);}
641 
642  for(it=x.cList.begin(); it != x.cList.end(); it++) { // loop over clusters
643 
644  pix = &(x.pList[((*it)[0])]);
645  ID = pix->clusterID;
646  if(x.sCuts[ID-1]>0) continue; // apply selection cuts
647 
648  cid++;
649  id.clear(); // clear list of pixel IDs
650 
651  for(i=0; i<it->size(); i++) { // loop over pixels in the cluster
652  pix = &(x.pList[((*it)[i])]);
653  pix->neighbors.clear();
654  std::vector<int>().swap(pix->neighbors); // free memory
655  id.push_back(pid++);
656  this->append(*pix); // fill pixel list
657  }
658 
659  for(i=0; i<it->size(); i++) { // loop over pixels in the cluster
660  pix = &(x.pList[((*it)[i])]);
661  M = int(pix->layers); // number of wavelet layers
662  J = int(pix->time); // pixel index
663  if(!(J%M) || !((J-1)%M) || !((J-2)%M) || !((J+1)%M)) continue;
664 
665  jj[0] = J;
666  if(mode==1) { // store packet pattern in jj
667  jj[1]=J-M+1; jj[2]=J+1; jj[3]=J+M+1;
668  jj[4]=J-M-1; jj[5]=J-1; jj[6]=J+M-1;
669  K = 7;
670  } else if(mode==3) {
671  jj[1]=J-M-1; jj[2]=J+M+1; K=3;
672  } else if(mode==-3) {
673  jj[1]=J+M-1; jj[2]=J-M+1; K=3;
674  } else if(mode==5) {
675  jj[1]=J-2*M-2; jj[2]=J+2*M+3;
676  jj[3]=J-M-1; jj[4]=J+M+1; K=5;
677  } else if(mode==-5) {
678  jj[1]=J+2*M-2; jj[2]=J-2*M+3;
679  jj[3]=J+M-1; jj[4]=J-M+1; K=5;
680  } else {
681  jj[1]=J-M-1; jj[2]=J+M+1;
682  jj[3]=J+M-1; jj[4]=J-M+1; K=5;
683  }
684 
685  for(k=0; k<K; k++) nid[k]=0;
686  for(j=0; j<id.size(); j++) { // loop over pixels in the cluster
687  PIX = &(this->pList[id[j]]);
688  N = int(PIX->layers); // number of wavelet bands (binary wavelet)
689  if(N!=M) continue; // skip different resolutions
690  J = int(PIX->time); // number of wavelet bands (binary wavelet)
691  for(k=0; k<K; k++) { // find pixels already in the pattern
692  if(J==jj[k]) nid[k] = id[j]+1; // already saved
693  }
694  }
695 
696  tmp = *pix;
697  for(k=1; k<K; k++) {
698  if(nid[k]!=0) continue;
699  id.push_back(pid++);
700  nid[k] = pid;
701  tmp.time = jj[k];
702  for(n=0; n<nIFO; n++) { // store original index
703  pix->data[n].index+=jj[k]-jj[0]; // update index in the detectors
704  }
705  pix->core = false;
706  this->append(tmp); // append halo pixel
707  }
708 
709  pn = &(this->pList[nid[0]-1].neighbors); // neighbour size in test pixel
710  for(k=1; k<K; k++) {
711  save = true;
712  for(j=0; j<pn->size(); j++)
713  if(nid[k]==(*pn)[j]+1) save=false; // find is naighbor is already saved
714  if(save) pn->push_back(nid[k]-1); // save packet neighbor
715  }
716  }
717 
718  cList.push_back(id); // fill cluster list
719  sCuts.push_back(0); // fill selection cuts
720  cData.push_back(x.cData[ID-1]); // fill cluster metadata
721  cRate.push_back(refI);
722  p_Ind.push_back(refI); // create other arrays
723  p_Map.push_back(refF);
724  sArea.push_back(refF);
725  nTofF.push_back(refI);
726  cTime.push_back(x.cTime[ID-1]); // fill cluster central time
727  cFreq.push_back(x.cFreq[ID-1]); // fill cluster frequency
728 
729  i = id.size();
730  if(!i) cout<<"netcluster::addhalo() error: empty cluster.";
731  if(i<2) continue;
732 
733  pList[id[i-1]].append(id[0]-id[i-1]);
734  pList[id[0]].append(id[i-1]-id[0]);
735  while(--i > 0) { // set neighbors
736  pList[id[i-1]].append(id[i]-id[i-1]);
737  pList[id[i]].append(id[i-1]-id[i]);
738  }
739 
740  //cout<<"new cluster\n";
741  //for(j=0; j<id.size(); j++) { // loop over pixels in the cluster
742  // PIX = &(this->pList[id[j]]);
743  // cout<<"list: "<<PIX->clusterID<<" "<<PIX->neighbors.size()<<" "<<PIX->layers<<endl;
744  //}
745 
746  }
747  return pList.size();
748 }
749 
751 {
752 // append pixel list.
753 // - to reconstruct clusters and cluster metadata run cluster() utility
754 
755  size_t i;
756  size_t in = w.pList.size();
757  size_t on = pList.size();
758 
759  if(!on) {
760  *this = w;
761  this->clear();
762  return in;
763  }
764  if(!in) { return on; }
765 
766  netpixel p;
767 
768  if(w.start!=start || w.shift!=shift || w.rate!=rate) {
769  printf("\n netcluster::append(): cluster type mismatch");
770  printf("%f / %f, %f / %f\n",w.start,start,w.shift,shift);
771 
772  return on;
773  }
774 
775  this->pList.reserve(in+on+2);
776  for(i=0; i<in; i++){
777  p = w.pList[i];
778  p.clusterID = 0; // update cluster ID
779  this->append(p); // add pixel to pList
780  }
781 
782  return pList.size();
783 }
784 
785 
786 //**************************************************************************
787 // construct super clusters (used in 1G pipeline)
788 //**************************************************************************
789 size_t netcluster::supercluster(char atype, double S, bool core)
790 {
791  size_t i,j,k,m,M;
792  size_t n = pList.size();
793  int l;
794 
795  if(!n) return 0;
796 
797  netpixel* p = NULL; // pointer to pixel structure
798  netpixel* q = NULL; // pointer to pixel structure
799  std::vector<int>* v;
800  float eps;
801  double E;
802  bool insert;
803  double ptime, pfreq;
804  double qtime, qfreq;
805 
806  netpixel** pp = (netpixel**)malloc(n*sizeof(netpixel*));
807  netpixel** ppo = pp;
808  netpixel* g;
809 
810 // sort pixels
811 
812  for(i=0; i<n; i++) { pp[i] = &(pList[i]);}
813  g = pp[0];
814  qsort(pp, n, sizeof(netpixel*), &compare_PIX); // sort pixels
815 
816 // update neighbors
817 
818  for(i=0; i<n; i++) {
819  p = pp[i];
820  M = size_t(this->rate/p->rate+0.5); // number of frequency layers
821  ptime = (p->time/M+0.5)/p->rate; // extract time
822  pfreq = (p->frequency+0.5)*p->rate;
823 
824  for(j=i+1; j<n; j++){
825  q = pp[j];
826 
827  eps = 0.55/p->rate + 0.55/q->rate;
828  M = size_t(this->rate/q->rate+0.5); // number of frequency layers
829  qtime = (q->time/M+0.5)/q->rate;
830 
831  if(qtime<ptime-eps) cout<<"netcluster::merge() error"<<endl;
832 
833  if(qtime-ptime > 1.) break;
834  if(fabs(qtime-ptime) > eps) continue;
835  if(p->rate==q->rate) continue;
836  if(!(p->rate==2*q->rate || q->rate==2*p->rate)) continue;
837 
838  eps = 0.55*(p->rate+q->rate);
839  qfreq = (q->frequency+0.5)*q->rate;
840  if(fabs(pfreq-qfreq) > eps) continue;
841 
842 // insert in p
843 
844  l = q-p;
845 
846  insert = true;
847  v = &(p->neighbors);
848  m = v->size();
849  for(k=0; k<m; k++) {
850  if((*v)[k] == l) {insert=false; break;}
851  }
852  if(insert) p->append(l); // add new neighbor
853 
854 // insert in q
855 
856  l = p-q;
857 
858  insert = true;
859  v = &(q->neighbors);
860  m = v->size();
861  for(k=0; k<m; k++) {
862  if((*v)[k] == l) {insert=false; break;}
863  }
864  if(insert) q->append(l); // add new neighbor
865 
866  }
867  }
868 
869  if(ppo==pp) free(pp);
870  else {cout<<"netcluster::cluster() free()\n"; exit(1);}
871 
872 //***************
873  cluster();
874 //***************
875 
876  std::vector<vector_int>::iterator it;
877  netpixel* pix = NULL;
878  std::vector<int> rate;
879  std::vector<int> temp;
880  std::vector<int> sIZe;
881  std::vector<bool> cuts;
882  std::vector<double> ampl;
883  std::vector<double> powr;
884  std::vector<double> like;
885 
886  double a,L,e,tt,cT,cF,nT,nF;
887  size_t ID,mm;
888  size_t max = 0;
889  size_t min = 0;
890  size_t count=0;
891  bool cut;
892  bool oEo = atype=='E' || atype=='P';
893 
894  for(it=cList.begin(); it != cList.end(); it++) {
895  k = it->size();
896  if(!k) cout<<"netcluster::supercluster() error: empty cluster.\n";
897 
898 // fill cluster statistics
899 
900  m = 0; E = 0;
901  cT=cF=nT=nF=0.;
902  rate.clear();
903  ampl.clear();
904  powr.clear();
905  like.clear();
906  cuts.clear();
907  sIZe.clear();
908  temp.clear();
909 
910  ID = pList[((*it)[0])].clusterID;
911 
912  for(i=0; i<k; i++) {
913  pix = &(pList[((*it)[i])]);
914  if(!pix->core && core) continue;
915  L = pix->likelihood;
916  e = 0.;
917  for(j=0; j<pix->size(); j++) {
918  a = pix->data[j].asnr;
919  e+= fabs(a)>1. ? a*a-1 : 0.;
920  }
921 
922  a = atype=='L' ? L : e;
923  tt = 1./pix->rate; // wavelet time resolution
924  mm = size_t(this->rate*tt+0.1); // number of wavelet layers
925  cT += (pix->time/mm + 0.5)*a; // pixel time sum
926  nT += a/tt; // use weight L/t
927  cF += (pix->frequency+0.5)*a; // pixel frequency sum
928  nF += a*2.*tt; // use weight L*2t
929 
930  insert = true;
931  for(j=0; j<rate.size(); j++) {
932  if(rate[j] == int(pix->rate+0.1)) {
933  insert=false;
934  ampl[j] += e;
935  sIZe[j] += 1;
936  like[j] += L;
937  }
938  }
939 
940  if(insert) {
941  rate.push_back(int(pix->rate+0.1));
942  ampl.push_back(e);
943  powr.push_back(0.);
944  sIZe.push_back(1);
945  cuts.push_back(true);
946  like.push_back(L);
947  }
948 
949  m++; E += e;
950 
951  if(ID != pix->clusterID)
952  cout<<"netcluster::merge() error: cluster ID mismatch.\n";
953  }
954 
955 // cut off single level clusters
956 // coincidence between levels
957 
958  if(rate.size()<size_t(1+this->pair) || m<nPIX){ sCuts[ID-1] = true; continue; }
959 
960  cut = true;
961  for(i=0; i<rate.size(); i++) {
962  if((atype=='L' && like[i]<S) || (oEo && ampl[i]<S)) continue;
963  if(!pair) { cuts[i] = cut = false; continue; }
964  for(j=0; j<rate.size(); j++) {
965  if((atype=='L' && like[j]<S) || (oEo && ampl[j]<S)) continue;
966  if(rate[i]/2==rate[j] || rate[j]/2==rate[i]) {
967  cuts[i] = cuts[j] = cut = false;
968  }
969  }
970  }
971  if(cut || sCuts[ID-1]) { sCuts[ID-1] = true; continue; }
972 
973 // select optimal resolution
974 
975  a = -1.e99;
976  for(j=0; j<rate.size(); j++) { // select max excess power or likelihood
977  powr[j] = ampl[j]/sIZe[j];
978  if(atype=='E' && ampl[j]>a && !cuts[j]) {max=j; a=ampl[j];}
979  if(atype=='L' && like[j]>a && !cuts[j]) {max=j; a=like[j];}
980  if(atype=='P' && powr[j]>a && !cuts[j]) {max=j; a=powr[j];}
981  }
982 
983  if(a<S) { sCuts[ID-1] = true; continue; }
984 
985  a = -1.e99;
986  for(j=0; j<rate.size(); j++) {
987  if(max==j) continue;
988  if(atype=='E' && ampl[j]>a && !cuts[j]) {min=j; a=ampl[j];}
989  if(atype=='L' && like[j]>a && !cuts[j]) {min=j; a=like[j];}
990  if(atype=='P' && powr[j]>a && !cuts[j]) {max=j; a=powr[j];}
991  }
992 
993  temp.push_back(rate[max]);
994  temp.push_back(rate[min]);
995  cTime[ID-1] = cT/nT;
996  cFreq[ID-1] = cF/nF;
997  cRate[ID-1] = temp;
998  count++;
999 
1000  }
1001 
1002  return count;
1003 }
1004 
1005 
1006 //**************************************************************************
1007 // construct super clusters for 2G analysis
1008 //**************************************************************************
1009 size_t netcluster::supercluster(char atype, double S, double gap, bool core, TH1F* his)
1010 {
1011 //:reconstruct clusters at several TF resolutions (superclusters)
1012 //!param: statistic: 'E' - excess power, 'L' - likelihood
1013 //!param: selection threshold S defines a threshold on clusters
1014 //! in a superclusters.
1015 //!param: time-frequency gap used for clustering
1016 //!param: true - use only core pixels, false - use core & halo pixels
1017 //!return size of pixel list of selected superclusters.
1018 // algorithm:
1019 // - sort the pixel list with compare_PIX condition
1020 // - calculate the tim-frequency gap between pixels (1&2) with the same or
1021 // adjacent resolutions: eps = (dT>0?dT*R:0) + (dF>0?dF*T:0), where
1022 // dT/dF are time/frequency gaps, R/T are average rate and time:
1023 // R = rate1+rate2, T = 1/rate1+1/rqte2.
1024 // - if the clustering condition is satisfied, update the neighbor array
1025 // - cluster
1026 // - select superclusters with with clusters in the adjacent resolutions if
1027 // this->pair is true.
1028 // in this function the optimal resolution is defined but not used
1029 
1030  size_t i,j,k,m;
1031  size_t n = pList.size();
1032  int l;
1033 
1034  if(!n) return 0;
1035 
1036  netpixel* p = NULL; // pointer to pixel structure
1037  netpixel* q = NULL; // pointer to pixel structure
1038  std::vector<int>* v;
1039  double eps,E,R,T,dT,dF,prl,qrl,aa;
1040  bool insert;
1041  double ptime, pfreq;
1042  double qtime, qfreq;
1043  double Tgap = 0.;
1044  size_t nIFO = pList[0].size(); // number of detectors
1045 
1046  netpixel** pp = (netpixel**)malloc(n*sizeof(netpixel*));
1047  netpixel** ppo = pp;
1048  netpixel* g;
1049 
1050 // sort pixels
1051 
1052  for(i=0; i<n; i++) {
1053  pp[i] = &(pList[i]);
1054  R = pp[i]->rate;
1055  if(1./R > Tgap) Tgap = 1./R; // calculate max time bin
1056  }
1057  Tgap *= (1.+gap);
1058 
1059  // printf("gap = %lf\t dF = %lf\t S = %lf\n", gap, dF, S);
1060 
1061  g = pp[0];
1062  qsort(pp, n, sizeof(netpixel*), &compare_PIX); // sort pixels
1063 
1064  // update neighbors
1065 
1066  for(i=0; i<n; i++) {
1067  p = pp[i];
1068  prl = p->rate*p->layers;
1069  ptime = p->time/prl; // time in seconds
1070  pfreq = p->frequency*p->rate; // frequency in Hz
1071 
1072  for(j=i+1; j<n; j++){
1073  q = pp[j];
1074  qrl = q->rate*q->layers;
1075  if(p->clusterID && p->clusterID==q->clusterID) continue;
1076  qtime = q->time/qrl; // time in seconds
1077  if(qtime-ptime > Tgap) {break;} //printf("gap breaking!\n"); break;}
1078  if(p->rate/q->rate > 3) continue;
1079  if(q->rate/p->rate > 3) continue;
1080  qfreq = q->frequency*q->rate; // frequency in Hz
1081 
1082  if(qtime<ptime) {
1083  cout<<"netcluster::supercluster() error "<<qtime-ptime<<endl;
1084  cout<<p->rate<<" "<<q->rate<<" "<<p->time<<" "<<q->time<<endl;
1085  }
1086 
1087  R = p->rate+q->rate;
1088  T = 1/p->rate+1/q->rate;
1089 
1090  dT = 0.;
1091  for(k=0; k<nIFO; k++) { // max time gap among all detectors
1092  aa = p->data[k].index/prl; // time in seconds
1093  aa-= q->data[k].index/qrl; // time in seconds
1094  if(fabs(aa)>dT) dT = fabs(aa);
1095  }
1096 
1097  dT -= 0.5*T; // time gap between pixels
1098  dF = fabs(qfreq-pfreq) - 0.5*R; // frequency gap between pixels
1099  eps = (dT>0?dT*R:0) + (dF>0?dF*T:0); // 2 x number of pixels
1100  if(his) his->Fill(eps);
1101  if(gap < eps) continue;
1102 
1103  // insert in p
1104 
1105  l = q-p;
1106  insert = true;
1107  v = &(p->neighbors);
1108  m = v->size();
1109 
1110  for(k=0; k<m; k++) {
1111  if((*v)[k] == l) {insert=false; break;}
1112  }
1113 
1114  if(insert) p->append(l); // add new neighbor
1115 
1116  // insert in q
1117 
1118  l = p-q;
1119  insert = true;
1120  v = &(q->neighbors);
1121  m = v->size();
1122 
1123  for(k=0; k<m; k++) {
1124  if((*v)[k] == l) {insert=false; break;}
1125  }
1126 
1127  if(insert) q->append(l); // add new neighbor
1128  }
1129  }
1130 
1131  if(ppo==pp) free(pp);
1132  else {cout<<"netcluster::supercluster() free()\n"; exit(1);}
1133 
1134 //***************
1135  cluster();
1136 //***************
1137 
1138  std::vector<vector_int>::iterator it;
1139  netpixel* pix = NULL;
1140  std::vector<int> rate;
1141  std::vector<int> temp;
1142  std::vector<int> sIZe;
1143  std::vector<bool> cuts;
1144  std::vector<double> ampl;
1145  std::vector<double> powr;
1146  std::vector<double> like;
1147 
1148  double a,L,e,tt,cT,cF,nT,nF;
1149  size_t ID,mm;
1150  size_t max = 0;
1151  size_t min = 0;
1152  size_t count=0;
1153  bool cut;
1154  bool oEo = atype=='E' || atype=='P';
1155 
1156  for(it=cList.begin(); it != cList.end(); it++) {
1157  k = it->size();
1158  if(!k) cout<<"netcluster::supercluster() error: empty cluster.\n";
1159 
1160  // fill cluster statistics
1161 
1162  m = 0; E = 0;
1163  cT=cF=nT=nF=0.;
1164  rate.clear();
1165  ampl.clear();
1166  powr.clear();
1167  like.clear();
1168  cuts.clear();
1169  sIZe.clear();
1170  temp.clear();
1171 
1172  ID = pList[((*it)[0])].clusterID;
1173 
1174  for(i=0; i<k; i++) { // for each pixel in the cluster
1175  pix = &(pList[((*it)[i])]);
1176  if(!pix->core && core) continue;
1177  L = pix->likelihood;
1178  e = 0.;
1179  for(j=0; j<pix->size(); j++) {
1180  a = pix->data[j].asnr; // asnr is an energy
1181  e+= fabs(a)>1. ? a : 0.;
1182  }
1183 
1184  a = atype=='L' ? L : e;
1185  tt = 1./pix->rate; // wavelet time resolution
1186  mm = pix->layers; // number of wavelet layers
1187  cT += int(pix->time/mm)*a; // pixel time sum
1188  nT += a/tt; // use weight L/t
1189  cF += (pix->frequency+dF)*a; // pixel frequency sum
1190  nF += a*2.*tt; // use weight L*2t
1191 
1192  insert = true;
1193  for(j=0; j<rate.size(); j++) {
1194  if(rate[j] == int(pix->rate+0.1)) {
1195  insert=false;
1196  ampl[j] += e;
1197  sIZe[j] += 1;
1198  like[j] += L;
1199  }
1200  }
1201 
1202  if(insert) {
1203  rate.push_back(int(pix->rate+0.1));
1204  ampl.push_back(e);
1205  powr.push_back(0.);
1206  sIZe.push_back(1);
1207  cuts.push_back(true);
1208  like.push_back(L);
1209  }
1210 
1211  m++; E += e;
1212 
1213  if(ID != pix->clusterID)
1214  cout<<"netcluster::supercluster() error: cluster ID mismatch.\n";
1215  }
1216 
1217  // cut off single level clusters
1218  // coincidence between levels
1219 
1220  if((int)rate.size()< this->pair+1 || m<nPIX){ sCuts[ID-1] = 1; continue; }
1221 
1222  cut = true;
1223  for(i=0; i<rate.size(); i++) {
1224  if((atype=='L' && like[i]<S) || (oEo && ampl[i]<S)) continue;
1225  if(!pair) { cuts[i] = cut = false; continue; }
1226  for(j=0; j<rate.size(); j++) {
1227  if((atype=='L' && like[j]<S) || (oEo && ampl[j]<S)) continue;
1228  if(rate[i]/2==rate[j] || rate[j]/2==rate[i]) {
1229  cuts[i] = cuts[j] = cut = false;
1230  }
1231  }
1232  }
1233  if(cut || sCuts[ID-1]) { sCuts[ID-1] = 1; continue; }
1234 
1235  // select optimal resolution
1236 
1237  a = -1.e99;
1238  for(j=0; j<rate.size(); j++) { // select max excess power or likelihood
1239  powr[j] = ampl[j]/sIZe[j];
1240  if(atype=='E' && ampl[j]>a && !cuts[j]) {max=j; a=ampl[j];}
1241  if(atype=='L' && like[j]>a && !cuts[j]) {max=j; a=like[j];}
1242  if(atype=='P' && powr[j]>a && !cuts[j]) {max=j; a=powr[j];}
1243  }
1244 
1245  if(a<S) { sCuts[ID-1] = 1; continue; }
1246 
1247  a = -1.e99;
1248  for(j=0; j<rate.size(); j++) {
1249  if(max==j) continue;
1250  if(atype=='E' && ampl[j]>a && !cuts[j]) {min=j; a=ampl[j];}
1251  if(atype=='L' && like[j]>a && !cuts[j]) {min=j; a=like[j];}
1252  if(atype=='P' && powr[j]>a && !cuts[j]) {min=j; a=powr[j];}
1253  }
1254 
1255  temp.push_back(rate[max]);
1256  temp.push_back(rate[min]);
1257  temp.push_back(E);
1258  cTime[ID-1] = cT/nT;
1259  cFreq[ID-1] = cF/nF;
1260  cRate[ID-1] = temp;
1261  cData[ID-1].cTime = cT/nT;
1262  cData[ID-1].cFreq = cF/nF;
1263  cData[ID-1].energy = E;
1264  cData[ID-1].likenet = E;
1265  count++;
1266 
1267  }
1268 
1269  return count;
1270 }
1271 
1272 //**************************************************************************
1273 // construct duperclusters for 2G analysis
1274 //**************************************************************************
1275 size_t netcluster::defragment(double tgap, double fgap, TH2F* his)
1276 {
1277 // construct duperclusters for 2G analysis
1278 // merge clusters if they are close to each other in time and frequency
1279 // tgap - maximum time gap in seconds
1280 // fgap - maximum frequency gap in Hz
1281 
1282  size_t i,j,k;
1283  size_t I = pList.size();
1284  int l,n,m;
1285 
1286  if(!I) return 0;
1287  if(tgap<=0 && fgap<=0) return 0;
1288 
1289  netpixel* p = NULL; // pointer to pixel structure
1290  netpixel* q = NULL; // pointer to pixel structure
1291  std::vector<int>* v;
1292  std::vector<int>* u;
1293  double R,T,dT,dF,x,a,E,prl,qrl;
1294  bool insert;
1295  double ptime, pfreq;
1296  double qtime, qfreq;
1297  double Tgap = 0.;
1298  size_t nIFO = pList[0].size(); // number of detectors
1299 
1300  netpixel** pp = (netpixel**)malloc(I*sizeof(netpixel*));
1301  netpixel** ppo = pp;
1302 
1303  for(i=0; i<I; i++) {
1304  pp[i] = &(pList[i]);
1305  R = pp[i]->rate;
1306  if(!(pp[i]->clusterID)) {
1307  cout<<"defragment: un-clustered pixel list \n"; exit(1);
1308  }
1309  if(1./R > Tgap) Tgap = 1./R; // calculate max time bin
1310  }
1311  if(Tgap<tgap) Tgap = tgap;
1312 
1313  //printf("gap = %lf\t dF = %lf\t I = %d\n", Tgap, Fgap, I);
1314 
1315  // sort pixels
1316 
1317  qsort(pp, I, sizeof(netpixel*), &compare_PIX); // sort pixels
1318 
1319  // update neighbors
1320 
1321  for(i=0; i<I; i++) {
1322  p = pp[i];
1323  n = p->clusterID;
1324  prl = p->rate*p->layers;
1325  if(sCuts[n-1]==1) continue; // skip rejected pixels
1326  ptime = p->time/prl; // time in seconds
1327  pfreq = p->frequency*p->rate/2.; // frequency in Hz
1328 
1329  for(j=i+1; j<I; j++){
1330  q = pp[j];
1331  m = q->clusterID;
1332  qrl = q->rate*q->layers;
1333  if(sCuts[m-1]==1) continue; // skip rejected pixels
1334  if(n==m) continue; // skip the same cluster
1335  qtime = q->time/qrl; // time in seconds
1336  if(qtime-ptime > Tgap) {break;} //printf("gap breaking!\n"); break;}
1337  if(p->rate/q->rate > 3) continue;
1338  if(q->rate/p->rate > 3) continue;
1339  qfreq = q->frequency*q->rate/2.; // frequency in Hz
1340  T = 1/p->rate+1/q->rate;
1341  R = p->rate+q->rate;
1342 
1343  if(qtime<ptime) {
1344  cout<<"netcluster::defragment() error "<<qtime-ptime<<endl;
1345  cout<<p->rate<<" "<<q->rate<<" "<<p->time<<" "<<q->time<<endl;
1346  exit(1);
1347  }
1348 
1349  dT = 0.;
1350  for(k=0; k<nIFO; k++) { // max time gap among all detectors
1351  a = p->data[k].index/prl; // time in seconds
1352  a -= q->data[k].index/qrl; // time in seconds
1353  if(fabs(a)>dT) dT = fabs(a);
1354  }
1355 
1356  dT -= 0.5*T; // time gap between pixels
1357  dF = fabs(qfreq-pfreq) - 0.25*R; // frequency gap between pixels
1358  if(his) his->Fill(dT,dF);
1359  if(dT > tgap) continue;
1360  if(dF > fgap) continue;
1361 
1362  // insert in p
1363 
1364  l = q-p;
1365  insert = true;
1366  v = &(p->neighbors);
1367 
1368  for(k=0; k<v->size(); k++) {
1369  if((*v)[k] == l) {insert=false; break;}
1370  }
1371 
1372  if(insert) p->append(l); // add new neighbor
1373 
1374  // insert in q
1375 
1376  l = p-q;
1377  insert = true;
1378  v = &(q->neighbors);
1379 
1380  for(k=0; k<v->size(); k++) {
1381  if((*v)[k] == l) {insert=false; break;}
1382  }
1383 
1384  if(insert) q->append(l); // add new neighbor
1385 
1386  // replace cluster ID
1387 
1388  v = &(this->cList[n-1]); // append to this pixel list
1389  u = &(this->cList[m-1]); // append from this pixel list
1390  for(k=0; k<u->size(); k++) {
1391  pList[(*u)[k]].clusterID = n; // set cluster ID=n in q-pixel
1392  v->push_back((*u)[k]); // add q-pixel to n-cluster
1393  }
1394  sCuts[m-1] = 1; // mask m cluster
1395  u->clear(); // clear pixel list
1396  }
1397  }
1398 
1399  if(ppo==pp) free(pp);
1400  else {cout<<"netcluster::defragment() free()\n"; exit(1);}
1401  return esize();
1402 }
1403 
1404 
1405 double netcluster::mchirp(int ID, double chi2_thr, double tmerger_cut, double zmax_thr)
1406 {
1407 // Reconstruction of time-frequency trend parametrizied by the chirp mass parameter,
1408 // which becomes an astrophysical charp mass only in case of CBC sources.
1409 // param 1 - cluster ID
1410 // param 2 - chi2 threshold for selection of chirp pixels
1411 // param 3 - tmerger cut: exclude pixels with time > tmerger+param3 - special use
1412 // param 4 - threshold for pixel selection - special use
1413 // returns reconstructed chirp energy
1414  const double G = watconstants::GravitationalConstant();
1415  const double SM = watconstants::SolarMass();
1416  const double C = watconstants::SpeedOfLightInVacuo();
1417  const double Pi = TMath::Pi();
1418  double kk = 256.*Pi/5*pow(G*SM*Pi/C/C/C, 5./3);
1419 
1420  std::vector<int>* vint = &this->cList[ID-1];
1421  int V = vint->size();
1422  if(!V) return -1;
1423 
1424  bool chi2_cut = chi2_thr<0 ? true : false;
1425  chi2_thr = fabs(chi2_thr);
1426 
1427  double* x = new double[V];
1428  double* y = new double[V];
1429  double* xerr = new double[V];
1430  double* yerr = new double[V];
1431  double* wgt = new double[V];
1432 
1433  double tmin=1e20;
1434  double tmax=0.;
1435  double T, rms;
1436 
1437 
1438  this->cData[ID-1].chi2chirp = 0;
1439  this->cData[ID-1].mchirp = 0 ;
1440  this->cData[ID-1].mchirperr = -1;
1441  this->cData[ID-1].tmrgr = 0;
1442  this->cData[ID-1].tmrgrerr = -1;
1443  this->cData[ID-1].chirpEllip = 0; // chirp ellipticity
1444  this->cData[ID-1].chirpEfrac = 0; // chirp energy fraction
1445  this->cData[ID-1].chirpPfrac = 0; // chirp pixel fraction
1446 
1447  // scaling of frequency: in units of 128Hz
1448  double sF = 128;
1449  kk *= pow(sF, 8./3);
1450  int np = 0;
1451  double xmin,ymin, xmax, ymax;
1452  xmin = ymin = 1e100;
1453  xmax = ymax = -1e100;
1454 
1455  double emax = -1e100;
1456  for(int j=0; j<V; j++) {
1457  netpixel* pix = this->getPixel(ID, j);
1458  if(pix->likelihood>emax) emax = pix->likelihood;
1459  }
1460  double zthr = zmax_thr*emax;
1461 
1462  for(int j=0; j<V; j++) {
1463  netpixel* pix = this->getPixel(ID, j);
1464  if(pix->likelihood<=zthr || pix->frequency==0) continue;
1465 
1466  T = int(double(pix->time)/pix->layers);
1467  T = T/pix->rate; // time in seconds from the start
1468  if(T<tmin) tmin=T;
1469  if(T>tmax) tmax=T;
1470 
1471  x[np] = T ;
1472  xerr[np] = 0.5/pix->rate;
1473  xerr[np] = xerr[np]*sqrt(2.);
1474 
1475  y[np] = pix->frequency*pix->rate/2.;
1476  yerr[np] = pix->rate/4;
1477  yerr[np] = yerr[np]/sqrt(3.);
1478 
1479  y[np] /= sF;
1480  yerr[np] /= sF;
1481  wgt[np] = pix->likelihood;
1482  yerr[np] *= 8./3/pow(y[np], 11./3); // frequency transformation
1483  y[np] = 1./pow(y[np], 8./3);
1484 
1485  if(x[np]>xmax) xmax = x[np];
1486  if(x[np]<xmin) xmin = x[np];
1487  if(y[np]>ymax) ymax = y[np];
1488  if(y[np]<ymin) ymin = y[np];
1489  ++np;
1490  }
1491  if(np<5) return -1;
1492 
1493  double xcm, ycm, qxx, qyy, qxy;
1494  xcm = ycm = qxx = qyy = qxy = 0;
1495 
1496  for(int i=0; i<np; ++i){
1497  xcm += x[i];
1498  ycm += y[i];
1499  }
1500  xcm /= np;
1501  ycm /= np;
1502 
1503  for(int i=0; i<np; ++i){
1504  qxx += (x[i] - xcm)*(x[i] - xcm);
1505  qyy += (y[i] - ycm)*(y[i] - ycm);
1506  qxy += (x[i] - xcm)*(y[i] - ycm);
1507  }
1508 
1509  //printf(" | %lf , %lf |\n", qxx, qxy);
1510  //printf(" | %lf , %lf |\n", qxy, qyy);
1511 
1512  double sq_delta = sqrt( (qxx - qyy)*(qxx - qyy) + 4*qxy*qxy );
1513  double lam1 = (qxx + qyy + sq_delta)/2;
1514  double lam2 = (qxx + qyy - sq_delta)/2;
1515  lam1 = sqrt(lam1);
1516  lam2 = sqrt(lam2);
1517  double ellipt = fabs((lam1 - lam2)/(lam1 + lam2));
1518 
1519  const double maxM = 100;
1520  const double stepM = 0.2;
1521  const int massPoints = 1001;
1522 
1523  int maxMasses[massPoints];
1524  int nmaxm = 0;
1525 
1526  EndPoint* bint[massPoints]; // stores b intervals for all pixels, satisfying chi2<2
1527  for(int j=0; j<massPoints; ++j) bint[j] = new EndPoint[2*np];
1528 
1529  int nselmax = 0;
1530  int massIndex = 0;
1531 
1532  for(double m = -maxM; m<maxM + 0.01; m+=stepM){
1533  double sl = kk*pow(fabs(m), 5./3);
1534  if(m>0) sl = -sl; // this is real slope, proper sign
1535 
1536  int j=0;
1537  for(int i=0; i<np; ++i){
1538  double Db = sqrt( 2 * (sl*sl*xerr[i]*xerr[i] + yerr[i]*yerr[i]) );
1539  double bmini = y[i] - sl*x[i] - Db;
1540  double bmaxi = bmini + 2*Db;
1541  bint[massIndex][j].value = bmini;
1542  bint[massIndex][j].type = 1;
1543  bint[massIndex][++j].value = bmaxi;
1544  bint[massIndex][j++].type = -1;
1545  }
1546  qsort(bint[massIndex], 2*np, sizeof(EndPoint), compEndP);
1547 
1548  int nsel = 1;
1549  for(j=1; j<2*np; ++j){
1550  bint[massIndex][j].type += bint[massIndex][j-1].type;
1551  if(bint[massIndex][j].type>nsel)nsel = bint[massIndex][j].type;
1552  }
1553  if(nsel>nselmax){
1554  nselmax = nsel;
1555  maxMasses[0] = massIndex;
1556  nmaxm = 1;
1557  }
1558  else if(nsel == nselmax) maxMasses[nmaxm++] = massIndex;
1559 
1560  ++massIndex;
1561  }
1562 
1563 
1564  double m0, b0;
1565  double chi2min = 1e100;
1566 
1567  // fine parsing in b range, optimize chi2:
1568  for(int j=0; j<nmaxm; ++j){
1569  double m = -maxM + maxMasses[j]*stepM;
1570  double sl = kk*pow(fabs(m), 5./3);
1571  if(m>0) sl = -sl;
1572 
1573  for(int k=0; k<2*np-1; ++k)if(bint[maxMasses[j]][k].type==nselmax)
1574  for(double b = bint[maxMasses[j]][k].value; b<bint[maxMasses[j]][k+1].value; b+=0.0025){
1575  double totchi = 0;
1576  double totwgt = 0;
1577  for(int i=0; i<np; ++i){
1578  double chi2 = y[i] - sl*x[i] - b;
1579  chi2 *= chi2;
1580  chi2 /= (sl*sl*xerr[i]*xerr[i] + yerr[i]*yerr[i]);
1581  if(chi2>chi2_thr) continue;
1582  totchi += chi2*wgt[i];
1583  totwgt += wgt[i];
1584  }
1585  totchi = totwgt ? totchi/totwgt : 2e100;
1586  if(totchi<chi2min){
1587  chi2min = totchi;
1588  m0 = m;
1589  b0 = b;
1590  }
1591  }
1592  }
1593 
1594  for(int j=0; j<massPoints; ++j) delete [] bint[j];
1595 
1596 
1597  double sl = kk*pow(fabs(m0), 5./3);
1598  if(m0>0) sl = -sl;
1599 
1600 
1601  double totEn = 0.;
1602  double selEn = 0.;
1603  double tmax2 = 0.;
1604  double chi2T = 0;
1605 
1606  for(int i=0; i<np; ++i){
1607  totEn += wgt[i];
1608  double chi2 = y[i] - sl*x[i] - b0;
1609  chi2 *= chi2;
1610  chi2 /= (sl*sl*xerr[i]*xerr[i] + yerr[i]*yerr[i]);
1611  chi2T += chi2*wgt[i];
1612  if(chi2>chi2_thr) continue;
1613  selEn += wgt[i];
1614  if(x[i]>tmax2) tmax2 = x[i];
1615  }
1616 
1617  double Efrac = selEn/totEn;
1618  chi2T = chi2T/totEn;
1619 
1620  tmax2 += 1e-6;
1621 
1622  // shift selected pixels on first positions
1623  double echirp=0;
1624  int j=0;
1625  double Pfrac = 0;
1626  int nifo = pList[0].size();
1627  for(int i=0; i<np; ++i){
1628  if(x[i]<tmax2) Pfrac += 1.0;
1629  double chi2 = y[i] - sl*x[i] -b0;
1630  chi2 *= chi2;
1631  chi2 /= (sl*sl*xerr[i]*xerr[i] + yerr[i]*yerr[i]);
1632 
1633  if(chi2>chi2_thr) continue;
1634  x[j] = x[i]; xerr[j] = xerr[i];
1635  y[j] = y[i]; yerr[j] = yerr[i];
1636  ++j;
1637  }
1638  np = j;
1639  Pfrac = np/Pfrac;
1640 
1641  // set pix->likelihood=0 for all pixels with chi2<chi2_thr
1642  // compute chirp energy for chi2<chi2_thr
1643  for(int i=0; i<V; ++i){
1644  netpixel* pix = this->getPixel(ID, i);
1645 
1646  T = int(double(pix->time)/pix->layers);
1647  T = T/pix->rate; // time in seconds from the start
1648 
1649  double eT = 0.5/pix->rate;
1650  double F = pix->frequency*pix->rate/2.;
1651  double eF = pix->rate/4;
1652  F /= sF;
1653  eF /= sF;
1654 
1655  eT*=sqrt(2.);
1656  eF/=sqrt(3.);
1657 
1658  eF *= 8./3/pow(F, 11./3); // frequency transformation
1659  F = 1./pow(F, 8./3);
1660 
1661  double chi2 = F - sl*T -b0;
1662  chi2 *= chi2;
1663  chi2 /= (sl*sl*eT*eT + eF*eF);
1664  if(chi2_cut && chi2<chi2_thr) { // set pixels likelihood=0 (used to select higher order mode)
1665  if(pix->likelihood>0) echirp += pix->likelihood;
1666  pix->likelihood=0;
1667  }
1668  }
1669 
1670 
1671  //if(Efrac > 1) printf("MCHIRP5ERR_EFRAC\n");
1672  //if(frac > 1) printf("MCHIRP5ERR_FRAC\n");
1673 
1674  // recompute ellipticity
1675 
1676  xcm = ycm = qxx = qyy = qxy = 0;
1677 
1678  for(int i=0; i<np; ++i){
1679  xcm += x[i];
1680  ycm += y[i];
1681  }
1682  xcm /= np;
1683  ycm /= np;
1684 
1685  for(int i=0; i<np; ++i){
1686  qxx += (x[i] - xcm)*(x[i] - xcm);
1687  qyy += (y[i] - ycm)*(y[i] - ycm);
1688  qxy += (x[i] - xcm)*(y[i] - ycm);
1689  }
1690 
1691  //printf(" | %lf , %lf |\n", qxx, qxy);
1692  //printf(" | %lf , %lf |\n", qxy, qyy);
1693 
1694  sq_delta = sqrt( (qxx - qyy)*(qxx - qyy) + 4*qxy*qxy );
1695  lam1 = (qxx + qyy + sq_delta)/2;
1696  lam2 = (qxx + qyy - sq_delta)/2;
1697  lam1 = sqrt(lam1);
1698  lam2 = sqrt(lam2);
1699  double ellipt2 = fabs((lam1 - lam2)/(lam1 + lam2));
1700 
1701 
1702  // bootstrapping section
1703 
1704  if(np<=0)return 0;
1705  //printf("MCHIRP5ERR_NPZERO\n");
1706 
1707  wavearray<int> used(np);
1708 
1709  int np2 = np*0.5, Trials=500;
1710  if(np2<3)np2 = np-1;
1711 
1712  if(np2<8)Trials = np2;
1713  else if(np2<15) Trials = np2*np2/2;
1714  else if(np2<20) Trials = np2*np2*np2/6;
1715  if(Trials>500) Trials = 500;
1716  if(Trials<0) Trials=0;
1717 
1718  this->cData[ID-1].mchpdf.resize(Trials);
1719  TRandom3 rnd(0);
1720  wavearray<float> slpv(Trials);
1721  wavearray<float> mchv(Trials);
1722  wavearray<float> bv(Trials);
1723 
1724  for(int ii=0; ii<Trials; ++ii){
1725  // generate random sequence
1726  used = 0;
1727  for(int k, i=0; i<np2; ++i){
1728  do k = rnd.Uniform(0. , np - 1e-10);
1729  while(used[k]);
1730  used[k]=1;
1731  }
1732 
1733  // linear fit, no weights for now
1734  double sx=0, sy=0, sx2=0, sxy=0;
1735  for(int i=0; i<np; ++i)if(used[i]){
1736  //x[i] -= tmin;
1737  sx += x[i];
1738  sy += y[i];
1739  sx2 += x[i]*x[i];
1740  sxy += x[i]*y[i];
1741  }
1742  double slp = (sy/np2 - sxy/sx)/(sx2/sx - sx/np2);
1743  double b = (sy + slp*sx)/np2;
1744 
1745  slpv.data[ii] = slp;
1746  mchv.data[ii] = slp>0 ? pow(slp/kk,0.6) : -pow(-slp/kk, 0.6);
1747  bv.data[ii] = b/slp;
1748  this->cData[ID-1].mchpdf.data[ii] = mchv.data[ii];
1749  }
1750 
1751 
1752  size_t nn = mchv.size()-1;
1753  size_t ns = size_t(mchv.size()*0.16);
1754  cData[ID-1].mchirperr = Trials>8 ? ( mchv.waveSplit(0,nn,nn-ns)-mchv.waveSplit(0,nn,ns) ) / 2 : 2*mchv.rms();
1755 
1756  // end bootstrapping section
1757 
1758  char name[100];
1759  sprintf(name, "netcluster::mchirp5:func_%d", ID);
1760 
1761 #ifdef _USE_ROOT6
1762  TGraphErrors *gr = new TGraphErrors(np, x, y, xerr, yerr);
1763  TF1 *f = new TF1(name, "[0]*x + [1]", xmin, xmax);
1764 
1765  this->cData[ID-1].chirp.Set(np);
1766  for(int i=0;i<np;i++) {
1767  this->cData[ID-1].chirp.SetPoint(i,x[i],y[i]);
1768  this->cData[ID-1].chirp.SetPointError(i,xerr[i],yerr[i]);
1769  }
1770  this->cData[ID-1].fit.SetName(TString("TGraphErrors_"+TString(name)).Data());
1771  this->cData[ID-1].chirp.SetName(TString("TF1_"+TString(name)).Data());
1772 #else
1773  TF1* f = &(this->cData[ID-1].fit);
1774  TGraphErrors* gr = &(this->cData[ID-1].chirp);
1775 
1776  *gr = TGraphErrors(np, x, y, xerr, yerr);
1777  *f = TF1(name, "[0]*x + [1]", xmin, xmax);
1778 #endif
1779 
1780  f->SetParameter(0, sl);
1781  f->SetParameter(1, b0);
1782  gr->Fit(f,"Q");
1783 
1784 
1785  int ndf = f->GetNDF();
1786  double mch = -f->GetParameter(0)/kk;
1787  double relerr = fabs(f->GetParError(0)/f->GetParameter(0));
1788  if(ndf==0) return -1;
1789  this->cData[ID-1].mchirp = mch>0 ? pow(mch, 0.6) : -pow(-mch, 0.6);
1790  this->cData[ID-1].tmrgr = -f->GetParameter(1)/f->GetParameter(0);
1791  this->cData[ID-1].tmrgrerr = chi2T; // total chi2 statistic;
1792  this->cData[ID-1].chirpEllip = ellipt2; // chirp ellipticity
1793  this->cData[ID-1].chirpEfrac = Efrac; // chirp energy fraction
1794  this->cData[ID-1].chirpPfrac = Pfrac; // chirp pixel fraction
1795  this->cData[ID-1].chi2chirp = chi2T; //f->GetChisquare()/ndf;
1796  //this->cData[ID-1].chi2chirp = f->GetChisquare()/ndf;
1797  this->cData[ID-1].tmrgrerr = 0.; // tmerger error
1798 
1799  // cut pixels with time > tmerger+tmerger_cut
1800  double tmerger = -f->GetParameter(1)/f->GetParameter(0);
1801  for(int i=0; i<V; ++i){
1802  netpixel* pix = this->getPixel(ID, i);
1803  T = int(double(pix->time)/pix->layers);
1804  T = T/pix->rate; // time in seconds from the start
1805  if(T>(tmerger+tmerger_cut)) pix->likelihood=0;
1806  }
1807 
1808 #ifdef _USE_ROOT6
1809  this->cData[ID-1].fit = *f;
1810  delete f;
1811  delete gr;
1812 #endif
1813 
1814  delete [] x;
1815  delete [] y;
1816  delete [] xerr;
1817  delete [] yerr;
1818  delete [] wgt;
1819 
1820  return echirp;
1821 
1822 }
1823 
1824 
1826 {
1827  const double G = watconstants::GravitationalConstant();
1828  const double SM = watconstants::SolarMass();
1829  const double C = watconstants::SpeedOfLightInVacuo();
1830  const double Pi = TMath::Pi();
1831  //double kk = 256.*Pi/5*pow(G*SM*Pi/C/C/C, 5./3);
1832 
1833  this->cData[ID-1].chi2chirp = 0;
1834  this->cData[ID-1].mchirp = 0 ;
1835  this->cData[ID-1].mchirperr = -1;
1836  this->cData[ID-1].tmrgr = 0;
1837  this->cData[ID-1].tmrgrerr = -1;
1838 
1839  double kf = pow(5./256, 3./8) * pow( C*C*C/G/SM, 5./8) / Pi; // f(t) = kf / Mc^(5/8) / (t0-t)^(3/8)
1840  double kdf = sqrt(0.6*kf*3./8); // df(t) = kdf / Mc^(5/16) / (t0-t)^(11/16)
1841 
1842  std::vector<int>* vint = &this->cList[ID-1];
1843  int V = vint->size();
1844  if(!V) return -1;
1845 
1846  int np=0;
1847  double minDT=1e10, minFreq=1e10;
1848 
1849  for(int j=0; j<V; j++) {
1850  netpixel* pix = this->getPixel(ID, j);
1851  if(pix->likelihood<1. || pix->frequency==0 || !pix->core) continue;
1852  ++np;
1853  if(pix->rate/2. < minFreq) minFreq = pix->rate/2;
1854  if(1./pix->rate < minDT) minDT = 1./pix->rate;
1855  }
1856  if(np<3)return -1;
1857  int naux = 1./(2*minDT*minFreq) + 0.5; // division
1858  int Vp = naux*V;
1859 
1860  //printf("minDT = %lf \t minFreq = %lf \t naux = %d\n", minDT, minFreq, naux);
1861 
1862  double* x = new double[Vp];
1863  double* y = new double[Vp];
1864  double* wgt = new double[Vp];
1865  bool* sel = new bool[Vp];
1866 
1867  np = 0;
1868  double tmin=1e20;
1869  double tmax=0.;
1870  double T; //, rms;
1871 
1872  double xmin,ymin, xmax, ymax;
1873  xmin = ymin = 1e100;
1874  xmax = ymax = -1e100;
1875 
1876  // break regular pixels
1877 
1878  for(int j=0; j<V; j++) {
1879  netpixel* pix = this->getPixel(ID, j);
1880  if(pix->likelihood<1. || pix->frequency==0 || !pix->core) continue;
1881  T = int(double(pix->time)/pix->layers);
1882  T = T/pix->rate; // time in seconds from the start
1883  if(T<tmin) tmin=T;
1884  if(T>tmax) tmax=T;
1885  int nx = 1./pix->rate/minDT + 0.5;
1886  int ny = pix->rate/2/minFreq + 0.5;
1887  //printf("nx = %d ny = %d\n", nx, ny);
1888  for(int ix=0; ix<nx; ++ix) {
1889  for(int iy=0; iy<ny; ++iy){
1890  x[np] = T - 0.5/pix->rate + (ix+0.5)*minDT; //xerr[np] = 0.5/pix->rate;
1891  y[np] = pix->frequency*pix->rate/2. - pix->rate/4 + (iy+0.5)*minFreq; //yerr[np] = pix->rate/4;
1892  wgt[np] = pix->likelihood/naux;
1893 
1894  if(x[np]>xmax)xmax = x[np];
1895  if(x[np]<xmin)xmin = x[np];
1896  if(y[np]>ymax)ymax = y[np];
1897  if(y[np]<ymin)ymin = y[np];
1898  ++np;
1899  }
1900  }
1901  }
1902 
1903  const double maxM = 30; // maximum chirp mass
1904  const double stepM = 0.1; // step
1905  //const int massPoints = 601;
1906 
1907  int nselmax = 0;
1908  double m0 = 0, t0max = 0;
1909  double t0 = (tmin*2 + tmax)/3;
1910 
1911  /*
1912  for(; t0<tmax+1; t0 += minDT){ // intercept loop
1913  for(double m = 0.1; m<maxM; m += stepM){ // mass scan
1914  double cf = kf/pow(m, 5./8);
1915  double cdf = kdf/pow(m, 5./16);
1916  int nsel = 0;
1917  for(int i=0; i<np; ++i){ // scan over elementary pixels
1918  double a = t0 - x[i];
1919  if(a<=0)continue;
1920  double b = sqrt(sqrt(a));
1921  b *= sqrt(b);
1922  double fi = cf/b;
1923  double df = cdf/sqrt(b*a); // evelope width in frequency
1924  if(y[i]>fi+df) continue;
1925  if(y[i]<fi-df) continue;
1926  ++nsel;
1927  }
1928  if(nsel>nselmax){ // new optimum
1929  nselmax = nsel;
1930  m0 = m;
1931  t0max = t0;
1932  }
1933  }
1934  }
1935  */
1936 
1937 
1938  int tPoints = (tmax + 1 - t0)/minDT + 1;
1939  double* maxTimes = new double[tPoints];
1940  double* maxMasses = new double[tPoints];
1941  int nmaxt = 0;
1942 
1943  EndPoint** mint = new EndPoint*[tPoints]; // stores valid m intervals for all pixels
1944  for(int j=0; j<tPoints; ++j) mint[j] = new EndPoint[2*np];
1945 
1946  int tIndex = 0;
1947  for(; t0<tmax+1; t0 += minDT){ // intercept loop
1948  int j=0;
1949  for(int i=0; i<np; ++i){
1950  double dt = t0 - x[i];
1951  if(dt<=0)continue;
1952  double dt38 = sqrt(sqrt(dt));
1953  dt38 *= sqrt(dt38);
1954  double a = kf/dt38;
1955  double b = kdf/sqrt(dt*dt38);
1956  double Delta = sqrt(b*b + 4*a*y[i]);
1957 
1958  mint[tIndex][j].value = pow( 2*a/(Delta + b), 16./5);
1959  mint[tIndex][j].type = 1;
1960  mint[tIndex][++j].value = pow( 2*a/(Delta - b), 16./5);
1961  mint[tIndex][j++].type = -1;
1962  //printf("%lf %lf\n", mint[tIndex][j-2].value, mint[tIndex][j-1].value) ;
1963  }
1964  qsort(mint[tIndex], j, sizeof(EndPoint), compEndP);
1965 
1966  int nsel = 1;
1967  double mmax;
1968  for(int k=1; k<j; ++k){
1969  mint[tIndex][k].type += mint[tIndex][k-1].type;
1970  if(mint[tIndex][k].type>=nsel){
1971  mmax = (mint[tIndex][k].value + mint[tIndex][k+1].value)/2;
1972  nsel = mint[tIndex][k].type;
1973  }
1974  }
1975  if(nsel>nselmax){
1976  nselmax = nsel;
1977  maxTimes[0] = t0;
1978  maxMasses[0] = mmax;
1979  nmaxt = 1;
1980  }
1981  else if(nsel == nselmax){ maxMasses[nmaxt] = mmax; maxTimes[nmaxt++] = t0;}
1982  ++tIndex;
1983  }
1984 
1985  t0max = maxTimes[nmaxt-1];
1986  m0 = maxMasses[nmaxt-1];
1987 
1988  for(int j=0; j<tPoints; ++j) delete [] mint[j];
1989  delete [] mint;
1990  delete [] maxTimes;
1991  delete [] maxMasses;
1992 
1993 
1994  // find selected pixels, max t among them
1995 
1996  double tmax2 = 0.;
1997 
1998  double cf = kf/pow(m0, 5./8);
1999  double cdf = kdf/pow(m0, 5./16);
2000  for(int i=0; i<np; ++i){
2001  sel[i] = false;
2002  double a = t0max - x[i];
2003  if(a<=0) continue;
2004  double b = sqrt(sqrt(a));
2005  b *= sqrt(b);
2006  double fi = cf/b;
2007  double df = cdf/sqrt(b*a);
2008  if(y[i]>fi+df) continue;
2009  if(y[i]<fi-df) continue;
2010  sel[i] = true; // flag pixels
2011  if(x[i]>tmax2) tmax2 = x[i];
2012  }
2013 
2014 
2015  // compute energy fraction (global) , pixel fraction (among those below tmax2!)s
2016  // shift selected pixels on first positions, too
2017 
2018  double totEn = 0.;
2019  double selEn = 0.;
2020  int j=0;
2021  double frac = 0;
2022  tmax2 += 1e-6;
2023 
2024  for(int i=0; i<np; ++i){
2025  totEn += wgt[i];
2026  if(x[i]<tmax2) frac += 1.0;
2027  if(sel[i]){
2028  selEn += wgt[i];
2029  x[j] = x[i];
2030  y[j] = y[i];
2031  ++j;
2032  }
2033  }
2034 
2035  double Efrac = selEn/totEn;
2036  np = j;
2037  frac = np/frac;
2038 
2039  // compute ellipticity
2040 
2041  double xcm, ycm, qxx, qyy, qxy;
2042  xcm = ycm = qxx = qyy = qxy = 0;
2043 
2044  for(int i=0; i<np; ++i){
2045  xcm += x[i];
2046  ycm += y[i];
2047  }
2048  xcm /= np;
2049  ycm /= np;
2050 
2051  for(int i=0; i<np; ++i){
2052  qxx += (x[i] - xcm)*(x[i] - xcm);
2053  qyy += (y[i] - ycm)*(y[i] - ycm);
2054  qxy += (x[i] - xcm)*(y[i] - ycm);
2055  }
2056 
2057  //printf(" | %lf , %lf |\n", qxx, qxy);
2058  //printf(" | %lf , %lf |\n", qxy, qyy);
2059 
2060  double sq_delta = sqrt( (qxx - qyy)*(qxx - qyy) + 4*qxy*qxy );
2061  double lam1 = (qxx + qyy + sq_delta)/2;
2062  double lam2 = (qxx + qyy - sq_delta)/2;
2063  lam1 = sqrt(lam1);
2064  lam2 = sqrt(lam2);
2065  double ellipt2 = fabs((lam1 - lam2)/(lam1 + lam2));
2066 
2067 
2068  /*/ bootstrapping section
2069 
2070  if(np<=0)return 0;
2071  //printf("MCHIRP5ERR_NPZERO\n");
2072 
2073  wavearray<int> used(np);
2074 
2075  int np2 = np*0.5, Trials=500;
2076  if(np2<3)np2 = np-1;
2077 
2078  if(np2<8)Trials = np2;
2079  else if(np2<15) Trials = np2*np2/2;
2080  else if(np2<20) Trials = np2*np2*np2/6;
2081  if(Trials>500) Trials = 500;
2082  if(Trials<0) Trials=0;
2083 
2084  this->cData[ID-1].mchpdf.resize(Trials);
2085  TRandom3 rnd(0);
2086  wavearray<float> slpv(Trials);
2087  wavearray<float> mchv(Trials);
2088  wavearray<float> bv(Trials);
2089 
2090  for(int ii=0; ii<Trials; ++ii){
2091  // generate random sequence
2092  used = 0;
2093  for(int k, i=0; i<np2; ++i){
2094  do k = rnd.Uniform(0. , np - 1e-10);
2095  while(used[k]);
2096  used[k]=1;
2097  }
2098 
2099  // linear fit, no weights for now
2100  double sx=0, sy=0, sx2=0, sxy=0;
2101  for(int i=0; i<np; ++i)if(used[i]){
2102  //x[i] -= tmin;
2103  sx += x[i];
2104  sy += y[i];
2105  sx2 += x[i]*x[i];
2106  sxy += x[i]*y[i];
2107  }
2108  double slp = (sy/np2 - sxy/sx)/(sx2/sx - sx/np2);
2109  double b = (sy + slp*sx)/np2;
2110 
2111  slpv.data[ii] = slp;
2112  mchv.data[ii] = slp>0 ? pow(slp/kk,0.6) : -pow(-slp/kk, 0.6);
2113  bv.data[ii] = b/slp;
2114  this->cData[ID-1].mchpdf.data[ii] = mchv.data[ii];
2115  }
2116 
2117 
2118  size_t nn = mchv.size()-1;
2119  size_t ns = size_t(mchv.size()*0.16);
2120  cData[ID-1].mchirperr = Trials>8 ? ( mchv.waveSplit(0,nn,nn-ns)-mchv.waveSplit(0,nn,ns) ) / 2 : 2*mchv.rms();
2121 
2122  // end bootstrapping section
2123 
2124 
2125  char name[100];
2126  sprintf(name, "netcluster::mchirp5:func_%d", ID);
2127  TF1* f = &(this->cData[ID-1].fit);
2128  TGraphErrors* gr = &(this->cData[ID-1].chirp);
2129 
2130  *gr = TGraphErrors(np, x, y, xerr, yerr);
2131  *f = TF1(name, "[0]*x + [1]", xmin, xmax);
2132  f->SetParameter(0, sl);
2133  f->SetParameter(1, b0);
2134  gr->Fit(f,"Q");
2135 
2136 
2137 
2138  int ndf = f->GetNDF();
2139  double mch = -f->GetParameter(0)/kk;
2140  double relerr = fabs(f->GetParError(0)/f->GetParameter(0));
2141  if(ndf==0) return -1;
2142  */
2143  this->cData[ID-1].chi2chirp = Efrac; //f->GetChisquare()/ndf;
2144  this->cData[ID-1].mchirp = m0; // mch>0 ? pow(mch, 0.6) : 0.0001;
2145  //this->cData[ID-1].mchirperr = 0.6*this->cData[ID-1].mchirp*relerr; // determined by bootstrapping!
2146  this->cData[ID-1].tmrgr = ellipt2; //-f->GetParameter(1)/f->GetParameter(0);
2147  this->cData[ID-1].tmrgrerr = frac; //ellipt;
2148 
2149  delete [] x;
2150  delete [] y;
2151  delete [] sel;
2152  delete [] wgt;
2153 
2154  return 0;
2155 
2156 }
2157 // draw chirp cluster
2159 {
2160 // Draw chirp object for cluster id
2161  TCanvas* c = new TCanvas("chirp", ""); c->cd();
2162  this->cData[id-1].chirp.Draw("AP");
2163  this->cData[id-1].fit.Draw("same");
2164  return;
2165 }
2166 
2168 { TCanvas* c = new TCanvas("cpc", "", 1200, 800);
2169  TH2F* h2 = new TH2F("h2h", "", 600, 0, 600, 2048, 0, 2048);
2170  int cntr = 0;
2171  std::vector<vector_int>::iterator it;
2172  for(it=cList.begin(); it != cList.end(); it++){
2173  size_t ID = pList[((*it)[0])].clusterID;
2174  if(sCuts[ID-1]==0){
2175  h2->Fill(cTime[ID-1], cFreq[ID-1], cRate[ID-1][2]);
2176  //printf("\nID = %lu time = %lf\t freq = %lf ", ID, cTime[ID-1], cFreq[ID-1]);
2177  ++cntr;
2178  }
2179  else if(sCuts[ID-1]==1)printf("*");
2180  }
2181  printf("\n# of zero sCuts lusters:%d\n", cntr);
2182  c->cd();
2183  h2->Draw("colz");
2184 }
2185 
2186 //**************************************************************************
2187 //**************************************************************************
2188 wavearray<double> netcluster::get(char* name, size_t index, char atype, int type, bool core)
2189 {
2190 // return cluster parameters defined by name
2191 // name="ID" clusterID
2192 // name="size" core size
2193 // name="SIZE" core+halo size
2194 // name="volume" volume
2195 // name="start" actual start time relative to segment start
2196 // name="stop" actual stop time relative to segment stop
2197 // name="duration" energy-weighted duration
2198 // name="low" low frequency
2199 // name="high" high frequency
2200 // name="energy" energy; 'R' - rank, 'S' - Gauss
2201 // name="subrho" subnetwork limit on coherent energy;
2202 // name="subnet" subnetwork energy fraction;
2203 // name="subnrg" subnetwork energy;
2204 // name="maxnrg" maximum detector energy;
2205 // name="power" energy/size
2206 // name="conf" cluster confidence; 'R' - rank, 'S' - Gauss
2207 // name="like" network likelihood
2208 // name="null" network null statistic
2209 // name="sign" significance; index<0 - rank, index>0 - Gauss
2210 // name="corr" xcorrelation
2211 // name="asym" asymmetry
2212 // name="grand" grandAmplitude
2213 // name="rate" cluster rate
2214 // name="SNR" cluster SNR: 'R' - rank, 'S' - Gaussian
2215 // name="hrss" log10(calibrated cluster hrss)
2216 // name="noise" log10(average calibrated noise): average of sigma^2
2217 // name="NOISE" log10(average calibrated noise): average of 1/sigma^2
2218 // name="elli" ellipticity
2219 // name="psi" source polarisation angle
2220 // name="phi" source coordinate phi
2221 // name="theta" source coordinate theta
2222 // name="time" zero lag time averaged over: 'S'-gSNR, 'R'-rSNR, 'L'-likelihood
2223 // name="TIME" zero lag time averaged over energy and all resolutions
2224 // name="freq" frequency averaged over: 'S'-gSNR, 'R'-rSNR, 'L'-likelihood
2225 // name="FREQ" frequency averaged over energy and all resolutions
2226 // name="bandwidth"energy-weighted bandwidth
2227 // name="chi2" chi2 significance: 1 - cumulative probability
2228 
2230  if(!cList.size() || !pList.size()) return out;
2231 
2232  size_t i,j,k,K,n,nifo;
2233  size_t mp,mm;
2234  size_t it_size;
2235  size_t it_core;
2236  size_t it_halo;
2237  size_t it_like;
2238  size_t out_size = 0;
2239  double x,y;
2240  double a,b,d,e;
2241  double t,r;
2242  double sum = 0.;
2243  double logbpp = -log(bpp);
2244  double nsd,msd,esub,emax,rho,subnet;
2245 
2246  // before Feb, 2007: ampbpp = sqrt(2*1.07*logbpp)-1.11/2.;
2247  // after Feb, 2007: more accurate approximation
2248  double ampbpp = sqrt(2*logbpp-2*log(1+pow(log(1+logbpp*(1+1.5*exp(-logbpp))),2)));
2249 
2250  int ID, rate, min_rate, max_rate;
2251  int RATE = abs(type)>2 ? abs(type) : 0;
2252 
2253  wavearray<int> skip;
2254  vector<vector_int>::iterator it;
2255  vector_int* pv = NULL;
2256  size_t M = pList.size();
2257  size_t m = index ? index : index+1;
2258 
2259  out.resize(cList.size());
2260  out.start(start);
2261  out.rate(1.);
2262  out = 0.;
2263 
2264  char c = '0';
2265 
2266  if(strstr(name,"ID")) c = 'i'; // clusterID
2267  if(strstr(name,"size")) c = 'k'; // core size
2268  if(strstr(name,"SIZE")) c = 'K'; // core+halo size
2269  if(strstr(name,"volume")) c = 'v'; // volume
2270  if(strstr(name,"VOLUME")) c = 'V'; // volume with likelihood>0
2271  if(strstr(name,"start")) c = 's'; // actual start time relative to segment start
2272  if(strstr(name,"stop")) c = 'd'; // actual stop time relative to segment stop
2273  if(strstr(name,"dura")) c = 'D'; // energy weghted duration for all resolutions
2274  if(strstr(name,"low")) c = 'l'; // low frequency
2275  if(strstr(name,"high")) c = 'h'; // high frequency
2276  if(strstr(name,"energy")) c = 'e'; // energy; 'R' - rank, 'S' - Gauss
2277  if(strstr(name,"subrho")) c = 'R'; // subnetwork limit on coherent energy;
2278  if(strstr(name,"subnet")) c = 'U'; // subnetwork energy fraction;
2279  if(strstr(name,"subnrg")) c = 'u'; // subnetwork energy;
2280  if(strstr(name,"maxnrg")) c = 'm'; // maximum detector energy;
2281  if(strstr(name,"power")) c = 'w'; // energy/size
2282  if(strstr(name,"conf")) c = 'Y'; // cluster confidence; 'R' - rank, 'S' - Gauss
2283  if(strstr(name,"like")) c = 'L'; // network likelihood
2284  if(strstr(name,"null")) c = 'N'; // network null statistic
2285  if(strstr(name,"sign")) c = 'z'; // significance; index<0 - rank, index>0 - Gauss
2286  if(strstr(name,"corr")) c = 'x'; // xcorrelation
2287  if(strstr(name,"asym")) c = 'a'; // asymmetry
2288  if(strstr(name,"grand")) c = 'g'; // grandAmplitude
2289  if(strstr(name,"rate")) c = 'r'; // cluster rate
2290  if(strstr(name,"SNR")) c = 'S'; // cluster SNR: 'R' - rank, 'S' - Gaussian
2291  if(strstr(name,"hrss")) c = 'H'; // log10(calibrated cluster hrss)
2292  if(strstr(name,"noise")) c = 'n'; // log10(average calibrated noise): average of sigma^2
2293  if(strstr(name,"NOISE")) c = 'I'; // log10(average calibrated noise): average of 1/sigma^2
2294  if(strstr(name,"elli")) c = 'o'; // ellipticity
2295  if(strstr(name,"psi")) c = 'O'; // source polarisation angle
2296  if(strstr(name,"phi")) c = 'P'; // source coordinate phi
2297  if(strstr(name,"theta")) c = 'p'; // source coordinate theta
2298  if(strstr(name,"time")) c = 't'; // zero lag time averaged over: 'S'-gSNR, 'R'-rSNR, 'L'-likelihood
2299  if(strstr(name,"TIME")) c = 'T'; // zero lag time averaged over energy and all resolutions
2300  if(strstr(name,"freq")) c = 'f'; // frequency averaged over: 'S'-gSNR, 'R'-rSNR, 'L'-likelihood
2301  if(strstr(name,"FREQ")) c = 'F'; // frequency averaged over energy and all resolutions
2302  if(strstr(name,"band")) c = 'B'; // energy weghted bandwidth for all resolutions
2303  if(strstr(name,"chi2")) c = 'C'; // chi2 significance: 1 - cumulative probability
2304 
2305  if(c=='0') return out;
2306 
2307  k = K = 0;
2308 
2309  for(it=cList.begin(); it!=cList.end(); it++){
2310 
2311  ID = pList[((*it)[0])].clusterID;
2312  if(sCuts[ID-1]>0) continue; // apply selection cuts
2313  it_size = it->size();
2314  if(!it_size) continue;
2315 
2316  it_core = 0;
2317  it_halo = 0;
2318  it_like = 0;
2319  skip.resize(it_size);
2320  pv = cRate.size() ? &(cRate[ID-1]) : NULL;
2321  rate = 0;
2322 
2323  if(type<0) rate = -type;
2324  else if(!pv) rate = 0;
2325  else if(type==1 && pv->size()) rate = (*pv)[0];
2326  else if(pv->size() && RATE) rate = ((*pv)[0]==RATE) ? RATE : -1;
2327 
2328  min_rate=std::numeric_limits<int>::max();
2329  max_rate=0;
2330  for(k=0; k<it_size; k++) { // fill skip array
2331  M = (*it)[k];
2332  skip.data[k] = 1;
2333  int prate = int(pList[M].rate+0.1);
2334  if(rate && prate!=rate) continue;
2335  if(prate>max_rate) max_rate = prate;
2336  if(prate<min_rate) min_rate = prate;
2337  it_halo++;
2338  if(pList[M].core && pList[M].likelihood>0) it_like++;
2339  if(!pList[M].core && core) continue;
2340  skip.data[k] = 0;
2341  it_core++;
2342  }
2343 
2344  if(!it_core) continue; // skip cluster
2345 
2346  switch (c) {
2347 
2348  case 'i': // get cluster ID
2349  for(k=0; k<it_size; k++){
2350  M = (*it)[k];
2351  if(!skip.data[k]) {
2352  out.data[out_size++] = pList[M].clusterID;
2353  break;
2354  }
2355  }
2356  break;
2357 
2358  case 'k': // get cluster core size
2359  case 'K': // get cluster core+halo size
2360  out.data[out_size++] = c=='k' ? float(it_core) : float(it_halo);
2361  break;
2362 
2363  case 'P': // get source coordinate phi
2364  case 'p': // get source coordinate theta
2365  for(k=0; k<it_size; k++){
2366  M = (*it)[k];
2367  if(!skip.data[k]) {
2368  out.data[out_size++] = (c=='p') ? pList[M].theta : pList[M].phi;
2369  break;
2370  }
2371  }
2372  break;
2373 
2374  case 'O': // get source polarisation angle
2375  case 'o': // get source ellipticity
2376  for(k=0; k<it_size; k++){
2377  M = (*it)[k];
2378  if(!skip.data[k]) {
2379  out.data[out_size++] = (c=='o') ? pList[M].ellipticity : pList[M].polarisation;
2380  break;
2381  }
2382  }
2383  break;
2384 
2385  case 'r': // get cluster rate
2386  for(k=0; k<it_size; k++){
2387  M = (*it)[k];
2388  if(!skip.data[k]) {
2389  out.data[out_size++] = pList[M].rate;
2390  break;
2391  }
2392  }
2393  break;
2394 
2395  case 'a': // get cluster asymmetry
2396  case 'x': // get cluster x-correlation parameter
2397  mp = 0; mm = 0;
2398  for(k=0; k<it_size; k++){
2399  M = (*it)[k];
2400 
2401  if(!index) continue;
2402  if(skip.data[k]) continue;
2403  if(pList[M].size()<m) continue;
2404  x = pList[M].getdata(atype,m-1);
2405  if(x>0.) mp++;
2406  else mm++;
2407  }
2408  if(c == 'a') out.data[out_size++] = mp+mm>0 ? (float(mp)-float(mm))/(mp+mm) : 0;
2409  else out.data[out_size++] = mp+mm>0 ? signPDF(mp,mm) : 0;
2410  break;
2411 
2412  case 'u': // get subnetwork energy
2413  case 'm': // get maximum detector energy
2414  case 'U': // get subnetwork statistic (subnet energy fraction)
2415  case 'R': // subnetwork limit on coherent energy
2416  double v,E;
2417  mm = it_core;
2418  esub = emax = sum = rho = 0;
2419  for(k=0; k<it_size; k++){
2420  M = (*it)[k];
2421  nifo = pList[M].size();
2422  if(skip.data[k]) continue;
2423  a = E = e = nsd = 0;
2424  for(n=0; n<nifo; n++) {
2425  a+= fabs(pList[M].getdata(atype,n)); // pixel amplitude
2426  x = pList[M].getdata(atype,n); x*=x; // pixel energy
2427  v = pList[M].data[n].noiserms; v*=v; // noise variance
2428  if(x>E) {E=x; msd=v;}
2429  e += x;
2430  nsd += v>0 ? 1/v : 0.;
2431  }
2432 
2433  if(nsd==0. && c=='U') {
2434  cout<<"netcluster::get():empty noiserms array"<<endl; exit(0);
2435  }
2436 
2437  a = a>0 ? e/(a*a) : 1;
2438  rho += (1-a)*(e-nSUB*2); // estimator of coherent energy
2439  y = e-E;
2440  x = y*(1+y/(E+1.e-5)); // corrected subnetwork energy
2441  nsd -= msd>0 ? 1./msd : 0; // subnetwork inverse PSD
2442  v = (2*E-e)*msd*nsd/10.;
2443  esub+= e-E;
2444  emax+= E;
2445  a = x/(x+nSUB);
2446  sum += (e*x/(x+(v>0?v:1.e-5)))*(a>0.5?a:0);
2447  }
2448  sum = sum/(emax+esub+0.01);
2449  if(c=='u') out.data[out_size++] = esub;
2450  if(c=='m') out.data[out_size++] = emax;
2451  if(c=='U') out.data[out_size++] = sum;
2452  if(c=='R') out.data[out_size++] = sqrt(rho); // coherent amplitude
2453  //if(rho<0.01) cout<<"debugx: "<<mm<<" "<<a<<" "<<esub<<" "<<emax<<" "<<rho<<" "<<sum<<endl;
2454  break;
2455 
2456  case 'e': // get cluster energy
2457  case 'S': // get cluster SNR
2458  case 'Y': // get cluster confidence
2459  case 'z': // get cluster significance
2460  case 'w': // get cluster power
2461  case 'C': // get cluster chi2 probability
2462  y = 0.;
2463  mm = 0;
2464  for(k=0; k<it_size; k++){
2465  M = (*it)[k];
2466 
2467  if(!index) continue;
2468  if(skip.data[k]) continue;
2469  if(pList[M].size()<m) continue;
2470 
2471  x = pList[M].getdata(atype,m-1);
2472  x/= (atype=='W' || atype=='w') ? pList[M].data[m-1].noiserms : 1.;
2473  x/= (atype=='U' || atype=='u') ? pList[M].data[m-1].noiserms : 1.;
2474  x = fabs(x);
2475 
2476  if(atype=='R' || atype=='r'){ // get rank statistics
2477  a = x+logbpp;
2478  a-= log(1+pow(log(1+a*(1+1.5*exp(-a))),2)); // new approximation for rank SNR
2479  a = sqrt(2*a); // was a = sqrt(2*1.07*(x+logbpp))-1.11/2.;
2480 
2481  if(x==0.) a = 0.;
2482 
2483  if(c=='Y' || c=='z') {
2484  if(atype=='R') { y += x; mm++; }
2485  if(atype=='r' && x>0) { y += x; mm++; }
2486  }
2487  else if(c=='e' || c=='C') { y += a*a; mm++; }
2488  else if(a*a>1.) { y += a*a; mm++; }
2489  }
2490 
2491  else { // get Gaussian statistics
2492  if(c=='Y' || c=='z') {
2493  a = pow(x+1.11/2,2)/2./1.07;
2494  y+= (a>logbpp) ? a-logbpp : 0.;
2495  if(atype=='S' || atype=='W' || atype=='P' || atype=='U') mm++; // total size
2496  else if(a>logbpp) mm++; // reduced size
2497  }
2498  else if(c=='e' || c=='C' || c=='w') {
2499  if(atype=='S' || atype=='W' || atype=='P'|| atype=='U') {
2500  y += x*x; mm++; // total energy
2501  }
2502  else if(x>ampbpp) { y += x*x; mm++; } // reduced energy
2503  }
2504  else if(x*x>1.) { y += x*x; mm++; }
2505  }
2506 
2507  }
2508 
2509  if(c=='S' && mm) y -= double(mm);
2510  if(c=='w' && mm) y /= double(mm);
2511  if(c=='z' && mm) y = gammaCL(y,mm);
2512 
2513  out.data[out_size++] = y;
2514  break;
2515 
2516  case 'g': // get cluster grand amplitude
2517  y = 0.;
2518  for(k=0; k<it_size; k++){
2519  M = (*it)[k];
2520 
2521  if(!index) continue;
2522  if(skip.data[k]) continue;
2523  if(pList[M].size()<m) continue;
2524 
2525  x = fabs(pList[M].getdata(atype,m-1));
2526  if(x>y) y = x;
2527  }
2528  out.data[out_size++] = y;
2529  break;
2530 
2531  case 's': // get cluster start time
2532  case 'd': // get cluster stop time
2533  a = 1.e99;
2534  b = 0.;
2535  for(k=0; k<it_size; k++){
2536  M = (*it)[k];
2537  if(skip.data[k]) continue;
2538  y = 1./pList[M].rate; // time resolution
2539  mm= pList[M].layers;
2540  x = index ? y*int(pList[M].data[m-1].index/mm) :
2541  y*int(pList[M].time/mm);
2542  if(x <a) a = x; // first channel may be shifted
2543  if(x+y>b) b = x+y;
2544  }
2545  out.data[out_size++] = (c=='s') ? a : b;
2546  break;
2547 
2548  case 'l': // get low frequency
2549  case 'h': // get high frequency
2550  a = 1.e99;
2551  b = 0.;
2552  for(k=0; k<it_size; k++){
2553  M = (*it)[k];
2554  if(skip.data[k]) continue;
2555  mp= size_t(this->rate/pList[M].rate+0.1);
2556  mm= pList[M].layers; // number of wavelet layers
2557  double dF = mm==mp ? 0. : -0.5; // wavelet : WDM
2558  y = pList[M].rate/2.; // frequency resolution
2559  x = y * (pList[M].frequency+dF); // pixel frequency
2560  if(x <a) a = x;
2561  if(x+y>b) b = x+y;
2562  }
2563  out.data[out_size++] = (c=='l') ? a : b;
2564  break;
2565 
2566  case 'L': // get network likelihood
2567  case 'N': // get network null stream
2568  a = 0.;
2569  x = 0.;
2570  for(k=0; k<it_size; k++){
2571  M = (*it)[k];
2572  if(skip.data[k]) continue;
2573 
2574  if(atype=='S' || atype=='s' || atype=='P' || atype=='p' || !index) {
2575  for(i=0; i<pList[M].size(); i++) {
2576  x += pow(pList[M].data[i].asnr,2);
2577  }
2578  x -= 2*pList[M].likelihood;
2579  }
2580  else if(c=='N'){
2581  b = pList[M].data[m-1].asnr;
2582  b -= pList[M].data[m-1].wave/pList[M].data[m-1].noiserms;
2583  x += b*b;
2584  }
2585 
2586  a += pList[M].likelihood; // pixel network likelihood
2587  }
2588  if(c=='N') a=x;
2589  out.data[out_size++] = a;
2590  break;
2591 
2592  case 't': // get central time optimal resolution
2593  case 'T': // get central time for all resolutions
2594  case 'f': // get central frequency for optimal resolution
2595  case 'F': // get central frequency for all resolutions
2596  case 'D': // get energy-weighted duration for all resolutions
2597  case 'B': // get energy-weighted bandwidth for all resolutions
2598  a = 0.;
2599  b = 0.;
2600  d = 0.;
2601 
2602  if(c=='F' && (int)cFreq.size()>ID-1) { // get supercluster frequency
2603  out.data[out_size++] = cFreq[ID-1];
2604  break;
2605  }
2606  if(c=='T' && (int)cTime.size()>ID-1) { // get supercluster time
2607  out.data[out_size++] = cTime[ID-1];
2608  break;
2609  }
2610 
2611  for(k=0; k<it_size; k++) {
2612  M = (*it)[k];
2613 
2614  if(!index && atype!='L') continue;
2615  if(skip.data[k]) continue;
2616  if(pList[M].size()<m && atype!='L') continue;
2617 
2618  mp= size_t(this->rate/pList[M].rate+0.1);
2619  t = 1./pList[M].rate; // wavelet time resolution
2620  mm= pList[M].layers; // number of wavelet layers
2621  if(atype=='S' || atype=='s' || atype=='P' || atype=='p') { // get Gaussian statistics
2622  x = pList[M].getdata(atype,m-1);
2623  x = x*x;
2624  }
2625  else if (atype=='R' || atype=='r'){ // get rank statistics
2626  x = pList[M].getdata(atype,m-1);
2627  x = pow(sqrt(2*1.07*(fabs(x)-log(bpp)))-1.11/2.,2);
2628  }
2629  else {
2630  x = pList[M].likelihood;
2631  }
2632  if(x<0.) x = 0.;
2633 
2634  if(c=='t' || c=='T' || c=='D') {
2635  double dT = mm==mp ? 0. : 0.5; // wavelet : WDM
2636  double iT = (pList[M].time/mm - dT)*t; // left bin time (all detectors)
2637 
2638  if(index)
2639  iT = (pList[M].data[m-1].index/mm - dT)*t; // left bin time (individual detectors)
2640 
2641  int n = max_rate*t; // number of sub time bins
2642  double dt = 1./max_rate; // max time resolution
2643  iT+=dt/2.; // central bin time
2644  x/=n*n; // rescale weight
2645  for(j=0;j<n;j++) {
2646  a += iT*x; // pixel time sum
2647  b += x; // use weight x
2648  d += iT*iT*x; // duration
2649  iT += dt; // increment time
2650  }
2651  }
2652  else {
2653  double dF = mm==mp ? 0. : 0.5; // wavelet : WDM
2654  double iF = (pList[M].frequency - dF)/t/2.; // left bin frequency (all detectors)
2655 
2656  int n = 1./(min_rate*t); // number of sub freq bins
2657  double df = min_rate/2.; // max frequency resolution
2658  iF+=df/2.; // central bin frequency
2659  x/=n*n; // rescale weight
2660  for(j=0;j<n;j++) {
2661  a += iF*x; // pixel frequency sum
2662  b += x; // use weight x
2663  d += iF*iF*x; // bandwidth
2664  iF += df; // increment freq
2665  }
2666  }
2667  }
2668 
2669  if(c=='B' && b>0) {
2670  a = (d-a*a/b)/b; // bandwidth^2
2671  a = a>0 ? sqrt(a)*b : min_rate/2.; // bandwidth * b
2672  }
2673 
2674  if(c=='D' && b>0) {
2675  a = (d-a*a/b)/b; // duration^2
2676  a = a>0 ? sqrt(a)*b : 1./max_rate; // duration * b
2677  }
2678 
2679  out.data[out_size++] = b>0. ? a/b : -1.;
2680  break;
2681 
2682  case 'H': // get calibrated hrss
2683  case 'n': // get calibrated noise sigma^2
2684  case 'I': // get calibrated noise 1/sigma^2
2685 
2686  mp = 0;
2687  sum = 0.;
2688  out.data[out_size] = 0.;
2689 
2690  for(k=0; k<it_size; k++) {
2691  M = (*it)[k];
2692 
2693  if(!index) continue;
2694  if(skip.data[k]) continue;
2695  if(pList[M].size()<m) continue;
2696 
2697  r = pList[M].getdata('N',m-1);
2698 
2699  mp++;
2700 
2701  if(c == 'H'){
2702  a = pow(pList[M].getdata(atype,m-1),2);
2703  if(atype=='S' || atype=='s' || atype=='P' || atype=='p') { a -= 1.; a *= r*r; }
2704  sum += a<0. ? 0. : a;
2705  }
2706  else if(r>0){
2707  sum += c=='n' ? r*r : 1./r/r;
2708  }
2709 
2710  }
2711 
2712  if(c != 'H' && mp) { sum = sum/double(mp); } // noise hrss
2713  if(c == 'I' && mp) { sum = 1./sum; }
2714  out.data[out_size++] = sum>0. ? float(log(sum)/2./log(10.)) : 0.;
2715  break;
2716 
2717  case 'V': // get cluster core size with likelihood>0
2718  out.data[out_size++] = float(it_like);
2719  break;
2720 
2721  case 'v':
2722  default:
2723  for(k=0; k<it_size; k++){
2724  M = (*it)[k];
2725  if(!skip.data[k]) {
2726  out.data[out_size++] = it_size;
2727  break;
2728  }
2729  }
2730  break;
2731  }
2732  }
2733 
2734  out.resize(out_size);
2735  return out;
2736 }
2737 
2738 
2739 //**************************************************************************
2740 // extract WSeries for specified cluster ID and detector index
2741 // does not work with WDM
2742 //**************************************************************************
2743 double netcluster::getwave(int cid, WSeries<double>& W, char atype, size_t n)
2744 {
2745  if(!cList.size()) return 0.;
2746 // if(atype != 'W' && atype != 'S') return 0.;
2747 
2748  int t,offset;
2749  int ID, R;
2750  int level,mm;
2751 
2752  size_t k,f;
2753  size_t mp = 0;
2754  size_t max_layer;
2755  size_t max,min;
2756  size_t it_size;
2757  size_t it_core;
2758  size_t pixtime;
2759 
2760  double a;
2761  double tsRate = W.rate();
2762  double fl = tsRate/2.;
2763  double fh = 0.;
2764  double sum = 0.;
2765  double temp=0.;
2766 
2767  slice S;
2768 
2769  wavearray<int> skip;
2770  vector<vector_int>::iterator it;
2771  vector_int* pv = NULL;
2772  netpixel* pix;
2773  size_t M = pList.size();
2774 
2775 // extract cluster
2776 
2777  for(it=cList.begin(); it!=cList.end(); it++){
2778 
2779  ID = pList[((*it)[0])].clusterID;
2780  it_size = it->size();
2781 
2782  if(ID != cid) continue; // find the cluster
2783  if(!it_size) continue; // skip empty cluster
2784 
2785  it_core = 0;
2786  skip.resize(it_size);
2787 
2788  pv =&(cRate[ID-1]);
2789  R = pv->size() ? (*pv)[0] : 0;
2790 
2791  max = 0; // max time index
2792  min = 1234567890; // min time index
2793 
2794  for(k=0; k<it_size; k++) { // fill skip array
2795  M = (*it)[k];
2796  pix = &pList[M];
2797 
2798  skip.data[k] = 1;
2799  if(!pList[M].core) continue;
2800  if(R && int(pix->rate+0.1)!=R) continue;
2801  if(!R) R = int(pix->rate+0.1); // case of elementary clusters
2802  mm = pix->layers; // number of wavelet layers
2803  pixtime = pix->getdata('I',n)/mm;
2804  if(pixtime > max) max = pixtime; // max pixel time index
2805  if(pixtime < min) min = pixtime; // min pixel time index
2806  skip.data[k] = 0;
2807  it_core++;
2808  }
2809 
2810  k = size_t((max-min+2*W.pWavelet->m_H)/R)+1; // W duration in seconds
2811 
2812 // cout<<"duration="<<k<<" filter="<<W.pWavelet->m_L<<endl;
2813 
2814 // setup WSeries metadata
2815 
2816 // cout<<"wrate="<<tsRate<<" rate="<<R<<endl;
2817 
2818  W.resize(size_t(k*this->rate+0.1));
2819  W.setLevel(0);
2820  level = int(log(tsRate/R)/log(2.)+0.1);
2821  while(W.getMaxLevel()<level) W.resize(W.size()*2);
2822  W.Forward(level);
2823  W = 0.;
2824 
2825  max_layer = W.maxLayer();
2826 
2827 // cout<<"maxlayer="<<max_layer<<" wsize="<<W.size()<<endl;
2828 
2829  S = W.getSlice(0);
2830  offset = (int(max+min) - int(S.size()))/2;
2831  W.start(double(offset)/R);
2832 
2833 // cout<<"min="<<min<<" max="<<max<<" Ssize="<<S.size()<<endl;
2834 // cout<<"offset="<<offset<<" wsize="<<W.size()<<endl;
2835 
2836  if(!it_core) continue; // skip cluster
2837 
2838  for(k=0; k<it_size; k++){
2839  M = (*it)[k];
2840  pix = &pList[M];
2841 
2842  if(skip.data[k]) continue;
2843  if(!(pix->size())) continue;
2844  mm = pix->layers; // number of wavelet layers
2845  pixtime = size_t(pix->getdata('I',n)/mm);
2846 
2847  f = pix->frequency; // pixel frequency
2848  t = int(pixtime)-offset; // pixel time index
2849 
2850  if(f > max_layer) continue;
2851  if(f*R/2. <= fl) { fl = f*R/2.; W.setlow(fl); }
2852  if((f+1)*R/2. >= fh) { fh = (f+1)*R/2.; W.sethigh(fh); }
2853 
2854  S = W.getSlice(f);
2855 
2856  if(t < 0 || size_t(t) >= S.size()) continue;
2857  if(pix->size() <= n) continue;
2858 
2859  a = pix->getdata(atype,n);
2860  if(atype=='W') a /= pix->getdata('N',n);
2861  W.data[S.start()+t*S.stride()] = a;
2862 
2863  a = pix->getdata('N',n);
2864  mp++; sum += 1./a/a;
2865  temp += pList[M].time/double(R);
2866 
2867  }
2868 
2869 // cout<<"cid="<<cid<<" size="<<mp<<" "<<pow(W.rms(),2.)*W.size()/tsRate;
2870 // cout<<" time="<<temp/mp<<" rate="<<R<<" duration="<<W.size()/tsRate<<endl;
2871 
2872  sum = sqrt(double(mp)/sum); // noise hrss
2873 
2874  return sum;
2875  }
2876  return 0.;
2877 }
2878 
2879 
2881 {
2882 //**************************************************************************
2883 // !!! may violate WDM parity for non-integer seconds lags !!!!
2884 // construct waveform from MRA pixels at different resolutions
2885 // extract MRA waveforms for specified cluster ID and detector index n
2886 // works only with WDM. Create WSeries<> objects for each resolution,
2887 // find principle components, fill in waveForm and waveBand arrays
2888 // atype = 'W' - get whitened detector output (Wavelet data)
2889 // atype = 'w' - get detector output (Wavelet data)
2890 // atype = 'S' - get whitened reconstructed response (Signal)
2891 // atype = 's' - get reconstructed response (Signal)
2892 // mode: -1/0/1 - return 90/mra/0 phase
2893 //**************************************************************************
2895 
2896  if(!cList.size()) return z;
2897 
2898  bool signal = atype=='S' || atype=='s';
2899  bool strain = atype=='w' || atype=='s';
2900 
2901  int nRES = net->wdmList.size();
2902 
2903  double maxfLen = 0; // find max filter length
2904  for(int l=0;l<nRES;l++) {
2905  double fLen = net->wdmList[l]->m_H/this->rate;
2906  if(maxfLen<fLen) maxfLen=fLen;
2907  }
2908 
2909  WDM<double>* wdm;
2910  wavearray<double> x00;
2911  wavearray<double> x90;
2912  std::vector<int>* vint;
2913  wavearray<double> cid;
2914  netpixel* pix;
2915 
2916  cid = this->get((char*)"ID",0,'S',0); // get cluster ID
2917 
2918  int K = cid.size();
2919 
2920  for(int k=0; k<K; k++) { // loop over clusters
2921 
2922  int id = size_t(cid.data[k]+0.1);
2923  if(id!=ID) continue;
2924 
2925  vint = &(this->cList[id-1]); // pixel list
2926 
2927  int V = vint->size();
2928  if(!V) continue;
2929 
2930 // find event time interval, fill in amplitudes
2931 
2932  double tmin=1e20;
2933  double tmax=0.;
2934  double T, a00, a90, rms;
2935  for(int j=0; j<V; j++) {
2936  pix = this->getPixel(id,j);
2937  T = int(pix->time/pix->layers); // get time index
2938  T = T/pix->rate; // time in seconds from the start
2939  if(T<tmin) tmin=T;
2940  if(T>tmax) tmax=T;
2941  }
2942 
2943  tmin = int(tmin-maxfLen)-1; // start event time in sec
2944  tmax = int(tmax+maxfLen)+1; // end event time in sec
2945  z.resize(size_t(this->rate*(tmax-tmin)+0.1));
2946  z.rate(this->rate); z.start(tmin); z.stop(tmax), z=0;
2947 
2948  int io = int(tmin*z.rate()+0.01); // index offset of z-array
2949  int M, j00, j90;
2950 
2951  //cout<<"+++ "<<tmin<<" "<<tmax<<" "<<io<<" "<<z.rate()<<" "<<z.size()<<" "<<maxfLen<<endl;
2952 
2953  float s00=0.;
2954  float s90=0.;
2955 
2956  for(int j=0; j<V; j++) {
2957  pix = this->getPixel(id,j);
2958  if(!pix->core) continue;
2959 
2960  rms = pix->getdata('N',ifo);
2961  a00 = signal ? pix->getdata('s',ifo) : pix->getdata('w',ifo);
2962  a90 = signal ? pix->getdata('p',ifo) : pix->getdata('u',ifo);
2963  a00*= strain ? rms : 1.;
2964  a90*= strain ? rms : 1.;
2965  wdm = net->getwdm(pix->layers); // pointer to WDM transform stored in network
2966  j00 = wdm->getBaseWave(pix->time,x00,false)-io;
2967  j90 = wdm->getBaseWave(pix->time,x90,true)-io;
2968  if(mode < 0) a00=0.; // select phase 90
2969  if(mode > 0) a90=0.; // select phase 00
2970 
2971  s00 += a00*a00;
2972  s90 += a90*a90;
2973 
2974  for(int i=0; i<x00.size(); i++){
2975  if(j00+i<0 || j00+i>=z.size()) continue;
2976  z.data[j00+i] += x00[i]*a00;
2977  z.data[j90+i] += x90[i]*a90;
2978  }
2979  //cout<<"*** "<<pix->layers<<" "<<pix->data[ifo].index<<" "<<j00<<" "<<j90<<" "
2980  // <<x00.size()<<" "<<x90.size()<<" "<<z.size()<<endl;
2981  }
2982  //cout<<mode<<" s00/s90: "<<s00<<" "<<s90<<" "<<z.rms()*z.rms()*z.size()<<endl;
2983 
2984  break;
2985  }
2986  return z;
2987 }
2988 
2989 size_t netcluster::write(const char *fname, int app)
2990 {
2991 // write the entire pixel structure into a file
2992 // only metadata and pixels are written, no cluster metadata is stored
2993 // app = 0 - open new file and dump metadata and pixel structure
2994 // app = 1 - append pixel structure to existing file
2995 
2996  size_t i;
2997  size_t I = this->pList.size(); // number of pixels;
2998  FILE *fp;
2999 
3000  if(app) fp=fopen(fname, "ab");
3001  else fp=fopen(fname, "wb");
3002 
3003  if(!fp) {
3004  cout<<"netcluster::write() error : cannot open file "<<fname<<"\n";
3005  fclose(fp); return 0;
3006  }
3007 
3008  if(!app) { // write metadata
3009  if(!write(fp,app)) { fclose(fp); return 0; };
3010  }
3011 
3012  for(i=0; i<I; i++) { // write pixels
3013  if(!pList[i].write(fp)) { fclose(fp); return 0; }
3014  }
3015  fclose(fp);
3016  return I;
3017 }
3018 
3019 size_t netcluster::write(FILE *fp, int app)
3020 {
3021 // write pixel structure with TD vectors attached into a file
3022 // only some metadata and pixels are written, no cluster metadata is stored
3023 // app = 0 - store metadata
3024 // app = 1 - store pixels with the TD vectors attached by setTDAmp()
3025 
3026  size_t i,k;
3027  size_t I = this->pList.size(); // number of pixels;
3028  size_t II= 0;
3029  netpixel pix;
3030 
3031  // write metadata
3032 
3033  if(!app) {
3034  double db[9];
3035  double rest = this->nPIX*10+2*this->pair;
3036  db[0] = this->rate; // original Time series rate
3037  db[1] = this->start; // interval start GPS time
3038  db[2] = this->stop; // interval stop GPS time
3039  db[3] = this->bpp; // black pixel probability
3040  db[4] = this->shift; // time shift
3041  db[5] = this->flow; // low frequency boundary
3042  db[6] = this->fhigh; // high frequency boundary
3043  db[7] = (double)this->run; // run ID
3044  db[8] = rest; // store the rest
3045  if(fwrite(db, 9*sizeof(double), 1, fp) !=1) {
3046  fclose(fp); return 0;
3047  }
3048  return 1;
3049  }
3050 
3051  if(!I) return 0;
3052 
3053  // write pixels
3054 
3055  for(i=0; i<this->cList.size(); ++i) {
3056  if(sCuts[i]==1) continue;
3057 
3058  const vector_int& v = cList[i];
3059  size_t K = v.size();
3060  bool skip = true;
3061  if(!K) continue;
3062 
3063  for(k=0; k<K; ++k) { // loop over pixels
3064  if(pList[v[k]].tdAmp.size()) skip=false;
3065  }
3066  if(skip) continue;
3067 
3068  netpixel** pp = (netpixel**)malloc(K*sizeof(netpixel*));
3069  for(k=0; k<K; k++) pp[k] = &pList[v[k]];
3070  qsort(pp, K, sizeof(netpixel*), &compareLIKE); // sort pixels
3071 
3072  for(k=0; k<K; k++) { // loop over pixels
3073  if(!pp[k]->tdAmp.size()) continue;
3074  pix = *pp[k];
3075  pp[k]->clean(); // clean TD amplitudes
3076  pix.neighbors.clear();
3077  if(k<K-1) pix.neighbors.push_back(1);
3078  if(k>0) pix.neighbors.push_back(-1);
3079  // set right index (set in subNetCuts) for netcc[3] after pixels sorting
3080  if(k==0) pix.ellipticity = pList[v[0]].ellipticity;
3081  if(k==1) pix.ellipticity = pList[v[1]].ellipticity;
3082  if(k==0) pix.polarisation = pList[v[0]].polarisation;
3083  if(k==1) pix.polarisation = pList[v[1]].polarisation;
3084  pix.write(fp);
3085  II++;
3086  //printf("k = %lu , clID = %lu\n", k, pix->clusterID);
3087  //printf("pixel %d from cluster %d written\n", k, i);
3088  }
3089 
3090  free(pp);
3091  }
3092  return II;
3093 }
3094 
3095 
3096 size_t netcluster::read(const char* fname)
3097 {
3098 // read pixel structure from file
3099 // the entire content is loaded into pList structure
3100  size_t i;
3101  netpixel pix;
3102 
3103  FILE *fp = fopen(fname,"rb");
3104 
3105  if (!fp) {
3106  cout << "netcluster::read() error : cannot open file " << fname <<". \n";
3107  fclose(fp); return 0;
3108  }
3109 
3110  if(!read(fp,0)) {fclose(fp); return 0;} // read metadata
3111 
3112  // read pixels
3113  bool end = false;
3114  do {
3115  pList.push_back(pix);
3116  i = pList.size()-1;
3117  end = pList[i].read(fp);
3118  } while(end);
3119  pList.pop_back();
3120 
3121  size_t I = pList.size();
3122  fclose(fp);
3123  if(I) this->cluster();
3124  return I;
3125 }
3126 
3127 
3128 // read clusters from file
3129 size_t netcluster::read(FILE* fp, int nmax)
3130 {
3131 // read metadata and pixels stored in a file on cluster by cluster basis
3132 // clusters should be contiguous in the file (written by write(FILE*))
3133 // nmax = 0 - read metadata
3134 // nmax > 0 - read no more than maxPix pixels from a cluster
3135 
3136  size_t i;
3137 
3138  if(nmax==0){ // read nextcluster metadata from file
3139  this->clear();
3140  double db[9];
3141  if(fread(db, 9*sizeof(double), 1, fp) !=1) return 0;
3142  int kk = int(db[8]+0.1); // rest
3143  db[8] += db[8]>0. ? 0.1 : -0.1; // prepare for conversion to int
3144  this->rate = db[0]; // original Time series rate
3145  this->start = db[1]; // interval start GPS time
3146  this->stop = db[2]; // interval stop GPS time
3147  this->bpp = db[3]; // black pixel probability
3148  this->shift = db[4]; // time shift
3149  this->flow = db[5]; // low frequency boundary
3150  this->fhigh = db[6]; // high frequency boundary
3151  this->run = int(db[7]+0.1); // run ID
3152  this->nPIX = kk/10; // recover nPIX
3153  this->pair = (kk%10)/2; // recover pair
3154  return 1;
3155  }
3156 
3157  // clean TD amplitudes in pList structure
3158  size_t I = pList.size();
3159  for(i=0; i<I; ++i) pList[i].clean(); // clean TD amplitudes
3160 
3161  // reads first pixel
3162  netpixel pix;
3163  bool stop = false;
3164  size_t II = 0;
3165  int ID = cList.size()+1;
3166 
3167  while(pix.read(fp)){
3168  II++; // update counter
3169  if(II<2 && pix.neighbors.size()<1) stop=true; // just one pixel
3170  if(II>1 && pix.neighbors.size()<2) stop=true; // last pixel
3171  if((int)II>nmax) pix.clean(); // clean cluster tail
3172  pix.clusterID = ID; // setup new ID
3173  pList.push_back(pix); // update pList and counter
3174  if(stop) break;
3175  }
3176 
3177  if(!II) return II;
3178  sCuts.push_back(0); // to be processed by likelihood
3179 
3180  std::vector<int> list(II); // update cluster list
3181  std::vector<int> vtof(NIFO); // recreate time configuration array
3182  std::vector<int> vtmp; // recreate sky index array
3183  for(i=0; i<II; ++i) list[i] = I++;
3184  cList.push_back(list);
3185  nTofF.push_back(vtof);
3186  p_Ind.push_back(vtmp);
3187  return II;
3188 }
3189 
3190 
3191 //**************************************************************************
3192 // set arrays for time-delayed amplitudes in collected coherent pixels
3193 // !!! works only with WDM transformation
3194 //**************************************************************************
3195 size_t netcluster::loadTDamp(network &net, char c, size_t BATCH, size_t LOUD)
3196 {
3197 // set time-delayed amplitude vectors in collected coherent pixels
3198 // returns number of pixels to process, if zero - nothing to process
3199 // net: network
3200 // c: 'a','A' - delayed amplitudes, 'p','P' - delayed power
3201 // BATCH - max number of pixels to process in one batch
3202 // LOUD - max number of loudest pixels to process in a cluster
3203 // state of pixel core field (true/false) indicates if the pixel was
3204 // visited/not_visited by loadTDamp. Time-delay amplitudes are attached only
3205 // if core=false. Therefore, before the first loadTDamp call the core status
3206 // of pixels should be set to false.
3207 
3208  if(!net.ifoListSize()) {
3209  cout<<"netcluster::setTDvec() error: empty network.";
3210  exit(1);
3211  }
3212  if(net.rTDF<=0.) {
3213  cout<<"netcluster::setTDvec() error: run network::setDelayIndex() first.";
3214  exit(1);
3215  }
3216 
3217  WSeries<double>* pTF = net.getifo(0)->getTFmap();
3218 
3219  size_t i,j,k,K,KK;
3220  size_t batch = BATCH ? BATCH : this->size()+1;
3221  size_t L = size_t(net.getDelay((char*)"MAX")*net.rTDF)+1;
3222  size_t nIFO = net.ifoListSize();
3223  size_t loud = LOUD ? LOUD : batch;
3224  size_t count = 0;
3225  size_t npix = 0;
3226  int waveR = int(pTF->wrate()+0.1); // wavelet rate
3227  int ind;
3228 
3229  netpixel* pix; // pointer to pixel
3230  const vector_int* v; // pointer to cluster array of pixels
3231  wavearray<float> vec; // storage for delayed amplitudes
3232 
3233 // set time delayed amplitudes
3234 
3235  for(i=0; i<this->cList.size(); i++){
3236 
3237  if(this->sCuts[i]==1) continue; // skip rejected clusters
3238  v = &(this->cList[i]);
3239  K = v->size();
3240  if(!K) continue;
3241  KK = LOUD && K>loud ? loud : K;
3242  if(this->sCuts[i]==-2) {count+=KK; continue;} // skip loaded clusters
3243 
3244  bool skip = true;
3245  npix = 0;
3246  for(k=0; k<K; k++) { // loop over pixels
3247  pix = &(this->pList[(*v)[k]]);
3248  if(!pix->core) skip=false;
3249  if(pix->tdAmp.size()) {skip=false; npix++;}
3250  }
3251  if(npix==K) {count+=K; continue;} // skip loaded clusters
3252  if(skip) continue; // skip processed clusters
3253 
3254 // sort pixels
3255 
3256  netpixel** pp = (netpixel**)malloc(K*sizeof(netpixel*));
3257  for(k=0; k<K; k++) pp[k] = &(pList[(*v)[k]]);
3258  qsort(pp, K, sizeof(netpixel*), &compareLIKE);
3259 
3260  skip = false;
3261  npix = 0;
3262  for(k=0; k<KK; k++) { // loop over loud pixels
3263  pix = pp[k];
3264 
3265  if(count>=batch) {skip = true; break;}
3266  if(pix->tdAmp.size() && pix->core) {
3267  npix++; // count loaded pixels in the cluster
3268  count++; // count loaded pixels in the batch
3269  continue; // skip loaded pixels
3270  }
3271  if(!pix->core) count++; //
3272  else continue; // skip processed pixels
3273  if(int(pix->rate+0.1)!= waveR) continue; // skip wrong resolutions
3274 
3275  for(j=0; j<nIFO; j++) { // loop over detectors
3276  pTF = net.getifo(j)->getTFmap(); // pointer to TF array
3277  ind = int(pix->data[j].index); // index in TF array
3278  vec = pTF->pWavelet->getTDvec(ind,L,c); // obtain TD vector
3279  pix->tdAmp.push_back(vec); // store TD vector
3280  }
3281 
3282  pix->core = true; // mark pixel as processed
3283  npix++;
3284  }
3285  //cout<<i<<" "<<npix<<" "<<KK<<" "<<K<<" "<<LOUD<<endl;
3286  free(pp);
3287  if(LOUD && npix==KK) this->sCuts[i] = -2; // mark fully loaded cluster
3288  if(skip) break;
3289  }
3290  return count;
3291 }
3292 
3293 
3294 //**************************************************************************
3295 // set arrays for time-delayed amplitudes in collected coherent pixels
3296 // !!! works only with WDM transformation
3297 //**************************************************************************
3298 size_t netcluster::loadTDampSSE(network &net, char c, size_t BATCH, size_t LOUD)
3299 {
3300 // set time-delayed amplitude vectors in collected coherent pixels
3301 // fast version by using sparse TF arrays and SSE instructions
3302 // returns number of pixels to process, if zero - nothing to process
3303 // net: network
3304 // c: 'a','A' - delayed amplitudes, 'p','P' - delayed power
3305 // BATCH - max number of pixels to process in one batch
3306 // LOUD - max number of loudest pixels to process in a cluster
3307 // state of pixel core field (true/false) indicates if the pixel was
3308 // visited/not_visited by loadTDamp. Time-delay amplitudes are attached only
3309 // if core=false. Therefore, before the first loadTDamp call the core status
3310 // of pixels should be set to false.
3311 
3312  if(!net.ifoListSize()) {
3313  cout<<"netcluster::setTDvec() error: empty network.";
3314  exit(1);
3315  }
3316  if(net.rTDF<=0.) {
3317  cout<<"netcluster::setTDvec() error: run network::setDelayIndex() first.";
3318  exit(1);
3319  }
3320 
3321  size_t i,j,k,K,KK,M;
3322  size_t batch = BATCH ? BATCH : this->size()+1;
3323  size_t L = size_t(net.getDelay((char*)"MAX")*net.rTDF)+1;
3324  size_t nIFO = net.ifoListSize();
3325  size_t loud = LOUD ? LOUD : batch;
3326  size_t count = 0;
3327  size_t npix = 0;
3328  size_t nres = net.getifo(0)->ssize(); // number of resolutions
3329  int ind;
3330 
3331  netpixel* pix; // pointer to pixel
3332  const vector_int* v; // pointer to cluster array of pixels
3333  wavearray<float> vec; // storage for delayed amplitudes
3334  WDM<double>* wdm; // pointer to wdm transform
3335  SSeries<double>* pSS; // pointer to sparse TF map
3336 
3337 // set time delayed amplitudes
3338 
3339  for(i=0; i<this->cList.size(); i++){
3340 
3341  if(this->sCuts[i]==-1) continue; // skip analized clusters
3342  if(this->sCuts[i]==1) continue; // skip rejected clusters
3343  v = &(this->cList[i]);
3344  K = v->size();
3345  if(!K) continue;
3346  KK = LOUD && K>loud ? loud : K;
3347  if(this->sCuts[i]==-2) {count+=KK; continue;} // skip loaded clusters
3348 
3349  bool skip = true;
3350  npix = 0;
3351  for(k=0; k<K; k++) { // loop over pixels
3352  pix = &(this->pList[(*v)[k]]);
3353  if(!pix->core) skip=false;
3354  if(pix->tdAmp.size()) {skip=false; npix++;}
3355  }
3356  if(npix==K) {count+=K; continue;} // skip loaded clusters
3357  if(skip) continue; // skip processed clusters
3358 
3359 // sort pixels
3360 
3361  netpixel** pp = (netpixel**)malloc(K*sizeof(netpixel*));
3362  for(k=0; k<K; k++) pp[k] = &(pList[(*v)[k]]);
3363  qsort(pp, K, sizeof(netpixel*), &compareLIKE);
3364 
3365  skip = false;
3366  npix = 0;
3367  for(k=0; k<KK; k++) { // loop over loud pixels
3368  pix = pp[k];
3369 
3370  if(count>=batch) {skip = true; break;}
3371  if(pix->tdAmp.size() && pix->core) {
3372  npix++; // count loaded pixels in the cluster
3373  count++; // count loaded pixels in the batch
3374  continue; // skip loaded pixels
3375  }
3376  if(!pix->core) count++;
3377  else continue; // skip processed pixels
3378 
3379  for(j=0; j<nIFO; j++) { // loop over detectors
3380  ind = net.getifo(j)->getSTFind(pix->rate); // pointer to sparse TF array
3381  pSS = net.getifo(j)->getSTFmap(ind); // pointer to sparse TF array
3382  M = pSS->maxLayer()+1; // number of layers
3383  wdm = net.getwdm(M); // pointer to WDM transform stored in network
3384  ind = int(pix->data[j].index); // index in TF array
3385  vec = wdm->getTDvecSSE(ind,L,c,pSS); // obtain TD vector
3386 
3387  for(int qqq=0; qqq<vec.size(); qqq++){
3388  if(fabs(vec.data[qqq])>1.e6) cout<<vec.data[qqq]<<" nun in loadTDampSSE\n";
3389  }
3390 
3391  pix->tdAmp.push_back(vec); // store TD vector
3392  }
3393 
3394  pix->core = true; // mark pixel as processed
3395  npix++;
3396  }
3397  //cout<<i<<" "<<npix<<" "<<KK<<" "<<K<<endl;
3398  free(pp);
3399  if(LOUD && npix==KK) this->sCuts[i] = -2; // mark fully loaded cluster
3400  if(skip) break;
3401  }
3402  return count;
3403 }
3404 
3405 
3406 size_t netcluster::write(TFile *froot, TString tdir, TString tname, int app, int cycle, int irate, int cID)
3407 {
3408 // write pixel structure with TD vectors attached into a file
3409 // froot - root file pointer
3410 // tdir - internal root directory where the tree is located
3411 // tname - name of tree containing the cluster
3412 // app = 0 - store light netcluster
3413 // app = 1 - store pixels with the TD vectors attached by setTDAmp()
3414 // app < 0 - store all pixels
3415 // cycle - sim -> it is factor id : prod -> it is the lag number
3416 // irate - wavelet layer irate
3417 // if irate is negative the value 'irate' is used to build the tree name
3418 // this permits to create a tree for each irate
3419 // cID - cluster id (cID=0 -> write all clusters)
3420 
3421  size_t i,k;
3422  size_t I = this->pList.size(); // number of pixels;
3423  size_t II= 0;
3424 
3425  // check root file mode
3426  if(TString(froot->GetOption())!="CREATE" && TString(froot->GetOption())!="UPDATE") {
3427  cout<<"netcluster::write error: input root file wrong mode (must be CREATE or UPDATE) "
3428  <<froot->GetPath()<<endl;
3429  exit(1);
3430  } else froot->cd();
3431 
3432  // check if tdir exists otherwise it is created
3433  TDirectory* cdtree = tdir!="" ? (TDirectory*)froot->Get(tdir) : (TDirectory*)froot;
3434  if(cdtree==NULL) cdtree = froot->mkdir(tdir);
3435  cdtree->cd();
3436 
3437  int cid;
3438  int rate; // rate = pix->rate
3439  int orate; // optimal rate
3440  float ctime; // supercluster central time
3441  float cfreq; // supercluster central frequency
3442  netpixel* pix = new netpixel;
3443 
3444  // check if tree tname exists otherwise it is created
3445  char trName[64];
3446  if(irate<0) sprintf(trName,"%s-cycle:%d:%d",tname.Data(),cycle,-irate);
3447  else sprintf(trName,"%s-cycle:%d",tname.Data(),cycle);
3448  TTree* tree = (TTree*)cdtree->Get(trName);
3449  if(tree==NULL) {
3450  tree = new TTree(trName,trName);
3451  tree->Branch("cid",&cid,"cid/I");
3452  tree->Branch("rate",&rate,"rate/I");
3453  tree->Branch("orate",&orate,"orate/I");
3454  tree->Branch("ctime",&ctime,"ctime/F");
3455  tree->Branch("cfreq",&cfreq,"cfreq/F");
3456  tree->Branch("pix","netpixel",&pix,32000,0);
3457  } else {
3458  tree->SetBranchAddress("cid",&cid);
3459  tree->SetBranchAddress("rate",&rate);
3460  tree->SetBranchAddress("orate",&orate);
3461  tree->SetBranchAddress("ctime",&ctime);
3462  tree->SetBranchAddress("cfreq",&cfreq);
3463  tree->SetBranchAddress("pix",&pix);
3464  }
3465 
3466  // disable the AutoFlush mechanism : corrupts the tree (probably a ROOT bug)
3467  tree->SetAutoFlush(0);
3468 
3469  // write metadata netcluster object to the tree user info
3470 
3471  if(!app) {
3472  TList* ulist = tree->GetUserInfo();
3473  if(ulist->GetSize()>0) return 1; // cluster header already presents
3474  netcluster* nc = new netcluster;
3475  nc->cpf(*this,false,0);
3476  nc->clear();
3477  char title[256];sprintf(title,"cycle:%d",cycle);
3478  nc->SetTitle(title);
3479  ulist->Add(nc);
3480  return 0;
3481  }
3482 
3483  if(!I) return 0;
3484 
3485  // write pixels to the cluster tree
3486 
3487  for(i=0; i<this->cList.size(); ++i) {
3488  if(sCuts[i]==1) continue;
3489 
3490  const vector_int& r = cRate[i];
3491  orate = r.size()>0 ? r[0] : 0; // optimal rate
3492 
3493  ctime = cTime[i]; // supercluster central time
3494  cfreq = cFreq[i]; // supercluster central frequency
3495 
3496  const vector_int& v = cList[i];
3497  size_t K = v.size();
3498  if(!K) continue; // skip empty clusters
3499 
3500  if((cID!=0)&&(pList[v[0]].clusterID!=cID)) continue;
3501 
3502  bool skip = true;
3503  for(k=0; k<K; ++k) { // loop over pixels
3504  if(pList[v[k]].tdAmp.size()) skip=false;
3505  }
3506  if(app>0 && skip) continue;
3507 
3508  netpixel** pp = (netpixel**)malloc(K*sizeof(netpixel*));
3509  for(k=0; k<K; k++) pp[k] = &pList[v[k]];
3510  qsort(pp, K, sizeof(netpixel*), &compareLIKE); // sort pixels
3511 
3512  for(k=0; k<K; k++) { // loop over pixels
3513  if(app>0 && !pp[k]->tdAmp.size()) continue;
3514  *pix = *pp[k];
3515  pp[k]->clean(); // clean TD amplitudes
3516  pix->neighbors.clear();
3517  if(k<K-1) pix->neighbors.push_back(1);
3518  if(k>0) pix->neighbors.push_back(-1);
3519 
3520  // set right index (set in subNetCuts) for netcc[3] after pixels sorting
3521  if(k==0) pix->ellipticity = pList[v[0]].ellipticity;
3522  if(k==1) pix->ellipticity = pList[v[1]].ellipticity;
3523  if(k==0) pix->polarisation = pList[v[0]].polarisation;
3524  if(k==1) pix->polarisation = pList[v[1]].polarisation;
3525  cid = pix->clusterID; // setup new ID
3526  rate = pix->rate;
3527  tree->Fill();
3528  II++;
3529 
3530  //printf("k = %lu , clID = %lu\n", k, pix->clusterID);
3531  //printf("pixel %d from cluster %d written\n", k, i);
3532  }
3533 
3534  free(pp);
3535  }
3536 
3537  delete pix;
3538 
3539  return II;
3540 }
3541 
3542 // read clusters from root file
3543 std::vector<int>
3544 netcluster::read(TFile* froot, TString tdir, TString tname, int nmax, int cycle, int rate, int cID)
3545 {
3546 // read metadata and pixels stored in a file on cluster by cluster basis
3547 // clusters should be contiguous in the file (written by write(FILE*))
3548 // froot - root file pointer
3549 // tdir - internal root directory where the tree is located
3550 // tname - name of tree containing the cluster
3551 // nmax = 0 - read metadata
3552 // nmax > 0 - read no more than maxPix heavy pixels from a cluster
3553 // nmax < 0 - read all heavy pixels from a cluster
3554 // nmax -2 - as for (nmax<0) & skip heavy instructions to speedup read
3555 // cycle - sim -> it is factor id : prod -> it is the lag number
3556 // rate - wavelet layer rate
3557 // if rate is negative the value 'rate' is used to build the tree name
3558 // cID - cluster ID
3559 
3560  size_t i;
3561  int cid;
3562  int orate;
3563  float ctime;
3564  float cfreq;
3565  netpixel* pix = new netpixel;
3566 
3567  std::vector<int> list; // cluster list
3568  std::vector<int> vtof(NIFO); // time configuration array
3569  std::vector<int> vtmp; // sky index array
3570  std::vector<float> varea; // sky error regions array
3571  std::vector<float> vpmap; // sky pixel map array
3572  clusterdata cd; // dummy cluster data
3573 
3574  bool skip = nmax==-2 ? true : false;
3575  if(nmax<0) nmax=std::numeric_limits<int>::max();
3576 
3577  // check if dir tdir exist
3578  TObject* obj = tdir!="" ? froot->Get(tdir) : (TObject*)froot;
3579  if(obj==NULL) {
3580  cout<<"netcluster::read error: input dir " << tdir << " not exist" << endl;
3581  exit(1);
3582  }
3583  if(tdir!="" && !TString(obj->ClassName()).Contains("TDirectory")) {
3584  cout<<"netcluster::read error: input dir " << tdir << " is not a directory" << endl;
3585  exit(1);
3586  }
3587  TDirectory* cdtree = tdir!="" ? (TDirectory*)froot->Get(tdir) : (TDirectory*)froot;
3588  if(cdtree==NULL) {
3589  cout<<"netcluster::read error: tree dir " << tdir
3590  << " not present in input root file " << froot->GetPath() << endl;
3591  exit(1);
3592  } else cdtree->cd();
3593 
3594  // check if tree tname exist
3595  char trName[64];
3596  if(rate<0) sprintf(trName,"%s-cycle:%d:%d",tname.Data(),cycle,-rate);
3597  else sprintf(trName,"%s-cycle:%d",tname.Data(),cycle);
3598  TTree* tree = (TTree*)cdtree->Get(trName);
3599  if(rate<0) {tree->LoadBaskets(100000000);rate=abs(rate);} // load baskets in memory
3600  if(tree==NULL) {
3601  cout<<"netcluster::read error: tree " << trName
3602  << " not present in input root file " << froot->GetPath() << endl;
3603  exit(1);
3604  } else {
3605  tree->SetBranchAddress("cid",&cid);
3606  tree->SetBranchAddress("orate",&orate);
3607  tree->SetBranchAddress("ctime",&ctime);
3608  tree->SetBranchAddress("cfreq",&cfreq);
3609  tree->SetBranchAddress("pix",&pix);
3610  }
3611 
3612  // Extract requested infos from tree
3613  char sel[128]="";
3614  if(rate>0) sprintf(sel,"rate==%d ",rate);
3615  if(cID) {if(TString(sel)=="") sprintf(sel,"cid==%d",cID);
3616  else sprintf(sel,"%s && cid==%d",sel,cID);}
3617  if(TString(sel)=="") sprintf(sel,"1==1"); // TTreeFormula needs a non empty string
3618  TTreeFormula cut("cuts", sel, tree); // Draw substituted with TTreeFormula because of bug
3619  // sstrace -> -1 ENOENT (No such file or directory)
3620  // this get rid of the unwanted htemp;1 in root file created by Draw
3621  if(cdtree->Get("htemp")!=NULL) cdtree->Delete("htemp");
3622 
3623  // fill entry,icint arrays with the selected entries
3624  size_t size = tree->GetEntries();
3625  wavearray<double> entry(size);
3626  wavearray<double> icid(size);
3627  int cnt=0;
3628  tree->SetBranchStatus("orate",false);
3629  tree->SetBranchStatus("ctime",false);
3630  tree->SetBranchStatus("cfreq",false);
3631  tree->SetBranchStatus("pix",false);
3632  for(i=0;i<size;i++) {
3633  tree->GetEntry(i);
3634  if(cut.EvalInstance()==0) continue;
3635  entry[cnt]=i;
3636  icid[cnt]=cid;
3637  cnt++;
3638  }
3639  tree->SetBranchStatus("orate",true);
3640  tree->SetBranchStatus("ctime",true);
3641  tree->SetBranchStatus("cfreq",true);
3642  tree->SetBranchStatus("pix",true);
3643  size=cnt;
3644 
3645  // fill vector with cluster ids
3646  std::vector<int> clist;
3647  for(i=0;i<size;i++) clist.push_back(int(icid[i]+0.5));
3648  // erase duplicate entries
3649  removeDuplicates<int>(clist);
3650 
3651  if(nmax==0) {
3652  if(rate<=0 && cID==0){ // read nextcluster metadata from file
3653  TList* ulist = tree->GetUserInfo();
3654  if(ulist->GetSize()==0) {
3655  cout<<"netcluster::read error: header is null" << endl; exit(1);
3656  }
3657  this->clear();
3658  *this = *(netcluster*)ulist->At(0);
3659  delete tree;
3660  return clist; // return the full list of clusters in the tree
3661  } else {
3662  delete tree;
3663  return clist; // return the selected list of clusters in the tree
3664  }
3665  }
3666 
3667  if(rate<0) {cout<<"netcluster::read error: input rate par must be >= 0" << endl; exit(1);}
3668 
3669  int os=0;
3670  for(size_t k=0;k<clist.size();k++) { // read cluster id in the list
3671 
3672  int id = clist[k];
3673 
3674  // clean TD amplitudes in pList structure
3675  size_t I = pList.size();
3676  if(!skip) for(i=0; i<I; ++i) pList[i].clean(); // clean TD amplitudes
3677 
3678  // reads first pixel
3679  bool stop = false;
3680  size_t II = 0;
3681  int ID = cList.size()+1;
3682 
3683  std::vector<int> crate;
3684  for(i=os;i<size;i++) {
3685  if(int(icid[i]+0.5)!=id) continue;
3686  tree->GetEntry(int(entry[i]+0.5));
3687  II++; // update counter
3688  if(II<2 && pix->neighbors.size()<1) stop=true; // just one pixel
3689  if(II>1 && pix->neighbors.size()<2) stop=true; // last pixel
3690  if(II>nmax) pix->clean(); // clean cluster tail
3691  pix->clusterID = ID; // setup new ID
3692  pList.push_back(*pix); // update pList and counter
3693  if(orate&&!crate.size()) crate.push_back(orate);// update cluster rate
3694  if(os==i) os++; // updated the already processed entry index
3695  if(stop) break;
3696  }
3697 
3698  if(!II) {delete tree;return clist;}
3699  sCuts.push_back(0); // to be processed by likelihood
3700 
3701  list.clear();
3702  for(i=0; i<II; ++i) list.push_back(I++); // update cluster list
3703  cList.push_back(list);
3704  cRate.push_back(crate);
3705  cTime.push_back(ctime);
3706  cFreq.push_back(cfreq);
3707  sArea.push_back(varea); // recreate sky error regions array
3708  p_Map.push_back(vpmap); // recreate sky pixel map array
3709  nTofF.push_back(vtof); // recreate time configuration array
3710  p_Ind.push_back(vtmp); // recreate sky index array
3711  if(!skip) cData.push_back(cd); // recreate dummy cluster data
3712  }
3713  delete pix;
3714  delete tree;
3715  return clist; // return the selected list of clusters in the tree
3716 }
3717 
3719 {
3720  int nhpix = 0; // total number of heavy pixels in the netcluster object
3721  for(size_t i=0; i<this->cList.size(); ++i) {
3722  if(sCuts[i]==1) continue;
3723 
3724  const vector_int& v = cList[i];
3725  size_t K = v.size();
3726  if(!K) continue;
3727 
3728  for(size_t k=0; k<K; ++k) { // loop over pixels
3729  if(pList[v[k]].tdAmp.size()) nhpix++;
3730  }
3731  }
3732  ;
3733  cout << endl;
3734  cout.precision(14);
3735  cout << "rate\t= " << this->rate << endl;
3736  cout << "start\t= " << this->start << endl;
3737  cout << "stop\t= " << this->stop << endl;
3738  cout << "shift\t= " << this->shift << endl;
3739  cout << "bpp\t= " << this->bpp << endl;
3740  cout << "flow\t= " << this->flow << endl;
3741  cout << "ghigh\t= " << this->fhigh << endl;
3742  cout << "run\t= " << this->run << endl;
3743  cout << "nPIX\t= " << this->nPIX << endl;
3744  cout << "pair\t= " << this->pair << endl;
3745  cout << endl;
3746  cout << "cList\t= " << this->cList.size() << endl;
3747  cout << "pList\t= " << this->pList.size() << endl;
3748  cout << "hpList\t= " << nhpix << endl;
3749  cout << endl;
3750 
3751  return;
3752 }
3753 
3754 
3755 
wavearray< double > t(hp.size())
TTree * tree
Definition: TimeSortTree.C:20
void sethigh(double f)
Definition: wseries.hh:114
detector * getifo(size_t n)
param: detector index
Definition: network.hh:418
virtual size_t defragment(double T, double F, TH2F *=NULL)
T - maximum time gap in seconds F - maximum frequency gap in Hz.
Definition: netcluster.cc:1275
double rho
char cut[512]
double stop
Definition: netcluster.hh:362
virtual void resize(unsigned int)
Definition: wseries.cc:883
std::vector< int > vector_int
Definition: cluster.hh:17
virtual size_t size() const
Definition: wavearray.hh:127
int getBaseWave(int m, int n, SymmArray< double > &w)
Definition: WDM.cc:305
static const double C
Definition: GNGen.cc:10
#define NIFO
Definition: wat.hh:56
size_t write(const char *file, int app=0)
Definition: netcluster.cc:2989
double gammaCL(double x, double n)
Definition: watfun.hh:113
std::vector< vector_int > cRate
Definition: netcluster.hh:380
static double g(double e)
Definition: GNGen.cc:98
par[0] value
wavearray< double > getMRAwave(network *net, int ID, size_t n, char atype='S', int mode=0)
Definition: netcluster.cc:2880
int j00
int getMaxLevel()
Definition: wseries.cc:85
tuple f
Definition: cwb_online.py:91
printf("total live time: non-zero lags = %10.1f \n", liveTot)
size_t clusterID
Definition: netpixel.hh:91
double min(double x, double y)
Definition: eBBH.cc:13
int offset
Definition: TestSTFT_2.C:19
virtual void rate(double r)
Definition: wavearray.hh:123
std::vector< wavearray< float > > tdAmp
Definition: netpixel.hh:105
int compEndP(const void *p, const void *q)
Definition: netcluster.cc:60
int irate
std::vector< pixel > cluster
Definition: wavepath.hh:43
CWB run(runID)
wavearray< float > getTDvecSSE(int j, int K, char c, SSeries< double > *pss)
Definition: WDM.cc:1183
#define np
plot hist2D SetName("WSeries-1")
wavearray< double > a(hp.size())
size_t frequency
Definition: netpixel.hh:93
float likelihood
Definition: netpixel.hh:96
WSeries< float > v[nIFO]
Definition: cwb_net.C:62
par[0] name
int n
Definition: cwb_net.C:10
wavearray< double > z
Definition: Test10.C:32
double fhigh
Definition: netcluster.hh:366
std::vector< int > neighbors
Definition: netpixel.hh:106
double iGamma(double r, double p)
Definition: watfun.hh:187
TString("c")
int ID
Definition: TestMDC.C:70
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
std::vector< pixdata > data
Definition: netpixel.hh:104
wavearray< double > get(char *name, size_t index=0, char atype='R', int type=1, bool=true)
param: string with parameter name param: index in the amplitude array, which define detector param: c...
Definition: netcluster.cc:2188
double SolarMass()
Definition: constants.hh:184
double bpp
Definition: test_config1.C:22
float theta
double mchirpTEST(int ID)
Definition: netcluster.cc:1825
WDM< double > wdm(nLAYERS, nLAYERS, 6, 10)
netpixel pix(nifo)
void setlow(double f)
Definition: wseries.hh:107
double flow
Definition: netcluster.hh:365
STL namespace.
std::slice getSlice(double n)
Definition: wseries.hh:134
double & gap
size_t setcore(bool core, int id=0)
Definition: netcluster.cc:224
Long_t size
#define M
Definition: UniqSLagsList.C:3
virtual size_t supercluster(char atype, double S, bool core)
param: statistic: E - excess power, L - likelihood param: selection threshold T for likelihood cluste...
Definition: netcluster.cc:789
size_t layers
Definition: netpixel.hh:94
int m
Definition: cwb_net.C:10
std::vector< vector_int > cList
Definition: netcluster.hh:379
virtual void start(double s)
Definition: wavearray.hh:119
int j
Definition: cwb_net.C:10
canvas cd(1)
i drho i
TRandom3 rnd(1)
double rate
Definition: netcluster.hh:360
TList * list
bool write(const FILE *)
Definition: netpixel.cc:73
wc clear()
#define N
bool core
Definition: netpixel.hh:102
char ifo[NIFO_MAX][8]
double Tgap
Definition: test_config1.C:23
size_t ssize()
Definition: detector.hh:172
network ** net
NOISE_MDC_SIMULATION.
size_t ifoListSize()
Definition: network.hh:413
nT
Definition: cbc_plots.C:659
WDM< double > * getwdm(size_t M)
param: number of wdm layers
Definition: network.hh:430
void clean(int cID=0)
Definition: netcluster.hh:433
size_t mode
virtual double rms()
Definition: wavearray.cc:1188
wavearray< double > w
Definition: Test1.C:27
#define nIFO
nc append(pix)
void wrate(double r)
Definition: wseries.hh:102
ofstream out
Definition: cwb_merge.C:196
TH1 * t0
float phi
double signPDF(const size_t m, const size_t k)
Definition: watfun.hh:79
size_t size()
Definition: netpixel.hh:71
virtual size_t cluster()
return number of clusters
Definition: netcluster.cc:450
int BATCH
double time[6]
Definition: cbc_plots.C:435
double G
Definition: DrawEBHH.C:12
double shift
Definition: netcluster.hh:364
unsigned long nSTS
Definition: WaveDWT.hh:125
TGraph * gr
virtual ~netcluster()
Definition: netcluster.cc:94
double getwave(int, WSeries< double > &, char='W', size_t=0)
param: cluster ID param: WSeries where to put the waveform return: noise rms
Definition: netcluster.cc:2743
size_t size() const
Definition: wslice.hh:71
static const double SM
Definition: GNGen.cc:8
i() int(T_cor *100))
std::vector< netpixel > pList
Definition: netcluster.hh:372
float polarisation
Definition: netpixel.hh:101
double Pi
bool log
Definition: WaveMDC.C:41
double fhigh
double * tmp
Definition: testWDM_5.C:31
double getDelay(const char *c="")
Definition: network.cc:2787
std::vector< WDM< double > * > wdmList
Definition: network.hh:599
WSeries< double > pTF[nRES]
Definition: revMonster.cc:8
double start
Definition: netcluster.hh:361
char fname[1024]
int compareLIKE(const void *x, const void *y)
Definition: netcluster.cc:47
virtual wavearray< float > getTDvec(int j, int k, char c='p')
Definition: WaveDWT.hh:66
std::vector< float > cFreq
Definition: netcluster.hh:382
virtual size_t append(netcluster &wc)
param: input netcluster return size of appended pixel list
Definition: netcluster.cc:750
int k
void append(int n)
Definition: netpixel.hh:85
size_t cpf(const netcluster &, bool=false, int=0)
Definition: netcluster.cc:99
float chi2
Definition: cbc_plots.C:603
double mchirp(int ID, double=2.5, double=1.e20, double=0)
Definition: netcluster.cc:1405
double F
size_t time
Definition: netpixel.hh:92
size_t loadTDampSSE(network &net, char c, size_t BATCH=10000, size_t LOUD=0)
Definition: netcluster.cc:3298
virtual size_t delink()
Definition: netcluster.cc:354
double * entry
Definition: cwb_setcuts.C:206
double e
void setLevel(size_t n)
Definition: wseries.hh:94
void removeDuplicates(std::vector< T > &vec)
Definition: netcluster.cc:29
TFile * froot
char tdir[256]
int npix
double dt
void PlotClusters()
Definition: netcluster.cc:2167
regression r
Definition: Regression_H1.C:44
double GravitationalConstant()
Definition: constants.hh:113
double flow
#define RATE
int nifo
unsigned long nWWS
pointer to wavelet work space
Definition: WaveDWT.hh:124
char title[256]
Definition: SSeriesExample.C:1
float ellipticity
Definition: netpixel.hh:100
double T
Definition: testWDM_4.C:11
netcluster & operator=(const netcluster &)
Definition: netcluster.cc:217
ifstream in
std::vector< int > sCuts
Definition: netcluster.hh:374
std::vector< float > cTime
Definition: netcluster.hh:381
int LOUD
WSeries< double > * getTFmap()
param: no parameters
Definition: detector.hh:161
wavearray< int > index
int compare_PIX(const void *x, const void *y)
Definition: netcluster.cc:36
virtual void stop(double s)
Definition: wavearray.hh:121
double fabs(const Complex &x)
Definition: numpy.cc:37
virtual size_t cleanhalo(bool=false)
param: if false - de-cluster pixels return size of the list
Definition: netcluster.cc:542
TString sel("slag[1]:rho[1]")
bool read(const FILE *)
Definition: netpixel.cc:129
void Forward(int n=-1)
param: wavelet - n is number of steps (-1 means full decomposition)
Definition: wseries.cc:228
int cnt
void print()
Definition: netcluster.cc:3718
Meyer< double > S(1024, 2)
double df
int l
Definition: cbc_plots.C:434
sprintf(tfres,"(1/%g)x(%g) (sec)x(Hz)", 2 *df, df)
std::vector< clusterdata > cData
Definition: netcluster.hh:373
double asnr
double mmax
virtual wavearray< double > select(char *, double)
Definition: netcluster.cc:244
void chirpDraw(int id)
Definition: netcluster.cc:2158
DataType_t * data
Definition: wavearray.hh:301
const int nRES
Definition: revMonster.cc:7
Long_t id
double rTDF
Definition: network.hh:558
double bpp
Definition: netcluster.hh:363
WaveDWT< DataType_t > * pWavelet
Definition: wseries.hh:438
double dT
Definition: testWDM_5.C:12
SSeries< double > * getSTFmap(size_t n)
Definition: detector.hh:169
bool save
double ctime
fclose(ftrig)
float rate
Definition: netpixel.hh:95
size_t read(const char *)
Definition: netcluster.cc:3096
double getdata(char type='R', size_t n=0)
Definition: netpixel.hh:56
size_t stride() const
Definition: wslice.hh:75
size_t addhalo(int=0)
param: packet pattern mode return size of the list
Definition: netcluster.cc:612
double shift[NIFO_MAX]
volume[m][l]
Definition: cbc_plots.C:678
virtual void resize(unsigned int)
Definition: wavearray.cc:445
static double pr
Definition: geodesics.cc:8
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
size_t nPIX
Definition: netcluster.hh:367
int getSTFind(double r)
Definition: detector.hh:164
size_t loadTDamp(network &net, char c, size_t BATCH=10000, size_t LOUD=0)
Definition: netcluster.cc:3195
size_t start() const
Definition: wslice.hh:67
int nsel
Definition: cwb_setcuts.C:219
int maxLayer()
Definition: wseries.hh:121
static double Delta
Definition: geodesics.cc:8
int m_H
Definition: Wavelet.hh:103
exit(0)
void clean()
Definition: netpixel.hh:81
double SpeedOfLightInVacuo()
Definition: constants.hh:96
char os[1024]
void clear()
Definition: netcluster.hh:409