Logo Coherent WaveBurst  
Reference Guide
Logo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
network.cc
Go to the documentation of this file.
1 // ++++++++++++++++++++++++++++++++++++++++++++++
2 // S. Klimenko, University of Florida, Gainesville, FL
3 // G.Vedovato, University of Padova, Padova, Italy
4 // WAT network class
5 // ++++++++++++++++++++++++++++++++++++++++++++++
6 
7 #define NETWORK_CC
8 #include <time.h>
9 #include <iostream>
10 #include <stdexcept>
11 #include <xmmintrin.h>
12 #include <immintrin.h>
13 #include "TRandom3.h"
14 #include "TMath.h"
15 #include <fstream>
16 #include "Meyer.hh"
17 #include "injection.hh"
18 #include "network.hh"
19 #include "watplot.hh" // remove
20 #include "TComplex.h"
21 
22 using namespace std;
23 
24 ClassImp(network)
25 
26 // constructors
27 
29  nRun(0), nLag(1), nSky(0), mIFO(0), rTDF(0), Step(0.), Edge(0.), gNET(0.), aNET(0.), iNET(0),
30  eCOR(0.), norm(1.), e2or(0.), acor(sqrt(2.)), pOUT(false), EFEC(true), local(true), optim(true),
31  delta(0.), gamma(0.), precision(0.02), pSigma(4.), penalty(1.), netCC(-1.), netRHO(0.),
32  eDisbalance(true), MRA(false), wfsave(false), pattern(1), _WDM(false), _LIKE(' ')
33 {
34  this->ifoList.clear();
35  this->ifoName.clear();
36  this->segList.clear();
37  this->mdcList.clear();
38  this->livTime.clear();
39  this->mdcTime.clear();
40  this->mdcType.clear();
41  this->mdc__ID.clear();
42 }
43 
44 
46 {
47  *this = value;
48 }
49 
50 // destructor
51 
53 {
54  return;
55 }
56 
57 //**************************************************************************
58 //:select TF samples by value of the network excess energy: 2-8 detectors
59 //**************************************************************************
60 long network::getNetworkPixels(int LAG, double Eo, double norm, TH1F* hist)
61 {
62 // 2G analysis algorithm for selection of significant network pixles
63 // works with WDM/wavelet energy TF maps
64 // LAG - time shift lag defining how detectors are shifted wrt each other.
65 // Eo - pixel energy threshold
66 // norm - dummy
67 // hist- pointer to a diagnostic histogram showing network pixel energy.
68 
69  size_t nIFO = this->ifoList.size(); // number of detectors
70 
71  if(nIFO>NIFO) {
72  cout<<"network::getNetworkPixels(): "
73  <<"invalid number of detectors or\n";
74  return 0;
75  }
76  if(getifo(0)->getTFmap()->w_mode != 1) {
77  cout<<"network::getNetworkPixels(): invalid whitening mode.\n";
78  return 0;
79  }
80 
81  WSeries<double>* pTF = this->getifo(0)->getTFmap(); // pointer to first TF map
82  WSeries<double> MAP; MAP = *pTF; MAP=0.; // initialize TF map
83  wavearray<double>* hTS = this->getifo(0)->getHoT(); // pointer to first TS data
84 
85  int i,j,k,m,n,NN,jj,nM,jE,jb,je,J,K;
86 
87  double Em = 2*Eo; // maximum (sole pixel) threshold
88  double Eh = Em*Em; // halo energy^2
89  double R = pTF->wrate(); // pixel layer rate
90  double r = hTS->rate(); // TS rate
91  int N = pTF->size(); // size of TF array
92  int M = hTS->size(); // size of TS array
93  int I = pTF->maxLayer()+1; // number of layers
94  int II = pTF->maxLayer()-1; // number of layers - 2
95  int jB = int(this->Edge*R+0.001); // number of samples in the edges
96  if(jB&1) {cout<<"getNetworkPixels(1): WDM parity violation\n"; exit(1);}
97 
98  if(jB < 3) {
99  cout<<"network::getNetworkPixels(): insufficient data edge length.\n";
100  exit(1);
101  }
102 
103  netpixel pix(nIFO);
104  pix.core = true;
105  pix.rate = R;
106  pix.layers = I;
107 
108  int in[NIFO]; // pixel time index
109  int IN[NIFO]; // pixel time index
110  double* PDATA;
111  double* pmap;
112  double* pdata[NIFO]; // pointers to data
113  double* pp[5]; // pointers to sorted F-arrays
114  for(n=0; n<nIFO; n++) { // pointers to data
115  pdata[n] = getifo(n)->getTFmap()->data;
116  }
117 
118  long nPix = 0;
119  size_t count = 0; // live pixel counter
120  double a,b,E,Ct,Cb,Ht,Hb;
121 
122  if(hist) {pixeLHood = *pTF; pixeLHood=-1.;}
123  if(this->veto.size() != M) { // set veto array if it is not set
124  veto.resize(M); veto = 1;
125  }
126  short* pveto = this->veto.data; // pointer to veto
127 
128  this->wc_List[LAG].clear(); // clear netcluster structure
129  this->livTime[LAG] = 0.; // clear live time counters
130  this->wc_List[LAG].setlow(pTF->getlow());
131  this->wc_List[LAG].sethigh(pTF->gethigh());
132 
133  a = 1.e10; nM = 0; // master detector
134  for(n=0; n<nIFO; n++) {
135  b = this->getifo(n)->lagShift.data[LAG]; // shift in seconds
136  if(a>b) { a = b; nM = n; }
137  }
138 
139  for(n=0; n<nIFO; n++) {
140  b = this->getifo(n)->lagShift.data[LAG]; // shift in seconds
141  K = int((b-a)*R+0.001); // time shift wrt reference
142  if(K&1) {cout<<"getNetworkPixels(2): WDM parity violation\n"; exit(1);}
143  in[n] = IN[n] = K+jB; // time index of first pixel in the layer
144  }
145 
146  int ib=1;
147  int ie=I;
148  for(i=0; i<I; i++) { // select bandwidth
149  if(pTF->frequency(i) <= pTF->gethigh()) ie=i;
150  if(pTF->frequency(i) <= pTF->getlow()) ib=i+1;
151  }
152  if(ie>I-1) ie = I-1; // required by catalog
153  if(ib<1) ib = 1; // required by catalog
154 
155  slice S = pTF->getSlice(0);
156  jE = S.size()-jB; // last good sample in the layer
157  NN = jE-jB; // #of good samples in the layer
158  if(jE&1) {cout<<"getNetworkPixels(3): WDM parity violation\n"; exit(1);}
159 
160  //cout<<r<<" "<<R<<" "<<I<<" "<<jB<<" "<<this->veto.size()<<endl;
161  //cout<<ib<<" "<<ie<<" "<<NN<<" "<<jB<<" "<<jE<<endl;
162 
163  for(jj=0; jj<NN; jj++) { // loop over time stamps
164 
165  double VETO = 1.;
166  pmap = MAP.data+(jj+jB)*I; // pointer to 0 F sample in MAP
167  for(n=0; n<nIFO; n++) {
168  if(in[n] >= jE) in[n] -= NN; // go to jB sample
169  jb = int(in[n]*r/R+0.01); // first veto index
170  je = int((in[n]+1)*r/R+0.01); // last veto index
171  while(jb<je) if(!pveto[jb++]) VETO=0.; // set veto value
172  PDATA = &(pdata[n][in[n]*I]); // pointer to 0 F sample
173  for(i=0; i<I; i++) pmap[i]+=*PDATA++; // sum energy
174  in[n]++; // increment index pointer
175  }
176 
177  for(i=0; i<I; i++) {
178  pmap[i] *= VETO;
179  if(pmap[i]<Eo || i<ib) pmap[i]=0.; // zero sub-threshold pixels
180  if(pmap[i]>Em) pmap[i]=Em+0.1; // degrade loud pixels
181  }
182  count += VETO; // count live time
183  }
184 
185  for(jj=0; jj<NN; jj++) { // loop over time stamps
186 
187  pmap = MAP.data+(jj+jB)*I; // pointer to 0 F sample in MAP
188  for(n=0; n<nIFO; n++) {
189  if(IN[n] >= jE) IN[n] -= NN; // go to jB sample
190  }
191  for(n=0; n<5; n++) pp[n]=pmap+(n-2)*I; // initialize set of pointers
192  for(i=ib; i<ie; i++) {
193  if((E=pp[2][i])<Eo) continue; // skip subthreshold pixels
194  Ct = pp[2][i+1]+pp[3][ i ]+pp[3][i+1]; // top core
195  Cb = pp[2][i-1]+pp[1][ i ]+pp[1][i-1]; // bottom core
196  Ht = pp[4][i+1]; // top halo
197  Ht+= i<II? pp[4][i+2]+pp[3][i+2]:0.; // top halo
198  Hb = pp[0][i-1]; // bottom halo
199  Hb+= i>1 ? pp[0][i-2]+pp[1][i-2]:0.; // bottom halo
200 
201  if((Ct+Cb)*E<Eh &&
202  (Ct+Ht)*E<Eh &&
203  (Cb+Hb)*E<Eh &&
204  E<Em) continue;
205 
206  E = 0;
207  for(n=0; n<nIFO; n++) {
208  j = IN[n]*I+i; // sample index
209  pix.data[n].index = j;
210  pix.data[n].asnr = sqrt(pdata[n][j]);
211  E += pdata[n][j];
212  }
213  j = IN[nM]*I+i; // reference sample index
214  if(hist) hist->Fill(E);
215  if(hist) pixeLHood.data[j] = E;
216  pix.time = j;
217  pix.frequency = i;
218  pix.likelihood = E;
219  pix.phi = 1; // set pixel mark 1 (will be owerriden in likelihood)
220  wc_List[LAG].append(pix); // save pixels in wc_List
221  nPix++;
222  }
223  for(n=0; n<nIFO; n++) IN[n]++; // increment IN
224  }
225 
226 // set metadata in wc_List
227  this->wc_List[LAG].start = pTF->start();
228  this->wc_List[LAG].stop = pTF->stop();
229  this->wc_List[LAG].rate = pTF->rate();
230  this->livTime[LAG] = count/R; // live time depends on resolution
231 
232  if(nPix) this->setRMS();
233 
234  return nPix;
235 }
236 
237 
238 void network::test_sse(int n, int m) {
239  wavearray<float> a(n*4);
240  wavearray<float> b(n*4);
241  wavearray<float> x(n*4);
242  float qq[4];
243  float rq[4];
244  float sq[4];
245  float* pa = a.data;
246  float* pb = b.data;
247  float* px = x.data;
248  __m128* _pa = (__m128*) pa;
249  __m128* _pb = (__m128*) pb;
250  __m128* _px = (__m128*) px;
251 
252  for(int i=0; i<n*4; i++) {
253  a.data[i]=i/float(n*4*m);
254  b.data[i]=i/float(n*4*m);
255  x.data[i]=i*float(m)/float(n*4);
256  }
257 
258  for(int i=0; i<n; i++) {
259  *(_pa+i) = _mm_sqrt_ps(*(_px+i));
260  *(_pa+i) = _mm_div_ps(_mm_set1_ps(1.),*(_pa+i));
261  *(_pb+i) = _mm_rsqrt_ps(*(_px+i));
262  _mm_storeu_ps(qq,*(_px+i));
263  _mm_storeu_ps(sq,*(_pa+i));
264  _mm_storeu_ps(rq,*(_pb+i));
265  printf("%d %9.7f %9.7f %9.7f \n",i,qq[0],sq[0],rq[0]);
266  printf("%d %9.7f %9.7f %9.7f \n",i,qq[1],sq[1],rq[1]);
267  printf("%d %9.7f %9.7f %9.7f \n",i,qq[2],sq[2],rq[2]);
268  printf("%d %9.7f %9.7f %9.7f \n",i,qq[3],sq[3],rq[3]);
269  }
270 
271  return;
272 }
273 
274 
275 long network::likelihoodWP(char mode, int lag, int iID, TH2F* hist)
276 {
277 // Likelihood analysis with packets
278 // mode: analysis mode:
279 // OPTRES analyses, if upper case and optim=true
280 // MRA analysis in low case or optim=false
281 // r - un-modeled
282 // i - iota - wave: no,partial dispersion correction
283 // p - Psi - wave (no dispersion correction)
284 // l,s - linear, loose linear
285 // c,g - circular. loose circular
286 // e,b - elliptical (no dispersion correction), b=p for now
287 // iID: cluster ID, if negative - sky error regions are calculated
288 // lag: lag index
289 // hist: chirp histogram: If not needed, TGraphErrors* hist=NULL
290 // shold be used as input
291 // return number of processed pixels
292 // Negative gamma regulator turns on the AP prior for sky localization
293 //
294 
295  if(!this->wc_List[lag].size()) return 0;
296 
297  this->like('2');
298  this->wdm(true);
299  this->tYPe = mode;
300 
301  bool cirwave = mode=='g' || mode=='G' || mode=='c' || mode=='C';
302  bool linwave = mode=='l' || mode=='L' || mode=='s' || mode=='S';
303  bool iotwave = mode=='i' || mode=='l' || mode=='e' || mode=='c' ||
304  mode=='I' || mode=='L' || mode=='E' || mode=='C';
305  bool psiwave = mode=='l' || mode=='e' || mode=='p' ||
306  mode=='L' || mode=='E' || mode=='P';
307  bool mureana = mode=='i' || mode=='e' || mode=='c' ||
308  mode=='r' || mode=='p' || mode=='b' ||
309  mode=='l' || mode=='s' || mode=='g';
310  bool rndwave = mode=='r' || mode=='R';
311 
312  bool prior = this->gamma<0 ? true : false; // gamma<0 : antenna pattern prior is used
313  bool m_chirp = this->optim ? false : mureana;
314 
315  if(!this->optim) mureana = true;
316 
317  size_t nIFO = this->ifoList.size();
318  size_t ID = abs(iID);
319 
320  if(nIFO>NIFO) {
321  cout<<"network::likelihoodAVX(): invalid network.\n";
322  exit(0);
323  }
324 
325  float En = 2*acor*acor*nIFO; // network energy threshold in the sky loop
326  float gama = this->gamma*this->gamma*2./3.; // gamma regulator for x componet
327  float deta = fabs(this->delta); if(deta>1) deta=1; // delta regulator for + component
328  float REG[2]; REG[0] = deta*sqrt(2);
329  float netEC = this->netRHO*this->netRHO*2; // netEC/netRHO threshold
330 
331  static const __m128 _oo = _mm_set1_ps(1.e-16); // nusance parameter
332  static const __m128 _sm = _mm_set1_ps(-0.f); // sign mask: -0.f = 1 << 31
333  static const __m128 _En = _mm_set1_ps(En); // network threshold
334 
335  float aa,AA,Lo,Eo,Co,No,Ep,Lp,Np,Cp,Ec,Dc,To,Fo,Em,Lm,Rc,Mo,Mw,Eh;
336  float STAT,ee,EE,cc,ff,FF,Lw,Ew,Cw,Nw,Gn,rho,norm,ch,CH,Cr,Mp,N;
337 
338  size_t i,j,k,l,m,Vm,lm,V,V4,V44,id,K,M;
339  size_t L = this->index.size(); // total number of source locations
340  wavearray<short> skyMMcc(L);
341  short* mm = this->skyMask.data;
342  short* MM = skyMMcc.data;
343  bool skymaskcc = (skyMaskCC.size()==L);
344  int f_ = NIFO/4;
345 
346  float vvv[8];
347  float* v00[NIFO];
348  float* v90[NIFO];
349  float* pe[NIFO];
350  float* pa[NIFO];
351  float* pA[NIFO];
352  float *pd[NIFO], *pD[NIFO];
353  float *ps[NIFO], *pS[NIFO];
354  float *pn[NIFO], *pN[NIFO];
355  short* ml[NIFO];
356  double* FP[NIFO];
357  double* FX[NIFO];
358  double xx[NIFO];
359 
360  std::vector<float*> _vtd; // vectors of TD amplitudes
361  std::vector<float*> _vTD; // vectors of TD amplitudes
362  std::vector<float*> _eTD; // vectors of TD energies
363  std::vector<float*> _AVX; // vectors for network pixel statistics
364  std::vector<float*> _APN; // vectors for noise and antenna patterns
365  std::vector<float*> _DAT; // vectors for packet amplitudes
366  std::vector<float*> _SIG; // vectors for packet amplitudes
367  std::vector<float*> _NUL; // vectors for packet amplitudes
368  std::vector<float*> _TMP; // temp array for _avx_norm_ps() function
369 
370  for(i=0; i<NIFO; i++) {
371  if(i<nIFO) {
372  ml[i] = getifo(i)->index.data;
373  FP[i] = getifo(i)->fp.data;
374  FX[i] = getifo(i)->fx.data;
375  }
376  else {
377  ml[i] = getifo(0)->index.data;
378  FP[i] = getifo(0)->fp.data;
379  FX[i] = getifo(0)->fx.data;
380  }
381  }
382 
383  // allocate buffers
384  std::vector<int> pI; // buffer for pixel IDs
385  std::vector<int> pJ; // buffer for pixel index
386  wavearray<double> cid; // buffers for cluster ID
387  wavearray<double> cTo; // buffers for cluster time
388  wavearray<float> S_snr(NIFO); // energy SNR of signal
389  wavearray<float> D_snr(NIFO); // energy SNR of data time series
390  wavearray<float> N_snr(NIFO); // energy of null streams
391  netpixel* pix;
392  std::vector<int>* vint;
393  std::vector<int>* vtof;
394  netcluster* pwc = &this->wc_List[lag];
395 
396  size_t count = 0;
397  size_t tsize = 0;
398 
399  std::map<int,float> vLr; // resolution map
400 
401  // initialize parameters to manage big clusters
402  int precision = int(fabs(this->precision));
403  int csize = precision%65536; // get number of pixels threshold per level
404  int healpix = this->nSkyStat.getOrder(); // get healpix order of likelihood skymap
405  int order = (precision-csize)/65536; // get resampled order
406  wavearray<short> BB(L);BB=1; // index array for setting sky mask
407  bool bBB = false;
408  if(healpix && csize && order && order<healpix) {
409  skymap rsm(order); // resampled skymap
410  for(int l=0;l<rsm.size();l++) {
411  int m = this->nSkyStat.getSkyIndex(rsm.getTheta(l),rsm.getPhi(l));
412  BB[m]=0;
413  }
414  for(int l=0;l<L;l++) BB[l] = BB[l] ? 0 : 1;
415  }
416 
417 //+++++++++++++++++++++++++++++++++++++++
418 // loop over clusters
419 //+++++++++++++++++++++++++++++++++++++++
420 
421  cid = pwc->get((char*)"ID", 0,'S',0); // get cluster ID
422  cTo = pwc->get((char*)"time",0,'L',0); // get cluster time
423 
424  K = cid.size();
425  for(k=0; k<K; k++) { // loop over clusters
426  id = size_t(cid.data[k]+0.1);
427 
428  if(pwc->sCuts[id-1] != -2) continue; // skip rejected/processed clusters
429 
430  vint = &(pwc->cList[id-1]); // pixel list
431  vtof = &(pwc->nTofF[id-1]); // TofFlight configurations
432  V = vint->size();
433  if(!V) continue;
434 
435  pI = wdmMRA.getXTalk(pwc, id);
436  V = pI.size();
437  if(!V) continue;
438 
439  bBB = (V>this->wdmMRA.nRes*csize) ? true : false; // check big cluster size condition
440 
441  if(ID==id) {
442  this->nSensitivity = 0.;
443  this->nAlignment = 0.;
444  this->nNetIndex = 0.;
445  this->nDisbalance = 0.;
446  this->nLikelihood = 0.;
447  this->nNullEnergy = 0.;
448  this->nCorrEnergy = 0.;
449  this->nCorrelation = 0.;
450  this->nSkyStat = 0.;
451  this->nEllipticity = 0.;
452  this->nPolarisation = 0.;
453  this->nProbability = 0.;
454  }
455  this->nAntenaPrior = 0.;
456 
457  pix = pwc->getPixel(id,pI[0]);
458  tsize = pix->tdAmp[0].size();
459  if(!tsize || tsize&1) { // tsize%1 = 1/0 = power/amplitude
460  cout<<"network::likelihoodWP() error: wrong pixel TD data\n";
461  exit(1);
462  }
463 
464  tsize /= 2;
465 
466  if(!(V=pI.size())) continue;
467  V4 = V + (V%4 ? 4 - V%4 : 0);
468  V44 = V4 + 4;
469  pJ.clear();
470  for(j=0; j<V4; j++) pJ.push_back(0);
471 
472  float* ptmp; // allocate aligned arrays
473  if(_vtd.size()) _avx_free_ps(_vtd); // array for 00 amplitudes
474  if(_vTD.size()) _avx_free_ps(_vTD); // array for 90 amplitudes
475  if(_eTD.size()) _avx_free_ps(_eTD); // array for pixel energy
476  if(_APN.size()) _avx_free_ps(_APN); // container for noise rms and antenna patterns
477  if(_DAT.size()) _avx_free_ps(_DAT); // container for data packet amplitudes
478  if(_SIG.size()) _avx_free_ps(_SIG); // container for signal packet amplitudes
479  if(_NUL.size()) _avx_free_ps(_NUL); // container for null packet amplitudes
480  for(i=0; i<NIFO; i++) {
481  ptmp = (float*)_mm_malloc(tsize*V4*sizeof(float),32);
482  for(j=0; j<tsize*V4; j++) ptmp[j]=0; _vtd.push_back(ptmp); // array of aligned vectors
483  ptmp = (float*)_mm_malloc(tsize*V4*sizeof(float),32);
484  for(j=0; j<tsize*V4; j++) ptmp[j]=0; _vTD.push_back(ptmp); // array of aligned vectors
485  ptmp = (float*)_mm_malloc(tsize*V4*sizeof(float),32);
486  for(j=0; j<tsize*V4; j++) ptmp[j]=0; _eTD.push_back(ptmp); // array of aligned vectors
487  ptmp = (float*)_mm_malloc((V4*3+16)*sizeof(float),32);
488  for(j=0; j<(V4*3+16); j++) ptmp[j]=0; _APN.push_back(ptmp); // concatenated arrays {f+}{fx}{rms}{a+,A+,ax,AX}
489  ptmp = (float*)_mm_malloc((V4*3+8)*sizeof(float),32);
490  for(j=0; j<(V4*3+8); j++) ptmp[j]=0; _DAT.push_back(ptmp); // concatenated arrays {amp}{AMP}{norm}{n,N,c,s}
491  ptmp = (float*)_mm_malloc((V4*3+8)*sizeof(float),32);
492  for(j=0; j<(V4*3+8); j++) ptmp[j]=0; _SIG.push_back(ptmp); // concatenated arrays {amp}{AMP}{norm}{n,N,c,s}
493  ptmp = (float*)_mm_malloc((V4*3+8)*sizeof(float),32);
494  for(j=0; j<(V4*3+8); j++) ptmp[j]=0; _NUL.push_back(ptmp); // concatenated arrays {amp}{AMP}{norm}{n,N,c,s}
495  }
496 
497  for(i=0; i<NIFO; i++) { // set up zero delay and packet pointers
498  pa[i] = _vtd[i] + (tsize/2)*V4;
499  pA[i] = _vTD[i] + (tsize/2)*V4;
500  pe[i] = _eTD[i] + (tsize/2)*V4;
501  pd[i] = _DAT[i]; pD[i] = _DAT[i]+V4;
502  ps[i] = _SIG[i]; pS[i] = _SIG[i]+V4;
503  pn[i] = _NUL[i]; pN[i] = _NUL[i]+V4;
504  }
505 
506  this->a_00.resize(NIFO*V44); this->a_00=0.; // array for pixel amplitudes in sky loop
507  this->a_90.resize(NIFO*V44); this->a_90=0.; // array for pixel amplitudes in sky loop
508  this->rNRG.resize(V4); this->rNRG=0.;
509  this->pNRG.resize(V4); this->pNRG=0.;
510 
511  __m128* _aa = (__m128*) this->a_00.data; // set pointer to 00 array
512  __m128* _AA = (__m128*) this->a_90.data; // set pointer to 90 array
513 
514  if(_AVX.size()) _avx_free_ps(_AVX);
515  float* p_et = (float*)_mm_malloc(V4*sizeof(float),32); // 0
516  for(j=0; j<V4; j++) p_et[j]=0; _AVX.push_back(p_et);
517  float* pMSK = (float*)_mm_malloc(V44*sizeof(float),32); // 1 - pixel mask
518  for(j=0; j<V44; j++) pMSK[j]=0; _AVX.push_back(pMSK); pMSK[V4]=nIFO;
519  float* p_fp = (float*)_mm_malloc(V44*sizeof(float),32); // 2- |f+|^2 (0:V4), +norm (V4:V4+4)
520  for(j=0; j<V44; j++) p_fp[j]=0; _AVX.push_back(p_fp);
521  float* p_fx = (float*)_mm_malloc(V44*sizeof(float),32); // 3- |fx|^2 (0:V4), xnorm (V4:V4+4)
522  for(j=0; j<V44; j++) p_fx[j]=0; _AVX.push_back(p_fx);
523  float* p_si = (float*)_mm_malloc(V4*sizeof(float),32); // 4
524  for(j=0; j<V4; j++) p_si[j]=0; _AVX.push_back(p_si);
525  float* p_co = (float*)_mm_malloc(V4*sizeof(float),32); // 5
526  for(j=0; j<V4; j++) p_co[j]=0; _AVX.push_back(p_co);
527  float* p_uu = (float*)_mm_malloc((V4+16)*sizeof(float),32); // 6 - 00+ unit vector(0:V4), norm(V4), cos(V4+4)
528  for(j=0; j<V4+16; j++) p_uu[j]=0; _AVX.push_back(p_uu);
529  float* p_UU = (float*)_mm_malloc((V4+16)*sizeof(float),32); // 7 - 90+ unit vector(0:V4), norm(V4), sin(V4+4)
530  for(j=0; j<V4+16; j++) p_UU[j]=0; _AVX.push_back(p_UU);
531  float* p_vv = (float*)_mm_malloc((V4+16)*sizeof(float),32); // 8- 00x unit vector(0:V4), norm(V4), cos(V4+4)
532  for(j=0; j<V4+16; j++) p_vv[j]=0; _AVX.push_back(p_vv);
533  float* p_VV = (float*)_mm_malloc((V4+16)*sizeof(float),32); // 9- 90x unit vector(0:V4), norm(V4), sin(V4+4)
534  for(j=0; j<V4+16; j++) p_VV[j]=0; _AVX.push_back(p_VV);
535  float* p_au = (float*)_mm_malloc(V4*sizeof(float),32); // 10
536  for(j=0; j<V4; j++) p_au[j]=0; _AVX.push_back(p_au);
537  float* p_AU = (float*)_mm_malloc(V4*sizeof(float),32); // 11
538  for(j=0; j<V4; j++) p_AU[j]=0; _AVX.push_back(p_AU);
539  float* p_av = (float*)_mm_malloc(V4*sizeof(float),32); // 12
540  for(j=0; j<V4; j++) p_av[j]=0; _AVX.push_back(p_av);
541  float* p_AV = (float*)_mm_malloc(V4*sizeof(float),32); // 13
542  for(j=0; j<V4; j++) p_AV[j]=0; _AVX.push_back(p_AV);
543  float* p_uv = (float*)_mm_malloc(V4*4*sizeof(float),32); // 14 special array for GW norm calculation
544  for(j=0; j<V4*4; j++) p_uv[j]=0; _AVX.push_back(p_uv);
545  float* p_ee = (float*)_mm_malloc(V4*sizeof(float),32); // 15 + energy array
546  for(j=0; j<V4; j++) p_ee[j]=0; _AVX.push_back(p_ee);
547  float* p_EE = (float*)_mm_malloc(V4*sizeof(float),32); // 16 x energy array
548  for(j=0; j<V4; j++) p_EE[j]=0; _AVX.push_back(p_EE);
549  float* pTMP=(float*)_mm_malloc(V4*4*NIFO*sizeof(float),32); // 17 temporary array for _avx_norm_ps()
550  for(j=0; j<V4*4*NIFO; j++) pTMP[j]=0; _AVX.push_back(pTMP);
551  float* p_ni = (float*)_mm_malloc(V4*sizeof(float),32); // 18 + network index
552  for(j=0; j<V4; j++) p_ni[j]=0; _AVX.push_back(p_ni);
553  float* p_ec = (float*)_mm_malloc(V4*sizeof(float),32); // 19 + coherent energy
554  for(j=0; j<V4; j++) p_ec[j]=0; _AVX.push_back(p_ec);
555  float* p_gn = (float*)_mm_malloc(V4*sizeof(float),32); // 20 + Gaussian noise correction
556  for(j=0; j<V4; j++) p_gn[j]=0; _AVX.push_back(p_gn);
557  float* p_ed = (float*)_mm_malloc(V4*sizeof(float),32); // 21 + energy disbalance
558  for(j=0; j<V4; j++) p_ed[j]=0; _AVX.push_back(p_ed);
559  float* p_rn = (float*)_mm_malloc(V4*sizeof(float),32); // 22 + sattelite noise in TF domain
560  for(j=0; j<V4; j++) p_rn[j]=0; _AVX.push_back(p_rn);
561 
562 
563  this->pList.clear();
564  for(j=0; j<V; j++) { // loop over selected pixels
565  pix = pwc->getPixel(id,pI[j]);
566  this->pList.push_back(pix); // store pixel pointers for MRA
567 
568  double rms = 0.;
569  for(i=0; i<nIFO; i++) {
570  xx[i] = 1./pix->data[i].noiserms;
571  rms += xx[i]*xx[i]; // total inverse variance
572  }
573 
574  rms = sqrt(rms);
575  for(i=0; i<nIFO; i++) {
576  _APN[i][V4*2+j] =(float)xx[i]/rms; // noise array for AVX processing
577  for(l=0; l<tsize; l++) {
578  aa = pix->tdAmp[i].data[l]; // copy TD 00 data
579  AA = pix->tdAmp[i].data[l+tsize]; // copy TD 90 data
580  _vtd[i][l*V4+j] = aa; // copy 00 data
581  _vTD[i][l*V4+j] = AA; // copy 90 data
582  _eTD[i][l*V4+j] = aa*aa+AA*AA; // copy power
583  }
584  }
585  }
586 
587 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
588 // sky loop
589 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
590 
591  __m256 _CC;
592  size_t lb = 0;
593  size_t le = L-1;
594  double sky = 0.;
595  STAT=-1.e12; lm=0; Em=Lm=ff=FF=0;
596 
597  skyMMcc = 0;
598  for(l=lb; l<=le; l++) { // loop over sky locations
599  if(!mm[l]) continue; // skip delay configurations
600  if(bBB && !BB[l]) continue; // skip delay configurations : big clusters
601 
602  if(skymaskcc) { // transform l into celestial coordinates lc
603  skymap* sm = &(this->nSkyStat);
604  double gT = cTo.data[k]+pwc->start; // trigger gps time
605  double RA = sm->phi2RA(sm->getPhi(l),gT); // phi -> RA
606  int lc=this->getIndex(sm->getTheta(l),RA); // get sky index in celestial coordinates
607  if (!skyMaskCC.data[lc]) continue;
608  }
609  MM[l] = 1; FF += 1; // set final skymap
610  aa = _avx_dpf_ps(FP,FX,l,_APN,_AVX,V4); // calculate DPF f+,fx and their norms
611  if(aa > gama) ff += 1;
612  }
613  REG[1] = (FF*FF/(ff*ff+1.e-9)-1)*En; // setup x regulator
614 
615  optsky:
616 
617  AA = 0.; // initialize sky statistic
618  for(l=lb; l<=le; l++) { // loop over sky locations
619  skyProb.data[l] = -1.e12;
620  if(!MM[l]) continue; // apply sky mask
621  pnt_(v00, pa, ml, (int)l, (int)V4); // pointers to first pixel 00 data
622  pnt_(v90, pA, ml, (int)l, (int)V4); // pointers to first pixel 90 data
623  Eo=_avx_loadata_ps(v00,v90,pd,pD,En,_AVX,V4); // calculate data stats and store in _AVX
624 
625  _avx_dpf_ps(FP,FX,l,_APN,_AVX,V4); // calculate DPF f+,fx and their norms
626  _avx_cpf_ps(v00,v90,ps,pS,V4); // copy data for GW reconstruction
627  Mo = _avx_GW_ps(ps,pS,_APN,REG,_AVX,V4); // gw strain packet, return number of selected pixels
628 
629  if(lb==le) _avx_saveGW_ps(ps,pS,V); // save gw strain packet into a_00,a_90
630 
631  Lo = _avx_ort_ps(ps,pS,_AVX,V4); // othogonalize signal amplitudes
632  _CC = _avx_stat_ps(pd,pD,ps,pS,_AVX,V4); // coherent statistics
633  _mm256_storeu_ps(vvv,_CC); // extract coherent statistics
634  Cr = vvv[0]; // cc statistics
635  Ec = vvv[1]; // signal coherent energy in TF domain
636  Mp = vvv[2]; // signal energy disbalance in TF domain
637  No = vvv[3]; // total noise in TF domain
638  CH = No/(nIFO*Mo+sqrt(Mo)); // chi2 in TF domain
639  cc = CH>1 ? CH : 1; // noise correction factor in TF domain
640  Co = Ec/(Ec+No*cc-Mo*(nIFO-1)); // network correlation coefficient in TF
641 
642  if(Cr<netCC) continue;
643 
644  aa = Eo>0. ? Eo-No : 0.; // likelihood skystat
645  AA = aa*Co; // x-correlation skystat
646  skyProb.data[l] = this->delta<0 ? aa : AA;
647 
648  ff = FF = ee = 0.;
649  for(j=0; j<V; j++) {
650  if(pMSK[j]==0) continue;
651  ee += p_et[j]; // total energy
652  ff += p_fp[j]*p_et[j]; // |f+|^2
653  FF += p_fx[j]*p_et[j]; // |fx|^2
654  }
655  ff = ee>0. ? ff/ee : 0.;
656  FF = ee>0. ? FF/ee : 0.;
657  this->nAntenaPrior.set(l, sqrt(ff+FF));
658 
659  if(ID==id) {
660  this->nSensitivity.set(l, sqrt(ff+FF));
661  this->nAlignment.set(l, ff>0 ? sqrt(FF/ff):0);
662  this->nLikelihood.set(l, Eo-No);
663  this->nNullEnergy.set(l, No);
664  this->nCorrEnergy.set(l, Ec);
665  this->nCorrelation.set(l,Co);
666  this->nSkyStat.set(l,AA);
667  this->nProbability.set(l, skyProb.data[l]);
668  this->nDisbalance.set(l,CH);
669  this->nNetIndex.set(l,cc);
670  this->nEllipticity.set(l,Cr);
671  this->nPolarisation.set(l,Mp);
672  }
673 
674  if(AA>=STAT) {STAT=AA; lm=l; Em=Eo-Eh;}
675  if(skyProb.data[l]>sky) sky=skyProb.data[l]; // find max of skyloc stat
676 
677  if(lb!=le) continue;
678 
679  Eo = _avx_packet_ps(pd,pD,_AVX,V4); // get data packet
680  Lo = _avx_packet_ps(ps,pS,_AVX,V4); // get signal packet
681  D_snr = _avx_norm_ps(pd,pD,_AVX,V4); // data packet energy snr
682  S_snr = _avx_norm_ps(pS,pD,p_ec,V4); // set signal norms, return signal SNR
683  Ep = D_snr[0];
684  Lp = S_snr[0];
685 
686  _CC = _avx_noise_ps(pS,pD,_AVX,V4); // get G-noise correction
687  _mm256_storeu_ps(vvv,_CC); // extract coherent statistics
688  Gn = vvv[0]; // gaussian noise correction
689  Ec = vvv[1]; // core coherent energy in TF domain
690  Dc = vvv[2]; // signal-core coherent energy in TF domain
691  Rc = vvv[3]; // EC normalization
692  Eh = vvv[4]; // satellite energy in TF domain
693  Em = Eo-Eh;
694  norm = Em>0 ? Ep/Em : 0; // inverse norm
695  norm*= norm<1 ? 1. : 1./norm; // corrected inverse norm
696  Ec*= norm; // signal coherent energy in TF domain
697  Dc*= norm; // signal coherent energy in TF domain
698  rho= Ec>0 ? sqrt(Ec*Rc/2.) : 0.; // cWB detection stat
699 
700  N = _avx_setAMP_ps(pd,pD,_AVX,V4)-1; // set data packet amplitudes
701 
702  _avx_setAMP_ps(ps,pS,_AVX,V4); // set signal packet amplitudes
703  _avx_loadNULL_ps(pn,pN,pd,pD,ps,pS,V4); // load noise TF domain amplitudes
704  D_snr = _avx_norm_ps(pd,pD,_AVX,-V4); // data packet energy snr
705  N_snr = _avx_norm_ps(pn,pN,_AVX,-V4); // noise packet energy snr
706  Np = N_snr.data[0]; // time-domain NULL
707  Ep = D_snr.data[0]; // time domain energy
708  Lm = Ep-Np-Gn;
709  ch = (Np+Gn)/(N*nIFO); // chi2
710  cc = ch>1 ? ch : 1; // rho correction factor
711  }
712 
713  if(le-lb) {lb=le=lm; goto optsky;} // process all pixels at opt sky location
714 
715  if(Lm<=0. || Em<=0. || Ec*Rc/cc<netEC || N<1) {
716  pwc->sCuts[id-1]=1; count=0; // reject cluster
717  pwc->clean(id); continue;
718  }
719 
720 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
721 // detection statistics at selected sky location
722 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
723 
724  vint = &(pwc->cList[id-1]); // pixel list
725  for(j=0; j<vint->size(); j++) { // initialization for all pixels
726  pix = pwc->getPixel(id,j);
727  pix->core = false;
728  pix->likelihood = 0.;
729  pix->null = 0;
730  }
731 
732 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
733 // detection statistics at selected sky location
734 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
735  M = Mw = 0; // add denoised pixels
736  for(j=0; j<V; j++) { // loop over pixels
737  pix = pwc->getPixel(id,pI[j]);
738  if(pMSK[j]>0) { // Mo - EP pixels: stored in size[0]
739  pix->core = true;
740  pix->likelihood = -(p_ee[j]+p_EE[j])/2; // negative total pixel energy
741  }
742 
743  for(i=0; i<nIFO; i++) {
744  pix->setdata(double(pd[i][j]),'W',i); // 00 whitened
745  pix->setdata(double(pD[i][j]),'U',i); // 90 whitened
746  pix->setdata(double(ps[i][j]),'S',i); // 00 reconstructed whitened response
747  pix->setdata(double(pS[i][j]),'P',i); // 90 reconstructed whitened response
748  }
749  }
750 
751  for(j=0; j<V; j++) { // loop over pixels
752  pix = pwc->getPixel(id,pI[j]);
753  if(!pix->core) continue;
754  if(p_gn[j]<=0) continue; // skip satellites
755  Mw += 1.; // event size stored in size[1]
756  for(k=0; k<V; k++) { // loop over xtalk components
757  netpixel* xpix = pwc->getPixel(id,pI[k]);
758  struct xtalk xt = wdmMRA.getXTalk(pix->layers, pix->time, xpix->layers, xpix->time);
759  if(!xpix->core || p_gn[k]<=0 || xt.CC[0]>2) continue;
760  for(i=0; i<nIFO; i++) {
761  pix->null += xt.CC[0]*pn[i][j]*pn[i][k];
762  pix->null += xt.CC[1]*pn[i][j]*pN[i][k];
763  pix->null += xt.CC[2]*pN[i][j]*pn[i][k];
764  pix->null += xt.CC[3]*pN[i][j]*pN[i][k];
765  }
766  }
767 
768  if(p_ec[j]<=0) continue; // skip incoherent pixels
769  M += 1; // M - signal size: stored in volume[1]
770  pix->likelihood = 0; // total pixel energy
771  for(k=0; k<V; k++) { // loop over xtalk components
772  netpixel* xpix = pwc->getPixel(id,pI[k]);
773  struct xtalk xt = wdmMRA.getXTalk(pix->layers, pix->time, xpix->layers, xpix->time);
774  if(!xpix->core || p_ec[k]<=0 || xt.CC[0]>2) continue;
775  for(i=0; i<nIFO; i++) {
776  pix->likelihood += xt.CC[0]*ps[i][j]*ps[i][k];
777  pix->likelihood += xt.CC[1]*ps[i][j]*pS[i][k];
778  pix->likelihood += xt.CC[2]*pS[i][j]*ps[i][k];
779  pix->likelihood += xt.CC[3]*pS[i][j]*pS[i][k];
780  }
781  }
782  }
783 
784  // subnetwork statistic
785  double Emax = 0;
786  double Nmax = 0;
787  for(j=1; j<=nIFO; j++) { // loop over detectors
788  if(S_snr[j]>Emax) Emax=S_snr[j]; // detector with max energy
789  }
790  double Esub = S_snr.data[0]-Emax;
791  Esub = Esub*(1+2*Rc*Esub/Emax);
792  Nmax = Gn+Np-N*(nIFO-1);
793 
794  //if(hist) hist->Fill(pwc->cData[id-1].skycc,pwc->cData[id-1].netcc);
795 
796 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
797 // fill in detection statistics, prepare output data
798 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
799 
800 // fill in backward delay configuration
801 
802  vtof->clear();
803  NETX (vtof->push_back(ml[0][lm]); ,
804  vtof->push_back(ml[1][lm]); ,
805  vtof->push_back(ml[2][lm]); ,
806  vtof->push_back(ml[3][lm]); ,
807  vtof->push_back(ml[4][lm]); ,
808  vtof->push_back(ml[5][lm]); ,
809  vtof->push_back(ml[6][lm]); ,
810  vtof->push_back(ml[7][lm]); )
811 
812  // need to fix a problem below
813  if((wfsave)||(mdcListSize() && !lag)) { // if wfsave=false only simulated wf are saved
814  if(this->getMRAwave(id,lag,'S',0,true)) { // reconstruct whitened shifted pd->waveForm
815  detector* pd;
816  for(i=0; i<nIFO; i++) { // loop over detectors
817  pd = this->getifo(i);
818  pd->RWFID.push_back(id); // save cluster ID
820  *wf = pd->waveForm;
821  wf->start(pwc->start+pd->waveForm.start());
822  pd->RWFP.push_back(wf);
823  }
824  }
825  if(this->getMRAwave(id,lag,'s',0,true)) { // reconstruct strain shifted pd->waveForm
826  detector* pd;
827  for(i=0; i<nIFO; i++) { // loop over detectors
828  pd = this->getifo(i);
829  pd->RWFID.push_back(-id); // save cluster -ID
831  *wf = pd->waveForm;
832  wf->start(pwc->start+pd->waveForm.start());
833  pd->RWFP.push_back(wf);
834  }
835  }
836  }
837 
838  Lw = Ew = To = Fo = Nw = ee = norm = 0.;
839  for(i=0; i<nIFO; i++) {
840  detector* d = this->getifo(i);
841  d->sSNR = d->xSNR = d->null = d->enrg = 0.;
842  }
843 
844  this->getMRAwave(id,lag,'W',0);
845  this->getMRAwave(id,lag,'S',0);
846  for(i=0; i<nIFO; i++) {
847  detector* d = this->getifo(i);
848  d->waveNull = d->waveBand;
849  d->waveNull-= d->waveForm;
850  float sSNR = d->get_SS();
851  float xSNR = d->get_XS();
852  float null = d->get_NN();
853  float enrg = d->get_XX();
854  d->sSNR += sSNR;
855  d->xSNR += xSNR;
856  d->null += null;
857  d->enrg += enrg;
858  To += sSNR*d->getWFtime();
859  Fo += sSNR*d->getWFfreq();
860  Lw += sSNR;
861  Ew += enrg;
862  Nw += null;
863  }
864  To /= Lw; Fo /= Lw;
865  ch = (Nw+Gn)/(N*nIFO); // chi2
866  cc = ch>1 ? 1+(ch-1)*2*(1-Rc) : 1; // Cr correction factor
867  Cr = Ec*Rc/(Ec*Rc+(Dc+Nw+Gn)*cc-N*(nIFO-1)); // reduced network correlation coefficient
868  cc = ch>1 ? ch : 1; // rho correction factor
869  Cp = Ec*Rc/(Ec*Rc+(Dc+Nw+Gn)-N*(nIFO-1)); // network correlation coefficient
870  norm = (Eo-Eh)/Ew;
871 
872  pwc->cData[id-1].norm = norm*2; // packet norm (saved in norm)
873  pwc->cData[id-1].skyStat = 0; // packet norm (saved in norm)
874  pwc->cData[id-1].skySize = Mw; // event size in the skyloop (size[1])
875  pwc->cData[id-1].netcc = Cp; // network cc (netcc[0])
876  pwc->cData[id-1].skycc = Cr; // reduced network cc (netcc[1])
877  pwc->cData[id-1].subnet = Esub/(Esub+Nmax); // sub-network statistic (netcc[2])
878  pwc->cData[id-1].SUBNET = Co; // sky cc (netcc[3])
879  pwc->cData[id-1].likenet = Lw; // waveform likelihood
880  pwc->cData[id-1].netED = Nw+Gn+Dc-N*nIFO; // residual NULL energy (neted[0])
881  pwc->cData[id-1].netnull = Nw+Gn; // packet NULL (neted[1])
882  pwc->cData[id-1].energy = Ew; // energy of the event (neted[2])
883  pwc->cData[id-1].likesky = Eo-No; // TF-domain all-res Likelihood (neted[3])
884  pwc->cData[id-1].enrgsky = Eo; // TF-domain all res energy (neted[4])
885  pwc->cData[id-1].netecor = Ec; // packet (signal) coherent energy
886  pwc->cData[id-1].normcor = Ec*Rc; // normalized coherent energy
887  pwc->cData[id-1].netRHO = rho/sqrt(cc); // reguced rho - stored in rho[0]
888  pwc->cData[id-1].netrho = rho; // chirp rho - stored in rho[1]
889  pwc->cData[id-1].cTime = To;
890  pwc->cData[id-1].cFreq = Fo;
891  pwc->cData[id-1].theta = nLikelihood.getTheta(lm);
892  pwc->cData[id-1].phi = nLikelihood.getPhi(lm);
893  pwc->cData[id-1].gNET = sqrt(ff+FF);
894  pwc->cData[id-1].aNET = sqrt(FF/ff);
895  pwc->cData[id-1].iNET = 0; // degrees of freedom
896  pwc->cData[id-1].nDoF = N; // degrees of freedom
897  pwc->cData[id-1].skyChi2 = CH;
898  pwc->cData[id-1].Gnoise = Gn;
899  pwc->cData[id-1].iota = 0;
900  pwc->cData[id-1].psi = 0;
901  pwc->cData[id-1].ellipticity = 0.;
902 
903  cc = pwc->cData[id-1].netcc;
904  if(hist) {
905  printf("rho=%4.2f|%4.2f cc: %5.3f|%5.3f|%5.3f subnet=%4.3f|%4.3f \n",
906  rho,rho*sqrt(Cp),Co,Cp,Cr,pwc->cData[id-1].subnet,pwc->cData[id-1].SUBNET);
907  printf(" L: %5.1f|%5.1f|%5.1f E: %5.1f|%5.1f|%5.1f N: %4.1f|%4.1f|%4.1f|%4.1f|%4.1f \n",
908  Lw,Lp,Lo,Ew,Ep,Eo,Nw,Np,Rc,Eh,No);
909  printf("id|lm %3d|%6d Vm|m=%3d|%3d|%3d|%3d T|F: %6.3f|%4.1f (t,p)=(%4.1f|%4.1f) \n",
910  int(id),int(lm),int(V),int(Mo),int(Mw),int(M),To,Fo,nLikelihood.getTheta(lm),nLikelihood.getPhi(lm));
911  cout<<" L: |"; for(i=1; i<nIFO+1; i++) {printf("%5.1f|",S_snr[i]);}
912  cout<<" E: |"; for(i=1; i<nIFO+1; i++) {printf("%5.1f|",D_snr[i]);}
913  cout<<" N: |"; for(i=1; i<nIFO+1; i++) {printf("%5.1f|",N_snr[i]);}
914  cout<<endl<<" dof|G|G+R "; printf("%5.1f|%5.1f|%5.1f r[1]=%4.1f",N,Gn,Nw+Gn,REG[1]);
915  printf(" norm=%3.1f chi2 %3.2f|%3.2f Rc=%3.2f, Dc=%4.1f\n",norm,ch,CH,Rc,Dc);
916  // cout<<" r1="<<REG[1]<<" norm="<<norm<<" chi2="<<ch<<"|"<<CH<<" Rc="<<Rc<<" Dc="<<Dc<<endl;
917  //hist->Fill(pwc->cData[id-1].subnet,pwc->cData[id-1].SUBNET);
918  }
919  count++;
920 
921 // calculation of error regions
922 
923  pwc->p_Ind[id-1].push_back(Mo);
924  double T = To+pwc->start; // trigger time
925  std::vector<float> sArea;
926  pwc->sArea.push_back(sArea);
927  pwc->p_Map.push_back(sArea);
928 
929  double var = norm*Rc*sqrt(Mo)*(1+fabs(1-CH));
930 
931  if(iID<=0 || ID==id) {
932  getSkyArea(id,lag,T,var); // calculate error regions
933  }
934 // calculation of chirp mass
935 
936  pwc->cData[id-1].mchirp = 0;
937  pwc->cData[id-1].mchirperr = 0;
938  pwc->cData[id-1].tmrgr = 0;
939  pwc->cData[id-1].tmrgrerr = 0;
940  pwc->cData[id-1].chi2chirp = 0;
941 
942  if(m_chirp) { // work only for MRA
943  ee = pwc->mchirp(id);
944  cc = Ec/(fabs(Ec)+ee); // chirp cc
945  printf("mchirp : %d %g %.2e %.3f %.3f %.3f %.3f \n\n",
946  int(id),cc,pwc->cData[id-1].mchirp,
947  pwc->cData[id-1].mchirperr, pwc->cData[id-1].tmrgr,
948  pwc->cData[id-1].tmrgrerr, pwc->cData[id-1].chi2chirp);
949  }
950 
951  if(ID==id && !EFEC) {
952  this->nSensitivity.gps = T;
953  this->nAlignment.gps = T;
954  this->nDisbalance.gps = T;
955  this->nLikelihood.gps = T;
956  this->nNullEnergy.gps = T;
957  this->nCorrEnergy.gps = T;
958  this->nCorrelation.gps = T;
959  this->nSkyStat.gps = T;
960  this->nEllipticity.gps = T;
961  this->nPolarisation.gps= T;
962  this->nNetIndex.gps = T;
963  }
964 
965  pwc->sCuts[id-1] = -1;
966  pwc->clean(id);
967  } // end of loop over clusters
968 
969  if(_vtd.size()) _avx_free_ps(_vtd);
970  if(_vTD.size()) _avx_free_ps(_vTD);
971  if(_eTD.size()) _avx_free_ps(_eTD);
972  if(_AVX.size()) _avx_free_ps(_AVX);
973  if(_APN.size()) _avx_free_ps(_APN); // container for antenna patterns and noise RMS
974  if(_DAT.size()) _avx_free_ps(_DAT); // container for data packet amplitudes
975  if(_SIG.size()) _avx_free_ps(_SIG); // container for signal packet amplitudes
976  if(_NUL.size()) _avx_free_ps(_NUL); // container for null packet amplitudes
977 
978  return count;
979 }
980 
981 
982 
983 long network::subNetCut(int lag, float subnet, float subcut, TH2F* hist)
984 {
985 // sub-network cut with dsp regulator
986 // lag: lag index
987 // subnet: sub network threshold
988 // subcut: sub network threshold in the skyloop
989 // hist: diagnostic histogram
990 // return number of processed pixels
991 
992  if(!this->wc_List[lag].size()) return 0;
993 
994  size_t nIFO = this->ifoList.size();
995 
996  if(nIFO>NIFO) {
997  cout<<"network::subNetCut(): invalid network.\n";
998  exit(0);
999  }
1000 
1001  float En = 2*acor*acor*nIFO; // network energy threshold in the sky loop
1002  float Es = 2*e2or; // subnet energy threshold in the sky loop
1003 
1004  subnet = fabs(subnet); // sub network threshold
1005  subcut = fabs(subcut); // sub network threshold in the skyloop
1006 
1007  __m128 _En = _mm_set1_ps(En);
1008  __m128 _Es = _mm_set1_ps(Es);
1009  __m128 _oo = _mm_set1_ps(1.e-12);
1010  __m128 _0 = _mm_set1_ps(0.);
1011  __m128 _05 = _mm_set1_ps(0.5);
1012  __m128 _1 = _mm_set1_ps(1.);
1013  __m128* _pe[NIFO];
1014 
1015  int f_ = NIFO/4;
1016  int l,lm,Vm;
1017  float Lm,Em,Am,Lo,Eo,Co,Lr,Er,ee,em,To;
1018  float cc,aa,AA,rHo,stat,Ls,Ln,EE;
1019 
1020  size_t i,j,k,m,V,V4,id,K,M;
1021  int Lsky = int(this->index.size()); // total number of source locations
1022  short* mm = this->skyMask.data;
1023 
1024  float vvv[NIFO] _ALIGNED;
1025  float* v00[NIFO] _ALIGNED;
1026  float* v90[NIFO] _ALIGNED;
1027  float* pe[NIFO] _ALIGNED;
1028  float* pa[NIFO] _ALIGNED;
1029  float* pA[NIFO] _ALIGNED;
1030  short* ml[NIFO] _ALIGNED;
1031  double* FP[NIFO] _ALIGNED;
1032  double* FX[NIFO] _ALIGNED;
1033  double xx[NIFO] _ALIGNED;
1034 
1035  for(i=0; i<NIFO; i++) {
1036  if(i<nIFO) {
1037  ml[i] = getifo(i)->index.data;
1038  FP[i] = getifo(i)->fp.data;
1039  FX[i] = getifo(i)->fx.data;
1040  }
1041  else {
1042  ml[i] = getifo(0)->index.data;
1043  FP[i] = getifo(0)->fp.data;
1044  FX[i] = getifo(0)->fx.data;
1045  }
1046  }
1047 
1048  // allocate buffers
1049  std::vector<int> pI; // buffer for pixel IDs
1050  wavearray<double> cid; // buffers for cluster ID
1051  wavearray<double> cTo; // buffers for cluster time
1052  netpixel* pix;
1053  std::vector<int>* vint;
1054  netcluster* pwc = &this->wc_List[lag];
1055 
1056  size_t count = 0;
1057  size_t tsize = 0;
1058 
1059 //+++++++++++++++++++++++++++++++++++++++
1060 // loop over clusters
1061 //+++++++++++++++++++++++++++++++++++++++
1062 
1063  cid = pwc->get((char*)"ID", 0,'S',0); // get cluster ID
1064  cTo = pwc->get((char*)"time",0,'L',0); // get cluster time
1065 
1066  K = cid.size();
1067  for(k=0; k<K; k++) { // loop over clusters
1068  id = size_t(cid.data[k]+0.1);
1069  if(pwc->sCuts[id-1] != -2) continue; // skip rejected/processed clusters
1070  vint = &(pwc->cList[id-1]); // pixel list
1071  V = vint->size(); // pixel list size
1072  if(!V) continue;
1073 
1074  pI = wdmMRA.getXTalk(pwc, id);
1075 
1076  V = pI.size(); // number of loaded pixels
1077  if(!V) continue;
1078 
1079  pix = pwc->getPixel(id,pI[0]);
1080  tsize = pix->tdAmp[0].size();
1081  if(!tsize || tsize&1) { // tsize%1 = 1/0 = power/amplitude
1082  cout<<"network::subNetCut() error: wrong pixel TD data\n";
1083  exit(1);
1084  }
1085  tsize /= 2;
1086  V4 = V + (V%4 ? 4 - V%4 : 0);
1087 
1088  //cout<<En<<" "<<Es<<" "<<lag<<" "<<id<<" "<<V4<<" "<<" "<<tsize<<endl;
1089 
1090  std::vector<wavearray<float> > vtd; // vectors of TD amplitudes
1091  std::vector<wavearray<float> > vTD; // vectors of TD amplitudes
1092  std::vector<wavearray<float> > eTD; // vectors of TD energies
1093 
1094  wavearray<float> tmp(tsize*V4); tmp=0; // aligned array for TD amplitudes
1095  wavearray<float> fp(NIFO*V4); fp=0; // aligned array for + antenna pattern
1096  wavearray<float> fx(NIFO*V4); fx=0; // aligned array for x antenna pattern
1097  wavearray<float> nr(NIFO*V4); nr=0; // aligned array for inverse rms
1098  wavearray<float> Fp(NIFO*V4); Fp=0; // aligned array for pattern
1099  wavearray<float> Fx(NIFO*V4); Fx=0; // aligned array for patterns
1100  wavearray<float> am(NIFO*V4); am=0; // aligned array for TD amplitudes
1101  wavearray<float> AM(NIFO*V4); AM=0; // aligned array for TD amplitudes
1102  wavearray<float> bb(NIFO*V4); bb=0; // temporary array for MRA amplitudes
1103  wavearray<float> BB(NIFO*V4); BB=0; // temporary array for MRA amplitudes
1104  wavearray<float> xi(NIFO*V4); xi=0; // 00 array for reconctructed responses
1105  wavearray<float> XI(NIFO*V4); XI=0; // 90 array for reconstructed responses
1106  wavearray<float> ww(NIFO*V4); ww=0; // 00 array for phase-shifted data vectors
1107  wavearray<float> WW(NIFO*V4); WW=0; // 90 array for phase-shifted data vectors
1108  wavearray<float> u4(NIFO*4); u4=0; // temp array
1109  wavearray<float> U4(NIFO*4); U4=0; // temp array
1110 
1111  __m128* _Fp = (__m128*) Fp.data;
1112  __m128* _Fx = (__m128*) Fx.data;
1113  __m128* _am = (__m128*) am.data;
1114  __m128* _AM = (__m128*) AM.data;
1115  __m128* _xi = (__m128*) xi.data;
1116  __m128* _XI = (__m128*) XI.data;
1117  __m128* _fp = (__m128*) fp.data;
1118  __m128* _fx = (__m128*) fx.data;
1119  __m128* _nr = (__m128*) nr.data;
1120  __m128* _ww = (__m128*) ww.data;
1121  __m128* _WW = (__m128*) WW.data;
1122  __m128* _bb = (__m128*) bb.data;
1123  __m128* _BB = (__m128*) BB.data;
1124 
1125  for(i=0; i<NIFO; i++) {
1126  vtd.push_back(tmp); // array of aligned energy vectors
1127  vTD.push_back(tmp); // array of aligned energy vectors
1128  eTD.push_back(tmp); // array of aligned energy vectors
1129  }
1130 
1131  for(i=0; i<NIFO; i++) { // set up zero deley pointers
1132  pa[i] = vtd[i].data + (tsize/2)*V4;
1133  pA[i] = vTD[i].data + (tsize/2)*V4;
1134  pe[i] = eTD[i].data + (tsize/2)*V4;
1135  }
1136 
1137  this->a_00.resize(NIFO*V4); this->a_00=0.;
1138  this->a_90.resize(NIFO*V4); this->a_90=0.;
1139  this->rNRG.resize(V4); this->rNRG=0.;
1140  this->pNRG.resize(V4); this->pNRG=0.;
1141 
1142  __m128* _aa = (__m128*) this->a_00.data; // set pointer to 00 array
1143  __m128* _AA = (__m128*) this->a_90.data; // set pointer to 90 array
1144 
1145  this->pList.clear();
1146  for(j=0; j<V; j++) { // loop over selected pixels
1147  pix = pwc->getPixel(id,pI[j]); // get pixel pointer
1148  pList.push_back(pix); // store pixel pointers for MRA
1149 
1150  double rms = 0.;
1151  for(i=0; i<nIFO; i++) {
1152  xx[i] = 1./pix->data[i].noiserms;
1153  rms += xx[i]*xx[i]; // total inverse variance
1154  }
1155 
1156  for(i=0; i<nIFO; i++) {
1157  nr.data[j*NIFO+i]=(float)xx[i]/sqrt(rms); // normalized 1/rms
1158  for(l=0; l<tsize; l++) {
1159  aa = pix->tdAmp[i].data[l]; // copy TD 00 data
1160  AA = pix->tdAmp[i].data[l+tsize]; // copy TD 90 data
1161  vtd[i].data[l*V4+j] = aa; // copy 00 data
1162  vTD[i].data[l*V4+j] = AA; // copy 90 data
1163  eTD[i].data[l*V4+j] = aa*aa+AA*AA; // copy power
1164  }
1165  }
1166  }
1167 
1168 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1169 // first sky loop
1170 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1171 
1172  int lb = 0;
1173  int le = Lsky-1;
1174  bool mra = false;
1175  double suball=0;
1176  double submra=0;
1177  bool skymaskcc = (skyMaskCC.size()==Lsky);
1178 
1179  stat=Lm=Em=Am=EE=0.; lm=Vm= -1;
1180 
1181  skyloop:
1182 
1183  for(l=lb; l<=le; l++) { // loop over sky locations
1184  if(!mm[l] || l<0) continue; // skip delay configurations
1185 
1186  if(skymaskcc) { // transform l into celestial coordinates lc
1187  skymap* sm = &(this->nSkyStat);
1188  double gT = cTo.data[k]+pwc->start; // trigger gps time
1189  double RA = sm->phi2RA(sm->getPhi(l),gT); // phi -> RA
1190  int lc=this->getIndex(sm->getTheta(l),RA); // get sky index in celestial coordinates
1191  if (!skyMaskCC.data[lc]) continue;
1192  }
1193 
1194  _sse_point_ps(_pe, pe, ml, int(l), (int)V4); // point _pe to energy vectors
1195 
1196  __m128 _msk;
1197  __m128 _E_o = _mm_setzero_ps(); // total network energy
1198  __m128 _E_n = _mm_setzero_ps(); // network energy above the threshold
1199  __m128 _E_s = _mm_setzero_ps(); // subnet energy above the threshold
1200  __m128 _M_m = _mm_setzero_ps(); // # of pixels above threshold
1201  __m128* _rE = (__m128*) rNRG.data; // m128 pointer to energy array
1202  __m128* _pE = (__m128*) pNRG.data; // m128 pointer to energy array
1203 
1204  for(j=0; j<V4; j+=4) { // loop over selected pixels
1205  *_rE = _sse_sum_ps(_pe); // get pixel energy
1206  _msk = _mm_and_ps(_1,_mm_cmpge_ps(*_rE,_En)); // E>En 0/1 mask
1207  _M_m = _mm_add_ps(_M_m,_msk); // count pixels above threshold
1208  *_pE = _mm_mul_ps(*_rE,_msk); // zero sub-threshold pixels
1209  _E_o = _mm_add_ps(_E_o,*_pE); // network energy
1210  _sse_minSNE_ps(_rE,_pe,_pE); // subnetwork energy with _pe increment
1211  _E_s = _mm_add_ps(_E_s,*_pE); // subnetwork energy
1212  _msk = _mm_and_ps(_1,_mm_cmpge_ps(*_pE++,_Es)); // subnet energy > Es 0/1 mask
1213  _E_n = _mm_add_ps(_E_n,_mm_mul_ps(*_rE++,_msk)); // network energy
1214  }
1215 
1216  _mm_storeu_ps(vvv,_E_n);
1217  Ln = vvv[0]+vvv[1]+vvv[2]+vvv[3]; // network energy above subnet threshold
1218  _mm_storeu_ps(vvv,_E_o);
1219  Eo = vvv[0]+vvv[1]+vvv[2]+vvv[3]+0.01; // total network energy
1220  _mm_storeu_ps(vvv,_E_s);
1221  Ls = vvv[0]+vvv[1]+vvv[2]+vvv[3]; // subnetwork energy
1222  _mm_storeu_ps(vvv,_M_m);
1223  m = 2*(vvv[0]+vvv[1]+vvv[2]+vvv[3])+0.01; // pixels above threshold
1224 
1225  aa = Ls*Ln/(Eo-Ls);
1226  if((aa-m)/(aa+m)<subcut) continue;
1227 
1228  pnt_(v00, pa, ml, (int)l, (int)V4); // pointers to first pixel 00 data
1229  pnt_(v90, pA, ml, (int)l, (int)V4); // pointers to first pixel 90 data
1230  float* pfp = fp.data; // set pointer to fp
1231  float* pfx = fx.data; // set pointer tp fx
1232  float* p00 = this->a_00.data; // set pointer for 00 array
1233  float* p90 = this->a_90.data; // set pointer for 90 array
1234 
1235  m = 0;
1236  for(j=0; j<V; j++) {
1237  int jf = j*f_; // source sse pointer increment
1238  cpp_(p00,v00); cpp_(p90,v90); // copy amplitudes with target increment
1239  cpf_(pfp,FP,l); cpf_(pfx,FX,l); // copy antenna with target increment
1240  _sse_zero_ps(_xi+jf); // zero MRA amplitudes
1241  _sse_zero_ps(_XI+jf); // zero MRA amplitudes
1242  _sse_cpf_ps(_am+jf,_aa+jf); // duplicate 00
1243  _sse_cpf_ps(_AM+jf,_AA+jf); // duplicate 90
1244  if(rNRG.data[j]>En) m++; // count superthreshold pixels
1245  }
1246 
1247  __m128* _pp = (__m128*) am.data; // point to multi-res amplitudes
1248  __m128* _PP = (__m128*) AM.data; // point to multi-res amplitudes
1249 
1250  if(mra) { // do MRA
1251  _sse_MRA_ps(xi.data,XI.data,En,m); // get principle components
1252  _pp = (__m128*) xi.data; // point to PC amplitudes
1253  _PP = (__m128*) XI.data; // point to PC amplitudes
1254  }
1255 
1256  m = 0; Ls=Ln=Eo=0;
1257  for(j=0; j<V; j++) {
1258  int jf = j*f_; // source sse pointer increment
1259  int mf = m*f_; // target sse pointer increment
1260  _sse_zero_ps(_bb+jf); // reset array for MRA amplitudes
1261  _sse_zero_ps(_BB+jf); // reset array for MRA amplitudes
1262  ee = _sse_abs_ps(_pp+jf,_PP+jf); // total pixel energy
1263  if(ee<En) continue;
1264  _sse_cpf_ps(_bb+mf,_pp+jf); // copy 00 amplitude/PC
1265  _sse_cpf_ps(_BB+mf,_PP+jf); // copy 90 amplitude/PC
1266  _sse_cpf_ps(_Fp+mf,_fp+jf); // copy F+
1267  _sse_cpf_ps(_Fx+mf,_fx+jf); // copy Fx
1268  _sse_mul_ps(_Fp+mf,_nr+jf); // normalize f+ by rms
1269  _sse_mul_ps(_Fx+mf,_nr+jf); // normalize fx by rms
1270  m++;
1271  em = _sse_maxE_ps(_pp+jf,_PP+jf); // dominant pixel energy
1272  Ls += ee-em; Eo += ee; // subnetwork energy, network energy
1273  if(ee-em>Es) Ln += ee; // network energy above subnet threshold
1274  }
1275  if(Eo<=0) continue;
1276 
1277  size_t m4 = m + (m%4 ? 4 - m%4 : 0);
1278  _E_n = _mm_setzero_ps(); // + likelihood
1279 
1280  for(j=0; j<m4; j+=4) {
1281  int jf = j*f_;
1282  _sse_dpf4_ps(_Fp+jf,_Fx+jf,_fp+jf,_fx+jf); // go to DPF
1283  _E_s = _sse_like4_ps(_fp+jf,_fx+jf,_bb+jf,_BB+jf); // std likelihood
1284  _E_n = _mm_add_ps(_E_n,_E_s); // total likelihood
1285  }
1286  _mm_storeu_ps(vvv,_E_n);
1287 
1288  Lo = vvv[0]+vvv[1]+vvv[2]+vvv[3];
1289  AA = aa/(fabs(aa)+fabs(Eo-Lo)+2*m*(Eo-Ln)/Eo); // subnet stat with threshold
1290  ee = Ls*Eo/(Eo-Ls);
1291  em = fabs(Eo-Lo)+2*m; // suball NULL
1292  ee = ee/(ee+em); // subnet stat without threshold
1293  aa = (aa-m)/(aa+m);
1294 
1295  if(AA>stat && !mra) {
1296  stat=AA; Lm=Lo; Em=Eo; Am=aa; lm=l; Vm=m; suball=ee; EE=em;
1297  }
1298  }
1299 
1300  if(!mra && lm>=0) {mra=true; le=lb=lm; goto skyloop;} // get MRA principle components
1301 
1302  pwc->sCuts[id-1] = -1;
1303  pwc->cData[id-1].likenet = Lm;
1304  pwc->cData[id-1].energy = Em;
1305  pwc->cData[id-1].theta = nLikelihood.getTheta(lm);
1306  pwc->cData[id-1].phi = nLikelihood.getPhi(lm);
1307  pwc->cData[id-1].skyIndex = lm;
1308 
1309  rHo = 0.;
1310  if(mra) {
1311  submra = Ls*Eo/(Eo-Ls); // MRA subnet statistic
1312  submra/= fabs(submra)+fabs(Eo-Lo)+2*(m+6); // MRA subnet coefficient
1313  To = 0;
1314  pwc->p_Ind[id-1].push_back(lm);
1315  for(j=0; j<vint->size(); j++) {
1316  pix = pwc->getPixel(id,j);
1317  pix->theta = nLikelihood.getTheta(lm);
1318  pix->phi = nLikelihood.getPhi(lm);
1319  To += pix->time/pix->rate/pix->layers;
1320  if(j==0&&mra) pix->ellipticity = submra; // subnet MRA propagated to L-stage
1321  if(j==0&&mra) pix->polarisation = fabs(Eo-Lo)+2*(m+6); // submra NULL propagated to L-stage
1322  if(j==1&&mra) pix->ellipticity = suball; // subnet all-sky propagated to L-stage
1323  if(j==1&&mra) pix->polarisation = EE; // suball NULL propagated to L-stage
1324  }
1325  To /= vint->size();
1326  rHo = sqrt(Lo*Lo/(Eo+2*m)/2); // estimator of coherent amplitude
1327  }
1328 
1329  if(hist && rHo>this->netRHO)
1330  for(j=0;j<vint->size();j++) hist->Fill(suball,submra);
1331 
1332  if(fmin(suball,submra)>subnet && rHo>this->netRHO) {
1333  count += vint->size();
1334  if(hist) {
1335  printf("lag|id %3d|%3d rho=%5.2f To=%5.1f stat: %5.3f|%5.3f|%5.3f ",
1336  int(lag),int(id),rHo,To,suball,submra,stat);
1337  printf("E: %6.1f|%6.1f L: %6.1f|%6.1f|%6.1f pix: %4d|%4d|%3d|%2d \n",
1338  Em,Eo,Lm,Lo,Ls,int(vint->size()),int(V),Vm,int(m));
1339  }
1340  }
1341  else pwc->sCuts[id-1]=1;
1342 
1343 // clean time delay data
1344 
1345  V = vint->size();
1346  for(j=0; j<V; j++) { // loop over pixels
1347  pix = pwc->getPixel(id,j);
1348  pix->core = true;
1349  if(pix->tdAmp.size()) pix->clean();
1350  }
1351  } // end of loop over clusters
1352  return count;
1353 }
1354 
1355 
1356 long network::likelihood2G(char mode, int lag, int iID, TH2F* hist)
1357 {
1358 // 2G likelihood analysis
1359 // mode: analysis mode:
1360 // OPTRES analyses, if upper case and optim=true
1361 // MRA analysis in low case or optim=false
1362 // r - un-modeled
1363 // i - iota - wave: no,partial dispersion correction
1364 // p - Psi - wave (no dispersion correction)
1365 // l,s - linear, loose linear
1366 // c,g - circular. loose circular
1367 // e,b - elliptical (no dispersion correction), b=p for now
1368 // iID: cluster ID, if negative - sky error regions are calculated
1369 // lag: lag index
1370 // hist: chirp histogram: If not needed, TGraphErrors* hist=NULL
1371 // shold be used as input
1372 // return number of processed pixels
1373 // Negative gamma regulator turns on the AP prior for sky localization
1374 //
1375 // Delta Regulator:
1376 // constraint w(weak) g(circ) h(hard)
1377 // D0 1----------0.5--------0.5 // value of D0 (00-phase) threshold
1378 // |delta|: 0----------0.5---------1 // value of delta regulator
1379 // D9 1-----------1---------0.5 // value of D9 (90-phase) threshold
1380 
1381  if(!this->wc_List[lag].size()) return 0;
1382 
1383  this->like('2');
1384  this->wdm(true);
1385  this->tYPe = mode;
1386 
1387  bool cirwave = mode=='g' || mode=='G' || mode=='c' || mode=='C';
1388  bool linwave = mode=='l' || mode=='L' || mode=='s' || mode=='S';
1389  bool iotwave = mode=='i' || mode=='l' || mode=='e' || mode=='c' ||
1390  mode=='I' || mode=='L' || mode=='E' || mode=='C';
1391  bool psiwave = mode=='l' || mode=='e' || mode=='p' ||
1392  mode=='L' || mode=='E' || mode=='P';
1393  bool mureana = mode=='i' || mode=='e' || mode=='c' ||
1394  mode=='r' || mode=='p' || mode=='b' ||
1395  mode=='l' || mode=='s' || mode=='g';
1396  bool rndwave = mode=='r' || mode=='R';
1397 
1398  bool prior = this->gamma<0 ? true : false; // gamma<0 : antenna pattern prior is used
1399  bool m_chirp = this->optim ? false : mureana;
1400 
1401  if(!this->optim) mureana = true;
1402 
1403  size_t nIFO = this->ifoList.size();
1404  size_t ID = abs(iID);
1405 
1406  if(nIFO>NIFO) {
1407  cout<<"network::likelihood2G(): invalid network.\n";
1408  exit(0);
1409  }
1410 
1411  float En = 2*acor*acor*nIFO; // network energy threshold in the sky loop
1412  float Es = 2*e2or; // subnet energy threshold
1413  float gama = fabs(this->gamma); // gamma regulator - hard/kill
1414  float deta = fabs(this->delta); // delta regulator - weak/circular/hard
1415  if(gama<=0) gama = 1.e-24; // limit gamma
1416  if(gama>=1) gama = 0.999999; // limit gamma
1417 
1418 // delta regulator:
1419 // constraint w(weak) g(circ) h(hard) // w - no constraint
1420 // DI 1----------0.5--------0.5 // value of DI (00-phase) threshold
1421 // |delta|: 0----------0.5---------1 // value of delta regulator
1422 // DQ 1-----------1---------0.5 // value of DQ (90-phase) threshold
1423 
1424  static const __m128 _D0 = _mm_set1_ps(deta<0.5?1-deta:0.5);
1425  static const __m128 _D9 = _mm_set1_ps(deta<0.5?1:1.5-deta);
1426 
1427  static const __m128 _oo = _mm_set1_ps(1.e-16); // nusance parameter
1428  static const __m128 _sm = _mm_set1_ps(-0.f); // sign mask: -0.f = 1 << 31
1429  static const __m128 _En = _mm_set1_ps(En); // network threshold
1430  static const __m128 _rG = _mm_set1_ps(-1./log(gama)); // regulator-gamma threshold
1431  static const __m128 _kG = _mm_set1_ps(gama); // kill-gamma threshold
1432  static const __m128 _PW = _mm_set1_ps(psiwave?0:1); // flag for psiwave option
1433  static const __m128 _01 = _mm_set1_ps(0.1);
1434  static const __m128 _05 = _mm_set1_ps(0.5);
1435  static const __m128 _09 = _mm_set1_ps(0.9);
1436  static const __m128 _1 = _mm_set1_ps(1.0+1.e-16);
1437  static const __m128 _2 = _mm_set1_ps(2.0);
1438  static const __m128 _4 = _mm_set1_ps(4.0);
1439 
1440  __m128* _pe[NIFO];
1441 
1442  int f_ = NIFO/4;
1443  float NRG,Lm,Em,Lo,Eo,No,Nm,cc,Cm,Co,Do,To,Fo,Ln,Ns;
1444  float STAT,CHR,aa,AA,ee,em,EE,ff,FF,Lr,Cr,ss,Ls,Nc,gg;
1445  double eLp, s2p, c2p;
1446  int optR = 0; // optimal resolution (used by SRA)
1447 
1448  size_t i,j,k,l,m,Vm,lm,V,V4,V44,id,K,M;
1449  size_t L = this->index.size(); // total number of source locations
1450  short* mm = this->skyMask.data;
1451  bool skymaskcc = (skyMaskCC.size()==L);
1452 
1453  float vvv[NIFO] _ALIGNED;
1454  float uuu[NIFO] _ALIGNED;
1455  float* v00[NIFO] _ALIGNED;
1456  float* v90[NIFO] _ALIGNED;
1457  float* pe[NIFO] _ALIGNED;
1458  float* pa[NIFO] _ALIGNED;
1459  float* pA[NIFO] _ALIGNED;
1460  short* ml[NIFO] _ALIGNED;
1461  double* FP[NIFO] _ALIGNED;
1462  double* FX[NIFO] _ALIGNED;
1463  double xx[NIFO] _ALIGNED;
1464 
1465  for(i=0; i<NIFO; i++) {
1466  if(i<nIFO) {
1467  ml[i] = getifo(i)->index.data;
1468  FP[i] = getifo(i)->fp.data;
1469  FX[i] = getifo(i)->fx.data;
1470  }
1471  else {
1472  ml[i] = getifo(0)->index.data;
1473  FP[i] = getifo(0)->fp.data;
1474  FX[i] = getifo(0)->fx.data;
1475  }
1476  }
1477 
1478  // allocate buffers
1479  std::vector<int> pI; // buffer for pixel IDs
1480  std::vector<int> pJ; // buffer for pixel index
1481  wavearray<double> cid; // buffers for cluster ID
1482  wavearray<double> cTo; // buffers for cluster time
1483  netpixel* pix;
1484  std::vector<int>* vint;
1485  std::vector<int>* vtof;
1486  std::vector<int> pRate;
1487  netcluster* pwc = &this->wc_List[lag];
1488 
1489  size_t count = 0;
1490  size_t tsize = 0;
1491 
1492  std::map<int,float> vLr; // resolution map
1493 
1494 //+++++++++++++++++++++++++++++++++++++++
1495 // loop over clusters
1496 //+++++++++++++++++++++++++++++++++++++++
1497 
1498  cid = pwc->get((char*)"ID", 0,'S',0); // get cluster ID
1499  cTo = pwc->get((char*)"time",0,'L',0); // get cluster time
1500 
1501  K = cid.size();
1502  for(k=0; k<K; k++) { // loop over clusters
1503  id = size_t(cid.data[k]+0.1);
1504 
1505  if(pwc->sCuts[id-1] != -2) continue; // skip rejected/processed clusters
1506 
1507  vint = &(pwc->cList[id-1]); // pixel list
1508  vtof = &(pwc->nTofF[id-1]); // TofFlight configurations
1509  V = vint->size();
1510  if(!V) continue;
1511 
1512  pI = wdmMRA.getXTalk(pwc, id);
1513  V = pI.size();
1514  if(!V) continue;
1515 
1516  if(ID==id) {
1517  this->nSensitivity = 0.;
1518  this->nAlignment = 0.;
1519  this->nNetIndex = 0.;
1520  this->nDisbalance = 0.;
1521  this->nLikelihood = 0.;
1522  this->nNullEnergy = 0.;
1523  this->nCorrEnergy = 0.;
1524  this->nCorrelation = 0.;
1525  this->nSkyStat = 0.;
1526  this->nEllipticity = 0.;
1527  this->nPolarisation = 0.;
1528  this->nProbability = 0.;
1529  }
1530  this->nAntenaPrior = 0.;
1531 
1532  pix = pwc->getPixel(id,pI[0]);
1533  tsize = pix->tdAmp[0].size();
1534  if(!tsize || tsize&1) { // tsize%1 = 1/0 = power/amplitude
1535  cout<<"network::likelihood2G() error: wrong pixel TD data\n";
1536  exit(1);
1537  }
1538 
1539  tsize /= 2;
1540 
1541  if(!(V=pI.size())) continue;
1542  V4 = V + (V%4 ? 4 - V%4 : 0);
1543  V44 = V4 + 4;
1544  pJ.clear();
1545  for(j=0; j<V4; j++) pJ.push_back(0);
1546 
1547  //cout<<En<<" "<<Es<<" "<<lag<<" "<<id<<" "<<V4<<" "<<" "<<tsize<<endl;
1548 
1549  std::vector<wavearray<float> > vtd; // vectors of TD amplitudes
1550  std::vector<wavearray<float> > vTD; // vectors of TD amplitudes
1551  std::vector<wavearray<float> > eTD; // vectors of TD energies
1552 
1553  wavearray<float> tmp(tsize*V4); tmp=0; // aligned array for TD amplitudes
1554  wavearray<float> nr(NIFO*V44); nr=0; // aligned array for inverse rms
1555  wavearray<float> fp(NIFO*V44); fp=0; // aligned array for + antenna pattern
1556  wavearray<float> fx(NIFO*V44); fx=0; // aligned array for x antenna pattern
1557  wavearray<float> ep(NIFO*V44); ep=0; // aligned array for + unity vector
1558  wavearray<float> ex(NIFO*V44); ex=0; // aligned array for x unity vector
1559  wavearray<float> Fp(NIFO*V44); Fp=0; // aligned array for F+ patterns
1560  wavearray<float> Fx(NIFO*V44); Fx=0; // aligned array for Fx patterns
1561  wavearray<float> am(NIFO*V44); am=0; // aligned array for pixel amplitudes
1562  wavearray<float> AM(NIFO*V44); AM=0; // aligned array for pixel amplitudes
1563  wavearray<float> bb(NIFO*V44); bb=0; // temporary array for MRA amplitudes
1564  wavearray<float> BB(NIFO*V44); BB=0; // temporary array for MRA amplitudes
1565  wavearray<float> xi(NIFO*V44); xi=0; // 00 array for reconctructed responses
1566  wavearray<float> XI(NIFO*V44); XI=0; // 90 array for reconstructed responses
1567  wavearray<float> ww(NIFO*V44); ww=0; // 00 array for phase-shifted data vectors
1568  wavearray<float> WW(NIFO*V44); WW=0; // 90 array for phase-shifted data vectors
1569  wavearray<float> xp(NIFO*V44); xp=0; // 00 array for network projection
1570  wavearray<float> XP(NIFO*V44); XP=0; // 90 array for network projection
1571 
1572  // data arrays for polar coordinates storage : [0,1] = [radius,angle]
1573  for(i=0;i<2;i++) {
1574  this->p00_POL[i].resize(V4); this->p00_POL[i]=0.;
1575  this->p90_POL[i].resize(V4); this->p90_POL[i]=0.;
1576  this->r00_POL[i].resize(V4); this->r00_POL[i]=0.;
1577  this->r90_POL[i].resize(V4); this->r90_POL[i]=0.;
1578  }
1579 
1580  __m128* _Fp = (__m128*) Fp.data;
1581  __m128* _Fx = (__m128*) Fx.data;
1582  __m128* _am = (__m128*) am.data;
1583  __m128* _AM = (__m128*) AM.data;
1584  __m128* _xi = (__m128*) xi.data;
1585  __m128* _XI = (__m128*) XI.data;
1586  __m128* _xp = (__m128*) xp.data;
1587  __m128* _XP = (__m128*) XP.data;
1588  __m128* _ww = (__m128*) ww.data;
1589  __m128* _WW = (__m128*) WW.data;
1590  __m128* _bb = (__m128*) bb.data;
1591  __m128* _BB = (__m128*) BB.data;
1592  __m128* _fp = (__m128*) fp.data;
1593  __m128* _fx = (__m128*) fx.data;
1594  __m128* _nr = (__m128*) nr.data;
1595  __m128* _ep = (__m128*) ep.data; // point to + unity vector
1596  __m128* _ex = (__m128*) ex.data; // point to x unity vector
1597 
1598  __m128* _fp4 = _fp+V4*f_;
1599  __m128* _fx4 = _fx+V4*f_;
1600  __m128* _uu4 = _am+V4*f_;
1601  __m128* _vv4 = _AM+V4*f_;
1602  __m128* _bb4 = _bb+V4*f_;
1603  __m128* _BB4 = _BB+V4*f_;
1604 
1605  for(i=0; i<NIFO; i++) {
1606  vtd.push_back(tmp); // array of aligned energy vectors
1607  vTD.push_back(tmp); // array of aligned energy vectors
1608  eTD.push_back(tmp); // array of aligned energy vectors
1609  }
1610 
1611  for(i=0; i<NIFO; i++) { // set up zero deley pointers
1612  pa[i] = vtd[i].data + (tsize/2)*V4;
1613  pA[i] = vTD[i].data + (tsize/2)*V4;
1614  pe[i] = eTD[i].data + (tsize/2)*V4;
1615  }
1616 
1617  wavearray<float> siDPF(V4); siDPF=0; // temporary array for DPF sin
1618  wavearray<float> coDPF(V4); coDPF=0; // temporary array for DPF cos
1619  wavearray<float> siORT(V4); siORT=0; // temporary array for ort4 sin
1620  wavearray<float> coORT(V4); coORT=0; // temporary array for ort4 cos
1621  wavearray<float> siPHS(V4); siPHS=0; // temporary array for Phase sin
1622  wavearray<float> coPHS(V4); coPHS=0; // temporary array for Phase cos
1623  wavearray<float> chir(V4); chir=0; // chirality array
1624  wavearray<float> q2Q2(V4); q2Q2=0; // energy array q^2+Q^2
1625  wavearray<float> ec00(V4); ec00=0; // 00-phase coherent energy array
1626  wavearray<float> EC90(V4); EC90=0; // 90-phase coherent energy array
1627  wavearray<float> zzz(V4); zzz=0; // temporary array
1628  wavearray<float> yyy(V4); yyy=0; // temporary array
1629  wavearray<float> xxx(V4); xxx=0; // temporary array
1630  wavearray<float> rrr(V4); rrr=0; // regulator flag array
1631 
1632  this->a_00.resize(NIFO*V44); this->a_00=0.; // array for pixel amplitudes in sky loop
1633  this->a_90.resize(NIFO*V44); this->a_90=0.; // array for pixel amplitudes in sky loop
1634  this->rNRG.resize(V4); this->rNRG=0.;
1635  this->pNRG.resize(V4); this->pNRG=0.;
1636 
1637  __m128* _aa = (__m128*) this->a_00.data; // set pointer to 00 array
1638  __m128* _AA = (__m128*) this->a_90.data; // set pointer to 90 array
1639 
1640 
1641  this->pList.clear(); pRate.clear();
1642  for(j=0; j<V; j++) { // loop over selected pixels
1643  pix = pwc->getPixel(id,pI[j]);
1644  this->pList.push_back(pix); // store pixel pointers for MRA
1645  pRate.push_back(int(pix->rate+0.5)); // store pixel rates for MRA
1646 
1647  if(vLr.find(pRate[j]) == vLr.end()) // initialize vLr map
1648  vLr[pRate[j]] = 0.;
1649 
1650  double rms = 0.;
1651  for(i=0; i<nIFO; i++) {
1652  xx[i] = 1./pix->data[i].noiserms;
1653  rms += xx[i]*xx[i]; // total inverse variance
1654  }
1655 
1656  rms = sqrt(rms);
1657  for(i=0; i<nIFO; i++) {
1658  nr.data[j*NIFO+i]=(float)xx[i]/rms; // normalized 1/rms
1659  for(l=0; l<tsize; l++) {
1660  aa = pix->tdAmp[i].data[l]; // copy TD 00 data
1661  AA = pix->tdAmp[i].data[l+tsize]; // copy TD 90 data
1662  vtd[i].data[l*V4+j] = aa; // copy 00 data
1663  vTD[i].data[l*V4+j] = AA; // copy 90 data
1664  eTD[i].data[l*V4+j] = aa*aa+AA*AA; // copy power
1665  }
1666  }
1667  }
1668 
1669 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1670 // sky loop
1671 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1672 
1673  STAT=0.; lm=0; Vm=0;
1674  double skystat = 0.;
1675  size_t lb = 0;
1676  size_t le = L-1;
1677  bool mra = false;
1678 
1679  optsky:
1680 
1681  AA = 0.; // initialize sky statistic
1682  for(l=lb; l<=le; l++) { // loop over sky locations
1683  if(!mra) skyProb.data[l] = 0.;
1684  if(!mm[l]) continue; // skip delay configurations
1685 
1686  if(skymaskcc) { // transform l into celestial coordinates lc
1687  skymap* sm = &(this->nSkyStat);
1688  double gT = cTo.data[k]+pwc->start; // trigger gps time
1689  double RA = sm->phi2RA(sm->getPhi(l),gT); // phi -> RA
1690  int lc=this->getIndex(sm->getTheta(l),RA); // get sky index in celestial coordinates
1691  if (!skyMaskCC.data[lc]) continue;
1692  }
1693 
1694  pnt_(v00, pa, ml, (int)l, (int)V4); // pointers to first pixel 00 data
1695  pnt_(v90, pA, ml, (int)l, (int)V4); // pointers to first pixel 90 data
1696  float* pfp = fp.data; // set pointer to fp
1697  float* pfx = fx.data; // set pointer to fx
1698  float* p00 = this->a_00.data; // set pointer for 00 array
1699  float* p90 = this->a_90.data; // set pointer for 90 array
1700  float mxLr = 0.;
1701  optR = 0;
1702 
1703  for(j=0; j<V; j++) {
1704  cpp_(p00,v00); cpp_(p90,v90); // copy amplitudes with target increment
1705  cpf_(pfp,FP,l); cpf_(pfx,FX,l); // copy antenna with target increment
1706  if(!this->optim || !mra) continue; // skip if not optimal resolution or !mra
1707  if(vLr[pRate[j]] <= mxLr) continue; // skip small Lr
1708  mxLr = vLr[pRate[j]]; // update maximum Lr
1709  optR = pRate[j]; // select optimal rate
1710  }
1711 
1712  m = 0;
1713  for(j=0; j<V; j++) {
1714  int jf = j*f_; // source sse pointer increment
1715  _sse_zero_ps(_xi+jf); // zero MRA amplitudes
1716  _sse_zero_ps(_XI+jf); // zero MRA amplitudes
1717  rNRG.data[j] = 1; // SRA flag
1718  if(optR && optR!=pRate[j]) { // clear non optimal rate amplitudes
1719  _sse_zero_ps(_aa+jf);
1720  _sse_zero_ps(_AA+jf);
1721  rNRG.data[j] = 0; // exclude these resolutions
1722  }
1723  _sse_cpf_ps(_am+jf,_aa+jf); // duplicate 00
1724  _sse_cpf_ps(_AM+jf,_AA+jf); // duplicate 90
1725  ee = _sse_abs_ps(_aa+jf,_AA+jf); // total pixel energy / quadrature
1726  if(ee>En) m++; else ee=0.; // count core pixels
1727  rNRG.data[j]*= ee; // init residual energy array
1728  pNRG.data[j] = rNRG.data[j]; // init residual energy array
1729  }
1730 
1731  __m128* _pp = (__m128*) am.data; // point to multi-res amplitudes
1732  __m128* _PP = (__m128*) AM.data; // point to multi-res amplitudes
1733 
1734  if(mra && mureana) { // do MRA
1735  _sse_mra_ps(xi.data,XI.data,En,m); // get principle components
1736  _pp = (__m128*) xi.data; // point to PC amplitudes
1737  _PP = (__m128*) XI.data; // point to PC amplitudes
1738  }
1739 
1740  m = 0; Em = 0.;
1741  for(j=0; j<V; j++) {
1742  int jf = j*f_; // source sse pointer increment
1743  int mf = m*f_; // target sse pointer increment
1744  pJ[j] = 0;
1745  _sse_zero_ps(_bb+jf); // reset array for MRA amplitudes
1746  _sse_zero_ps(_BB+jf); // reset array for MRA amplitudes
1747  ee = pNRG.data[j]; // total pixel energy
1748  if(ee<En) continue;
1749  _sse_cpf_ps(_bb+mf,_pp+jf); // copy 00 amplitude/PC
1750  _sse_cpf_ps(_BB+mf,_PP+jf); // copy 90 amplitude/PC
1751  _sse_cpf_ps(_Fp+mf,_fp+jf); // copy F+
1752  _sse_cpf_ps(_Fx+mf,_fx+jf); // copy Fx
1753  _sse_mul_ps(_Fp+mf,_nr+jf); // normalize f+ by rms
1754  _sse_mul_ps(_Fx+mf,_nr+jf); // normalize fx by rms
1755  pJ[m++]= j; // store pixel index
1756  }
1757 
1758  size_t m4 = m + (m%4 ? 4 - m%4 : 0);
1759  __m128 _ll,_LL,_ec,_EC,_ee,_EE,_NI,_s2,_c2,_AX,_NN,_FF,_QQ,_ie,_gg;
1760  __m128 _en,_EN,_ed,_ED,_cc,_ss,_ni,_si,_co,_ax,_nn,_ff,_mm,_IE,_GG;
1761 
1762  __m128* _siP = (__m128*) siPHS.data; // phase sin
1763  __m128* _coP = (__m128*) coPHS.data; // phase cos
1764  __m128* _siO = (__m128*) siORT.data; // ort4 sin
1765  __m128* _coO = (__m128*) coORT.data; // ort4 cos
1766  __m128* _siD = (__m128*) siDPF.data; // DPF sin
1767  __m128* _coD = (__m128*) coDPF.data; // DPF cos
1768  __m128* _nrg = (__m128*) q2Q2.data; // energy (1+e^2)*(q^2+Q^2)
1769  __m128* _chr = (__m128*) chir.data; // chirality (sign of e)
1770 
1771  if(mra) {
1772  _pp = (__m128*) xi.data; // point to PC amplitudes
1773  _PP = (__m128*) XI.data; // point to PC amplitudes
1774  }
1775 
1776 // test sky location
1777 
1778  Lo = Ln = Co = Eo = 0.;
1779  for(j=0; j<m4; j+=4) {
1780  int jf = j*f_; // sse index increment
1781 
1782  __m128* _pbb = _bb+jf;
1783  __m128* _pBB = _BB+jf;
1784  __m128* _pxi = _pp+jf;
1785  __m128* _pXI = _PP+jf;
1786  __m128* _pxp = _xp+jf;
1787  __m128* _pXP = _XP+jf;
1788  __m128* _pww = _ww+jf;
1789  __m128* _pWW = _WW+jf;
1790  __m128* _pfp = _fp+jf;
1791  __m128* _pfx = _fx+jf;
1792  __m128* _pFp = _Fp+jf;
1793  __m128* _pFx = _Fx+jf;
1794 
1795 // do transformations
1796 
1797  _sse_ort4_ps(_pFp,_pFx,_siD,_coD); // get DPF sin and cos
1798  _sse_rot4p_ps(_pFp,_coD,_pFx,_siD,_pfp); // get DPF fp=Fp*c+Fx*s
1799  _sse_rot4m_ps(_pFx,_coD,_pFp,_siD,_pfx); // get DPF fx=Fx*c-Fp*s
1800  _sse_pnp4_ps(_pfp,_pfx,_pbb,_pBB,_pxp,_pXP); // projection on network plane
1801  _sse_ort4_ps(_pxp,_pXP,_siO,_coO); // dual-stream phase sin and cos
1802  _sse_rot4p_ps(_pxp,_coO,_pXP,_siO,_pxi); // get 00 standard response
1803  _sse_rot4m_ps(_pXP,_coO,_pxp,_siO,_pXI); // get 90 standard response
1804  _sse_rot4p_ps(_pbb,_coO,_pBB,_siO,_pww); // get 00 phase data vector
1805  _sse_rot4m_ps(_pBB,_coO,_pbb,_siO,_pWW); // get 90 phase data vector
1806  _coO++; _siO++; _coD++; _siD++; // increment to next 4 pixels
1807 
1808 // save projection on network plane and standard response in polar coordinates
1809  if(le==lb && (optR==0)) {
1810  _sse_pol4_ps(_pfp, _pfx, _pxp, p00_POL[0].data+j, p00_POL[1].data+j);
1811  _sse_pol4_ps(_pfp, _pfx, _pXP, p90_POL[0].data+j, p90_POL[1].data+j);
1812  _sse_pol4_ps(_pfp, _pfx, _pxi, r00_POL[0].data+j, r00_POL[1].data+j);
1813  _sse_pol4_ps(_pfp, _pfx, _pXI, r90_POL[0].data+j, r90_POL[1].data+j);
1814  }
1815 
1816 // standard statistics
1817 
1818  _ee = _sse_abs4_ps(_pww); // 00 energy
1819  _ll = _sse_abs4_ps(_pxi); // standard 00 likelihood
1820  _ec = _sse_ecoh4_ps(_pww,_pxi,_ll); // 00 coherent energy
1821  _EE = _sse_abs4_ps(_pWW); // 90 energy
1822  _LL = _sse_abs4_ps(_pXI); // standard 00 likelihood
1823  _EC = _sse_ecoh4_ps(_pWW,_pXI,_LL); // 90 coherent energy
1824  _cc = _mm_and_ps(_mm_cmpge_ps(_ec,_05),_1); // 00-phase denoising
1825  _ss = _mm_and_ps(_mm_cmpgt_ps(_EC,_05),_cc); // 90-phase denoising
1826 
1827  _ec = _sse_rotp_ps(_ec,_cc,_EC,_ss); // total coherent energy
1828  _ll = _sse_rotp_ps(_ll,_cc,_LL,_ss); // total likelihood
1829  _mm = _sse_rotp_ps(_1,_cc,_1,_ss); // Gaussian noise
1830  _nn = _mm_add_ps(_mm_add_ps(_ee,_EE),_2); // total energy
1831  _cc = _mm_add_ps(_ec,_mm_sub_ps(_nn,_ll));
1832  _cc = _mm_div_ps(_ec,_mm_add_ps(_cc,_mm)); // network correlation coefficient
1833 
1834  _mm_storeu_ps(vvv,_mm_add_ps(_ee,_EE));
1835  Eo += vvv[0]+vvv[1]+vvv[2]+vvv[3]; // network null energy
1836  _mm_storeu_ps(vvv,_ll);
1837  Lo += vvv[0]+vvv[1]+vvv[2]+vvv[3]; // network likelihood
1838  _mm_storeu_ps(vvv,_mm_mul_ps(_ll,_cc));
1839  Ln += vvv[0]+vvv[1]+vvv[2]+vvv[3]; // network likelihood
1840  _mm_storeu_ps(vvv,_ec);
1841  Co += vvv[0]+vvv[1]+vvv[2]+vvv[3]; // network coherent energy
1842  _mm_storeu_ps(vvv,_mm_mul_ps(_ec,_ll));
1843  if(le==lb && !mra) { // optimal resolution likelihood
1844  vLr[pRate[pJ[j+0]]] += vvv[0];
1845  vLr[pRate[pJ[j+1]]] += vvv[1];
1846  vLr[pRate[pJ[j+2]]] += vvv[2];
1847  vLr[pRate[pJ[j+3]]] += vvv[3];
1848  }
1849  }
1850  Ln = Eo>0 ? Ln/Eo : 0;
1851  if(Ln<this->netCC) continue; // skip
1852  _IE = _mm_set1_ps(1-Co/Lo); // global event index
1853 
1854 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1855 // reconstruction loop
1856 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1857  __m128* _xx = (__m128*) xxx.data; // store |f+|
1858  __m128* _yy = (__m128*) yyy.data; // store |fx|
1859  __m128* _zz = (__m128*) zzz.data; // store total amplitude
1860  __m128* _rr = (__m128*) rrr.data; // store regulator flag
1861 
1862  for(j=0; j<m4; j+=4) {
1863  int jf = j*f_; // sse index increment
1864  __m128* _pfp = _fp+jf;
1865  __m128* _pfx = _fx+jf;
1866  *_xx = _sse_abs4_ps(_pfp); // |f+|^2
1867  *_yy = _sse_abs4_ps(_pfx); // |fx|^2
1868  _ee = _mm_add_ps(_mm_sqrt_ps(*_xx++),_oo); // |f+| + eps
1869  _EE = _mm_add_ps(_mm_sqrt_ps(*_yy++),_oo); // |fx| + eps
1870  _sse_cpf4_ps(_ep+jf,_pfp,_mm_div_ps(_1,_ee)); // store + unity vector in ep
1871  _sse_cpf4_ps(_ex+jf,_pfx,_mm_div_ps(_1,_EE)); // store x unity vector in ex
1872  }
1873 
1874  _xx = (__m128*) xxx.data; // store 1/|f+|
1875  _yy = (__m128*) yyy.data; // store 1/|fx|
1876  _zz = (__m128*) zzz.data; // store (1-e*e)*(qq+QQ)*|fx|^2
1877  _rr = (__m128*) rrr.data; // regulator flag
1878  _siP = (__m128*) siPHS.data; // phase sin
1879  _coP = (__m128*) coPHS.data; // phase cos
1880  _siD = (__m128*) siDPF.data; // DPF sin
1881  _coD = (__m128*) coDPF.data; // DPF cos
1882  _nrg = (__m128*) q2Q2.data; // energy (1+e^2)*(q^2+Q^2)
1883 
1884  __m128 linw = linwave ? _oo : _1;
1885  __m128 cirw = cirwave ? _oo : _1;
1886  __m128 _ch = _mm_setzero_ps(); // chirality
1887  __m128 _eqQ = _mm_setzero_ps(); // e*(qq+QQ)*|fx|^2
1888  __m128 _qQ2 = _mm_setzero_ps(); // 2*(qq+QQ)*|fx|^2
1889 
1890  _c2 = _mm_setzero_ps(); // cos[-2p] polarization angle
1891  _s2 = _mm_setzero_ps(); // sin[-2p]
1892  _cc = _mm_setzero_ps(); // cos[t] average vector angle
1893  _ss = _mm_setzero_ps(); // sin[t]
1894 
1895  for(j=0; j<m4; j+=4) { // produce NEW pattern
1896  int jf = j*f_; // sse index increment
1897  __m128* _pfp = _fp+jf;
1898  __m128* _pfx = _fx+jf;
1899  __m128* _pep = _ep+jf;
1900  __m128* _pex = _ex+jf;
1901  __m128* _pxp = _xp+jf;
1902  __m128* _pXP = _XP+jf;
1903  __m128* _pxi = _pp+jf;
1904  __m128* _pXI = _PP+jf;
1905 
1906  _ee = _mm_div_ps(_1,_mm_add_ps(*_xx,_oo)); // 1/|f+|^2
1907  _co = _mm_mul_ps(_sse_dot4_ps(_pfp,_pxi),_ee); // (fp,x)/|f+|^2
1908  _si = _mm_mul_ps(_sse_dot4_ps(_pfp,_pXI),_ee); // (fp,X)/|f+|^2
1909  _sse_rot4p_ps(_pxi,&_co,_pXI,&_si,_bb4); // y 00 phase pattern
1910  _sse_rot4m_ps(_pXI,&_co,_pxi,&_si,_BB4); // Y 90 phase pattern
1911  _NN = _sse_rotp_ps(_co,_co,_si,_si); // (xp*xp+XP*XP) - norm^2
1912  _nn = _mm_div_ps(_1,_mm_add_ps(_NN,_oo)); // 1/(xp*xp+XP*XP) - 1/norm^2
1913  *_siP = _mm_mul_ps(_si,_nn); // normalize siP (used later)
1914  *_coP = _mm_mul_ps(_co,_nn); // normalize coP (used later)
1915 
1916  if(le==lb && (optR==0)) { // save polargrams
1917  __m128 _snn = _mm_sqrt_ps(_nn);
1918  _sse_cpf4_ps(_uu4,_bb4,_snn); // normalize bb4
1919  _sse_cpf4_ps(_vv4,_BB4,_snn); // normalize BB4
1920  _sse_pol4_ps(_ep+jf, _ex+jf, _uu4, r00_POL[0].data+j, r00_POL[1].data+j);
1921  _sse_pol4_ps(_ep+jf, _ex+jf, _vv4, r90_POL[0].data+j, r90_POL[1].data+j);
1922  }
1923 
1924  _en = _sse_dot4_ps(_pex,_bb4); // (ex,y)=-(1-e*e)*(qq+QQ)*S[2d-2p]*|fx|/2
1925  _EN = _sse_dot4_ps(_pex,_BB4); // e*(qq+QQ)*|fx|
1926  _ch = _mm_add_ps(_ch,_EN); // total e*(qq+QQ)*|fx|
1927  _ll = _mm_and_ps(_mm_cmpgt_ps(_EN,_oo),_1); // 1 if e positive
1928  *_chr = _mm_sub_ps(_mm_mul_ps(_ll,_2),_1); // +1/-1 e positive/negative
1929 
1930  _ll = _sse_abs4_ps(_pxi); // 00 energy in ORT pattern
1931  _ni = _sse_ind4_ps(_pfp,*_xx); // f+ index
1932  _NI = _sse_ind4_ps(_pfx,*_yy); // fx index
1933  _ie = _sse_ind4_ps(_pxi,_ll); // normalized incoherent energy
1934  _ff = _mm_div_ps(_mm_add_ps(*_xx,*_yy),_ni); // (|f+|^2+|fx|^2)/ni
1935 
1936  _LL = _sse_rotp_ps(_en,_en,_EN,_EN); // (fx,y)^2+(fx,Y)^2
1937  _LL = _mm_mul_ps(_LL,_nn); // {(1+e*e)-(1-e*e)*C[2d-2p]}*|fx|^2*(qq+QQ)/2
1938  _FF = _mm_mul_ps(*_yy,_ee); // FF = |fx|^2/|f+|^2 - alignment factor
1939  _gg = _mm_mul_ps(_01,_ff); // 0.1*ff
1940  _NN = _mm_mul_ps(_NN,*_xx); // {(1+e*e)+(1-e*e)*C[2d-2p]}*|f+|^2*(qq+QQ)/2
1941  _ll = _mm_mul_ps(_NN,_mm_add_ps(_FF,_gg)); // {(1+e*e)+(1-e*e)*C[2d-2p]}*|f+|^2*(qq+QQ)/2 * (FF+0.1*ff)
1942  _co = _mm_sub_ps(_ll,_LL); // C2*(1-e*e)*(qq+QQ)*|fx|^2
1943  _si = _mm_mul_ps(_2,_sse_dot4_ps(_pfx,_bb4)); //-S2*(1-e*e)*(qq+QQ)*|fx|^2
1944  *_zz = _sse_rotp_ps(_co,_co,_si,_si); // [(1-e*e)*(qq+QQ)*|fx|^2]^2
1945  *_zz = _mm_add_ps(_mm_sqrt_ps(*_zz),_oo); // (1-e*e)*(qq+QQ)*|fx|^2
1946  _ll = _mm_mul_ps(_NN,_FF); // {(1+e*e)+(1-e*e)*C[2d-2p]}*|fx|^2*(qq+QQ)/2
1947  _QQ = _mm_add_ps(_mm_add_ps(_ll,_LL),*_zz); // 2*(qq+QQ)*|fx|^2
1948  _ff = _mm_sqrt_ps(_mm_mul_ps(_ff,_05)); // sqrt[(|f+|^2+|fx|^2)/ni/2]
1949  _FF = _mm_sqrt_ps(_FF); // a = FF = |fx|/|f+| - alignment factor
1950  // CHANGE MEANING OF _ll and _LL
1951  _ax = _mm_add_ps(_1,_mm_div_ps(_co,*_zz)); // 2*sin(d-p)^2 (solution for cos[2d-2p] ~ -1)
1952  _ax = _mm_sqrt_ps(_mm_mul_ps(_ax,_05)); // sin(d-p)
1953  _AX = _sse_dot4_ps(_pfx,_BB4); // e*(qq+QQ)*|fx|^2
1954  _qQ2 = _mm_add_ps(_qQ2,_QQ); // store amplitude term
1955  _eqQ = _mm_add_ps(_eqQ,_AX); // store ellipticity term
1956  _AX = _mm_div_ps(_mm_mul_ps(_2,_AX),_QQ); // e
1957  _GG = _mm_sqrt_ps(_sse_rotp_ps(_ax,_ax,_AX,_AX)); // sqrt(e*e + sin(d-p)^2) - gamma regulator
1958  _gg = _mm_mul_ps(_mm_sub_ps(_05,_ni),
1959  _mm_sub_ps(_1,_FF)); // network index correction
1960  _GG = _mm_sub_ps(_mm_sub_ps(_09,_GG),_gg); // 0.9-sqrt(e*e + sin(d-p)^2) - (0.5-ni)*(1-a)
1961  _GG = _mm_mul_ps(_mm_mul_ps(_IE,_rG),_GG); // gamma regulator value
1962  _GG = _mm_mul_ps(_mm_mul_ps(_IE,_4),_GG); // enhanced gamma regulator value
1963 
1964  _gg = _mm_mul_ps(_mm_sub_ps(_IE,_ff),_kG); // AP threshold
1965  _gg = _mm_mul_ps(_ni,_gg); // network index correction
1966  _nn = _mm_and_ps(_mm_cmpgt_ps(_ff,_gg),_1); // AP regulator --> kill flag
1967  _ee = _mm_mul_ps(_sse_dot4_ps(_pep,_bb4),_nn); // regulated + amplitude: DO NOT UPDATE _ee !!!
1968  _sse_cpf4_ps(_pxi,_pep,_ee); // store + projection
1969 
1970  _mm = _mm_and_ps(_mm_cmpgt_ps(_ff,_GG),_nn); // gamma regulator condition
1971 
1972  _gg = _mm_andnot_ps(_sm,_mm_sub_ps(_NI,_ni)); // |NI-ni|
1973  _gg = _mm_sub_ps(_IE,_mm_mul_ps(_gg,_FF)); // IE-|NI-ni| * |fx|/|f+|
1974  _nn = _mm_and_ps(_mm_cmplt_ps(_gg,_D0),_mm); // 00-phase regulator flag
1975  _mm = _mm_and_ps(_mm_cmplt_ps(_gg,_D9),_mm); // 90-phase regulator flag
1976  _nn = _mm_mul_ps(_nn,cirw); // zero nn if circular wave
1977  _mm = _mm_mul_ps(_mm,linw); // zero mm if linear wave
1978  _EE = _mm_mul_ps(_en,_nn); // 00 x-projection regulator: DO NOT UPDATE _EE !!!
1979  _sse_add4_ps(_pxi,_pex,_EE); // updated 00-phase response
1980  _sse_cpf4_ps(_pXI,_BB4,_mm); // updated 90-phase response
1981 
1982  _nn = _mm_mul_ps(_nn,_PW); // kill 1 dof for psiwave
1983  *_rr = _mm_add_ps(_mm_add_ps(_mm,_nn),_1); // store G-noise bias
1984  _coP++;_siP++;_chr++;_xx++;_yy++;_zz++,_rr++; // advance pointers
1985 
1986  _cc = _mm_add_ps(_cc,_ee); // + a*a* cos(t)
1987  _ss = _mm_add_ps(_ss,_EE); // + a*a* sin(t)
1988 
1989  _ll = _sse_rotm_ps(*_coD,*_coD,*_siD,*_siD); // cos(2d)
1990  _LL = _sse_rotp_ps(*_siD,*_coD,*_siD,*_coD); // sin(2d)
1991  _ec = _sse_rotm_ps(_co,_ll,_si,_LL); // C[-2p] term (si -> -si)
1992  _EC = _sse_rotp_ps(_si,_ll,_co,_LL); // S[-2p] term (si -> -si)
1993  _c2 = _mm_add_ps(_c2,_ec); // accumulate C[-2p]
1994  _s2 = _mm_sub_ps(_s2,_EC); // accumulate S[-2p] (si -> -si)
1995  _coD++;_siD++; // advance pointers
1996  }
1997 
1998  _mm_storeu_ps(vvv,_c2);
1999  c2p = vvv[0]+vvv[1]+vvv[2]+vvv[3]; // cos[-2p]
2000  _mm_storeu_ps(vvv,_s2);
2001  s2p = vvv[0]+vvv[1]+vvv[2]+vvv[3]; // sin[-2p]
2002  gg = sqrt(c2p*c2p+s2p*s2p+1.e-16);
2003  _si = _mm_set1_ps(s2p/gg); // sin[-2p]
2004  _co = _mm_set1_ps(c2p/gg); // cos[-2p]
2005 
2006  if(psiwave) { // reconstruct p-wave
2007  _zz = (__m128*) zzz.data; // store z-amplitude
2008  _siD = (__m128*) siDPF.data; // DPF sin
2009  _coD = (__m128*) coDPF.data; // DPF cos
2010 
2011  _mm_storeu_ps(vvv,_cc);
2012  cc = (vvv[0]+vvv[1]+vvv[2]+vvv[3]); // cos[t]
2013  _mm_storeu_ps(vvv,_ss);
2014  ss = (vvv[0]+vvv[1]+vvv[2]+vvv[3]); // sin[t]
2015  gg = sqrt(cc*cc+ss*ss+1.e-16);
2016  _si = _mm_set1_ps(ss/gg); // sin[-2p]
2017  _co = _mm_set1_ps(cc/gg); // cos[-2p]
2018 
2019  for(j=0; j<m4; j+=4) { // fix chirality and average vector
2020  int jf = j*f_; // sse index increment
2021  __m128* _pxi = _pp+jf;
2022  __m128* _pXI = _PP+jf;
2023 
2024  _sse_rot4p_ps(_ep+jf,&_co,_ex+jf,&_si,_bb4); // rotate e+,ex by theta
2025  _sse_cpf4_ps(_pxi,_bb4,_sse_dot4_ps(_pxi,_bb4));// 0 residual: do not enforce sign
2026 
2027 /* dispersion correction code
2028  _cc = _sse_rotm_ps(*_coD,*_coD,*_siD,*_siD); // cos(2d)
2029  _ss = _sse_rotp_ps(*_siD,*_coD,*_siD,*_coD); // sin(2d)
2030  _ss = _sse_rotp_ps(_si,_cc,_ss,_co); // S[2d-2p] term
2031  _sse_cpf4_ps(_pxi,_pep,_sse_dot4_ps(_pep,_pxi)); // store + projection
2032  _sse_sub4_ps(_pxi,_pex,_mm_mul_ps(_ss,*_zz)); // subtract 0-phase x response
2033  _coD++;_siD++;_zz++; // advance pointers
2034 */
2035  }
2036  }
2037 
2038  // orthogonalize responces before calculate sky statistics
2039 
2040  _siO = (__m128*) siORT.data; // ort4 sin
2041  _coO = (__m128*) coORT.data; // ort4 cos
2042  _siP = (__m128*) siPHS.data; // phase sin
2043  _coP = (__m128*) coPHS.data; // phase cos
2044  _chr = (__m128*) chir.data; // chirality (sign of ellipticity)
2045 
2046  _mm_storeu_ps(vvv,_eqQ);
2047  _mm_storeu_ps(uuu,_qQ2);
2048  eLp = 2.*(vvv[0]+vvv[1]+vvv[2]+vvv[3]); // average ellipticity
2049  eLp/= uuu[0]+uuu[1]+uuu[2]+uuu[3]+1.e-16; // average ellipticity
2050  _mm_storeu_ps(vvv,_ch);
2051  CHR = vvv[0]+vvv[1]+vvv[2]+vvv[3]; // average chirality
2052  ff = CHR>0. ? 1. : -1.; // chirality
2053  _ch = _mm_set1_ps(ff);
2054  _gg = rndwave ? _oo : _mm_set1_ps(0.5); // check or not chirality
2055 
2056  for(j=0; j<m4; j+=4) { // Orthogonalize
2057  int jf = j*f_; // sse index increment
2058  __m128* _pbb = _bb+jf;
2059  __m128* _pBB = _BB+jf;
2060  __m128* _pxp = _xp+jf;
2061  __m128* _pXP = _XP+jf;
2062  __m128* _pxi = _pp+jf;
2063  __m128* _pXI = _PP+jf;
2064 
2065  _ee = _mm_sub_ps(_mm_mul_ps(_ch,*_chr),_1); // -1 or 0
2066  _sse_add4_ps(_pXI,_pXI,_mm_mul_ps(_ee,_gg)); // set chirality
2067 
2068  _co = _sse_rotm_ps(*_coO,*_coP,*_siO,*_siP); // cos(ort4+phase)
2069  _si = _sse_rotp_ps(*_siO,*_coP,*_siP,*_coO); // sin(ort4+phase)
2070  _sse_rot4m_ps(_pxi,&_co,_pXI,&_si,_pxp); // get 00 phase response
2071  _sse_rot4p_ps(_pXI,&_co,_pxi,&_si,_pXP); // get 90 phase response
2072  _sse_ort4_ps(_pxp,_pXP,_siO,_coO); // dual-stream phase sin and cos
2073  _sse_rot4p_ps(_pxp,_coO,_pXP,_siO,_pxi); // get 00 standard response
2074  _sse_rot4m_ps(_pXP,_coO,_pxp,_siO,_pXI); // get 90 standard response
2075  _sse_rot4p_ps(_pbb,_coO,_pBB,_siO,_ww+jf); // get 00 phase data vector
2076  _sse_rot4m_ps(_pBB,_coO,_pbb,_siO,_WW+jf); // get 90 phase data vector
2077  _coO++; _siO++; _coP++; _siP++; _chr++; // increment to next 4 pixels
2078  }
2079 
2080 // calculation of likelihood statistics
2081 
2082  Nm = Lo;
2083 
2084  _rr = (__m128*) rrr.data; // regulator flag
2085 
2086  Lo = Co = Eo = Lr = Cr = Do = 0.;
2087  for(j=0; j<m4; j+=4) {
2088  int jf = j*f_; // sse index increment
2089 
2090  __m128* _pbb = _bb+jf;
2091  __m128* _pBB = _BB+jf;
2092  __m128* _pxi = _pp+jf;
2093  __m128* _pXI = _PP+jf;
2094  __m128* _pww = _ww+jf;
2095  __m128* _pWW = _WW+jf;
2096 
2097  _ee = _sse_abs4_ps(_pbb); // 00 total energy
2098  _ll = _mm_add_ps(_sse_abs4_ps(_pxi),_oo); // standard 00 likelihood
2099  _ed = _sse_ed4_ps(_pww,_pxi,_ll); // 00 energy disbalance
2100  _ec = _sse_ecoh4_ps(_pww,_pxi,_ll); // coherent energy
2101 
2102  _EE = _sse_abs4_ps(_pBB); // 90 total energy
2103  _LL = _mm_add_ps(_sse_abs4_ps(_pXI),_oo); // standard 90 likelihood
2104  _ED = _sse_ed4_ps(_pWW,_pXI,_LL); // 90 energy disbalance
2105  _EC = _sse_ecoh4_ps(_pWW,_pXI,_LL); // coherent energy
2106 
2107  _ll = _mm_add_ps(_ll,_LL); // total signal energy
2108  _ec = _mm_add_ps(_ec,_EC); // total coherent energy
2109  _ed = _mm_add_ps(_ed,_ED); // total energy disbalance
2110  _ee = _mm_add_ps(_ee,_EE); // total energy
2111 
2112  _mm_storeu_ps(vvv,_ee);
2113  Eo += vvv[0]+vvv[1]+vvv[2]+vvv[3]; // total network energy
2114  _mm_storeu_ps(vvv,_ec);
2115  Co += vvv[0]+vvv[1]+vvv[2]+vvv[3]; // network coherent energy
2116  _mm_storeu_ps(vvv,_ed);
2117  Do += vvv[0]+vvv[1]+vvv[2]+vvv[3]; // network energy disbalance
2118  _mm_storeu_ps(vvv,_ll);
2119  Lo += vvv[0]+vvv[1]+vvv[2]+vvv[3]; // network likelihood
2120 
2121 // calculate sky statistics
2122 
2123  _en = _mm_andnot_ps(_sm,_mm_sub_ps(_ee,_ll)); // pixel null energy
2124  _en = _mm_add_ps(_en,*_rr); _rr++; // Gaussian bias added
2125  _EC = _mm_andnot_ps(_sm,_ec); // | coherent energy |
2126  _cc = _mm_add_ps(_mm_add_ps(_EC,_ed),_en); // |C|+null+ed
2127  _cc = _mm_div_ps(_mm_sub_ps(_ec,_ed),_cc); // network correlation
2128 
2129  _mm_storeu_ps(vvv,_mm_mul_ps(_ll,_cc));
2130  Lr += vvv[0]+vvv[1]+vvv[2]+vvv[3]; // reduced likelihood
2131  _mm_storeu_ps(vvv,_mm_mul_ps(_ec,_cc));
2132  Cr += vvv[0]+vvv[1]+vvv[2]+vvv[3]; // reduced coherent energy
2133 
2134  // _mm_storeu_ps(vvv,_gg);
2135  // _mm_storeu_ps(uuu,_ff);
2136  // if(hist && (le-lb) && vvv[0]!=0) hist->Fill(vvv[0], uuu[0]);
2137  // if(hist && (le-lb) && vvv[1]!=0) hist->Fill(vvv[1], uuu[1]);
2138  // if(hist && (le-lb) && vvv[2]!=0) hist->Fill(vvv[2], uuu[2]);
2139  // if(hist && (le-lb) && vvv[3]!=0) hist->Fill(vvv[3], uuu[3]);
2140  }
2141 
2142  aa = Eo>0. ? Lo/Eo : 0.; // detection skystat
2143  AA = Eo>0. ? Lr/Eo : 0.; // detection skystat
2144  if(!mra) skyProb.data[l] = this->delta<0 ? aa : AA;
2145 
2146  if(ID==id || mra) { // antenna patterns
2147  float ll,LL,Et;
2148  ff = FF = Et = Nm = 0.;
2149  for(j=0; j<m; j++) {
2150  int jf = j*f_; // sse pointer increment
2151  ee = _sse_abs_ps(_bb+jf,_BB+jf); // total energy
2152  if(ee<En) continue; // skip sub-threshold PC
2153  ff += _sse_abs_ps(_fp+jf)*ee; // |f+|^2
2154  FF += _sse_abs_ps(_fx+jf)*ee; // |fx|^2
2155  ll = _sse_mul_ps(_pp+jf,_pp+jf,_bb4)+1.e-12; // 00 likelihood
2156  LL = _sse_mul_ps(_PP+jf,_PP+jf,_BB4)+1.e-12; // 90 likelihood
2157  Nm+= _sse_abs_ps(_bb4)/ll+_sse_abs_ps(_BB4)/LL; // network index*L
2158  Et+= ll+LL;
2159  }
2160  Nm = Et>0.&&Nm>0 ? Et/Nm : 0.;
2161  ff = Eo>0. ? 2*ff/Eo : 0.;
2162  FF = Eo>0. ? 2*FF/Eo : 0.;
2163  }
2164 
2165  if(ID==id && !mra) { // fill skymaps
2166  Eo += 0.001; Cr += 0.001;
2167  this->nAntenaPrior.set(l, sqrt(ff+FF)); // fill sensitivity
2168  this->nSensitivity.set(l, sqrt(ff+FF));
2169  this->nAlignment.set(l, sqrt(FF/ff));
2170  this->nLikelihood.set(l, Lo/Eo);
2171  this->nNullEnergy.set(l, (Eo-Lo)/Eo);
2172  this->nCorrEnergy.set(l, Cr/Eo);
2173  this->nCorrelation.set(l, Ln);
2174  this->nSkyStat.set(l, AA);
2175  this->nProbability.set(l, skyProb.data[l]);
2176  this->nDisbalance.set(l, 2*Do/Eo);
2177  this->nEllipticity.set(l, eLp);
2178  this->nPolarisation.set(l, -atan2(s2p,c2p)*180./PI/4.);
2179  this->nNetIndex.set(l, Nm);
2180  }
2181 
2182  if(prior && !mra && ID!=id) { // used in getSkyArea with prior
2183  ff = FF = 0.;
2184  for(j=0; j<m; j++) {
2185  int jf = j*f_; // sse pointer increment
2186  ee = _sse_abs_ps(_bb+jf,_BB+jf); // total energy
2187  if(ee<En) continue; // skip sub-threshold PC
2188  ff += _sse_abs_ps(_fp+jf)*ee; // |f+|^2
2189  FF += _sse_abs_ps(_fx+jf)*ee; // |fx|^2
2190  }
2191  ff = Eo>0. ? 2*ff/Eo : 0.;
2192  FF = Eo>0. ? 2*FF/Eo : 0.;
2193  this->nAntenaPrior.set(l, sqrt(ff+FF)); // fill sensitivity
2194  }
2195 
2196  if(AA>STAT && !mra) {STAT=AA; lm=l; Vm=m;}
2197  }
2198 
2199  if(STAT==0. || (mra && AA<=0.)) {
2200  pwc->sCuts[id-1]=1; count=0; // reject cluster
2201  pwc->clean(id); continue;
2202  }
2203 
2204  if(le-lb) {lb=le=lm; goto optsky;} // process all pixels at opt sky location
2205 
2206  double Em_all,Ln_all,Ls_all,Lr_all;
2207  double Eo_all,Lo_all,Co_all,Do_all,cc_all;
2208  float GNoise = 0.;
2209 
2210  if(!mra) { // all resolution pixels
2211  Em_all=Ls_all=Ln_all = 0;
2212  Eo_all = Eo; // multiresolution energy
2213  Lo_all = Lo; // multiresolution likelihood
2214  Lr_all = Lr; // reduced likelihood
2215  Co_all = Co; // multiresolution coherent energy
2216  Do_all = Do*2; // multiresolution ED
2217  pwc->cData[id-1].skySize = m; // event size in the skyloop
2218  pwc->cData[id-1].likesky = Lo; // multires Likelihood - stored in neted[3]
2219  vint = &(pwc->cList[id-1]); // pixel list
2220  for(j=0; j<vint->size(); j++) { // initialization for all pixels
2221  pix = pwc->getPixel(id,j);
2222  pix->core = false;
2223  pix->likelihood = 0.;
2224  }
2225 
2226  for(j=0; j<Vm; j++) { // loop over significant pixels
2227  pix = pwc->getPixel(id,pI[pJ[j]]);
2228  int jf = j*f_; // source sse pointer increment
2229  ee = _sse_abs_ps(_bb+jf,_BB+jf);
2230  pix->likelihood = ee/2; // total pixel energy
2231  em = _sse_maxE_ps(_bb+jf,_BB+jf); // dominant pixel likelihood
2232  Ls_all += ee-em; // subnetwork Energy
2233  Em_all += em; // maximum detector energy
2234  if(ee-em>Es) Ln_all += ee; // reduced network energy
2235  GNoise += rrr.data[j]; // counter for G-noise bias
2236  }
2237 
2238  pwc->cData[id-1].skyStat = Lr/Eo; // all-resolution sky statistic (saved in norm)
2239  cc_all = Lr/Lo; // multiresolution cc
2240 
2241  Ns = Eo_all-Lo_all+Do+GNoise; // NULL stream with G-noise correction
2242  gg = Ls_all*Ln_all/Em_all; // L: all-sky subnet "energy"
2243  pwc->cData[id-1].SUBNET = gg/(fabs(gg)+Ns); // like2G sub-network statistic (saved in netcc[3])
2244 
2245  mra=true; goto optsky; // process mra pixels at opt sky location
2246  }
2247 
2248  if(AA<this->netCC || !m) {
2249  pwc->sCuts[id-1]=1; count=0; // reject cluster
2250  pwc->clean(id); continue;
2251  }
2252 
2253 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2254 // detection statistics at selected sky location
2255 // wavelet domain: netcc, ecor
2256 // time domain: energy, likelihood, xSNR, sSNR, neted
2257 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2258 
2259  double Em_mra,Ln_mra,Ls_mra;
2260  double Eo_mra,Lo_mra,Co_mra;
2261 
2262  M=m; m=0; GNoise=0.;
2263  Em_mra=Ln_mra=Ls_mra = 0;
2264  for(j=0; j<M; j++) { // loop over principle components
2265  pix = pwc->getPixel(id,pI[pJ[j]]);
2266  int jf = j*f_; // source sse pointer increment
2267  float* psi = siORT.data+j;
2268  float* pco = coORT.data+j;
2269  __m128* _pxi = _xi+jf;
2270  __m128* _pXI = _XI+jf;
2271  ee = _sse_abs_ps(_bb+jf,_BB+jf); // total pixel energy
2272  em = _sse_maxE_ps(_bb+jf,_BB+jf); // dominant pixel energy
2273  Em_mra += em; // maximum detector energy
2274  Ls_mra += ee-em; // subnetwork energy
2275  if(ee-em>Es) Ln_mra += ee; // reduced network energy
2276  GNoise += rrr.data[j]; // counter for G-noise bias
2277  if(em>0) m++; // counter for subnet pixels
2278  pix->core = true;
2279 
2280  _sse_rotm_ps(_pxi,pco,_pXI, psi,_bb4); // invDSP 00 response
2281  _sse_rotp_ps(_pXI,pco,_pxi, psi,_BB4); // invDSP 90 response
2282 
2283  for(i=0; i<nIFO; i++) {
2284  pix->setdata(double(bb.data[j*NIFO+i]),'W',i); // store 00 whitened PC
2285  pix->setdata(double(BB.data[j*NIFO+i]),'U',i); // store 90 whitened PC
2286  pix->setdata(double(bb.data[V4*NIFO+i]),'S',i); // 00 reconstructed whitened response
2287  pix->setdata(double(BB.data[V4*NIFO+i]),'P',i); // 90 reconstructed whitened response
2288  }
2289  }
2290 
2291  if(!m) { // zero reconstructed response
2292  pwc->sCuts[id-1]=1; count=0; // reject cluster
2293  pwc->clean(id); continue;
2294  }
2295 
2296  Em=Eo; Lm=Lo; Do*=2; // copy all-pixel statistics
2297  Eo_mra=Eo; Lo_mra=Lo; Co_mra=Co;
2298 
2299  pwc->cData[id-1].netcc = Lr/Eo; // network cc with mres correction (saved in netcc[0])
2300  Nc = Eo-Lo+Do/2+GNoise; // NULL stream with correction
2301  gg = Ls_mra*Ln_mra/Em_mra; // L: MRA subnet "energy"
2302  pwc->cData[id-1].subnet = gg/(fabs(gg)+Nc); // mra/sra sub-energy statistic (saved in netcc[2])
2303  pwc->cData[id-1].skycc = Co/(fabs(Co)+Nc); // classic SRA/MRA cc (saved in netcc[1])
2304 
2305  //if(hist) hist->Fill(pwc->cData[id-1].skycc,pwc->cData[id-1].netcc);
2306 
2307 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2308 // fill in detection statistics, prepare output data
2309 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2310 
2311 // fill in backward delay configuration
2312 
2313  vtof->clear();
2314  NETX (vtof->push_back(ml[0][lm]); ,
2315  vtof->push_back(ml[1][lm]); ,
2316  vtof->push_back(ml[2][lm]); ,
2317  vtof->push_back(ml[3][lm]); ,
2318  vtof->push_back(ml[4][lm]); ,
2319  vtof->push_back(ml[5][lm]); ,
2320  vtof->push_back(ml[6][lm]); ,
2321  vtof->push_back(ml[7][lm]); )
2322 
2323  // need to fix a problem below
2324  if((wfsave)||(mdcListSize() && !lag)) { // if wfsave=false only simulated wf are saved
2325  int m0d = mureana ? 0 : 1;
2326  if(this->getMRAwave(id,lag,'S',m0d,true)) { // reconstruct whitened shifted pd->waveForm
2327  detector* pd;
2328  for(i=0; i<nIFO; i++) { // loop over detectors
2329  pd = this->getifo(i);
2330  pd->RWFID.push_back(id); // save cluster ID
2332  *wf = pd->waveForm;
2333  wf->start(pwc->start+pd->waveForm.start());
2334  pd->RWFP.push_back(wf);
2335  }
2336  }
2337  if(this->getMRAwave(id,lag,'s',m0d,true)) { // reconstruct strain shifted pd->waveForm
2338  detector* pd;
2339  for(i=0; i<nIFO; i++) { // loop over detectors
2340  pd = this->getifo(i);
2341  pd->RWFID.push_back(-id); // save cluster -ID
2343  *wf = pd->waveForm;
2344  wf->start(pwc->start+pd->waveForm.start());
2345  pd->RWFP.push_back(wf);
2346  }
2347  }
2348  }
2349 
2350  Lo = Eo = To = Fo = No = 0.;
2351  for(i=0; i<nIFO; i++) {
2352  detector* d = this->getifo(i);
2353  d->sSNR = d->xSNR = d->null = d->enrg = 0.;
2354  }
2355 
2356  int two = mureana ? 1 : 2;
2357  int m0d = mureana ? 0 : -1;
2358  while(m0d < 2) {
2359  this->getMRAwave(id,lag,'W',m0d);
2360  this->getMRAwave(id,lag,'S',m0d);
2361  for(i=0; i<nIFO; i++) {
2362  detector* d = this->getifo(i);
2363  d->waveNull = d->waveBand;
2364  d->waveNull-= d->waveForm;
2365  float sSNR = d->get_SS()/two;
2366  float xSNR = d->get_XS()/two;
2367  float null = d->get_NN()/two;
2368  float enrg = d->get_XX()/two;
2369  d->sSNR += sSNR;
2370  d->xSNR += xSNR;
2371  d->null += null;
2372  d->enrg += enrg;
2373  To += sSNR*d->getWFtime();
2374  Fo += sSNR*d->getWFfreq();
2375  Lo += sSNR;
2376  Eo += enrg;
2377  No += null;
2378  }
2379  m0d += 2;
2380  }
2381  To /= Lo; Fo /= Lo;
2382 
2383  gg = Lo/Lo_mra;
2384  Co = Co*gg;
2385  Cr = Cr*gg;
2386  Do = Do*gg;
2387  Nc = Nc*gg;
2388 
2389  pwc->cData[id-1].likenet = Lo;
2390  pwc->cData[id-1].energy = Eo; // energy of the event - stored in neted[2]
2391  pwc->cData[id-1].enrgsky = Eo_all; // energy in the skyloop - stored in neted[4]
2392  pwc->cData[id-1].netecor = Co;
2393  pwc->cData[id-1].netnull = No+GNoise/2; // NULL with Gauss correction - stored in neted[1]
2394  pwc->cData[id-1].netED = Do; // network energy disbalance - stored in neted[0]
2395  pwc->cData[id-1].netRHO = sqrt(Co*cc_all/(nIFO-1.)); // signal rho - stored in rho[0]
2396  pwc->cData[id-1].netrho = sqrt(Cr/(nIFO-1.)); // reguced rho - stored in rho[1]
2397  pwc->cData[id-1].cTime = To;
2398  pwc->cData[id-1].cFreq = Fo;
2399  pwc->cData[id-1].theta = nLikelihood.getTheta(lm);
2400  pwc->cData[id-1].phi = nLikelihood.getPhi(lm);
2401  pwc->cData[id-1].gNET = sqrt(ff+FF);
2402  pwc->cData[id-1].aNET = sqrt(FF/ff);
2403  pwc->cData[id-1].iNET = Nm;
2404  pwc->cData[id-1].iota = Ns;
2405  pwc->cData[id-1].psi = -atan2(s2p,c2p)*180./PI/4.;
2406  pwc->cData[id-1].ellipticity = eLp;
2407 
2408  if(this->optim) pwc->cRate[id-1][0] = optR; // update optimal resolution
2409 
2410  if(sqrt(Co/(nIFO-1.))<this->netRHO || pwc->cData[id-1].skycc<this->netCC) {
2411  pwc->sCuts[id-1]=1; count=0; // reject cluster
2412  pwc->clean(id); continue;
2413  }
2414 
2415  cc = pwc->cData[id-1].skycc;
2416  if(hist) {
2417  printf("id|lm %3d|%6d rho=%4.2f cc: %5.3f|%5.3f|%5.3f|%5.3f \n",
2418  int(id),int(lm),sqrt(Co/(nIFO-1)),STAT,cc,pwc->cData[id-1].netcc,AA);
2419  printf(" (t,p)=(%4.1f|%4.1f) T|F: %6.3f|%4.1f L: %5.1f|%5.1f|%5.1f E: %5.1f|%5.1f|%5.1f \n",
2420  nLikelihood.getTheta(l),nLikelihood.getPhi(l),To,Fo,Lo,Lo_mra,Lo_all,Eo,Em,Eo_all);
2421  printf(" D|N: %4.1f|%4.1f|%4.1f Vm|m=%3d|%3d subnet=%4.3f|%4.3f \n",
2422  Do,No,Nc,int(Vm),int(M),pwc->cData[id-1].subnet,pwc->cData[id-1].SUBNET);
2423  hist->Fill(pwc->cData[id-1].subnet,pwc->cData[id-1].SUBNET);
2424  }
2425  count++;
2426 
2427 // calculation of error regions
2428 
2429  pwc->p_Ind[id-1].push_back(m);
2430  double T = To+pwc->start; // trigger time
2431  std::vector<float> sArea;
2432  pwc->sArea.push_back(sArea);
2433  pwc->p_Map.push_back(sArea);
2434 
2435  skyProb *= Lo;
2436  //double rMs = Ns/(nIFO*Vm);
2437  double rMs = this->delta<0 ? 0 : 2;
2438  if(iID<=0 || ID==id) getSkyArea(id,lag,T,rMs); // calculate error regions
2439 
2440 // calculation of chirp mass
2441 
2442  pwc->cData[id-1].mchirp = 0;
2443  pwc->cData[id-1].mchirperr = 0;
2444  pwc->cData[id-1].tmrgr = 0;
2445  pwc->cData[id-1].tmrgrerr = 0;
2446  pwc->cData[id-1].chi2chirp = 0;
2447 
2448  if(m_chirp) { // work only for MRA
2449  ee = pwc->mchirp(id);
2450  cc = Co_all/(fabs(Co_all)+ee); // chirp cc
2451  printf("mchirp : %d %g %.2e %.3f %.3f %.3f %.3f \n\n",
2452  int(id),cc,pwc->cData[id-1].mchirp,
2453  pwc->cData[id-1].mchirperr, pwc->cData[id-1].tmrgr,
2454  pwc->cData[id-1].tmrgrerr, pwc->cData[id-1].chi2chirp);
2455  }
2456 
2457  if(ID==id && !EFEC) {
2458  this->nSensitivity.gps = T;
2459  this->nAlignment.gps = T;
2460  this->nDisbalance.gps = T;
2461  this->nLikelihood.gps = T;
2462  this->nNullEnergy.gps = T;
2463  this->nCorrEnergy.gps = T;
2464  this->nCorrelation.gps = T;
2465  this->nSkyStat.gps = T;
2466  this->nEllipticity.gps = T;
2467  this->nPolarisation.gps= T;
2468  this->nNetIndex.gps = T;
2469  }
2470 
2471  pwc->sCuts[id-1] = -1;
2472  pwc->clean(id);
2473  } // end of loop over clusters
2474 
2475  return count;
2476 }
2477 
2478 //: operator =
2479 
2481 {
2482  this->wfsave = value.wfsave;
2483  this->MRA = value.MRA;
2484  this->nRun = value.nRun;
2485  this->nLag = value.nLag;
2486  this->nSky = value.nSky;
2487  this->mIFO = value.mIFO;
2488  this->Step = value.Step;
2489  this->Edge = value.Edge;
2490  this->gNET = value.gNET;
2491  this->aNET = value.aNET;
2492  this->iNET = value.iNET;
2493  this->eCOR = value.eCOR;
2494  this->e2or = value.e2or;
2495  this->acor = value.acor;
2496  this->norm = value.norm;
2497  this->pOUT = false;
2498  this->local = value.local;
2499  this->EFEC = value.EFEC;
2500  this->optim = value.optim;
2501  this->delta = value.delta;
2502  this->gamma = value.gamma;
2503  this->penalty = value.penalty;
2504  this->netCC = value.netCC;
2505  this->netRHO = value.netRHO;
2506  this->pSigma = value.pSigma;
2507  this->ifoList = value.ifoList;
2508  this->precision=value.precision;
2509 
2510  this->NDM.clear(); this->NDM=value.NDM;
2511  this->ifoList.clear(); this->ifoList=value.ifoList;
2512  this->ifoName.clear(); this->ifoName=value.ifoName;
2513  this->wc_List.clear(); this->wc_List=value.wc_List;
2514  this->segList.clear(); this->segList=value.segList;
2515  this->mdcList.clear(); this->mdcList=value.mdcList;
2516  this->livTime.clear(); this->livTime=value.livTime;
2517  this->mdcTime.clear(); this->mdcTime=value.mdcTime;
2518  this->mdcType.clear(); this->mdcType=value.mdcType;
2519  this->mdc__ID.clear(); this->mdc__ID=value.mdc__ID;
2520 
2521  return *this;
2522 }
2523 
2524 
2525 //**************************************************************************
2526 //: add detector to the network
2527 //**************************************************************************
2529 
2530  if(ifoList.size()==NIFO) {
2531  cout << "network::add - Error : max number of detectors is " << NIFO << endl;
2532  exit(1);
2533  }
2534 
2535  size_t i,n;
2536  vectorD v; v.clear();
2537  this->ifoList.push_back(d);
2538  this->ifoName.push_back(d->Name);
2539 
2540  n = ifoList.size();
2541  d->ifoID = n-1;
2542  for(i=0; i<n; i++) {
2543  v.push_back(0.);
2544  if(i<n-1) this->NDM[i].push_back(0);
2545  else this->NDM.push_back(v);
2546  }
2547 
2548 // cout<<"size="<<NDM.size()<<" size_0="<<NDM[0].size()<<endl;
2549  return ifoList.size();
2550 }
2551 
2552 //**************************************************************************
2553 // calculate WaveBurst pattern threshold for a given black pixel probability
2554 //**************************************************************************
2555 double network::THRESHOLD(double p, double shape) {
2556 // calculate WaveBurst energy threshold for a given black pixel probability p
2557 // and single detector Gamma distribution shape. TF data should contain pixel energy
2558  int N = ifoListSize();
2559  WSeries<double>* pw = &(getifo(0)->TFmap);
2560  size_t M = pw->maxLayer()+1;
2561  size_t nL = size_t(Edge*pw->wrate()*M);
2562  size_t nR = pw->size() - nL - 1;
2563  wavearray<double> w = *pw;
2564  for(int i=1; i<N; i++) w += getifo(i)->TFmap;
2565  double amp, avr, bbb, alp;
2566  avr = bbb = 0.;
2567  int nn = 0;
2568  for(int i=nL; i<nR; i++) { // get Gamma shape & mean
2569  amp = (double)w.data[i];
2570  if(amp>N*100) amp = N*100.;
2571  if(amp>0.001) {avr+=amp; bbb+=log(amp); nn++;}
2572  }
2573  avr = avr/nn; // Gamma mean
2574  alp = log(avr)-bbb/nn;
2575  alp = (3-alp+sqrt((alp-3)*(alp-3)+24*alp))/12./alp; // Gamma shape
2576  bbb = p*alp/shape; // corrected bpp
2577  //cout<<bbb<<" "<<avr<<" "<<alp<<" "<<shape<<" "<<iGamma(alp,bbb)<<endl;
2578  return avr*iGamma(alp,bbb)/alp/2;
2579 }
2580 
2581 //**************************************************************************
2582 // calculate WaveBurst energy threshold for a given black pixel probability
2583 //**************************************************************************
2584 double network::THRESHOLD(double p) {
2585 // calculate WaveBurst energy threshold for a given black pixel probability p
2586 // TF data should contain pixel energy
2587  int N = ifoListSize();
2588  WSeries<double>* pw = &(getifo(0)->TFmap);
2589  size_t M = pw->maxLayer()+1;
2590  size_t nL = size_t(Edge*pw->wrate()*M);
2591  size_t nR = pw->size() - nL;
2592  wavearray<double> w = *pw;
2593  for(int i=1; i<N; i++) w += getifo(i)->TFmap;
2594  double p10 = p*10.;
2595  double p00 = 0.0;
2596  double fff = w.wavecount(0.0001)/double(w.size());
2597  double v10 = w.waveSplit(nL,nR,nR-int(p10*fff*(nR-nL)));
2598  double val = w.waveSplit(nL,nR,nR-int(p*fff*(nR-nL)));
2599  double med = w.waveSplit(nL,nR,nR-int(0.2*fff*(nR-nL)));
2600  double m = 1.;
2601  while(p00<0.2) {p00 = 1-Gamma(N*m,med); m+=0.01;}
2602  if(m>1) m -= 0.01;
2603  printf("\nm\tM\tbpp\t0.2(D)\t0.2(G)\t0.01(D)\t0.01(G)\tbpp(D)\tbpp(G)\tN*log(m)\tfff\n");
2604  printf("%g\t%d\t%g\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t\t%.3f\n\n",
2605  m,M,p,med,iGamma(N*m,0.2),v10,iGamma(N*m,p10),val,iGamma(N*m,p),N*log(m),fff);
2606  return (iGamma(N*m,p)+val)*0.3+N*log(m);
2607 }
2608 
2609 
2610 //**************************************************************************
2611 // calculate WaveBurst threshold as a function of resolution and maximum delay (used by 1G)
2612 //**************************************************************************
2613 double network::threshold(double p, double t)
2614 {
2615  size_t I;
2616  size_t K = ifoListSize();
2617  double n = 1.;
2618  if(getifo(0) && t>0. && K) {
2619  I = getifo(0)->TFmap.maxLayer()+1; // number of wavelet layers
2620  n = 2*t*getifo(0)->TFmap.rate()/I + 1;
2621  if(!getifo(0)->TFmap.size()) n = 1.;
2622  }
2623  else if(t < 0.) n = -t; // special case: n=-t
2624  return sqrt(iGamma1G(K/2.,1.-(p/2.)/pow(n,K/2.))/K);
2625 }
2626 
2627 void network::printwc(size_t n) {
2628  netcluster* p = this->getwc(n);
2629  int iTYPE = this->MRA ? 0 : 1;
2630  wavearray<double> cid = p->get((char*)"ID",0,'S',iTYPE);
2631  wavearray<double> vol = p->get((char*)"volume",0,'S',iTYPE);
2632  wavearray<double> siz = p->get((char*)"size",0,'S',iTYPE);
2633  wavearray<double> lik = p->get((char*)"likelihood",0,'S',iTYPE);
2634  wavearray<double> rat = p->get((char*)"rate",0,'S',iTYPE);
2635  wavearray<double> tim = p->get((char*)"time",1,'L',0);
2636  wavearray<double> T_o = p->get((char*)"time",0,'L',0);
2637  wavearray<double> frq = p->get((char*)"frequency",1,'L',0);
2638  wavearray<double> rho = p->get((char*)"subrho",0,'S',0);
2639  wavearray<double> sub = p->get((char*)"subnet",0,'S',0);
2640 
2641  if(cid.size() != rho.size())
2642  cout<<"wrong size "<<cid.size()<<" "<<rho.size()<<endl;
2643 
2644  for(size_t i=0; i<cid.size(); i++){
2645  printf("%2d %5.0f vol=%4.0f size=%4.0f like=%5.1e rho=%5.1f ",
2646  int(n),cid[i],vol[i],siz[i],lik[i],rho[i]);
2647  printf("sub=%3.2f rate=%4.0f time=%8.3f To=%8.3f freq=%5.0f\n",
2648  sub[i],rat[i],tim[i],T_o[i],frq[i]);
2649  }
2650 }
2651 
2652 
2653 //**************************************************************************
2654 //: initialize network sky maps
2655 //**************************************************************************
2656 void network::setSkyMaps(double sms,double t1,double t2,double p1,double p2)
2657 {
2658  size_t i;
2659  detector* d;
2660  skymap temp(sms,t1,t2,p1,p2);
2661  size_t m = temp.size();
2662  size_t n = this->ifoList.size();
2663 
2664  nSensitivity = temp;
2665  nAlignment = temp;
2666  nCorrelation = temp;
2667  nLikelihood = temp;
2668  nNullEnergy = temp;
2669  nPenalty = temp;
2670  nCorrEnergy = temp;
2671  nNetIndex = temp;
2672  nDisbalance = temp;
2673  nSkyStat = temp;
2674  nEllipticity = temp;
2675  nProbability = temp;
2676  nPolarisation= temp;
2677  nAntenaPrior = temp;
2678 
2679  for(i=0; i<n; i++) {
2680  d = ifoList[i];
2681  d->setTau(sms,t1,t2,p1,p2);
2682  d->setFpFx(sms,t1,t2,p1,p2);
2683  }
2684  skyProb.resize(m);
2685  skyENRG.resize(m);
2686  skyMask.resize(m); skyMask = 1;
2687  skyMaskCC.resize(0);
2688  skyHole.resize(m); skyHole = 1.;
2689  index.resize(m);
2690  for(i=0; i<m; i++) index.data[i] = i;
2691 }
2692 
2693 //**************************************************************************
2694 //: initialize network sky maps (healpix)
2695 //**************************************************************************
2696 void network::setSkyMaps(int healpix_order)
2697 {
2698  size_t i;
2699  detector* d;
2700  skymap temp(healpix_order);
2701  size_t m = temp.size();
2702  size_t n = this->ifoList.size();
2703 
2704  nSensitivity = temp;
2705  nAlignment = temp;
2706  nCorrelation = temp;
2707  nLikelihood = temp;
2708  nNullEnergy = temp;
2709  nPenalty = temp;
2710  nCorrEnergy = temp;
2711  nNetIndex = temp;
2712  nDisbalance = temp;
2713  nSkyStat = temp;
2714  nEllipticity = temp;
2715  nProbability = temp;
2716  nPolarisation= temp;
2717  nAntenaPrior = temp;
2718 
2719  for(i=0; i<n; i++) {
2720  d = ifoList[i];
2721  d->setTau(healpix_order);
2722  d->setFpFx(healpix_order);
2723  }
2724  skyProb.resize(m);
2725  skyENRG.resize(m);
2726  skyMask.resize(m); skyMask = 1;
2727  skyMaskCC.resize(0);
2728  skyHole.resize(m); skyHole = 1.;
2729  index.resize(m);
2730  for(i=0; i<m; i++) index.data[i] = i;
2731 }
2732 
2733 //**************************************************************************
2734 // calculate delays in frame or in barycenter (B) or fermat frame (F)
2735 //**************************************************************************
2736 void network::setDelay(const char* frame) {
2737  size_t n,nn,m,mm;
2738  skymap s = ifoList[0]->tau;
2739  size_t N = this->ifoList.size();
2740  double t,tm,gg;
2741 
2742  if(N < 2) return;
2743 
2744  s = 0.;
2745 
2746  if(strstr(frame,"FL") || strstr(frame,"FS")) { // "Fermat" frame
2747  tm = strstr(frame,"FS") ? 1. : 0.;
2748  gg = strstr(frame,"FS") ? 1. : -1.;
2749  nn = 0;
2750  mm = 1;
2751  for(n=0; n<N; n++) {
2752  for(m=n+1; m<N; m++) {
2753  s = ifoList[n]->tau;
2754  s -= ifoList[m]->tau;
2755  t = gg*(s.max()-s.min());
2756  if(t < tm) { tm=t; nn = n; mm = m; }
2757  }
2758  }
2759 
2760  s = ifoList[nn]->tau;
2761  s+= ifoList[mm]->tau;
2762  s*= 0.5;
2763  mIFO = 99;
2764  }
2765 
2766  else if(strstr(frame,"BC")) { // barycenter frame
2767  for(n=1; n<N; n++) s += ifoList[n]->tau;
2768  s *= 1./N;
2769  mIFO = 99;
2770  }
2771 
2772  else { // detector frame
2773  for(n=0; n<N; n++) {
2774  if(strstr(frame,getifo(n)->Name)) this->mIFO = n;
2775  }
2776  s = ifoList[this->mIFO]->tau;
2777  }
2778 
2779 
2780  for(n=0; n<N; n++) ifoList[n]->tau -= s;
2781  return;
2782 }
2783 
2784 //**************************************************************************
2785 // calculate maximum delay between detectors
2786 //**************************************************************************
2787 double network::getDelay(const char* name) {
2788  size_t i;
2789  size_t n = this->ifoList.size();
2790  double maxTau = -1.;
2791  double minTau = 1.;
2792  double tmax, tmin;
2793 
2794  if(n < 2) return 0.;
2795 
2796  tmax = tmin = 0.;
2797  for(i=0; i<n; i++) {
2798  tmax = ifoList[i]->tau.max();
2799  tmin = ifoList[i]->tau.min();
2800  if(tmax > maxTau) maxTau = tmax;
2801  if(tmin < minTau) minTau = tmin;
2802  }
2803  if(strstr(name,"min")) return minTau;
2804  if(strstr(name,"max")) return maxTau;
2805  if(strstr(name,"MAX")) return fabs(maxTau)>fabs(minTau) ? fabs(maxTau) : fabs(minTau);
2806  return (maxTau-minTau)/2.;
2807 }
2808 
2809 
2810 
2811 
2812 //***************************************************************
2813 //:set antenna pattern buffers in input detector
2814 //***************************************************************
2816 {
2817  size_t n = di->mFp.size();
2818  double a, b;
2819 
2820  di->fp.resize(n);
2821  di->fx.resize(n);
2822  di->ffp.resize(n);
2823  di->ffm.resize(n);
2824  di->fpx.resize(n);
2825 
2826  while(n-- >0) {
2827  a = di->mFp.get(n);
2828  b = di->mFx.get(n);
2829  di->fp.data[n] = a;
2830  di->fx.data[n] = b;
2831  di->ffp.data[n] = a*a+b*b;
2832  di->ffm.data[n] = a*a-b*b;
2833  di->fpx.data[n] = 2*a*b;
2834  }
2835 
2836  return;
2837 }
2838 
2839 //***************************************************************
2840 //:set antenna patterns in the DPF
2841 //***************************************************************
2843 {
2844  size_t M = this->ifoList.size(); // number of detectors
2845  if(M > NIFO) return;
2846 
2847  detector* D[NIFO];
2848 
2849  for(size_t m=0; m<M; m++) {
2850  D[m] = this->getifo(m);
2851  if(D[m]->mFp.size() != D[0]->mFp.size()) {
2852  cout<<"network::setIndex(): invalid detector skymaps\n";
2853  return;
2854  }
2855  this->setAntenna(D[m]);
2856  }
2857  return;
2858 }
2859 
2860 //***************************************************************
2861 //:set index array for delayed amplitudes, used with WDM delay filters
2862 // time delay convention: t+tau - arrival time at the center of Earth
2863 // ta1-tau0 - how much det1 should be delayed to be sinchronized with det0
2864 ///***************************************************************
2866 {
2867  double t;
2868  int i,ii;
2869  size_t n,m,l,k;
2870  size_t N = ifoList.size(); // number of detectors
2871 
2872  double tt[NIFO][NIFO];
2873  double TT[NIFO];
2874  int mm[NIFO][NIFO];
2875 
2876  if(N<2) {
2877  cout<<"network::setDelayIndex(): invalid network\n";
2878  return;
2879  }
2880 
2881  detector* dr[NIFO];
2882  for(n=0; n<N; n++) dr[n] = ifoList[n];
2883 
2884  size_t L = dr[0]->tau.size(); // skymap size
2885  this->rTDF = rate; // effective time-delay rate
2886 
2887  // if(pOUT) cout<<"filter size="<<this->filter.size()
2888  // <<" layers="<<I<<" delays="<<K<<" samples="<<dr[0]->nDFS<<endl;
2889 
2890  for(n=0; n<N; n++) {
2891  if(dr[n]->index.size() != L) {
2892  dr[n]->index.resize(L);
2893  }
2894  }
2895 
2896 // calculate time interval the di detector is delayed to be
2897 // sinchronized with dr
2898 // time delay > 0 - shift di right (future)
2899 // time delay < 0 - shift di left (past)
2900 
2901  this->nPenalty = dr[0]->tau;
2902  this->nNetIndex = dr[0]->tau;
2903 
2904  for(l=0; l<L; l++){
2905 
2906 // calculate time delay matrix
2907 // 0 d01 d02
2908 // d10 0 d12
2909 // d20 d21 0
2910 
2911  for(n=0; n<N; n++) {
2912  for(m=0; m<N; m++) {
2913  t = dr[n]->tau.get(l)-dr[m]->tau.get(l);
2914  i = t>0 ? int(t*rTDF+0.5) : int(t*rTDF-0.5);
2915  mm[n][m] = i;
2916  tt[n][m] = t*rTDF;
2917  }
2918  }
2919 
2920  for(n=0; n<N; n++) {
2921  TT[n] = 0.; // max delay for n-th configuration
2922  for(m=0; m<N; m++) {
2923  for(k=0; k<N; k++) {
2924  t = fabs(mm[n][k]-mm[n][m]-tt[m][k]);
2925  if(TT[n] < t) TT[n] = t;
2926  }
2927  }
2928  }
2929 
2930  t = 20.; i = N;
2931  for(m=0; m<N; m++) {
2932  if(t>TT[m]) { t = TT[m]; k = m; } // first best configuration
2933  }
2934  this->nPenalty.set(l,double(t));
2935 
2936  t = dr[k]->tau.get(l);
2937  if(mIFO<9) i = mm[k][this->mIFO];
2938  else i = t>0 ? int(t*rTDF+0.5) : int(t*rTDF-0.5);
2939 
2940 // 0 d01 d02 0 d01 d02
2941 // d10 0 d12 -> 0 d'01 d'02
2942 // d20 d21 0 0 d"01 d"02
2943 
2944  for(m=0; m<N; m++) {
2945  ii = mm[k][m]-i; // convert to time delay with respect to master IFO
2946  dr[m]->index.data[l] = ii;
2947  //if(m!=this->mIFO) this->nNetIndex.set(l,double(ii));
2948  }
2949  }
2950  return;
2951 }
2952 
2953 //**************************************************************************
2954 //:selection of clusters based on:
2955 // 'C' - network correlation coefficient with incoherent energy
2956 // 'c' - network correlation coefficient with null energy
2957 // 'r' - rho(ecor)
2958 // 'X' - correlated energy
2959 // 'x' - correlated energy - null energy (reduced corr energy)
2960 // 'l' - likelihood (biased)
2961 // 'L' - likelihood (unbiased)
2962 // 'A' - snr - null assymetry (double OR)
2963 // 'E' - snr - null energy (double OR)
2964 // 'a' - snr - null assymetry (edon)
2965 // 'e' - snr - null energy (edon)
2966 //**************************************************************************
2967 size_t network::netcut(double CUT, char cut, size_t core_size, int TYPE)
2968 {
2969  size_t M = this->ifoList.size(); // number of detectors
2970  if(!M) return 0;
2971 
2972  size_t i,j,k,n,m,K;
2973  size_t count = 0;
2974  size_t ID;
2975  size_t I = this->ifoList[0]->TFmap.maxLayer()+1;
2976  int R = int(this->ifoList[0]->getTFmap()->rate()/I+0.5);
2977  int type = this->optim ? R : TYPE; // likelihoodI
2978 
2979  wavearray<double> cid; // buffers for cluster ID
2980  wavearray<double> siz; // buffers for cluster size (core)
2981  wavearray<double> SIZ; // buffers for cluster size (core+halo)
2982  vector<wavearray<double> > snr(M); // buffers for total normalized energy
2983  vector<wavearray<double> > nul(M); // biased null stream
2984 
2985  double xcut,xnul,xsnr,amin,emin,like,LIKE;
2986  bool skip=false;
2987 
2988  for(j=0; j<nLag; j++) { // loop on time shifts
2989 
2990  if(!this->wc_List[j].size()) continue;
2991 
2992  cid = this->wc_List[j].get((char*)"ID",0,'S',type); // get cluster ID
2993  K = cid.size();
2994  if(!K) continue; // no clusters
2995 
2996  siz = this->wc_List[j].get((char*)"size",0,'S',type); // get cluster C size
2997  SIZ = this->wc_List[j].get((char*)"SIZE",0,'S',type); // get cluster C+H size
2998 
2999  for(m=0; m<M; m++) { // loop on detectors
3000  snr[m] = this->wc_List[j].get((char*)"energy",m+1,'S',type); // get total energy
3001  nul[m] = this->wc_List[j].get((char*)"null",m+1,'W',type); // get biased null stream
3002  }
3003 
3004  for(k=0; k<K; k++) { // loop on clusters
3005 
3006  if(siz.data[k] < core_size) continue; // skip small clusters
3007  i = ID = size_t(cid.data[k]+0.1);
3008 
3009  if(tYPe=='i' || tYPe=='s' || tYPe=='g' || tYPe=='r' ||
3010  tYPe=='I' || tYPe=='S' || tYPe=='G' || tYPe=='R') {
3011  skip = !this->SETNDM(i,j,true,type); // fill network data matrix
3012  }
3013  else if(tYPe=='b' || tYPe=='B' || tYPe=='E') {
3014  skip = !this->setndm(i,j,true,type); // fill network data matrix
3015  }
3016  else {
3017  skip = true;
3018  }
3019 
3020  if(skip) {
3021  cout<<"network::netcut: - undefined NDM matrix"<<endl;
3022  this->wc_List[j].ignore(ID); // reject cluster
3023  count += size_t(SIZ.data[k]+0.1); // count rejected pixels
3024  continue;
3025  }
3026 
3027  xnul = xsnr = like = LIKE = 0;
3028  emin = amin = 1.e99;
3029  for(n=0; n<M; n++) {
3030  xnul += this->getifo(n)->null;
3031  xsnr += snr[n].data[k];
3032  like += snr[n].data[k]-this->getifo(n)->null;
3033  xcut = snr[n].data[k]-this->getifo(n)->null;
3034  if(xcut < emin) emin = xcut;
3035  xcut = (xcut-this->getifo(n)->null)/snr[n].data[k];
3036  if(xcut < amin) amin = xcut;
3037  for(m=0; m<M; m++) {
3038  LIKE += this->getNDM(n,m);
3039  }
3040  }
3041 
3042  if(cut == 'A' || cut == 'E') { // double OR selection
3043  emin = amin = 1.e99;
3044  for(n=0; n<M; n++) {
3045  xcut = snr[n].data[k] - this->getifo(n)->null;
3046  if(like-xcut < emin) emin = like-xcut;
3047  xcut = 2*(like-xcut)/(xsnr-xcut) - 1.;
3048  if(xcut < amin) amin = xcut;
3049  }
3050  }
3051 
3052  xcut = 0;
3053  if(cut == 'c' || cut == 'C') xcut = this->eCOR/(xnul + fabs(this->eCOR)); // network x-correlation
3054  if(cut == 'x' || cut == 'X') xcut = this->eCOR/sqrt(fabs(this->eCOR)*M); // network correlated amplitude
3055  if(cut == 'l' || cut == 'L') xcut = like;
3056  if(cut == 'a' || cut == 'A') xcut = amin;
3057  if(cut == 'e' || cut == 'E') xcut = emin;
3058  if(cut == 'r' || cut == 'R') xcut = this->eCOR/sqrt((xnul + fabs(this->eCOR))*M);
3059 
3060  if(xcut < CUT) {
3061  this->wc_List[j].ignore(ID); // reject cluster
3062  count += size_t(SIZ.data[k]+0.1); // count rejected pixels
3063  continue;
3064  }
3065  else
3066  if(cut=='X') cout<<xcut<<cut<<": size="<<SIZ.data[k]<<" L="<<LIKE<<" ID="<<ID<<endl;
3067 
3068 
3069  if(pOUT) {
3070  printf("%3d %4d %7.2e %7.2e %7.2e %7.2e %7.2e %7.2e %7.2e\n",
3071  (int)n,(int)i,getNDM(0,0),getNDM(1,1),getNDM(2,2),getNDM(0,1),getNDM(0,2),getNDM(1,2),
3072  getNDM(0,0)+getNDM(1,1)+getNDM(2,2)+2*(getNDM(0,1)+getNDM(0,2)+getNDM(1,2)));
3073  }
3074  }
3075  }
3076  return count;
3077 }
3078 
3079 
3080 
3081 //**************************************************************************
3082 //: set rank statistic for pixels in network netcluster structure
3083 //**************************************************************************
3084 
3085 size_t network::setRank(double T, double F)
3086 {
3087  size_t j,m,n,V;
3088  size_t cOUNt = 0;
3089 
3090  size_t I = this->ifoList[0]->TFmap.maxLayer()+1;
3091  size_t R = size_t(this->ifoList[0]->getTFmap()->rate()/I+0.5);
3092  size_t N = this->ifoList[0]->getTFmap()->size();
3093  size_t M = this->ifoList.size(); // number of detectors
3094 
3095  int window = int(T*R+0.5)*I/2; // rank half-window size
3096  int offset = int(this->Edge*ifoList[0]->getTFmap()->rate()+0.5);
3097 
3098  double amp, rank;
3099  int inD, frst, last, nB, nT;
3100 
3101 // pointers
3102 
3103  double* ppp;
3104  std::vector<detector*> pDet; pDet.clear();
3105  std::vector<double*> pDat; pDat.clear();
3106 
3107  for(m=0; m<M; m++) {
3108  pDet.push_back(ifoList[m]);
3109  pDat.push_back(ifoList[m]->getTFmap()->data);
3110  }
3111 
3112  size_t wmode = pDet[0]->getTFmap()->w_mode;
3113  if(wmode != 1) return 0;
3114 
3115 // get index arrays for delayed amplitudes
3116 
3117  wavearray<double> cid; // buffers for cluster ID
3118  netpixel* pix;
3119 
3120  for(n=0; n<nLag; n++) { // loop over time shifts
3121  V = this->wc_List[n].pList.size();
3122  nB = int(this->wc_List[n].getbpp()*2*window+0.5);
3123 
3124  if(!V) continue;
3125 
3126  for(j=0; j<V; j++) { // loop over pixels
3127 
3128  pix = &(this->wc_List[n].pList[j]);
3129  if(R != size_t(pix->rate+0.5)) continue;
3130 
3131 // printf("lag=%2d pixel=%4d ID=%4d ",n,j,pix->clusterID);
3132 
3133  for(m=0; m<M; m++) { // loop over detectors
3134 
3135  inD = size_t(pix->getdata('I',m)+0.1);
3136  ppp = pDat[m]+inD;
3137  amp = *ppp;
3138 
3139  *ppp = pix->getdata('S',m); // pixel SNR
3140  if(inD-window < offset) { // left boundary
3141  frst = offset;
3142  last = frst + 2*window;
3143  }
3144  else if(inD+window > int(N-offset)) {
3145  last = N-offset;
3146  frst = last - 2*window;
3147  }
3148  else {
3149  frst = inD-window;
3150  last = inD+window;
3151  }
3152 
3153  if( inD>int(N-offset) || inD<offset ||
3154  frst>int(N-offset) || frst<offset ||
3155  last>int(N-offset) || last<offset) {
3156  cout<<"network::setRank() error\n";
3157  *ppp = amp; // restore pixel value in the array
3158  pix->setdata(0.,'R',m);
3159  continue;
3160  }
3161 
3162  rank = pDet[m]->getTFmap()->getSampleRankE(inD,frst,last);
3163  nT = last-frst+1;
3164 
3165  if(rank > nT-nB) rank = log(nB/double(nT+1-rank));
3166  else rank = 0.;
3167 
3168 // printf("%8.1e|%8.1e ",rank,amp);
3169 
3170  *ppp = amp; // restore pixel value in the array
3171  pix->setdata(rank,'R',m);
3172  cOUNt++;
3173 
3174  }
3175 // cout<<endl;
3176  }
3177  }
3178  return cOUNt;
3179 }
3180 
3181 // read earth skyMask coordinates from file (1G)
3182 size_t network::setSkyMask(double f, char* file) {
3183  int i;
3184  size_t L = this->skyHole.size();
3185  size_t n = 0;
3186  size_t l;
3187  char str[1024];
3188  FILE* in;
3189  char* pc;
3190  double a;
3191 
3192  if(!L) {
3193  cout<<endl<<"network::setSkyMask() - skymap size L=0"<<endl<<endl;
3194  exit(1);
3195  } else if(!file) {
3196  cout<<endl<<"network::setSkyMask() - NULL input skymask file"<<endl<<endl;
3197  exit(1);
3198  } else if(!strlen(file)) {
3199  cout<<endl<<"network::setSkyMask() - input skymask file not defined"<<endl<<endl;
3200  exit(1);
3201  } else if( (in=fopen(file,"r"))==NULL ) {
3202  cout << endl << "network::setSkyMask() - input skymask file '"
3203  << file << "' not exist" << endl << endl;;
3204  exit(1);
3205  }
3206 
3207  while(fgets(str,1024,in) != NULL){
3208 
3209  if(str[0] == '#') continue;
3210  if((pc = strtok(str," \t")) == NULL) continue;
3211  if(pc) i = atoi(pc); // sky index
3212  if((pc = strtok(NULL," \t")) == NULL) continue;
3213  if(pc && i>=0 && i<int(L)) {
3214  this->skyHole.data[i] = atof(pc); // skyProb
3215  this->nSkyStat.set(i, atof(pc));
3216  n++;
3217  } else {
3218  cout<<endl<<"network::setSkyMask() - "
3219  <<"skymask file contains index > max L="<<L<<endl<<endl;
3220  exit(1);
3221  }
3222  }
3223  if(n!=L) {
3224  cout<<endl<<"network::setSkyMask() - "
3225  <<"the number of indexes in the skymask file != L="<<L<<endl<<endl;
3226  exit(1);
3227  }
3228  a = skyHole.mean()*skyHole.size();
3229  skyHole *= a>0. ? 1./a : 0.;
3230  if(f==0.) { skyHole = 1.; return n; }
3231 
3232  double* p = this->skyHole.data;
3233  double** pp = (double **)malloc(L*sizeof(double*));
3234  for(l=0; l<L; l++) pp[l] = p + l;
3235 
3236  skyProb.waveSort(pp,0,L-1);
3237 
3238  a = double(L);
3239  for(l=0; l<L; l++) {
3240  a -= 1.;
3241  *pp[l] = a/L<f ? 0. : 1.;
3242  if(*pp[l] == 0.) this->nSkyStat.set(pp[l]-p,*pp[l]);
3243  }
3244  free(pp);
3245  return n;
3246 }
3247 
3248 // read celestial/earth skyMask coordinates from file
3249 size_t network::setSkyMask(char* file, char skycoord) {
3250 
3251  int i;
3252  size_t L = this->skyHole.size();
3253  size_t n = 0;
3254  char str[1024];
3255  FILE* in;
3256  char* pc;
3257  double data=0;
3258 
3259  if(skycoord!='e' && skycoord!='c') {
3260  cout << "network::setSkyMask() - wrong input sky coordinates "
3261  << " must be 'e'/'c' earth/celestial" << endl;;
3262  exit(1);
3263  }
3264 
3265  if(!L) {
3266  cout<<endl<<"network::setSkyMaskCC() - skymap size L=0"<<endl<<endl;
3267  exit(1);
3268  } else if(!file) {
3269  cout<<endl<<"network::setSkyMaskCC() - NULL input skymask file"<<endl<<endl;
3270  exit(1);
3271  } else if(!strlen(file)) {
3272  cout<<endl<<"network::setSkyMaskCC() - input skymask file not defined"<<endl<<endl;
3273  exit(1);
3274  } else if( (in=fopen(file,"r"))==NULL ) {
3275  cout << endl << "network::setSkyMaskCC() - input skymask file '"
3276  << file << "' not exist" << endl << endl;;
3277  exit(1);
3278  }
3279 
3280  if(skycoord=='e') {skyMask.resize(L); skyMask = 1;}
3281  if(skycoord=='c') {skyMaskCC.resize(L); skyMaskCC = 1;}
3282 
3283  while(fgets(str,1024,in) != NULL){
3284 
3285  if(str[0] == '#') continue;
3286  if((pc = strtok(str," \t")) == NULL) continue;
3287  if(pc) i = atoi(pc); // sky index
3288  if((pc = strtok(NULL," \t")) == NULL) continue;
3289  if(pc && i>=0 && i<int(L)){
3290  data = atof(pc);
3291  if(skycoord=='e') this->skyHole.data[i]=data;
3292  if(skycoord=='c') this->skyMaskCC.data[i]=data;
3293  n++;
3294  } else {
3295  cout<<endl<<"network::setSkyMask() - "
3296  <<"skymask file contains index > max L="<<L<<endl<<endl;
3297  exit(1);
3298  }
3299  }
3300  if(n!=L) {
3301  cout<<endl<<"network::setSkyMask() - "
3302  <<"the number of indexes in the skymask file != L="<<L<<endl<<endl;
3303  exit(1);
3304  }
3305 
3306  if(in!=NULL) fclose(in);
3307  return n;
3308 }
3309 
3310 // read celestial/earth skyMask coordinates from skymap
3311 size_t network::setSkyMask(skymap sm, char skycoord) {
3312 
3313  if(skycoord!='e' && skycoord!='c') {
3314  cout << "network::setSkyMask() - wrong input sky coordinates "
3315  << " must be 'e'/'c' earth/celestial" << endl;;
3316  exit(1);
3317  }
3318 
3319  size_t L = this->skyHole.size();
3320  if((int)sm.size()!=L) {
3321  cout << "network::setSkyMask() - wrong input skymap size "
3322  << sm.size() << " instead of " << L << endl;;
3323  exit(1);
3324  }
3325 
3326  if(skycoord=='e') {
3327  skyMask.resize(L);
3328  for(int i=0;i<L;i++) this->skyHole.data[i]=sm.get(i);
3329  }
3330  if(skycoord=='c') {
3331  skyMaskCC.resize(L);
3332  for(int i=0;i<L;i++) this->skyMaskCC.data[i]=sm.get(i);
3333  }
3334 
3335  return L;
3336 }
3337 
3338 // read MDC log file with list of injections
3339 size_t network::readMDClog(char* file, double gps, int nTime, int nName) {
3340  int i;
3341  size_t j;
3342  FILE* in;
3343  char str[1024];
3344  char STR[1024];
3345  char* p;
3346  bool save;
3347  double GPS;
3348 
3349  int imdcMap=0;
3350  std::map <string, int> mdcMap; // used to check uniqueness of mdc types
3351 
3352  if( (in=fopen(file,"r"))==NULL ) {
3353  cout<<"network::readMDClog() - no file is found \n";
3354  exit(1);
3355  }
3356 
3357  while(fgets(str,1024,in) != NULL){
3358 
3359  if(str[0] == '#') continue;
3360  sprintf(STR,"%s",str); // copy string
3361 
3362 // find and save injection gps time
3363 
3364  if((p = strtok(STR," \t")) == NULL) continue;
3365 
3366  for(i=1; i<nTime; i++) {
3367  p = strtok(NULL," \t"); // get gps time
3368  if(!p) break;
3369  }
3370 
3371  if(p) {
3372  GPS = atof(p);
3373  if(gps==0. || fabs(GPS-gps)<7200.) {
3374  this->mdcList.push_back(str);
3375  this->mdcTime.push_back(GPS);
3376  }
3377  }
3378 
3379 // find and save injection type
3380 
3381  if((p = strtok(str," \t")) == NULL) continue;
3382 
3383  for(i=1; i<nName; i++) {
3384  p = strtok(NULL," \t"); // get name
3385  if(!p) break;
3386  }
3387 
3388  if(p) if(mdcMap.find(p)==mdcMap.end()) mdcMap[p]=imdcMap++;
3389  }
3390 
3391  // copy mdc type to mdcType vector
3392  // the data are sorted keeping the back compatibility with the 1G algorithm
3393  this->mdcType.resize(mdcMap.size());
3394  std::map<std::string, int>::iterator iter;
3395  for (iter=mdcMap.begin(); iter!=mdcMap.end(); iter++) {
3396  this->mdcType[iter->second]=iter->first;
3397  }
3398  // print list
3399  for(int j=0;j<this->mdcType.size();j++) {
3400  int step=1;
3401  if(j<100) step=1;
3402  else if(j<10000) step=100;
3403  else step=1000;
3404  if(j%step==0) {
3405  printf("type %3d\t",(int)j);
3406  cout<<" has been assigned to waveform "<<mdcType[j]<<endl;
3407  }
3408  }
3409 
3410  return this->mdcList.size();
3411 }
3412 
3413 
3414 // read file with segment list
3415 size_t network::readSEGlist(char* file, int n) {
3416  int i;
3417  char str[1024];
3418  char* p;
3419  FILE* in;
3420  waveSegment SEG;
3421  SEG.index = 0;
3422 
3423  if( (in=fopen(file,"r"))==NULL ) {
3424  cout<<"network::readSEGlist(): specified segment file "<<file<<" does not exist\n";
3425  exit(1);
3426  }
3427 
3428  while(fgets(str,1024,in) != NULL){
3429 
3430  if(str[0] == '#') continue;
3431 
3432 // find and save segment start time
3433 
3434  if((p = strtok(str," \t")) == NULL) continue;
3435 
3436  for(i=1; i<n; i++) {
3437  p = strtok(NULL," \t"); // get start
3438  if(!p) break;
3439  }
3440 
3441  if(p) {
3442  SEG.index++;
3443  SEG.start = atof(p);
3444  p = strtok(NULL," \t"); // get stop
3445  if(!p) continue;
3446  SEG.stop = atof(p);
3447 // printf("%12.2f %12.2f \n",SEG.start,SEG.stop);
3448  this->segList.push_back(SEG);
3449  }
3450  }
3451  return this->segList.size();
3452 }
3453 
3454 
3455 // set veto array
3456 double network::setVeto(double Tw) {
3457 // set veto array from the input list of DQ segments
3458 // Tw - time window around injections
3459 //
3460 
3461  int j, jb, je, jm;
3462  size_t i,k;
3463  double gps, EE;
3464  double live = 0.;
3466  this->mdc__ID.clear();
3467 
3468  size_t I = this->ifoList.size();
3469  if(Tw<2.) Tw = 2.;
3470  detector* d = this->ifoList[0];
3471 
3472  int N = d->getTFmap()->size(); // TF data size
3473  int M = d->getHoT()->size(); // TS data size
3474  double R = (d->getTFmap()->pWavelet->m_WaveType==WDMT) ? // time series rate
3475  d->getHoT()->rate() : d->getTFmap()->rate();
3476  double S = d->getTFmap()->start(); // segment start time
3477  double E = d->getTFmap()->stop(); // segment end time
3478  size_t K = this->segList.size(); // segment list size
3479  size_t L = this->mdcList.size(); // injection list size
3480  size_t n = size_t(this->Edge*R+0.5); // data offset
3481  int W = int(Tw*R/2.+0.5); // injection window size
3482 
3483  if(M>2) N=M; // use size of TS object
3484  if(!I || !N) return 0.;
3485 
3486  if(this->veto.size() != size_t(N)) { // initialize veto array
3487  this->veto.resize(N);
3488  }
3489  this->veto = 0;
3490  w = this->veto;
3491 
3492  for(k=0; k<K; k++) { // loop over segmets
3493  gps = segList[k].start;
3494  if(gps<S) gps=S;
3495  if(gps>E) gps=E;
3496  j = int((gps-S)*R); // index in data array
3497  jb = j<0 ? 0 : j;
3498  gps = segList[k].stop;
3499  if(gps<S) gps=S;
3500  if(gps>E) gps=E;
3501  j = int((gps-S)*R); // index in data array
3502  je = j>N ? N : j;
3503  for(j=jb; j<je; j++) this->veto.data[j] = 1;
3504  }
3505 
3506  if(!K) this->veto = 1; // no segment list
3507 
3508  for(k=0; k<L; k++) { // loop over injections
3509  gps = mdcTime[k]; // get LOG injection time
3510  if(gps == 0.) continue;
3511 
3512  if(d->HRSS.size()) { // get MDC injection time
3513  gps = EE = 0.;
3514  for(i=0; i<I; i++) {
3515  d = this->ifoList[i];
3516  gps += d->TIME.data[k]*d->ISNR.data[k];
3517  EE += d->ISNR.data[k];
3518  }
3519  gps /= EE;
3520  mdcTime[k] = gps;
3521  }
3522 
3523  jm = int((gps-S)*R); // index in data array
3524  jb = jm-W; je = jm+W;
3525  if(jb < 0) jb = 0;
3526  if(jb >=N) continue;
3527  if(je > N) je = N;
3528  if(je <=0) continue;
3529  if(je-jb < int(R)) continue;
3530  if(jm<jb || jm>je) continue;
3531 
3532  for(j=jb; j<je; j++) w.data[j] = 1;
3533 
3534  if(veto.data[jm]) this->mdc__ID.push_back(k); // save ID of selected injections
3535  }
3536 
3537  if(L) this->veto *= w; // apply injection mask
3538  live = 0.;
3539  for(k=n; k<N-n; k++) live+=this->veto.data[k];
3540 
3541  return live/R;
3542 }
3543 
3544 // get reconstructed detector responses
3545 bool network::getwave(size_t ID, size_t lag, char atype)
3546 {
3547  int n,m;
3548  size_t i,j,k,l;
3549  double R = 0;
3550  size_t M = this->ifoList.size();
3551  bool flag = true;
3552 
3553  netcluster* wc = this->getwc(lag);
3554  detector* pd = this->getifo(0);
3555 
3556  Meyer<double> Me(256,1);
3557  WSeries<double> w(Me);
3558  WSeries<double> W;
3560  wavearray<double> id = wc->get((char*)"ID");
3561  std::vector<int> v;
3562 
3563  flag = false;
3564  for(j=0; j<id.size(); j++) {
3565  if(id.data[j] == ID) { flag=true; break; }
3566  }
3567 
3568  if(!flag) return false;
3569  flag = true;
3570 
3571  v = wc->nTofF[ID-1]; // backward time delay configuration
3572  k = pd->nDFS/pd->nDFL; // up-sample factor
3573  l = size_t(log(k*1.)/log(2.)+0.1); // wavelet level
3574 
3575 // time-of-flight backward correction for reconstructed waveforms
3576 
3577  for(i=0; i<M; i++) {
3578  pd = this->getifo(i);
3579  if(pd->getwave(ID,*wc,atype,i) == 0.) { flag=false; break; }
3580 
3581  R = pd->waveForm.rate();
3582 
3583  w.rate(R*k); x.rate(R);
3584  m = int(pd->waveForm.size());
3585  n = m/int(R+0.1)+4; // integer number of seconds
3586  n *= int(R+0.1); // total number of samples in layer 0
3587  if(n!=int(x.size())) x.resize(n);
3588  x = 0.; x.cpf(pd->waveForm,m,0,n/2);
3589  n *= k; // total number of up samples
3590  if(n!=int(w.size())) w.resize(n);
3591  w.setLevel(l); // set wavelet level
3592  w = 0.; w.putLayer(x,0); // prepare for upsampling
3593  w.Inverse(); // up-sample
3594  W = w; w = 0.;
3595 
3596  if(v[i]>0) { // time-shift waveform
3597  w.cpf(W,w.size()-v[i],0,v[i]); // v[i] - backward time delay
3598  }
3599  else {
3600  w.cpf(W,w.size()+v[i],-v[i]);
3601  }
3602 
3603  n = x.size();
3604  w.Forward(l);
3605  w.getLayer(x,0);
3606  pd->waveForm.cpf(x,m,n/2); // align waveforms
3607 
3608  x = pd->waveForm; // produce null stream
3609  w = pd->waveNull;
3610  x *= -1.;
3611  n = int((x.start()-w.start())*x.rate()+0.1);
3612  w.add(x,m,0,n);
3613  w.Forward(pd->TFmap.getLevel());
3614 
3615  pd->waveNull.resize(4*int(R+0.1)+x.size());
3616  pd->waveNull.setLevel(pd->TFmap.getLevel());
3617  pd->waveNull = 0.;
3618  pd->waveNull.start(x.start()-2.);
3619 
3620  n = int((pd->waveNull.start()-w.start())*w.rate()+0.1);
3621  m = pd->waveNull.size();
3622  if(n>=0) {
3623  if(n+m > (int)w.size()) m = w.size()-n;
3624  pd->waveNull.cpf(w,m,n,0);
3625  }
3626  else {
3627  m += n;
3628  if(m > (int)w.size()) m = w.size();
3629  pd->waveNull.cpf(w,m,0,-n);
3630  }
3631  }
3632  return flag;
3633 }
3634 
3635 bool network::getMRAwave(size_t ID, size_t lag, char atype, int mode, bool tof)
3636 {
3637 // get MRA waveforms of type atype in time domain given lag nomber and cluster ID
3638 // mode: -1/0/1 - return 90/mra/0 phase
3639 // if tof = true, apply time-of-flight corrections
3640 // fill in waveform arrays in the detector class
3641  size_t i,j;
3642  double R = 0;
3643  size_t nIFO = this->ifoList.size();
3644 
3645  netcluster* pwc = this->getwc(lag);
3646  wavearray<double> id = pwc->get((char*)"ID",0,'S',0);
3647 
3648  bool signal = (abs(atype)=='W' || abs(atype)=='w') ? false : true;
3649  bool flag = false;
3650 
3651  for(j=0; j<id.size(); j++) {
3652  if(size_t(id.data[j]+0.1) == ID) flag=true;
3653  }
3654  if(!flag) return false;
3655 
3657  std::vector<int> v;
3658 
3659  v = pwc->nTofF[ID-1]; // backward time delay configuration
3660 
3661  // time-of-flight backward correction for reconstructed waveforms
3662 
3663  for(i=0; i<nIFO; i++) {
3664 
3665  x = pwc->getMRAwave(this,ID,i,atype,mode);
3666  if(x.size() == 0.) {cout<<"zero length\n"; return false;}
3667 
3668 // apply time delay
3669 
3670  if(tof) {
3671  double R = this->rTDF; // effective time-delay rate
3672  double tShift = -v[i]/R;
3673 
3674  x.FFTW(1);
3675  TComplex C;
3676  double df = x.rate()/x.size();
3677  for (int ii=0;ii<(int)x.size()/2;ii++) {
3678  TComplex X(x.data[2*ii],x.data[2*ii+1]);
3679  X=X*C.Exp(TComplex(0.,-2*PI*ii*df*tShift)); // Time Shift
3680  x.data[2*ii]=X.Re();
3681  x.data[2*ii+1]=X.Im();
3682  }
3683  x.FFTW(-1);
3684  }
3685 
3686  if(signal) this->getifo(i)->waveForm = x;
3687  else this->getifo(i)->waveBand = x;
3688 
3689  }
3690  return flag;
3691 }
3692 
3693 //**************************************************************************
3694 // initialize wc_List for a selected TF area
3695 //**************************************************************************
3696 size_t network::initwc(double sTARt, double duration)
3697 {
3698  size_t i,j,m,k;
3699  double a;
3700  size_t npix = 0;
3701  bool save = false;
3702 
3703  size_t I = this->ifoList[0]->TFmap.maxLayer()+1;
3704  size_t R = size_t(this->ifoList[0]->getTFmap()->rate()/I+0.5);
3705  size_t N = this->ifoList[0]->getTFmap()->size();
3706  size_t M = this->ifoList.size(); // number of detectors
3707  size_t jB = size_t(this->Edge*R)*I; // number of samples in the edges
3708 
3709 // pointers
3710 
3711  std::vector<detector*> pDet; pDet.clear();
3712  std::vector<double*> pDat; pDat.clear();
3713  std::vector<int> pLag; pLag.clear();
3714 
3715  netpixel pix(M); // initialize pixel for M detectors
3716  pix.clusterID = 0; // initialize cluster ID
3717  pix.rate = float(R); // pixel rate
3718  pix.core = true; // pixel core
3719  pix.neighbors.push_back(0); // just one neighbor for each pixel
3720 
3721  for(m=0; m<M; m++) {
3722  pDet.push_back(ifoList[m]);
3723  pDat.push_back(ifoList[m]->getTFmap()->data);
3724  pLag.push_back(int(ifoList[m]->sHIFt*R*I+0.5));
3725  }
3726 
3727  size_t il = size_t(2.*pDet[0]->TFmap.getlow()/R); // low frequency boundary index
3728  size_t ih = size_t(2.*pDet[0]->TFmap.gethigh()/R); // high frequency boundary index
3729  if(ih==0 || ih>=I) ih = I;
3730 
3731  size_t J = size_t(sTARt*R+0.1); // start index in the slice
3732  size_t K = size_t(duration*R+0.1); // number of pixels in the slice
3733  slice S;
3734 
3735  this->wc_List[0].clear(); // clear wc_List
3736 
3737 // cout<<"il="<<il<<" ih"<<ih<<" K="<<K<<" J="<<J<<endl;
3738 
3739  for(i=il; i<ih; i++){ // loop over layers
3740  pix.frequency = i;
3741  S = pDet[0]->TFmap.getSlice(i);
3742 
3743  for(j=0; j<K; j++){ // loop over pixels
3744  pix.time = (J+j)*I + S.start(); // LTF pixel index in the map;
3745 
3746  if(pix.time >= N) {
3747  cout<<"network::initwc() error - index out of limit \n";
3748  continue;
3749  }
3750 
3751  pix.likelihood = 0.;
3752  save = true;
3753  for(m=0; m<M; m++) { // loop over detectors
3754  k = pix.time+pLag[m];
3755  if(k>=N) k -= N-jB;
3756  if(!this->veto.data[k]) save = false;
3757  a = pDat[m][k];
3758  pix.likelihood += a*a/2.;
3759  pix.setdata(a,'S',m); // set amplitude
3760  pix.setdata(k,'I',m); // set index
3761  pix.setdata(pDet[m]->getNoise(i,k),'N',m); // set noise RMS
3762  }
3763  pix.neighbors[0] = ++npix;
3764  if(save) this->wc_List[0].append(pix);
3765  }
3766 
3767  }
3768 
3769  wc_List[0].start = pDet[0]->TFmap.start();
3770  wc_List[0].stop = N/R/I;
3771  wc_List[0].rate = pDet[0]->TFmap.rate();
3772 
3773  if(npix) {
3774  this->wc_List[0].pList[npix-1].neighbors[0]=0;
3775  this->wc_List[0].cluster();
3776  }
3777  return npix;
3778 }
3779 
3780 
3781 //**************************************************************************
3782 //:select TF samples by value of the network likelihood: 2-NIFO detectors
3783 //**************************************************************************
3784 long network::coherence(double Eo, double Es, double factor)
3785 {
3786  size_t nIFO = this->ifoList.size(); // number of detectors
3787 
3788  if(nIFO>NIFO || !this->filter.size() || this->filter[0].index.size()!=32) {
3789  cout<<"network::coherence(): \n"
3790  <<"invalid number of detectors or\n"
3791  <<"delay filter is not set\n";
3792  return 0;
3793  }
3794  if(getifo(0)->getTFmap()->w_mode != 1) {
3795  cout<<"network::coherence(): invalid whitening mode.\n";
3796  return 0;
3797  }
3798 
3799  if(factor > 1.) factor = float(nIFO-1)/nIFO;
3800  Eo = nIFO*Eo*Eo; // lognormal threshold on total pixel energy
3801  Es = nIFO*Es*Es; // final threshold on pixel energy
3802 
3803  size_t i,j,k,m,n,l,NN;
3804  size_t jS,jj,nM,jE,LL;
3805 
3806  double R = this->ifoList[0]->getTFmap()->rate();
3807  size_t N = this->ifoList[0]->getTFmap()->size();
3808  size_t I = this->ifoList[0]->TFmap.maxLayer()+1;
3809  size_t M = this->filter.size()/I; // total number of delays
3810  size_t K = this->filter[0].index.size(); // length of delay filter
3811  size_t L = this->index.size(); // total number of source locations
3812  size_t jB = size_t(this->Edge*R/I)*I; // number of samples in the edges
3813  double band = this->ifoList[0]->TFmap.rate()/I/2.;
3814  slice S = getifo(0)->getTFmap()->getSlice(0); // 0 wavelet slice
3815 
3816  delayFilter* pv;
3817  netpixel pix(nIFO);
3818  pix.core = true;
3819  pix.rate = R/I;
3820  pix.layers = I;
3821 
3822 // pointers to data
3823 
3824  wavearray<int> inTF;
3825  wavearray<double> emax[NIFO];
3826  double* pdata[NIFO];
3827  double* pq;
3828  for(n=0; n<NIFO; n++) {
3829  emax[n].resize(S.size()); emax[n] = 0.;
3830  if(n >= nIFO) continue;
3831  pdata[n] = getifo(n)->getTFmap()->data;
3832  }
3833  inTF.resize(S.size()); inTF = 0;
3834 
3835 // allocate buffers
3836  wavearray<double> eD[NIFO]; // array for delayed amplitudes^2
3837  double* pe[NIFO];
3838  int in[NIFO];
3839  for(n=0; n<NIFO; n++) { eD[n].resize(M); eD[n] = 0.; pe[n] = eD[n].data; }
3840 
3841 // get sky index arrays
3842  wavearray<short> inDEx[NIFO];
3843  short* ina;
3844 
3845  LL = 0;
3846  for(l=0; l<L; l++) if(skyMask.data[l]) LL++;
3847  for(n=0; n<NIFO; n++) {
3848  inDEx[n].resize(LL);
3849  if(n>=nIFO) inDEx[n] = 0;
3850  else {
3851  k = 0;
3852  ina = this->getifo(n)->index.data;
3853  for(l=0; l<L; l++) {
3854  if(skyMask.data[l]) inDEx[n].data[k++] = ina[l];
3855  }
3856  }
3857  }
3858 
3859  NETX(
3860  short* m0 = inDEx[0].data; ,
3861  short* m1 = inDEx[1].data; ,
3862  short* m2 = inDEx[2].data; ,
3863  short* m3 = inDEx[3].data; ,
3864  short* m4 = inDEx[4].data; ,
3865  short* m5 = inDEx[5].data; ,
3866  short* m6 = inDEx[6].data; ,
3867  short* m7 = inDEx[7].data; )
3868 
3869 // buffer for wavelet layer delay filter
3870  double* pF = (double*)malloc(K*M*sizeof(double));
3871  int* pJ = (int*)malloc(K*M*sizeof(int));
3872  double* F;
3873  int* J;
3874 
3875 // sky time delays
3876 
3877  size_t M1[NIFO];
3878  size_t M2[NIFO];
3879  double t1,t2;
3880  size_t KK = this->filter.size()/I; // number of time delay samples
3881  for(n=0; n<nIFO; n++) {
3882  t1 = getifo(n)->tau.min()*R*getifo(0)->nDFS/I;
3883  t2 = getifo(n)->tau.max()*R*getifo(0)->nDFS/I;
3884  M1[n] = short(t1+KK/2+0.5)-1;
3885  M2[n] = short(t2+KK/2+0.5)+1;
3886  }
3887 
3888 // time shifts
3889 
3890  long nZero = 0;
3891  bool skip = false;
3892  size_t Io = 0; // counter of number of layers
3893  double a,b,E;
3894 
3895  this->pixeLHood = getifo(0)->TFmap;
3896  this->pixeLHood = 0.;
3897 
3898 // set veto array if it is not set
3899  if(this->veto.size() != N) { veto.resize(N); veto = 1; }
3900 
3901  N -= jB; // correction for left boundary
3902 
3903  for(k=0; k<nLag; k++) {
3904  this->wc_List[k].clear(); // clear netcluster structure
3905  this->livTime[k] = 0.; // clear live time counters
3906  this->wc_List[k].setlow(getifo(0)->TFmap.getlow());
3907  this->wc_List[k].sethigh(getifo(0)->TFmap.gethigh());
3908  }
3909 
3910  for(i=1; i<I; i++) { // loop over wavelet layers
3911 
3912 // select bandwidth
3913  a = i*band;
3914  if(a >= getifo(0)->TFmap.gethigh()) continue;
3915  a = (i+1)*band;
3916  if(a <= getifo(0)->TFmap.getlow()) continue;
3917 
3918  Io++;
3919 
3920 // set filter array for this layer
3921  for(m=0; m<M; m++){
3922  for(k=0; k<K; k++){
3923  pv = &(filter[i*M+m]);
3924  pF[k+m*K] = double(pv->value[k]);
3925  pJ[k+m*K] = int(pv->index[k]);
3926  }
3927  }
3928 
3929  S = getifo(0)->getTFmap()->getSlice(i);
3930 
3931  NN = S.size();
3932  for(n=0; n<NIFO; n++) { // resize arrays for max amplitudes
3933  if(emax[n].size() != NN) emax[n].resize(NN);
3934  emax[n] = 0; in[n] = 0;
3935  }
3936  if(inTF.size() != NN) inTF.resize(NN);
3937 
3938 // apply delay filters to calculate emax[]
3939 
3940  jS = S.start()+jB;
3941  NN = NN - jB/I;
3942  jE = NN - jB/I;
3943 
3944  for(n=0; n<nIFO; n++) {
3945 
3946  jj = jB/I;
3947 
3948  for(j=jS; j<N; j+=I) { // loop over samples in the layer
3949 
3950  emax[n].data[jj] = 0.;
3951  inTF.data[jj] = j; // store index in TF map
3952 
3953  F = pF+M1[n]*K;
3954  J = pJ+M1[n]*K;
3955  pq = pdata[n]+j;
3956 
3957  b = 0.;
3958  for(m=M1[n]; m<M2[n]; m++){
3959  a = dot32(F,pq,J); // delayed amplitude
3960  a *= a;
3961  if(b < a) b = a; // max energy
3962  F+=K; J+=K;
3963  }
3964  emax[n].data[jj++] = b;
3965  }
3966  }
3967 
3968 // select shifted amplitudes
3969 // regular case: jS.......j*********.....N
3970 // left boundary handling: jS***.............j*****N shift becomes negative
3971 
3972  for(k=0; k<nLag; k++) { // over lags
3973 
3974  a = 1.e10;
3975  nM = 0; // master detector
3976 
3977  for(n=0; n<nIFO; n++) {
3978  b = this->getifo(n)->lagShift.data[k]; // shift in seconds
3979  if(a>b) { a = b; nM = n; }
3980  }
3981 
3982  for(n=0; n<nIFO; n++) {
3983  b = this->getifo(n)->lagShift.data[k]; // shift in seconds
3984  in[n] = (int((b-a)*R)+jB)/I - 1; // index of first pixel in emax -1
3985  }
3986 
3987  for(jj=jB/I; jj<NN; jj++) { // loop over samples in the emax
3988 
3989  m = 0; E = 0.;
3990  for(n=0; n<nIFO; n++) {
3991  if((++in[n]) >= int(NN)) in[n] -= jE; // check boundaries
3992  m += this->veto.data[inTF.data[in[n]]]; // check data quality
3993  E += emax[n].data[in[n]];
3994  }
3995  this->livTime[k] += float(m/nIFO); // calculate live time for each lag
3996  if(E<Eo || m<nIFO) continue;
3997 
3998  skip = false;
3999  for(n=0; n<nIFO; n++) {
4000  b = E - emax[n].data[in[n]];
4001  if(b<Eo*factor) skip = true;
4002  }
4003  if(skip) continue;
4004 
4005 // calculate delays again and run skyloop.
4006 
4007  for(n=0; n<nIFO; n++) {
4008  F = pF+M1[n]*K;
4009  J = pJ+M1[n]*K;
4010  pq = pdata[n]+inTF.data[in[n]];
4011 
4012  for(m=M1[n]; m<M2[n]; m++){
4013  a = dot32(F,pq,J); // delayed amplitude
4014  pe[n][m] = a*a; // delayed energy
4015  F+=K; J+=K;
4016  }
4017  }
4018 
4019  skip = true;
4020  for(l=0; l<LL; l++) {
4021  double pet = 0.;
4022  NETX(
4023  pet+=pe[0][m0[l]]; ,
4024  pet+=pe[1][m1[l]]; ,
4025  pet+=pe[2][m2[l]]; ,
4026  pet+=pe[3][m3[l]]; ,
4027  pet+=pe[4][m4[l]]; ,
4028  pet+=pe[5][m5[l]]; ,
4029  pet+=pe[6][m6[l]]; ,
4030  pet+=pe[7][m7[l]]; )
4031  if(pet > Eo)
4032  { skip = false; break; }
4033  }
4034  if(skip) continue;
4035 
4036 // save pixels in wc_List
4037 
4038  j = inTF.data[in[nM]]; // index in TF
4039  pix.rate = float(R/I);
4040  pix.time = j;
4041  pix.core = E>Es ? true : false;
4042  pix.frequency = i;
4043  pix.likelihood = E;
4044 
4045  for(n=0; n<nIFO; n++) {
4046  pix.data[n].index = inTF.data[in[n]];
4047  pix.data[n].asnr = emax[n].data[in[n]];
4048  }
4049 
4050  wc_List[k].append(pix);
4051  if(!k) this->pixeLHood.data[j] = sqrt(E/nIFO);
4052  nZero++;
4053  }
4054  }
4055  }
4056 
4057 // set metadata in wc_List
4058  for(k=0; k<nLag; k++) {
4059  a = getifo(0)->getTFmap()->start();
4060  b = getifo(0)->getTFmap()->size()/R;
4061  this->wc_List[k].start = a;
4062  this->wc_List[k].stop = a+b;
4063  this->wc_List[k].rate = R;
4064  this->livTime[k] *= double(I)/(Io*R);
4065  }
4066 
4067  if(nZero) this->setRMS();
4068 
4069  free(pF); free(pJ);
4070 
4071  return nZero;
4072 }
4073 
4074 // calculate sky error regions
4075 void network::getSkyArea(size_t id, size_t lag, double To, double rMs) {
4076 // calculate sky error regions
4077 // new version designed for 2G analysis
4078 //!param: cluster id
4079 //!param: time lag
4080 //!param: cluster time
4081 //!param: rms correction: noise rms is 1+rMs
4082 
4083  int in,im,IN,IM;
4084  size_t i,j,l,m,k,K;
4085  size_t N = this->wc_List[lag].csize();
4086  size_t M = this->mdc__IDSize();
4087  size_t L = this->skyProb.size();
4088  size_t Lm = L-int(0.9999*L);
4089  size_t nIFO = this->ifoList.size(); // number of detectors
4090  bool prior = this->gamma<0?true:false; // gamma<0 : antenna pattern prior is used
4091  skymap* sm = &(this->nSkyStat);
4092 
4093  if(Lm < 2) return;
4094  if(nSky > long(L-Lm)) nSky = L-Lm;
4095  if(id>N) return;
4096 
4097  double th,ph,a;
4098  double sum = 0.;
4099  double vol = 0.;
4100  double co1 = cos(sm->theta_1*PI/180.);
4101  double co2 = cos(sm->theta_2*PI/180.);
4102  double phi = sm->phi_2-sm->phi_1;
4103  double s = fabs(phi*(co1-co2))*180/PI/sm->size(); // sky solid angle
4104 
4105  std::vector<float>* vf = &(this->wc_List[lag].sArea[id-1]);
4106  size_t v[11];
4107 
4108  double* p = this->skyProb.data;
4109  double** pp = (double **)malloc(L*sizeof(double*));
4110  for(l=0; l<L; l++) pp[l] = p + l;
4111 
4112  skyProb.waveSort(pp,0,L-1);
4113 
4114  double Po = *pp[L-1];
4115  double rms = fabs(rMs); // rms for method 2
4116 
4117  double smax=nAntenaPrior.max(); // max sensitivity
4118 
4119  for(l=0; l<L; l++) {
4120  if(*pp[l] <= 0.) {*pp[l]=0.; continue;}
4121  *pp[l] = exp(-(Po - *pp[l])/2./rms);
4122  if(prior) *pp[l] *= pow(nAntenaPrior.get(int(pp[l]-p))/smax,4);
4123  sum += *pp[l];
4124  }
4125  if(prior) skyProb.waveSort(pp,0,L-1);
4126 
4127  for(l=0; l<L; l++) {
4128  p[l] /= sum; // normalize map
4129  nProbability.set(l,p[l]); // fill in skyProb map
4130  }
4131 
4132  if(pOUT) cout<<rMs<<" "<<*pp[L-1]<<" "<<*pp[L-2]<<" "<<*pp[L-3]<<"\n";
4133 
4134  vf->clear();
4135  for(m=0; m<11; m++) { v[m] = 0; vf->push_back(0.); }
4136 
4137  vol = 0;
4138  for(l=L-1; l>Lm; l--){
4139  vol += *pp[l];
4140  for(m=size_t(vol*10.)+1; m<10; m++) v[m] += 1;
4141  if(vol >= 0.9) break;
4142  }
4143 
4144  for(m=1; m<10; m++) {
4145  (*vf)[m] = sqrt(v[m]*s);
4146  if(pOUT && !M) cout<<m<<" error region: "<<(*vf)[m]<<endl;
4147  }
4148 
4149 
4150 // fill skyProb skymap
4151 
4152  std::vector<float>* vP = &(this->wc_List[lag].p_Map[id-1]);
4153  std::vector<int>* vI = &(this->wc_List[lag].p_Ind[id-1]);
4154 
4155  K = 0;
4156  sum = 0.;
4157  vP->clear();
4158  vI->clear();
4159  double pthr=0;
4160  // if nSky -> nSky is converted into a probability threshold nSky=-XYZ... -> pthr=0.XYZ...
4161  if(nSky<0) {char spthr[1024];sprintf(spthr,"0.%d",int(abs(nSky)));pthr=atof(spthr);}
4162  for(l=L-1; l>Lm; l--){
4163  sum += *pp[l];
4164  if(nSky==0 && (K==1000 || sum > 0.99) && K>0) break;
4165  else if(nSky<0 && sum > pthr && K>0) break;
4166  else if(nSky>0 && K==nSky && K>0) break;
4167  K++;
4168  vI->push_back(int(pp[l]-p));
4169  vP->push_back(float(*pp[l]));
4170  }
4171 
4172 // set injections if there are any
4173 
4174  if(!M) { free(pp); return; }
4175 
4176  double dT = 1.e13;
4177  double injTime = 1.e12;
4178  int injID = -1;
4179  int mdcID = -1;
4180  injection INJ(this->ifoList.size());
4181 
4182  for(m=0; m<M; m++) {
4183  mdcID = this->getmdc__ID(m);
4184  dT = fabs(To - this->getmdcTime(mdcID));
4185  if(dT<injTime && INJ.fill_in(this,mdcID)) {
4186  injTime = dT;
4187  injID = mdcID;
4188  if(pOUT) printf("getSkyArea: %4d %12.4f %7.3f %f \n",int(m),To,dT,s);
4189  }
4190  }
4191 
4192  if(INJ.fill_in(this,injID)) {
4193 
4194  th = INJ.theta[0];
4195  ph = INJ.phi[0];
4196  i = this->getIndex(th,ph);
4197 
4198  vI->push_back(int(i));
4199  vP->push_back(float(p[i]));
4200 
4201  vol = sum = 0.;
4202  for(l=L-1; l>Lm; l--){
4203  vol += s;
4204  sum = Po - *pp[l];
4205  if(pp[l]-p == int(i)) break;
4206  }
4207  (*vf)[0] = sqrt(vol);
4208  (*vf)[10] = sum;
4209  j = pp[L-1]-p; // reference sky index at max
4210 
4211  if(pOUT) {
4212  printf("getSkyArea: %5d %12.4f %6.1f %6.1f %6.1f %6.1f %6.2f %6.2f %6.2f %7.5f, %e %d \n",
4213  int(id),INJ.time[0]-this->getifo(0)->TFmap.start(),INJ.theta[0],INJ.phi[0],
4214  sm->getTheta(j),sm->getPhi(j),(*vf)[0],(*vf)[5],(*vf)[9],(*vf)[10],p[i],int(i));
4215  }
4216  }
4217 
4218  free(pp);
4219  return;
4220 }
4221 
4222 
4223 // calculate sky error regions
4224 void network::getSkyArea(size_t id, size_t lag, double To) {
4225  int in,im,IN,IM;
4226  size_t i,j,l,m,k,K;
4227  size_t N = this->wc_List[lag].csize();
4228  size_t L = this->skyProb.size();
4229  size_t Lm = L-int(0.9999*L);
4230  skymap* sm = &(this->nSkyStat);
4231 
4232  if(Lm < 2) return;
4233  if(nSky > long(L-Lm)) nSky = L-Lm;
4234  if(id>N) return;
4235 
4236  double a,th,ph,st,sp;
4237  double TH,PH,ST,SP,Eo;
4238  double sum = 0.;
4239  double vol = 0.;
4240  double co1 = cos(sm->theta_1*PI/180.);
4241  double co2 = cos(sm->theta_2*PI/180.);
4242  double phi = sm->phi_2-sm->phi_1;
4243  double s = fabs(phi*(co1-co2))*180/PI/sm->size(); // sky solid angle
4244 
4245  std::vector<float>* vf = &(this->wc_List[lag].sArea[id-1]);
4246  size_t v[11];
4247 
4248  double* p = this->skyProb.data;
4249  double** pp = (double **)malloc(L*sizeof(double*));
4250  for(l=0; l<L; l++) pp[l] = p + l;
4251 
4252  skyProb.waveSplit(pp,0,L-1,Lm);
4253  skyProb.waveSort(pp,Lm,L-1);
4254 
4255  Eo = *pp[L-1]; // max L
4256  for(l=L-1; l>=Lm; l--) *pp[l] -= Eo;
4257  for(l=0; l<Lm; l++) *pp[l] = -1.e10;
4258 
4259 // correction for sky segmentation
4260 
4261  if(sm->getOrder()==0) { // is disabled for HEALPix skymap
4262  for(l=Lm; l<L; l++){
4263  j = pp[l]-p; // reference sky index
4264  th = sm->getTheta(j);
4265  ph = sm->getPhi(j);
4266  st = sm->getThetaStep(j);
4267 
4268  for(in=-1; in<2; in++) {
4269  sp = sm->getPhiStep(getIndex(th+in*st,ph));
4270  for(im=-1; im<2; im++) {
4271  i = this->getIndex(th+in*st,ph+im*sp); // neighbour sky index
4272  if(p[i] >= p[j] || p[i] < -1.e9) continue;
4273 
4274  TH = sm->getTheta(i);
4275  PH = sm->getPhi(i);
4276  ST = sm->getThetaStep(i);
4277  m = 0; a = 0.;
4278  for(IN=-1; IN<2; IN++) {
4279  SP = sm->getPhiStep(getIndex(TH+IN*ST,PH));
4280  for(IM=-1; IM<2; IM++) {
4281  k = this->getIndex(TH+IN*ST,PH+IM*SP); // neighbour sky index
4282  if(p[i] >=p[k]) continue;
4283  m++; a += p[k];
4284  }
4285  }
4286  if(m>3) p[i] = a/m;
4287  }
4288  }
4289  }
4290  skyProb.waveSplit(pp,0,L-1,Lm);
4291  skyProb.waveSort(pp,Lm,L-1);
4292  }
4293 
4294  skyENRG = 0.;
4295  Eo = *pp[L-2]*0.9; // max L
4296  sum = vol = 0.;
4297  for(l=L-2; l>=Lm; l--) {
4298  a = (Eo - *pp[l]);
4299  skyENRG.data[L-l-1] = a;
4300  if(a < pSigma || vol<1.) {
4301  sum += a/(L-l-1);
4302  vol += 1;
4303  }
4304  *pp[l] -= Eo;
4305  }
4306 
4307  if(pOUT) cout<<sum/vol<<" "<<*pp[L-2]<<" "<<*pp[L-3]<<" "<<*pp[0]<<"\n";
4308 
4309  Eo = sum/vol/2.;
4310  *pp[0] = exp(-30.);
4311  for(l=L-1; l>0; l--) {
4312  a = l>Lm ? (L-l-1)*Eo : 30.;
4313  if(a > 30.) a = 30.;
4314  *pp[l] = exp(-a); // calculate skyProb map
4315  }
4316 
4317  if(pOUT) cout<<"norm: "<<(skyProb.mean()*L)<<endl;
4318  skyProb *= 1./(skyProb.mean()*L);
4319  for(l=0; l<L; l++) nProbability.set(l,log10(p[l])); // fill in skyProb map
4320 
4321  vf->clear();
4322  for(m=0; m<11; m++) { v[m] = 0; vf->push_back(0.); }
4323 
4324  sum = 0.;
4325  for(l=L-1; l>Lm; l--){
4326  for(m=size_t(sum*10.)+1; m<10; m++) v[m] += 1;
4327  sum += *pp[l];
4328  if(sum >= 0.9) break;
4329  }
4330 
4331  for(m=1; m<10; m++) (*vf)[m] = sqrt(v[m]*s);
4332 
4333 // fill skyProb skymap
4334 
4335  std::vector<float>* vP = &(this->wc_List[lag].p_Map[id-1]);
4336  std::vector<int>* vI = &(this->wc_List[lag].p_Ind[id-1]);
4337 
4338  K = 0;
4339  sum = 0.;
4340  vP->clear();
4341  vI->clear();
4342  double pthr=0;
4343  // if nSky -> nSky is converted into a probability threshold nSky=-XYZ... -> pthr=0.XYZ...
4344  if(nSky<0) {char spthr[1024];sprintf(spthr,"0.%d",int(abs(nSky)));pthr=atof(spthr);}
4345  for(l=L-1; l>Lm; l--){
4346  sum += *pp[l];
4347  if(nSky==0 && (K==1000 || sum > 0.99) && K>0) break;
4348  else if(nSky<0 && sum > pthr && K>0) break;
4349  else if(nSky>0 && K==nSky && K>0) break;
4350  K++;
4351  vI->push_back(int(pp[l]-p));
4352  vP->push_back(float(*pp[l]));
4353  }
4354 
4355 // set injections if there are any
4356 
4357  size_t M = this->mdc__IDSize();
4358 
4359  if(!M) { free(pp); return; }
4360 
4361  double dT = 1.e13;
4362  double injTime = 1.e12;
4363  int injID = -1;
4364  int mdcID = -1;
4365  injection INJ(this->ifoList.size());
4366 
4367  for(m=0; m<M; m++) {
4368  mdcID = this->getmdc__ID(m);
4369  dT = fabs(To - this->getmdcTime(mdcID));
4370  if(dT<injTime && INJ.fill_in(this,mdcID)) {
4371  injTime = dT;
4372  injID = mdcID;
4373  if(pOUT) printf("getSkyArea: %4d %12.4f %7.3f %f \n",int(m),To,dT,s);
4374  }
4375  }
4376 
4377  if(INJ.fill_in(this,injID)) {
4378 
4379  th = INJ.theta[0];
4380  ph = INJ.phi[0];
4381  i = this->getIndex(th,ph);
4382 
4383  vI->push_back(int(i));
4384  vP->push_back(float(p[i]));
4385 
4386  vol = sum = 0.;
4387  for(l=L-1; l>Lm; l--){
4388  vol += s;
4389  sum += *pp[l];
4390  if(pp[l]-p == int(i)) break;
4391  }
4392  (*vf)[0] = sqrt(vol);
4393  (*vf)[10] = sum;
4394  j = pp[L-1]-p; // reference sky index at max
4395 
4396  if(pOUT) {
4397  printf("getSkyArea: %5d %12.4f %6.1f %6.1f %6.1f %6.1f %6.2f %6.2f %6.2f %7.5f, %e %d \n",
4398  int(id),INJ.time[0]-this->getifo(0)->TFmap.start(),INJ.theta[0],INJ.phi[0],
4399  sm->getTheta(j),sm->getPhi(j),(*vf)[0],(*vf)[5],(*vf)[9],(*vf)[10],p[i],int(i));
4400  }
4401  }
4402 
4403  free(pp);
4404  return;
4405 }
4406 
4407 //**************************************************************************
4408 // calculate network likelihood for constructed clusters: 2-NIFO detectors
4409 // It is designed to replace likelihood functions for 2,3,4 and NIFO networks.
4410 // If the network has less then NIFO detectors, all arrays are allocated for NIFO
4411 // detectors anyway. The arrays are initialized so that the dummy detectors
4412 // do not contribute into calculation of the coherent statistics.
4413 // Both general and elliptical constraint can be executed
4414 //**************************************************************************
4415 long network::likelihood(char type, double Ao, int ID, size_t lag, int ind, bool core)
4416 {
4417  size_t nIFO = this->ifoList.size();
4418  this->tYPe = type;
4419  this->acor = Ao;
4420  if(nIFO>NIFO || !this->filter.size() || this->filter[0].index.size()!=32) {
4421  cout<<"network::likelihood(): invalid number of detectors or delay filter is not set.\n";
4422  return false;
4423  }
4424  if(type=='b' || type=='B' || type=='E')
4425  return likelihoodB(type, Ao, ID, lag, ind, core);
4426  else
4427  return likelihoodI(type, Ao, ID, lag, ind, core);
4428 }
4429 
4430 
4431 //**************************************************************************
4432 // calculate network likelihood for constructed clusters: 2-NIFO detectors
4433 // It is a new implementation for likelihood functions for networks of 2,3,4,NIFO
4434 // detectors with improved constraints. If the network has less then NIFO detectors,
4435 // all arrays are allocated for NIFO detectors anyway. The arrays are initialized
4436 // so that the dummy detectors do not contribute into calculation of the coherent
4437 // statistics.
4438 //**************************************************************************
4439 long network::likelihoodB(char type, double Ao, int iID, size_t lag, int ind, bool core)
4440 {
4441  this->like('B');
4442 
4443  size_t nIFO = this->ifoList.size();
4444  size_t ID = abs(iID);
4445  int N_1 = nIFO>2 ? int(nIFO)-1 : 2;
4446  int N_2 = nIFO>2 ? int(nIFO)-2 : 1;
4447  if(nIFO>NIFO || !this->filter.size() || this->filter[0].index.size()!=32) {
4448  cout<<"network::likelihood(): invalid number of detectors or delay filter is not set.\n";
4449  return false;
4450  }
4451 
4452 // regulators hard <- soft <0> weak -> hard
4453 // gamma = -1 <- 0 -> 1
4454 // delta = 0 -> 1
4455 
4456  double Eo = nIFO*Ao*Ao; // energy threshold in the sky loop
4457  double soft = delta>0 ? delta : 0.;
4458  double GAMMA = 1.-gamma*gamma; // network regulator
4459 
4460  int LOCAL = local ? 1 : 0; // ED minimization case
4461  double rho = this->netRHO*this->netRHO*nIFO; // threshold on rho
4462 
4463  double gr,gp,gx,gR,gI,gc,gg,gP,gX,T,rm,Le,E,LPm;
4464  double STAT,P,EE,Et,Lo,Lm,hh,Xp,Xx,XX,Lp,Em,Ep;
4465  double S,co,si,cc,em,um,vm,uc,us,vc,vs,Co,Cp;
4466  NETX(double c0;,double c1;,double c2;,double c3;,double c4;,double c5;,double c6;,double c7;)
4467  double inet;
4468 
4469  if(type=='E' && Eo<nIFO) Eo = double(nIFO);
4470  if(!ID && ind>=0) ind = -1;
4471  this->tYPe = type;
4472  this->acor = Ao;
4473 
4474  int ii,II,IIm;
4475  size_t i,j,k,l,m,n,V,U,K,id;
4476  size_t I = this->ifoList[0]->TFmap.maxLayer()+1;
4477  size_t M = this->filter.size()/I; // total number of delays
4478  size_t L = ind<0 ? this->index.size() : ind+1; // total number of source locations
4479  int R = int(this->ifoList[0]->getTFmap()->rate()/I+0.5);
4480 
4481 // pointers to data
4482  double* pdata[NIFO];
4483  double* qdata[NIFO];
4484  double* pq;
4485  for(n=0; n<nIFO; n++) {
4486  pdata[n] = getifo(n)->getTFmap()->data;
4487  qdata[n] = getifo(n)->getTFmap()->data;
4488  }
4489 
4490 // buffer for wavelet layer delay filter
4491  std::vector<float>* F;
4492  std::vector<short>* J;
4493 
4494 // get antenna patterns and index arrays
4495  double* fp[NIFO]; // f+
4496  double* fx[NIFO]; // fx
4497  double* ffp[NIFO]; // f+f+ + fxfx
4498  double* ffm[NIFO]; // f+f+ - fxfx
4499  double* fpx[NIFO]; // 2*f+fx
4500  wavearray<double> f00(L); f00 = 0.; // dummy zero array
4501 
4502  for(n=0; n<NIFO; n++) {
4503  fp[n] = n<nIFO ? getifo(n)->fp.data : f00.data;
4504  fx[n] = n<nIFO ? getifo(n)->fx.data : f00.data;
4505  ffp[n] = n<nIFO ? getifo(n)->ffp.data : f00.data;
4506  ffm[n] = n<nIFO ? getifo(n)->ffm.data : f00.data;
4507  fpx[n] = n<nIFO ? getifo(n)->fpx.data : f00.data;
4508  }
4509 
4510  short* mm = this->skyMask.data;
4511  NETX(
4512  short* m0 = getifo(0)->index.data; ,
4513  short* m1 = nIFO>1 ? getifo(1)->index.data : getifo(1)->index.data; ,
4514  short* m2 = nIFO>2 ? getifo(2)->index.data : getifo(1)->index.data; ,
4515  short* m3 = nIFO>3 ? getifo(3)->index.data : getifo(1)->index.data; ,
4516  short* m4 = nIFO>4 ? getifo(4)->index.data : getifo(1)->index.data; ,
4517  short* m5 = nIFO>5 ? getifo(5)->index.data : getifo(1)->index.data; ,
4518  short* m6 = nIFO>6 ? getifo(6)->index.data : getifo(1)->index.data; ,
4519  short* m7 = nIFO>7 ? getifo(7)->index.data : getifo(1)->index.data; )
4520 
4521 // allocate buffers
4522  std::vector<size_t> pI;
4523 
4524  wavearray<double> aS[NIFO]; // single whitened amplitude
4525  wavearray<double> eS[NIFO]; // energy SNR
4526  wavearray<double> NV[NIFO]; // noise variance
4527  wavearray<double> NR[NIFO]; // noise rms
4528  wavearray<double> cid; // buffers for cluster ID
4529  wavearray<double> cTo; // buffers for cluster time
4530  wavearray<double> vol; // buffers for cluster volume
4531  wavearray<double> xi(500); // buffers for detector responses
4532  wavearray<short> jU(2500); // buffers for likelihood normalization factor
4533  wavearray<double> Fplus(2500); // buffers for F+
4534  wavearray<double> Fcros(2500); // buffers for Fx
4535 
4536  double* px;
4537  double* nv[NIFO];
4538  double* nr[NIFO];
4539  double* pe[NIFO];
4540  double* pa[NIFO];
4541  double pp[NIFO];
4542  double qq[NIFO];
4543  double am[NIFO];
4544  double Fp[NIFO];
4545  double Fx[NIFO];
4546  double ee[NIFO];
4547  double rr[NIFO];
4548  double e[NIFO];
4549  double u[NIFO];
4550  double v[NIFO];
4551  double r[NIFO];
4552 
4553  U = 500;
4554  for(n=0; n<NIFO; n++) {
4555  NV[n].resize(U); NV[n] = 0.; nv[n] = NV[n].data;
4556  NR[n].resize(U); NR[n] = 0.; nr[n] = NR[n].data;
4557  aS[n].resize(U*M); aS[n] = 0.;
4558  eS[n].resize(U*M); eS[n] = 0.;
4559  rr[n] = 1.;
4560  }
4561 
4562  netpixel* pix;
4563  std::vector<int>* vint;
4564  std::vector<int>* vtof;
4565 
4566  bool skip;
4567  double logbpp;
4568  size_t count = 0;
4569 
4570  S = 0.;
4571  if(ID) {
4572  this->pixeLHood = getifo(0)->TFmap;
4573  this->pixeLHood = 0.;
4574  this->pixeLNull = getifo(0)->TFmap;
4575  this->pixeLNull = 0.;
4576  this->nSensitivity = 0.;
4577  this->nAlignment = 0.;
4578  this->nNetIndex = 0.;
4579  this->nDisbalance = 0.;
4580  this->nLikelihood = 0.;
4581  this->nNullEnergy = 0.;
4582  this->nCorrEnergy = 0.;
4583  this->nCorrelation = 0.;
4584  this->nSkyStat = 0.;
4585  this->nPenalty = 0.;
4586  this->nProbability = 0.;
4587  this->nAntenaPrior = 0.;
4588  }
4589 
4590 //+++++++++++++++++++++++++++++++++++++++
4591 // liklihood calculation for clusters
4592 //+++++++++++++++++++++++++++++++++++++++
4593 
4594  for(n=lag; n<nLag; n++) { // loop over time shifts
4595 
4596  if(!this->wc_List[n].size()) continue;
4597  logbpp = -log(this->wc_List[n].getbpp());
4598 
4599  cid = this->wc_List[n].get((char*)"ID",0,'S',optim ? R : -R); // get cluster ID
4600  cTo = this->wc_List[n].get((char*)"time",0,'L',optim ? R : -R); // get cluster time
4601 
4602  K = cid.size();
4603 
4604  for(k=0; k<K; k++) { // loop over clusters
4605 
4606  id = size_t(cid.data[k]+0.1);
4607 
4608  if(ID && id!=ID) continue;
4609 
4610  vint = &(this->wc_List[n].cList[id-1]); // pixel list
4611  vtof = &(this->wc_List[n].nTofF[id-1]); // TofFlight configurations
4612 
4613  V = vint->size();
4614  if(!V) continue;
4615 
4616  pI.clear();
4617 
4618  for(j=0; j<V; j++) { // loop over pixels
4619 
4620  pix = this->wc_List[n].getPixel(id,j);
4621 
4622  if(!pix) {
4623  cout<<"network::likelihood() error: NULL pointer"<<endl;
4624  exit(1);
4625  }
4626 
4627  if(R != int(pix->rate+0.5)) continue; // check rate
4628  if(!pix->core && core) continue; // check core flag
4629 
4630  pI.push_back(j); // save pixel index
4631 
4632  }
4633 
4634  V = pI.size();
4635  if(!V) continue;
4636 
4637  if(NV[0].size() < V) { // reallocate arrays
4638  U = V+100;
4639  for(i=0; i<NIFO; i++) {
4640  NV[i].resize(U); NV[i] = 0.; nv[i] = NV[i].data;
4641  NR[i].resize(U); NR[i] = 0.; nr[i] = NR[i].data;
4642  eS[i].resize(U*M); eS[i] = 0.;
4643  aS[i].resize(U*M); aS[i] = 0.;
4644  }
4645  jU.resize(U); xi.resize(U*NIFO);
4646  Fplus.resize(U*NIFO); Fcros.resize(U*NIFO);
4647  }
4648 
4649  for(j=0; j<V; j++) { // loop over selected pixels
4650 
4651  pix = this->wc_List[n].getPixel(id,pI[j]);
4652 
4653  cc = 0.;
4654  for(i=0; i<nIFO; i++) {
4655  ee[i] = 1./pix->data[i].noiserms;
4656  cc += ee[i]*ee[i]; // total inverse variance
4657  }
4658 
4659  for(i=0; i<nIFO; i++) {
4660  nv[i][j] = ee[i]*ee[i]; // inverse variance
4661  nr[i][j] = ee[i]/sqrt(cc); // normalized 1/rms
4662  qdata[i] = pdata[i] + pix->data[i].index; // pointer to data
4663  }
4664 
4665 // apply delay filter
4666 
4667  for(i=0; i<nIFO; i++) {
4668  pq = qdata[i];
4669 
4670  for(m=0; m<M; m++){ // loop over delays
4671  F = &(filter[pix->frequency*M+m].value);
4672  J = &(filter[pix->frequency*M+m].index);
4673  l = m*V + j;
4674 
4675  gg = dot32(F,pq,J); // apply filter
4676 
4677  eS[i].data[l] = gg*gg;
4678  aS[i].data[l] = gg;
4679  }
4680  }
4681  }
4682 
4683  STAT = -1.e64; m=IIm=0; Lm=Em=LPm= 0.;
4684 
4685 // Max Energy
4686 
4687  if(type == 'E') {
4688 
4689  skip = true;
4690  l = ind<0 ? 0 : ind; // process selected index
4691  for(; l<L; l++) { // loop over sky locations
4692  if(!mm[l]) continue; // skip identical delay configurations
4693 
4694  NETX(
4695  pe[0] = eS[0].data + m0[l]*V; ,
4696  pe[1] = eS[1].data + m1[l]*V; ,
4697  pe[2] = eS[2].data + m2[l]*V; ,
4698  pe[3] = eS[3].data + m3[l]*V; ,
4699  pe[4] = eS[4].data + m4[l]*V; ,
4700  pe[5] = eS[5].data + m5[l]*V; ,
4701  pe[6] = eS[6].data + m6[l]*V; ,
4702  pe[7] = eS[7].data + m7[l]*V; )
4703 
4704  NETX(c0=0.;,c1=0.;,c2=0.;,c3=0.;,c4=0.;,c5=0.;,c6=0.;,c7=0.;)
4705  i=0;
4706  for(j=0; j<V; j++) { // loop over selected pixels
4707  double pet = 0.;
4708  NETX(
4709  pet+=pe[0][j]; ,
4710  pet+=pe[1][j]; ,
4711  pet+=pe[2][j]; ,
4712  pet+=pe[3][j]; ,
4713  pet+=pe[4][j]; ,
4714  pet+=pe[5][j]; ,
4715  pet+=pe[6][j]; ,
4716  pet+=pe[7][j]; )
4717  if(pet > Eo) {
4718  NETX(
4719  c0 += pe[0][j]; ,
4720  c1 += pe[1][j]; ,
4721  c2 += pe[2][j]; ,
4722  c3 += pe[3][j]; ,
4723  c4 += pe[4][j]; ,
4724  c5 += pe[5][j]; ,
4725  c6 += pe[6][j]; ,
4726  c7 += pe[7][j]; )
4727  i++;
4728  }
4729  }
4730 
4731  E = 0.; NETX(E+=c0;,E+=c1;,E+=c2;,E+=c3;,E+=c4;,E+=c5;,E+=c6;,E+=c7;) E-=i*nIFO; // correction for dummy detectors
4732  if(E>STAT) { m = l; STAT = E; Lm = E; } // maximize energy
4733  E += i;
4734  if(NETX(E-c0>e2or &&,E-c1>e2or &&,E-c2>e2or &&,E-c3>e2or &&,E-c4>e2or &&,E-c5>e2or &&,E-c6>e2or &&,E-c7>e2or &&) true) skip = false;
4735  }
4736  if(skip) { this->wc_List[n].ignore(id); continue; }
4737  }
4738 
4739 // constraint: total (XkSk-ekSkSk)/Ek = 0
4740 
4741  else {
4742 
4743  l = ind<0 ? 0 : ind; // process selected index
4744  for(; l<L; l++) { // loop over sky locations
4745 
4746  skyProb.data[l] = 0.;
4747 
4748  if(skyMaskCC.size()==L) {
4749  // transform l in celestial coordinates cc_l and check the skyMaskCC
4750  skymap* sm = &(this->nSkyStat);
4751  double th = sm->getTheta(l);
4752  double ph = sm->getPhi(l);
4753  double gpsT = cTo.data[k]+getifo(0)->TFmap.start(); // trigger time
4754  double ra = sm->phi2RA(ph, gpsT);
4755  int cc_l = this->getIndex(th,ra);
4756  if (skyMaskCC.data[cc_l]<=0) continue;
4757  }
4758 
4759  if(!mm[l] && ind<0) continue; // skip sky configurations
4760 
4761  NETX(
4762  pa[0] = aS[0].data + m0[l]*V; , // single whitening
4763  pa[1] = aS[1].data + m1[l]*V; ,
4764  pa[2] = aS[2].data + m2[l]*V; ,
4765  pa[3] = aS[3].data + m3[l]*V; ,
4766  pa[4] = aS[4].data + m4[l]*V; ,
4767  pa[5] = aS[5].data + m5[l]*V; ,
4768  pa[6] = aS[6].data + m6[l]*V; ,
4769  pa[7] = aS[7].data + m7[l]*V; )
4770 
4771 // weak constraint
4772 // transformation to PCF,
4773 // u = [X x (f+ x fx)] x (f+ x fx)
4774 // u/(|u|*|X|) is a unity vector along the projection of X
4775 // u = Fp*uc + Fx*us
4776 
4777 
4778  EE=Lo=Co=Ep=Lp=Cp=inet = 0.; II=0;
4779 
4780  for(j=0; j<V; j++) { // loop over selected pixels
4781 
4782  Et = dotx(pa,j,pa,j); // total energy
4783  ii = int(Et>Eo);
4784  EE+= Et*ii;
4785 
4786  mulx(fp,l,nr,j,Fp);
4787  mulx(fx,l,nr,j,Fx);
4788 
4789  gp = dotx(Fp,Fp)+1.e-12; // fp^2
4790  gx = dotx(Fx,Fx)+1.e-12; // fx^2
4791  gI = dotx(Fp,Fx); // fp*fx
4792  Xp = dotx(Fp,pa,j); // (X*f+)
4793  Xx = dotx(Fx,pa,j); // (X*fx)
4794  uc = Xp*gx - Xx*gI; // u cos of rotation to PCF
4795  us = Xx*gp - Xp*gI; // u sin of rotation to PCF
4796  um = rotx(Fp,uc,Fx,us,u); // calculate u and return its norm
4797  hh = dotx(u,pa,j,e); // (u*X) - not normalized
4798  Le = hh*hh/um;
4799  cc = Le-dotx(e,e)/um;
4800  ii*= int(cc>0);
4801 
4802  Lp+= Le*cc*ii/(Et-Le+1+cc); // effective likelihood
4803  Ep+= Et*ii;
4804  Lo+= Le*ii; // baseline Likelihood
4805  Co+= cc*ii; // coherent energy
4806  II+= ii;
4807  mulx(u,hh*ii/um,xi.data+j*NIFO);
4808 
4809  }
4810 
4811  cc = Ep>0 ? Co/(Ep-Lo+II+fabs(Co)) : 0.;
4812  if(type=='B') Lp = Lo*cc;
4813 
4814  skyProb.data[l] = Lp/EE;
4815 
4816  if(Lp>LPm) { LPm=Lp; Em=EE; IIm=II; }
4817 
4818  cc = EE>0 ? Co/(EE-Lo+II+fabs(Co)) : 0.;
4819  if(cc<this->netCC || cc*Co<rho) continue;
4820 
4821 // weak and hard regulators used for estimation of u
4822 // v = u x (f+ x fx) is a vector perpendicular to u
4823 // u = Fp*uc + Fx*us, v = Fx*vc - Fp*vs
4824 
4825  Lo=Co=gP=gX = 0.;
4826 
4827  for(j=0; j<V; j++) { // loop over selected pixels
4828 
4829  NETX(
4830  am[0] = pa[0][j]; ,
4831  am[1] = pa[1][j]; ,
4832  am[2] = pa[2][j]; ,
4833  am[3] = pa[3][j]; ,
4834  am[4] = pa[4][j]; ,
4835  am[5] = pa[5][j]; ,
4836  am[6] = pa[6][j]; ,
4837  am[7] = pa[7][j]; )
4838 
4839  px = xi.data+j*NIFO;
4840  if(dotx(px,px)<=0) continue;
4841  Et = dotx(am,am);
4842 
4843  mulx(fp,l,nr,j,Fp);
4844  mulx(fx,l,nr,j,Fx);
4845 
4846  gp = dotx(Fp,Fp)+1.e-12; // fp^2
4847  gx = dotx(Fx,Fx)+1.e-12; // fx^2
4848  gI = dotx(Fp,Fx); // fp*fx
4849  gr = (gp+gx)/2.; // sensitivity
4850  gR = (gp-gx)/2.; // real part of gc
4851  gc = sqrt(gR*gR+gI*gI); // norm of complex antenna pattern
4852 
4853  Xp = dotx(Fp,am); // (X*f+)
4854  Xx = dotx(Fx,am); // (X*fx)
4855  uc = Xp*gx - Xx*gI; // u cos of rotation to PCF
4856  us = Xx*gp - Xp*gI; // u sin of rotation to PCF
4857  vc = gp*uc + gI*us; // (u*f+)/|u|^2 - 'cos' for v
4858  vs = gx*us + gI*uc; // (u*fx)/|u|^2 - 'sin' for v
4859  um = rotx(Fp,uc,Fx,us,u); // calculate new response vector
4860  vm = rotx(Fx,-vc,Fp,vs,v)+1.e-24; // calculate complementary vector
4861 
4862 // regulator
4863 
4864  ii = netx(u,um,v,vm,GAMMA); // network index
4865  inet += ii*Et;
4866  if(ii<N_2 && gamma<0) continue; // superclean selection cut
4867 
4868  gP+= (gr+gc)*Et; // + sensitivity
4869  gX+= (gr-gc)*Et; // x sensitivity
4870  gg = (gp+gx)*soft;
4871  uc = Xp*(gx+gg) - Xx*gI; // u cos of rotation to PCF
4872  us = Xx*(gp+gg) - Xp*gI; // u sin of rotation to PCF
4873 
4874  if(ii<N_1 && gamma!=0) {
4875  uc = Xp*(gc+gR)+Xx*gI;
4876  us = Xx*(gc-gR)+Xp*gI;
4877  }
4878 
4879  vc = gp*uc + gI*us; // (u*f+)/|u|^2 - 'cos' for v
4880  vs = gx*us + gI*uc; // (u*fx)/|u|^2 - 'sin' for v
4881  um = rotx(Fp,uc,Fx,us,u); // calculate new response vector
4882  vm = rotx(Fx,-vc,Fp,vs,v)+1.e-24; // calculate complementary vector
4883 
4884 // energy disbalance ratio vectors
4885 
4886  NETX (
4887  rr[0] = LOCAL*am[0]/(am[0]*am[0]+2.)+1-LOCAL; ,
4888  rr[1] = LOCAL*am[1]/(am[1]*am[1]+2.)+1-LOCAL; ,
4889  rr[2] = LOCAL*am[2]/(am[2]*am[2]+2.)+1-LOCAL; ,
4890  rr[3] = LOCAL*am[3]/(am[3]*am[3]+2.)+1-LOCAL; ,
4891  rr[4] = LOCAL*am[4]/(am[4]*am[4]+2.)+1-LOCAL; ,
4892  rr[5] = LOCAL*am[5]/(am[5]*am[5]+2.)+1-LOCAL; ,
4893  rr[6] = LOCAL*am[6]/(am[6]*am[6]+2.)+1-LOCAL; ,
4894  rr[7] = LOCAL*am[7]/(am[7]*am[7]+2.)+1-LOCAL; )
4895 
4896  hh = dotx(u,am)/um;
4897  NETX (
4898  pp[0] = rr[0]*(am[0]-hh*u[0])*u[0]; ,
4899  pp[1] = rr[1]*(am[1]-hh*u[1])*u[1]; ,
4900  pp[2] = rr[2]*(am[2]-hh*u[2])*u[2]; ,
4901  pp[3] = rr[3]*(am[3]-hh*u[3])*u[3]; ,
4902  pp[4] = rr[4]*(am[4]-hh*u[4])*u[4]; ,
4903  pp[5] = rr[5]*(am[5]-hh*u[5])*u[5]; ,
4904  pp[6] = rr[6]*(am[6]-hh*u[6])*u[6]; ,
4905  pp[7] = rr[7]*(am[7]-hh*u[7])*u[7]; )
4906 
4907  gg = dotx(v,am)/um;
4908  hh*= 2.;
4909  NETX (
4910  qq[0] = rr[0]*((hh*u[0]-am[0])*v[0]+u[0]*u[0]*gg); ,
4911  qq[1] = rr[1]*((hh*u[1]-am[1])*v[1]+u[1]*u[1]*gg); ,
4912  qq[2] = rr[2]*((hh*u[2]-am[2])*v[2]+u[2]*u[2]*gg); ,
4913  qq[3] = rr[3]*((hh*u[3]-am[3])*v[3]+u[3]*u[3]*gg); ,
4914  qq[4] = rr[4]*((hh*u[4]-am[4])*v[4]+u[4]*u[4]*gg); ,
4915  qq[5] = rr[5]*((hh*u[5]-am[5])*v[5]+u[5]*u[5]*gg); ,
4916  qq[6] = rr[6]*((hh*u[6]-am[6])*v[6]+u[6]*u[6]*gg); ,
4917  qq[7] = rr[7]*((hh*u[7]-am[7])*v[7]+u[7]*u[7]*gg); )
4918 
4919  co = dotx(qq,qq)/vm+dotx(pp,pp)/um+1.e-24; // cos term
4920  si = dotx(pp,qq); // sin term
4921  if(!eDisbalance) {co=1.;si=0.;}
4922  em = rotx(u,co,v,si/vm,e); // calculate rotated vector e
4923 
4924 // second iteration
4925 
4926  rm = rotx(v,co,u,-si/um,r)+1.e-24; // calculate rotated vector v
4927  hh = dotx(e,am)/em;
4928 
4929  NETX (
4930  pp[0] = rr[0]*(am[0]-hh*e[0])*e[0]; ,
4931  pp[1] = rr[1]*(am[1]-hh*e[1])*e[1]; ,
4932  pp[2] = rr[2]*(am[2]-hh*e[2])*e[2]; ,
4933  pp[3] = rr[3]*(am[3]-hh*e[3])*e[3]; ,
4934  pp[4] = rr[4]*(am[4]-hh*e[4])*e[4]; ,
4935  pp[5] = rr[5]*(am[5]-hh*e[5])*e[5]; ,
4936  pp[6] = rr[6]*(am[6]-hh*e[6])*e[6]; ,
4937  pp[7] = rr[7]*(am[7]-hh*e[7])*e[7]; )
4938 
4939  gg = dotx(r,am)/em;
4940  hh*= 2.;
4941  NETX (
4942  qq[0] = rr[0]*((hh*e[0]-am[0])*r[0]+e[0]*e[0]*gg); ,
4943  qq[1] = rr[1]*((hh*e[1]-am[1])*r[1]+e[1]*e[1]*gg); ,
4944  qq[2] = rr[2]*((hh*e[2]-am[2])*r[2]+e[2]*e[2]*gg); ,
4945  qq[3] = rr[3]*((hh*e[3]-am[3])*r[3]+e[3]*e[3]*gg); ,
4946  qq[4] = rr[4]*((hh*e[4]-am[4])*r[4]+e[4]*e[4]*gg); ,
4947  qq[5] = rr[5]*((hh*e[5]-am[5])*r[5]+e[5]*e[5]*gg); ,
4948  qq[6] = rr[6]*((hh*e[6]-am[6])*r[6]+e[6]*e[6]*gg); ,
4949  qq[7] = rr[7]*((hh*e[7]-am[7])*r[7]+e[7]*e[7]*gg); )
4950 
4951  co = dotx(qq,qq)/rm+dotx(pp,pp)/em+1.e-24; // cos term
4952  si = dotx(pp,qq); // sin term
4953  if(!eDisbalance) {co=1.;si=0.;}
4954  em = rotx(e,co,r,si/rm,e); // calculate ED vector
4955  hh = dotx(e,am,ee); // ee[i] = e[i]*am[i]
4956  Lo+= hh*hh/em; // corrected L
4957  Co+= (hh*hh-dotx(ee,ee))/em; // coherent energy
4958 
4959  }
4960 
4961 // <x*xi> penalty factor and asymmetry
4962 
4963  NETX(pp[0]=0.;,pp[1]=0.;,pp[2]=0.;,pp[3]=0.;,pp[4]=0.;,pp[5]=0.;,pp[6]=0.;,pp[7]=0.;)
4964  NETX(qq[0]=0.001;,qq[1]=0.001;,qq[2]=0.001;,qq[3]=0.001;,qq[4]=0.001;,qq[5]=0.001;,qq[6]=0.001;,qq[7]=0.001;)
4965  NETX(ee[0]=0.;,ee[1]=0.;,ee[2]=0.;,ee[3]=0.;,ee[4]=0.;,ee[5]=0.;,ee[6]=0.;,ee[7]=0.;)
4966 
4967  for(j=0; j<V; j++) { // loop over selected pixels
4968  px = xi.data+j*NIFO;
4969  addx(px,px,qq);
4970  addx(px,pa,j,pp);
4971  addx(pa,j,pa,j,ee);
4972  }
4973 
4974  S = 0.;
4975  NETX (
4976  S+= fabs(pp[0]-qq[0]); ,
4977  S+= fabs(pp[1]-qq[1]); ,
4978  S+= fabs(pp[2]-qq[2]); ,
4979  S+= fabs(pp[3]-qq[3]); ,
4980  S+= fabs(pp[4]-qq[4]); ,
4981  S+= fabs(pp[5]-qq[5]); ,
4982  S+= fabs(pp[6]-qq[6]); ,
4983  S+= fabs(pp[7]-qq[7]); )
4984 
4985  NETX (
4986  pp[0] /= sqrt(qq[0]); ,
4987  pp[1] /= sqrt(qq[1]); ,
4988  pp[2] /= sqrt(qq[2]); ,
4989  pp[3] /= sqrt(qq[3]); ,
4990  pp[4] /= sqrt(qq[4]); ,
4991  pp[5] /= sqrt(qq[5]); ,
4992  pp[6] /= sqrt(qq[6]); ,
4993  pp[7] /= sqrt(qq[7]); )
4994 
4995  hh = 0.;
4996  NETX (
4997  hh+= pp[0]; ,
4998  hh+= pp[1]; ,
4999  hh+= pp[2]; ,
5000  hh+= pp[3]; ,
5001  hh+= pp[4]; ,
5002  hh+= pp[5]; ,
5003  hh+= pp[6]; ,
5004  hh+= pp[7]; )
5005  gg = 0.;
5006  NETX (
5007  gg+= sqrt(ee[0]); ,
5008  gg+= sqrt(ee[1]); ,
5009  gg+= sqrt(ee[2]); ,
5010  gg+= sqrt(ee[3]); ,
5011  gg+= sqrt(ee[4]); ,
5012  gg+= sqrt(ee[5]); ,
5013  gg+= sqrt(ee[6]); ,
5014  gg+= sqrt(ee[7]); )
5015 
5016  P = hh/gg; // Pearson's correlation penalty
5017  cc = Co/(EE-Lo+fabs(Co)); // network correlation coefficient
5018  XX = Lo*cc/EE; // sky statistic
5019 
5020  skyProb.data[l] *= P;
5021 
5022  if(XX>=STAT) { m=l; STAT=XX; Lm=Lo; }
5023 
5024  if(ID) { // fill in skymaps
5025  this->nAntenaPrior.set(l, gP/EE);
5026  this->nSensitivity.set(l, gP/EE);
5027  this->nAlignment.set(l, gX/EE);
5028  this->nNetIndex.set(l, inet/EE);
5029  this->nDisbalance.set(l, S);
5030  this->nLikelihood.set(l, Lo);
5031  this->nNullEnergy.set(l, (EE-Lo));
5032  this->nCorrEnergy.set(l, Co);
5033  this->nCorrelation.set(l, cc);
5034  this->nSkyStat.set(l, XX);
5035  this->nPenalty.set(l, P);
5036  this->nProbability.set(l,skyProb.data[l]);
5037  }
5038  }
5039 
5040  if(STAT<=0.001 && ind<0) {
5041  this->wc_List[n].ignore(id); // reject cluster
5042  continue;
5043  }
5044  }
5045 
5046 // final calculation of likelihood for selected sky location
5047 
5048  Lo = E = 0.;
5049  l = ind<0 ? m : ind;
5050 
5051  NETX (
5052  pa[0] = aS[0].data + m0[l]*V; , // single whitening
5053  pa[1] = aS[1].data + m1[l]*V; ,
5054  pa[2] = aS[2].data + m2[l]*V; ,
5055  pa[3] = aS[3].data + m3[l]*V; ,
5056  pa[4] = aS[4].data + m4[l]*V; ,
5057  pa[5] = aS[5].data + m5[l]*V; ,
5058  pa[6] = aS[6].data + m6[l]*V; ,
5059  pa[7] = aS[7].data + m7[l]*V; )
5060 
5061 // initialize detector energy array
5062 
5063  for(j=0; j<V; j++) { // loop over selected pixels
5064 
5065  Et = 0.; U = 1;
5066  for(i=0; i<nIFO; i++) {
5067  am[i] = pa[i][j];
5068  Fp[i] = fp[i][l]*nr[i][j];
5069  Fx[i] = fx[i][l]*nr[i][j];
5070  Et += am[i]*am[i];
5071  if(!j) ee[i] = 0.;
5072  }
5073 
5074  gp = dotx(Fp,Fp)+1.e-12; // (fp^2)
5075  gx = dotx(Fx,Fx)+1.e-12; // (fx^2)
5076  gI = dotx(Fp,Fx); // (fp*fx)
5077  Xp = dotx(Fp,am); // (X*f+)
5078  Xx = dotx(Fx,am); // (X*fx)
5079  gR = (gp-gx)/2.;
5080  gc = sqrt(gR*gR+gI*gI); // norm of complex antenna pattern
5081  uc = Xp*gx - Xx*gI; // u cos
5082  us = Xx*gp - Xp*gI; // u sin
5083  vc = gp*uc + gI*us; // (u*f+)/|u|^2 - 'cos' for v
5084  vs = gx*us + gI*uc; // (u*fx)/|u|^2 - 'sin' for v
5085  um = rotx(Fp,uc,Fx,us,u); // calculate u and return its norm
5086  vm = rotx(Fx,-vc,Fp,vs,v)+1.e-24; // calculate v and return its norm
5087  hh = dotx(u,am,e); // GW amplitude
5088 
5089  if((hh*hh-dotx(e,e))/um<=0.) U=0;
5090 
5091 // regulator
5092 
5093  ii = 0;
5094  for(i=0; i<nIFO; i++) {
5095  if(u[i]*u[i]/um > 1-GAMMA) ii++;
5096  if(u[i]*u[i]/um+v[i]*v[i]/vm > GAMMA) ii--;
5097  }
5098 
5099  if(ii<N_2 && gamma<0.) U = 0;
5100 
5101  gg = (gp+gx)*soft;
5102  uc = Xp*(gx+gg) - Xx*gI; // u cos of rotation to PCF
5103  us = Xx*(gp+gg) - Xp*gI; // u sin of rotation to PCF
5104 
5105  if(ii<N_1 && gamma!=0) {
5106  uc = Xp*(gc+gR)+Xx*gI;
5107  us = Xx*(gc-gR)+Xp*gI;
5108  }
5109 
5110  vc = (gp*uc + gI*us); // (u*f+)/|u|^2 - 'cos' for v
5111  vs = (gx*us + gI*uc); // (u*fx)/|u|^2 - 'sin' for v
5112  um = rotx(Fp,uc,Fx,us,u); // calculate u and return its norm
5113  vm = rotx(Fx,-vc,Fp,vs,v)+1.e-24; // calculate v and return its norm
5114 
5115 // normalize u and v vectors
5116 
5117  um = sqrt(um);
5118  vm = sqrt(vm);
5119 
5120  hh = gg = 0.;
5121  for(i=0; i<nIFO; i++) {
5122  u[i] = u[i]/um;
5123  v[i] = v[i]/vm;
5124  hh += u[i]*am[i]; // (u*X) - solution
5125  gg += v[i]*am[i]; // (v*X) - solution
5126  }
5127 
5128 // calculate energy disbalance vectors
5129 
5130  co=si=0.;
5131  for(i=0; i<nIFO; i++) { // disbalance vectors
5132  cc = local ? am[i]/(am[i]*am[i]+2.) : 1.;
5133  pp[i] = cc*(am[i]-hh*u[i])*u[i];
5134  qq[i] = cc*((2.*hh*u[i]-am[i])*v[i] + u[i]*u[i]*gg);
5135  co += pp[i]*pp[i] + qq[i]*qq[i]; // cos (version 1)
5136  si += pp[i]*qq[i]; // sin
5137  }
5138  cc = sqrt(si*si+co*co)+1.e-24;
5139  co = co/cc;
5140  si = si/cc;
5141  if(!eDisbalance) {co=1.;si=0.;}
5142 
5143 // corrected likelihood
5144 
5145  hh=gg = 0.;
5146  for(i=0; i<nIFO; i++) { // solution for h(t,f)
5147  e[i] = u[i]*co + v[i]*si; // final projection vector
5148  r[i] = v[i]*co - u[i]*si; // orthogonal v vector
5149  hh += e[i]*am[i]; // solution for hu(t,f)
5150  gg += r[i]*am[i]; // solution for hv(t,f)
5151  }
5152 
5153 // second iteration
5154 
5155  co=si=0.;
5156  for(i=0; i<nIFO; i++) { // disbalance vectors
5157  cc = local ? am[i]/(am[i]*am[i]+2.) : 1.;
5158  pp[i] = cc*(am[i]-hh*e[i])*e[i];
5159  qq[i] = cc*((2.*hh*e[i]-am[i])*r[i] + e[i]*e[i]*gg);
5160  co += pp[i]*pp[i] + qq[i]*qq[i]; // cos (version 1)
5161  si += pp[i]*qq[i]; // sin
5162  }
5163  cc = sqrt(si*si+co*co)+1.e-24;
5164  co = co/cc;
5165  si = si/cc;
5166  if(!eDisbalance) {co=1.;si=0.;}
5167 
5168  if(type=='E') U = 0;
5169  hh = 0.;
5170  for(i=0; i<nIFO; i++) { // solution for h(t,f)
5171  e[i] = e[i]*co+r[i]*si; // final projection vector
5172  hh += e[i]*am[i]*U; // solution for h(t,f)
5173  }
5174 
5175 // fill in pix
5176 
5177  Lp = hh*hh; // likelihood
5178 
5179  if(Et>Eo) {
5180  Lo += (type=='E') ? Et-nIFO : Lp; // calculate Lc for x-check
5181  E += Et;
5182  }
5183 
5184  pix = this->wc_List[n].getPixel(id,pI[j]);
5185  pix->likelihood = (type=='E') ? Et-nIFO : Lp;
5186  pix->theta = nLikelihood.getTheta(l);
5187  pix->phi = nLikelihood.getPhi(l);
5188  if(!core) pix->core = Et<Eo ? false : true;
5189 
5190  for(i=0; i<nIFO; i++) {
5191  pix->setdata(am[i],'S',i); // whitened data
5192  pix->setdata(e[i]*hh/sqrt(nv[i][j]),'W',i); // detector response
5193  }
5194 
5195  if(ID) {
5196  this->pixeLHood.data[pix->time] = Lp;
5197  this->pixeLNull.data[pix->time] = Et-Lp+1.;
5198  if(pOUT) {
5199  cout<<j<<" SNR="<<Et<<" ";
5200  for(i=0; i<nIFO; i++) {
5201  cout<<e[i]*e[i]<<":"<<am[i]*am[i]/Et<<" ";
5202  }
5203  cout<<endl;
5204  }
5205  }
5206  count++;
5207  }
5208 
5209 // fill in backward delay configuration
5210 
5211  vtof->clear();
5212  NETX (
5213  vtof->push_back(int(M/2)-int(m0[l])); ,
5214  vtof->push_back(int(M/2)-int(m1[l])); ,
5215  vtof->push_back(int(M/2)-int(m2[l])); ,
5216  vtof->push_back(int(M/2)-int(m3[l])); ,
5217  vtof->push_back(int(M/2)-int(m4[l])); ,
5218  vtof->push_back(int(M/2)-int(m5[l])); ,
5219  vtof->push_back(int(M/2)-int(m6[l])); ,
5220  vtof->push_back(int(M/2)-int(m7[l])); )
5221 
5222  skyProb *= Em/IIm;
5223  T = cTo.data[k]+getifo(0)->TFmap.start(); // trigger time
5224  if(iID<=0 && type!='E') getSkyArea(id,n,T); // calculate error regions
5225 
5226  if(fabs((Lm-Lo)/Lo)>1.e-4)
5227  cout<<"likelihood: incorrect likelihood : "<<Lm<<" "<<Lo<<" "<<Em<<endl;
5228 
5229  if(E>0 && ID) {
5230  cout<<"max value: "<<STAT<<" at (theta,phi) = ("<<nLikelihood.getTheta(l)
5231  <<","<<nLikelihood.getPhi(l)<<") Likelihood: loop: "<<Lm
5232  <<", final: "<<Lo<<", eff: "<<Em<<endl;
5233  break;
5234  }
5235 
5236  if(ID && !EFEC) {
5237  this->nSensitivity.gps = T;
5238  this->nAlignment.gps = T;
5239  this->nNetIndex.gps = T;
5240  this->nDisbalance.gps = T;
5241  this->nLikelihood.gps = T;
5242  this->nNullEnergy.gps = T;
5243  this->nCorrEnergy.gps = T;
5244  this->nCorrelation.gps = T;
5245  this->nSkyStat.gps = T;
5246  this->nPenalty.gps = T;
5247  this->nProbability.gps = T;
5248  }
5249  } // end of loop over clusters
5250  if(ID) break;
5251  } // end of loop over time shifts
5252  return count;
5253 }
5254 
5255 
5256 //*********************************************************************************
5257 // calculate network likelihood for 2-NIFO detectors assuming elliptical polarisation.
5258 // elliptical constraint is used in a combination with the energy disbalance constraint
5259 // It is designed to replace likelihood functions for 2,3,4 and NIFO networks.
5260 // If the network has less then NIFO detectors, all arrays are allocated for NIFO
5261 // detectors anyway. The arrays are initialized so that the dummy detectors
5262 // do not contribute into calculation of the coherent statistics.
5263 //*********************************************************************************
5264 
5265 long network::likelihoodI(char type, double Ao, int iID, size_t lag, int ind, bool core)
5266 {
5267  this->like('I');
5268 
5269  size_t jN = 500;
5270  size_t nIFO = this->ifoList.size();
5271  size_t ID = abs(iID);
5272  int N_1 = nIFO>2 ? int(nIFO)-1 : 2;
5273  int N_2 = nIFO>2 ? int(nIFO)-2 : 1;
5274  if(nIFO>NIFO || !this->filter.size() || this->filter[0].index.size()!=32) {
5275  cout<<"network::likelihoodE(): invalid number of detectors or delay filter is not set.\n";
5276  return false;
5277  }
5278 
5279 // regulators hard <- soft <0> weak -> hard
5280 // gamma = -1 <- 0 -> 1
5281 // delta = 0 -> 1
5282 
5283  double Eo = nIFO*Ao*Ao; // energy threshold in the sky loop
5284  double soft = delta>0 ? delta : 0.;
5285  double GAMMA = 1.-gamma*gamma; // network regulator
5286  int LOCAL = local ? 1 : 0; // ED minimization case
5287 
5288  double rho = this->netRHO*this->netRHO*nIFO; // threshold on rho
5289  double one = (type=='g' || type=='G') ? 0. : 1.; // circular polarization
5290  double En = (type!='i' && type!='I') ? 1.e9 : 1.;
5291  bool ISG = false;
5292  bool isgr = false;
5293 
5294  if(type=='I' || type=='S' || type=='G') ISG = true;
5295  if(type=='i' || type=='s' || type=='g') ISG = true;
5296  if(type=='i' || type=='s' || type=='g' || type=='r') isgr = true;
5297 
5298  if(!ID && ind>=0) ind = -1;
5299  this->tYPe = type;
5300  this->acor = Ao;
5301 
5302  int ii,II,IIm;
5303  double gr,gg,gc,gp,gx,cc,gP,gX,gR,gI,EE,Et,T,Em,LPm,HH;
5304  double em,STAT,Lo,Lm,Lp,Co,E00,E90,L00,C00,AA,CO,SI;
5305  double co,si,stat,XP,XX,L90,C90,sI,cO,aa,bb,as,ac,ap,La;
5306  double xp,xx,hh,um,vm,uc,us,vc,vs,hp,hx,HP,HX,wp,wx,WP,WX;
5307  size_t i,j,k,l,m,n,V,U,K,id,j5;
5308 
5309  size_t I = this->ifoList[0]->TFmap.maxLayer()+1;
5310  size_t M = this->filter.size()/I; // total number of delays
5311  size_t L = ind<0 ? this->index.size() : ind+1; // total number of source locations
5312  int R = int(this->ifoList[0]->getTFmap()->rate()/I+0.5);
5313 
5314 // pointers to data
5315  double* pdata[NIFO];
5316  double* qdata[NIFO];
5317  double* pq;
5318  for(n=0; n<nIFO; n++) {
5319  pdata[n] = getifo(n)->getTFmap()->data;
5320  qdata[n] = getifo(n)->getTFmap()->data;
5321  }
5322 
5323 // buffer for wavelet layer delay filter
5324  std::vector<float>* F00;
5325  std::vector<short>* J00;
5326  std::vector<float>* F90;
5327  std::vector<short>* J90;
5328 
5329 // get antenna patterns and index arrays
5330  double* fp[NIFO]; // f+
5331  double* fx[NIFO]; // fx
5332  double* ffp[NIFO]; // f+f+ + fxfx
5333  double* ffm[NIFO]; // f+f+ - fxfx
5334  double* fpx[NIFO]; // 2*f+fx
5335  wavearray<double> f00(L); f00 = 0.; // dummy zero array
5336 
5337  for(n=0; n<NIFO; n++) {
5338  fp[n] = n<nIFO ? getifo(n)->fp.data : f00.data;
5339  fx[n] = n<nIFO ? getifo(n)->fx.data : f00.data;
5340  ffp[n] = n<nIFO ? getifo(n)->ffp.data : f00.data;
5341  ffm[n] = n<nIFO ? getifo(n)->ffm.data : f00.data;
5342  fpx[n] = n<nIFO ? getifo(n)->fpx.data : f00.data;
5343  }
5344  short* mm = skyMask.data;
5345  NETX (
5346  short* m0 = nIFO>1 ? getifo(0)->index.data : getifo(0)->index.data; ,
5347  short* m1 = nIFO>1 ? getifo(1)->index.data : getifo(1)->index.data; ,
5348  short* m2 = nIFO>2 ? getifo(2)->index.data : getifo(1)->index.data; ,
5349  short* m3 = nIFO>3 ? getifo(3)->index.data : getifo(1)->index.data; ,
5350  short* m4 = nIFO>4 ? getifo(4)->index.data : getifo(1)->index.data; ,
5351  short* m5 = nIFO>5 ? getifo(5)->index.data : getifo(1)->index.data; ,
5352  short* m6 = nIFO>6 ? getifo(6)->index.data : getifo(1)->index.data; ,
5353  short* m7 = nIFO>7 ? getifo(7)->index.data : getifo(1)->index.data; )
5354 
5355 // allocate buffers
5356  std::vector<size_t> pI;
5357 
5358  wavearray<double> LL(jN);
5359  wavearray<double> GG(jN);
5360  wavearray<short> jU(jN);
5361  wavearray<double> am00(jN*NIFO); // buffers for 00 data
5362  wavearray<double> am90(jN*NIFO); // buffers for 90 data
5363  wavearray<double> xi00(jN*NIFO); // buffers for 00 response
5364  wavearray<double> xi90(jN*NIFO); // buffers for 90 response
5365  wavearray<double> Fplus(jN*NIFO); // buffers for F+
5366  wavearray<double> Fcros(jN*NIFO); // buffers for Fx
5367 
5368 //BM wavearray<double> e00[NIFO];
5369 //BM wavearray<double> e90[NIFO];
5370  wavearray<double> a00[NIFO];
5371  wavearray<double> a90[NIFO];
5372  wavearray<double> NV[NIFO]; // noise variance
5373  wavearray<double> NR[NIFO]; // noise rms
5374  wavearray<double> cid; // buffers for cluster ID
5375  wavearray<double> cTo; // buffers for cluster time
5376  wavearray<double> vol; // buffers for cluster volume
5377 
5378  double u[NIFO];
5379  double v[NIFO];
5380  double e[NIFO];
5381  double ee[NIFO];
5382  double rr[NIFO];
5383  double pp[NIFO];
5384  double qq[NIFO];
5385 
5386  double* am;
5387  double* AM;
5388  double* xi;
5389  double* XI;
5390  double* Fp;
5391  double* Fx;
5392  double* nv[NIFO];
5393  double* nr[NIFO];
5394  double* pa00[NIFO];
5395  double* pa90[NIFO];
5396 
5397  for(n=0; n<NIFO; n++) {
5398  NV[n].resize(jN); NV[n] = 0.; nv[n] = NV[n].data;
5399  NR[n].resize(jN); NR[n] = 0.; nr[n] = NR[n].data;
5400  a00[n].resize(jN*M); a00[n] = 0.;
5401 //BM e00[n].resize(jN*M); e00[n] = 0.;
5402  a90[n].resize(jN*M); a90[n] = 0.;
5403 //BM e90[n].resize(jN*M); e90[n] = 0.;
5404  rr[n] = 1.;
5405  }
5406 
5407  netpixel* pix;
5408  std::vector<int>* vint;
5409  std::vector<int>* vtof;
5410 
5411  double logbpp,inet;
5412  size_t count = 0;
5413  ap = ac = as = 0.;
5414 
5415  if(ID) {
5416  this->pixeLHood = getifo(0)->TFmap;
5417  this->pixeLHood = 0.;
5418  this->pixeLNull = getifo(0)->TFmap;
5419  this->pixeLNull = 0.;
5420  this->nSensitivity = 0.;
5421  this->nAlignment = 0.;
5422  this->nNetIndex = 0.;
5423  this->nDisbalance = 0.;
5424  this->nLikelihood = 0.;
5425  this->nNullEnergy = 0.;
5426  this->nCorrEnergy = 0.;
5427  this->nCorrelation = 0.;
5428  this->nSkyStat = 0.;
5429  this->nEllipticity = 0.;
5430  this->nPolarisation = 0.;
5431  this->nProbability = 0.;
5432  this->nAntenaPrior = 0.;
5433  }
5434 
5435 //+++++++++++++++++++++++++++++++++++++++
5436 // liklihood calculation for clusters
5437 //+++++++++++++++++++++++++++++++++++++++
5438 
5439  for(n=lag; n<nLag; n++) { // loop over time shifts
5440 
5441  if(!this->wc_List[n].size()) continue;
5442  logbpp = -log(this->wc_List[n].getbpp());
5443 
5444  cid = this->wc_List[n].get((char*)"ID",0,'S',optim ? R : -R); // get cluster ID
5445  cTo = this->wc_List[n].get((char*)"time",0,'L',optim ? R : -R); // get cluster time
5446 
5447  K = cid.size();
5448 
5449  for(k=0; k<K; k++) { // loop over clusters
5450 
5451  id = size_t(cid.data[k]+0.1);
5452 
5453  if(ID && id!=ID) continue;
5454 
5455  vint = &(this->wc_List[n].cList[id-1]); // pixel list
5456  vtof = &(this->wc_List[n].nTofF[id-1]); // TofFlight configurations
5457 
5458  V = vint->size();
5459  if(!V) continue;
5460 
5461  pI.clear();
5462 
5463  for(j=0; j<V; j++) { // loop over pixels
5464 
5465  pix = this->wc_List[n].getPixel(id,j);
5466 
5467  if(!pix) {
5468  cout<<"network::likelihood() error: NULL pointer"<<endl;
5469  exit(1);
5470  }
5471 
5472  if(R != int(pix->rate+0.5)) continue; // check rate
5473  if(!pix->core && core) continue; // check core flag
5474 
5475  pI.push_back(j); // save pixel index
5476 
5477  }
5478 
5479  V = pI.size();
5480  if(!V) continue;
5481 
5482  if(NV[0].size() < V) { // reallocate arrays
5483  U = V+100;
5484  for(i=0; i<NIFO; i++) {
5485  NV[i].resize(U); NV[i] = 0.; nv[i] = NV[i].data;
5486  NR[i].resize(U); NR[i] = 0.; nr[i] = NR[i].data;
5487 //BM e00[i].resize(U*M); e00[i] = 0.;
5488  a00[i].resize(U*M); a00[i] = 0.;
5489 //BM e90[i].resize(U*M); e90[i] = 0.;
5490  a90[i].resize(U*M); a90[i] = 0.;
5491  }
5492  jU.resize(U); LL.resize(U); GG.resize(U);
5493  am00.resize(U*NIFO); am90.resize(U*NIFO);
5494  xi00.resize(U*NIFO); xi90.resize(U*NIFO);
5495  Fplus.resize(U*NIFO); Fcros.resize(U*NIFO);
5496  }
5497 
5498  for(j=0; j<V; j++) { // loop over selected pixels
5499 
5500  pix = this->wc_List[n].getPixel(id,pI[j]);
5501 
5502  cc = 0.;
5503  for(i=0; i<nIFO; i++) {
5504  ee[i] = 1./pix->data[i].noiserms;
5505  cc += ee[i]*ee[i]; // total inverse variance
5506  }
5507 
5508  GG.data[j] = sqrt(cc);
5509  for(i=0; i<nIFO; i++) {
5510  nv[i][j] = ee[i]*ee[i]; // inverse variance
5511  ee[i] /= sqrt(cc);
5512  nr[i][j] = ee[i]; // normalized 1/rms
5513  qdata[i] = pdata[i] + pix->data[i].index; // pointer to data
5514  }
5515 
5516 // apply delay filter
5517 
5518  for(i=0; i<nIFO; i++) {
5519  pq = qdata[i];
5520 
5521  for(m=0; m<M; m++){ // loop over delays
5522  F00 = &(filter[pix->frequency*M+m].value);
5523  J00 = &(filter[pix->frequency*M+m].index);
5524  F90 = &(filter90[pix->frequency*M+m].value);
5525  J90 = &(filter90[pix->frequency*M+m].index);
5526  l = m*V + j;
5527 
5528  gg = dot32(F00,pq,J00); // apply filter
5529 //BM e00[i].data[l] = gg*ee[i];
5530  a00[i].data[l] = gg;
5531 
5532  gg = dot32(F90,pq,J90); // apply filter
5533 //BM e90[i].data[l] = gg*ee[i];
5534  a90[i].data[l] = gg;
5535  }
5536  }
5537  }
5538 
5539  STAT = -1.e64; m=U=IIm=0; Em=Lm=LPm=AA=SI=CO=0.;
5540 
5541 //============================================================
5542 // weak constraint on 00 data
5543 //============================================================
5544 
5545  l = ind<0 ? 0 : ind; // process selected index
5546  for(; l<L; l++) { // loop over sky locations
5547 
5548  skyProb.data[l] = 0.;
5549 
5550  if(skyMaskCC.size()==L) {
5551  // transform l in celestial coordinates cc_l and check the skyMaskCC
5552  skymap* sm = &(this->nSkyStat);
5553  double th = sm->getTheta(l);
5554  double ph = sm->getPhi(l);
5555  double gpsT = cTo.data[k]+getifo(0)->TFmap.start(); // trigger time
5556  double ra = sm->phi2RA(ph, gpsT);
5557  int cc_l = this->getIndex(th,ra);
5558  if (!skyMaskCC.data[cc_l]) continue;
5559  }
5560 
5561  if(!mm[l] && ind<0) continue; // skip sky configurations
5562 
5563  NETX (
5564  pa00[0] = a00[0].data + m0[l]*V; ,
5565  pa00[1] = a00[1].data + m1[l]*V; ,
5566  pa00[2] = a00[2].data + m2[l]*V; ,
5567  pa00[3] = a00[3].data + m3[l]*V; ,
5568  pa00[4] = a00[4].data + m4[l]*V; ,
5569  pa00[5] = a00[5].data + m5[l]*V; ,
5570  pa00[6] = a00[6].data + m6[l]*V; ,
5571  pa00[7] = a00[7].data + m7[l]*V; )
5572 
5573  EE=E00=L00=C00=Lp=0.; II=0;
5574 
5575  for(j=0; j<V; j++) { // 00 phase
5576 
5577  j5 = j*NIFO;
5578  am = am00.data+j5;
5579  inix(pa00,j,am);
5580  Et = dotx(am,am); // total energy
5581  ii = int(Et>Eo);
5582  E00+= Et*ii;
5583 
5584  Fp = Fplus.data+j5;
5585  Fx = Fcros.data+j5;
5586  mulx(fp,l,nr,j,Fp);
5587  mulx(fx,l,nr,j,Fx);
5588 
5589  gp = dotx(Fp,Fp)+1.e-12; // fp^2
5590  gx = dotx(Fx,Fx)+1.e-12; // fx^2
5591  gI = dotx(Fp,Fx); // fp*fx
5592 
5593  xi = xi00.data+j5;
5594  xp = dotx(Fp,am); // (X*f+)
5595  xx = dotx(Fx,am); // (X*fx)
5596  um = rotx(Fp,xp*gx-xx*gI,
5597  Fx,xx*gp-xp*gI,xi);
5598  hh = dotx(xi,am,e);
5599  La = hh*hh/um;
5600  Co = La - dotx(e,e)/um;
5601  ii*= int(Co>0.);
5602  EE+= Et*ii;
5603  Lp+= La*Co*ii/(Et-La+1+Co);
5604  II+= ii;
5605  LL.data[j] = La*ii;
5606  L00+= La*ii;
5607  C00+= Co*ii;
5608  mulx(xi,hh*ii/um);
5609  }
5610 
5611  cc = E00>0 ? C00/(E00-L00+fabs(C00)) : 0.;
5612  if(cc<this->netCC || cc*C00<rho) continue;
5613 
5614  E90=L90=C90=inet=0.;
5615 
5616  NETX (
5617  pa90[0] = a90[0].data + m0[l]*V; ,
5618  pa90[1] = a90[1].data + m1[l]*V; ,
5619  pa90[2] = a90[2].data + m2[l]*V; ,
5620  pa90[3] = a90[3].data + m3[l]*V; ,
5621  pa90[4] = a90[4].data + m4[l]*V; ,
5622  pa90[5] = a90[5].data + m5[l]*V; ,
5623  pa90[6] = a90[6].data + m6[l]*V; ,
5624  pa90[7] = a90[7].data + m7[l]*V; )
5625 
5626  for(j=0; j<V; j++) { // 90 phase
5627 
5628  j5 = j*NIFO;
5629  AM = am90.data+j5;
5630  inix(pa90,j,AM);
5631  Et = dotx(AM,AM); // total energy
5632  ii = int(Et>Eo);
5633  E90+= Et*ii;
5634 
5635  Fp = Fplus.data+j5;
5636  Fx = Fcros.data+j5;
5637  gp = dotx(Fp,Fp)+1.e-12; // fp^2
5638  gx = dotx(Fx,Fx)+1.e-12; // fx^2
5639  gI = dotx(Fp,Fx); // fp*fx
5640 
5641  XI = xi90.data+j5;
5642  XP = dotx(Fp,AM); // (X(90)*f+)
5643  XX = dotx(Fx,AM); // (X(90)*fx)
5644  vm = rotx(Fp,XP*gx-XX*gI,
5645  Fx,XX*gp-XP*gI,XI);
5646  HH = dotx(XI,AM,e);
5647  La = HH*HH/vm;
5648  Co = La - dotx(e,e)/vm;
5649  ii*= int(Co>0.);
5650  EE+= Et*ii;
5651  Lp+= La*Co*ii/(Et-La+1+Co);
5652  II+= ii;
5653  LL.data[j] += La*ii;
5654  L90+= La*ii;
5655  C90+= Co*ii;
5656  mulx(XI,HH*ii/vm);
5657  }
5658 
5659  cc = E90>0 ? C90/(E90-L90+fabs(C90)) : 0.;
5660  if(cc<this->netCC || cc*C90<rho) continue;
5661 
5662  Co = C00+C90;
5663  Lo = L00+L90;
5664 
5665  sI=cO=aa=bb=0.;
5666 
5667 //++++++++++++++++elliptical case++++++++++++++++++++++
5668 // find solution for polarisation angle and ellipticity
5669 //++++++++++++++++elliptical case++++++++++++++++++++++
5670 
5671  if(ISG) {
5672 
5673  Lo=Lp=Co=0.;
5674 
5675  for(j=0; j<V; j++) { // loop over selected pixels
5676 
5677  j5 = j*NIFO;
5678  Fp = Fplus.data+j5;
5679  Fx = Fcros.data+j5;
5680  gp = dotx(Fp,Fp)+1.e-12; // fp^2
5681  gx = dotx(Fx,Fx)+1.e-12; // fx^2
5682  gI = dotx(Fp,Fx); // fp*fx
5683  gg = gp+gx;
5684 
5685  wp = dotx(Fp,xi00.data+j5); // +00 response
5686  wx = dotx(Fx,xi00.data+j5); // x00 response
5687  WP = dotx(Fp,xi90.data+j5); // +90 response
5688  WX = dotx(Fx,xi90.data+j5); // x90 response
5689 
5690  xp = (wp*wp + WP*WP);
5691  xx = (wx*wx + WX*WX);
5692  La = LL.data[j];
5693 
5694  sI += 2*(wp*wx+WP*WX-La*gI)/gg; // sin(4psi)
5695  cO += (xp-xx - La*(gp-gx))/gg; // cos(4psi)
5696  bb += La - (xp+xx)/gg;
5697  aa += 2*(wp*WX - wx*WP)/gg;
5698  }
5699 
5700  gg = sqrt(cO*cO+sI*sI);
5701  cO = cO/gg; sI = sI/gg;
5702  aa/= bb+gg+V*En; // ellipticity
5703  if(aa> one) aa = 1.;
5704  if(aa<-one) aa =-1.;
5705 
5706  for(j=0; j<V; j++) { // loop over selected pixels
5707 
5708  Fp = Fplus.data+j*NIFO;
5709  Fx = Fcros.data+j*NIFO;
5710  um = rotx(Fp,1+cO,Fx, sI,u); // rotate by 2*polarization angle
5711  vm = rotx(Fx,1+cO,Fp,-sI,v); // rotate by 2*polarization angle
5712  gp = dotx(u,u)+1.e-12; // fp^2
5713  gx = dotx(v,v)+1.e-12; // fx^2
5714  gI = dotx(u,v); // f+fx
5715  gg = gp+aa*aa*gx; // inverse network sensitivity
5716 
5717  am = am00.data+j*NIFO;
5718  xi = xi00.data+j*NIFO;
5719  um = dotx(xi,xi)+1.e-6;
5720  hh = dotx(xi,am,pp);
5721  xp = dotx(u,xi);
5722  xx = dotx(v,xi)*aa;
5723  bb = (xp*xp+xx*xx)/(um*gg*um);
5724  La = hh*hh*bb;
5725  cc = bb*dotx(pp,pp);
5726 
5727  AM = am90.data+j*NIFO;
5728  XI = xi90.data+j*NIFO;
5729  vm = dotx(XI,XI)+1.e-6;
5730  HH = dotx(XI,AM,qq);
5731  XP = dotx(u,XI);
5732  XX = dotx(v,XI)*aa;
5733  bb = (XP*XP+XX*XX)/(vm*gg*vm);
5734  La+= HH*HH*bb;
5735  cc+= bb*dotx(qq,qq);
5736 
5737  bb = 2*(xp*XX-xx*XP)/(um*gg*vm);
5738  La+= hh*HH*bb;
5739  cc+= bb*dotx(pp,qq);
5740  cc = La-cc;
5741  Lo+= La;
5742  Co+= cc;
5743  Et = dotx(am,am) + dotx(AM,AM);
5744  Lp+= La*cc/(Et-La+2+fabs(cc));
5745  }
5746  }
5747 
5748  cc = EE>0 ? Co/(EE-Lo+II+fabs(Co)) : 0.;
5749  EE = E00+E90;
5750  if(!isgr) Lp = Lo*cc;
5751  if(Lp>LPm) {LPm=Lp; Em=EE; IIm=II;} // max likelihood
5752 
5753  skyProb.data[l] = Lp/EE; // probability map
5754 
5755  cc = EE>0 ? Co/(EE-Lo+II+fabs(Co)) : 0.;
5756  if(cc<this->netCC || cc*Co<rho*2) continue;
5757 
5758 //=============================================================
5759 // zero phase data
5760 //=============================================================
5761 
5762  Lp=Lo=Co=gP=gX=0.;
5763 
5764  for(j=0; j<V; j++) { // loop over selected pixels
5765 
5766  xi = xi00.data+j*NIFO;
5767 
5768  if(dotx(xi,xi)<=0.) continue; // skip insignificant pixel
5769 
5770  am = am00.data+j*NIFO;
5771  Et = dotx(am,am);
5772  Fp = Fplus.data+j*NIFO;
5773  Fx = Fcros.data+j*NIFO;
5774  gp = dotx(Fp,Fp)+1.e-12; // fp^2
5775  gx = dotx(Fx,Fx)+1.e-12; // fx^2
5776  gI = dotx(Fp,Fx); // fp*fx
5777  xp = dotx(Fp,am); // (X*f+)
5778  xx = dotx(Fx,am); // (X*fx)
5779  uc = xp*gx - xx*gI; // u cos of rotation to PCF
5780  us = xx*gp - xp*gI; // u sin of rotation to PCF
5781  vc = gp*uc + gI*us; // (u*f+)/|u|^2 - 'cos' for v
5782  vs = gx*us + gI*uc; // (u*fx)/|u|^2 - 'sin' for v
5783  um = rotx(Fp,uc,Fx,us,u); // calculate new response vector
5784  vm = rotx(Fx,-vc,Fp,vs,v)+1.e-24; // calculate complementary vector
5785 
5786 // regulator
5787 
5788  ii = netx(u,um,v,vm,GAMMA);
5789  inet += ii*Et;
5790  if(ii<N_2 && gamma<0.) {inix(xi,0); continue;}
5791 
5792  gg = (gp+gx)*soft;
5793  uc += xp*gg; // u cos of rotation to PCF
5794  us += xx*gg; // u sin of rotation to PCF
5795 
5796  if(ii<N_1 && gamma!=0) {
5797  gR = (gp-gx)/2;
5798  gc = sqrt(gR*gR+gI*gI); // norm of complex antenna pattern
5799  uc = xp*(gc+gR)+xx*gI;
5800  us = xx*(gc-gR)+xp*gI;
5801  }
5802 
5803  vc = gp*uc + gI*us; // (u*f+)/|u|^2 - 'cos' for v
5804  vs = gx*us + gI*uc; // (u*fx)/|u|^2 - 'sin' for v
5805  um = rotx(Fp,uc,Fx,us,u); // calculate new response vector
5806  vm = rotx(Fx,-vc,Fp,vs,v)+1.e-24; // calculate complementary vector
5807 
5808 // energy disbalance vectors
5809 
5810  NETX (
5811  rr[0] = LOCAL*am[0]/(am[0]*am[0]+2.)+1-LOCAL; ,
5812  rr[1] = LOCAL*am[1]/(am[1]*am[1]+2.)+1-LOCAL; ,
5813  rr[2] = LOCAL*am[2]/(am[2]*am[2]+2.)+1-LOCAL; ,
5814  rr[3] = LOCAL*am[3]/(am[3]*am[3]+2.)+1-LOCAL; ,
5815  rr[4] = LOCAL*am[4]/(am[4]*am[4]+2.)+1-LOCAL; ,
5816  rr[5] = LOCAL*am[5]/(am[5]*am[5]+2.)+1-LOCAL; ,
5817  rr[6] = LOCAL*am[6]/(am[6]*am[6]+2.)+1-LOCAL; ,
5818  rr[7] = LOCAL*am[7]/(am[7]*am[7]+2.)+1-LOCAL; )
5819 
5820  hh = dotx(u,am)/um;
5821  NETX (
5822  pp[0] = rr[0]*(am[0]-hh*u[0])*u[0]; ,
5823  pp[1] = rr[1]*(am[1]-hh*u[1])*u[1]; ,
5824  pp[2] = rr[2]*(am[2]-hh*u[2])*u[2]; ,
5825  pp[3] = rr[3]*(am[3]-hh*u[3])*u[3]; ,
5826  pp[4] = rr[4]*(am[4]-hh*u[4])*u[4]; ,
5827  pp[5] = rr[5]*(am[5]-hh*u[5])*u[5]; ,
5828  pp[6] = rr[6]*(am[6]-hh*u[6])*u[6]; ,
5829  pp[7] = rr[7]*(am[7]-hh*u[7])*u[7]; )
5830 
5831  gg = dotx(v,am)/um;
5832  hh*= 2.;
5833  NETX (
5834  qq[0] = rr[0]*((hh*u[0]-am[0])*v[0]+u[0]*u[0]*gg); ,
5835  qq[1] = rr[1]*((hh*u[1]-am[1])*v[1]+u[1]*u[1]*gg); ,
5836  qq[2] = rr[2]*((hh*u[2]-am[2])*v[2]+u[2]*u[2]*gg); ,
5837  qq[3] = rr[3]*((hh*u[3]-am[3])*v[3]+u[3]*u[3]*gg); ,
5838  qq[4] = rr[4]*((hh*u[4]-am[4])*v[4]+u[4]*u[4]*gg); ,
5839  qq[5] = rr[5]*((hh*u[5]-am[5])*v[5]+u[5]*u[5]*gg); ,
5840  qq[6] = rr[6]*((hh*u[6]-am[6])*v[6]+u[6]*u[6]*gg); ,
5841  qq[7] = rr[7]*((hh*u[7]-am[7])*v[7]+u[7]*u[7]*gg); )
5842 
5843  co = dotx(qq,qq)/vm+dotx(pp,pp)/um+1.e-24; // cos term
5844  si = dotx(pp,qq); // sin term
5845  if(!eDisbalance) {co=1.;si=0.;}
5846  em = rotx(u,co,v,si/vm,e); // calculate rotated vector e
5847 
5848 // second iteration
5849 
5850  vm = rotx(v,co,u,-si/um,v)+1.e-24; // calculate rotated vector v
5851  hh = dotx(e,am)/em;
5852 
5853  NETX (
5854  pp[0] = rr[0]*(am[0]-hh*e[0])*e[0]; ,
5855  pp[1] = rr[1]*(am[1]-hh*e[1])*e[1]; ,
5856  pp[2] = rr[2]*(am[2]-hh*e[2])*e[2]; ,
5857  pp[3] = rr[3]*(am[3]-hh*e[3])*e[3]; ,
5858  pp[4] = rr[4]*(am[4]-hh*e[4])*e[4]; ,
5859  pp[5] = rr[5]*(am[5]-hh*e[5])*e[5]; ,
5860  pp[6] = rr[6]*(am[6]-hh*e[6])*e[6]; ,
5861  pp[7] = rr[7]*(am[7]-hh*e[7])*e[7]; )
5862 
5863  gg = dotx(v,am)/em;
5864  hh*= 2.;
5865  NETX (
5866  qq[0] = rr[0]*((hh*e[0]-am[0])*v[0]+e[0]*e[0]*gg); ,
5867  qq[1] = rr[1]*((hh*e[1]-am[1])*v[1]+e[1]*e[1]*gg); ,
5868  qq[2] = rr[2]*((hh*e[2]-am[2])*v[2]+e[2]*e[2]*gg); ,
5869  qq[3] = rr[3]*((hh*e[3]-am[3])*v[3]+e[3]*e[3]*gg); ,
5870  qq[4] = rr[4]*((hh*e[4]-am[4])*v[4]+e[4]*e[4]*gg); ,
5871  qq[5] = rr[5]*((hh*e[5]-am[5])*v[5]+e[5]*e[5]*gg); ,
5872  qq[6] = rr[6]*((hh*e[6]-am[6])*v[6]+e[6]*e[6]*gg); ,
5873  qq[7] = rr[7]*((hh*e[7]-am[7])*v[7]+e[7]*e[7]*gg); )
5874 
5875  co = dotx(qq,qq)/vm+dotx(pp,pp)/em+1.e-24; // cos term
5876  si = dotx(pp,qq); // sin term
5877  if(!eDisbalance) {co=1.;si=0.;}
5878  em = rotx(e,co,v,si/vm,e); // calculate final vector
5879  hh = dotx(e,am,ee); // GW amplitude
5880  La = hh*hh/em;
5881  cc = La-dotx(ee,ee)/em;
5882  Lo+= La;
5883  Co+= cc;
5884  Lp+= La*cc*int(cc>0)/(Et-La+1+cc);
5885  mulx(e,hh/em,xi);
5886  }
5887 
5888 //=============================================================
5889 // 90 degrees phase energy disbalance
5890 //=============================================================
5891 
5892  for(j=0; j<V; j++) { // select pixels and get dot ptoducts
5893 
5894  XI = xi90.data+j*NIFO;
5895 
5896  if(dotx(XI,XI)<=0) continue; // skip insignificant pixel
5897 
5898  AM = am90.data+j*NIFO;
5899  Et = dotx(AM,AM);
5900  Fp = Fplus.data+j*NIFO;
5901  Fx = Fcros.data+j*NIFO;
5902  gp = dotx(Fp,Fp)+1.e-12; // fp^2
5903  gx = dotx(Fx,Fx)+1.e-12; // fx^2
5904  gI = dotx(Fp,Fx); // fp*fx
5905  XP = dotx(Fp,AM); // (X*f+)
5906  XX = dotx(Fx,AM); // (X*fx)
5907  uc = XP*gx - XX*gI; // u cos of rotation to PCF
5908  us = XX*gp - XP*gI; // u sin of rotation to PCF
5909  vc = gp*uc + gI*us; // (u*f+)/|u|^2 - 'cos' for v
5910  vs = gx*us + gI*uc; // (u*fx)/|u|^2 - 'sin' for v
5911  um = rotx(Fp,uc,Fx,us,u); // calculate new response vector
5912  vm = rotx(Fx,-vc,Fp,vs,v)+1.e-24; // calculate complementary vector
5913 
5914 // regulator
5915 
5916  ii = netx(u,um,v,vm,GAMMA);
5917  inet += ii*Et;
5918  if(ii<N_2 && gamma<0.) {inix(XI,0.); continue;}
5919 
5920  gg = (gp+gx)*soft;
5921  uc += XP*gg; // u cos of rotation to PCF
5922  us += XX*gg; // u sin of rotation to PCF
5923 
5924  if(ii<N_1 && gamma!=0) {
5925  gR = (gp-gx)/2;
5926  gc = sqrt(gR*gR+gI*gI); // norm of complex antenna pattern
5927  uc = XP*(gc+gR)+XX*gI;
5928  us = XX*(gc-gR)+XP*gI;
5929  }
5930 
5931  vc = gp*uc + gI*us; // (u*f+)/|u|^2 - 'cos' for v
5932  vs = gx*us + gI*uc; // (u*fx)/|u|^2 - 'sin' for v
5933  um = rotx(Fp,uc,Fx,us,u); // calculate new response vector
5934  vm = rotx(Fx,-vc,Fp,vs,v)+1.e-24; // calculate complementary vector
5935 
5936 // energy disbalance vectors
5937 
5938  NETX (
5939  rr[0] = LOCAL*AM[0]/(AM[0]*AM[0]+2.)+1-LOCAL; ,
5940  rr[1] = LOCAL*AM[1]/(AM[1]*AM[1]+2.)+1-LOCAL; ,
5941  rr[2] = LOCAL*AM[2]/(AM[2]*AM[2]+2.)+1-LOCAL; ,
5942  rr[3] = LOCAL*AM[3]/(AM[3]*AM[3]+2.)+1-LOCAL; ,
5943  rr[4] = LOCAL*AM[4]/(AM[4]*AM[4]+2.)+1-LOCAL; ,
5944  rr[5] = LOCAL*AM[5]/(AM[5]*AM[5]+2.)+1-LOCAL; ,
5945  rr[6] = LOCAL*AM[6]/(AM[6]*AM[6]+2.)+1-LOCAL; ,
5946  rr[7] = LOCAL*AM[7]/(AM[7]*AM[7]+2.)+1-LOCAL; )
5947 
5948  hh = dotx(u,AM)/um;
5949  NETX (
5950  pp[0] = rr[0]*(AM[0]-hh*u[0])*u[0]; ,
5951  pp[1] = rr[1]*(AM[1]-hh*u[1])*u[1]; ,
5952  pp[2] = rr[2]*(AM[2]-hh*u[2])*u[2]; ,
5953  pp[3] = rr[3]*(AM[3]-hh*u[3])*u[3]; ,
5954  pp[4] = rr[4]*(AM[4]-hh*u[4])*u[4]; ,
5955  pp[5] = rr[5]*(AM[5]-hh*u[5])*u[5]; ,
5956  pp[6] = rr[6]*(AM[6]-hh*u[6])*u[6]; ,
5957  pp[7] = rr[7]*(AM[7]-hh*u[7])*u[7]; )
5958 
5959  gg = dotx(v,AM)/um;
5960  hh*= 2.;
5961  NETX (
5962  qq[0] = rr[0]*((hh*u[0]-AM[0])*v[0]+u[0]*u[0]*gg); ,
5963  qq[1] = rr[1]*((hh*u[1]-AM[1])*v[1]+u[1]*u[1]*gg); ,
5964  qq[2] = rr[2]*((hh*u[2]-AM[2])*v[2]+u[2]*u[2]*gg); ,
5965  qq[3] = rr[3]*((hh*u[3]-AM[3])*v[3]+u[3]*u[3]*gg); ,
5966  qq[4] = rr[4]*((hh*u[4]-AM[4])*v[4]+u[4]*u[4]*gg); ,
5967  qq[5] = rr[5]*((hh*u[5]-AM[5])*v[5]+u[5]*u[5]*gg); ,
5968  qq[6] = rr[6]*((hh*u[6]-AM[6])*v[6]+u[6]*u[6]*gg); ,
5969  qq[7] = rr[7]*((hh*u[7]-AM[7])*v[7]+u[7]*u[7]*gg); )
5970 
5971  co = dotx(qq,qq)/vm+dotx(pp,pp)/um+1.e-24; // cos term
5972  si = dotx(pp,qq); // sin term
5973  if(!eDisbalance) {co=1.;si=0.;}
5974  em = rotx(u,co,v,si/vm,e); // calculate rotated vector e
5975 
5976 // second iteration
5977 
5978  vm = rotx(v,co,u,-si/um,v)+1.e-24; // calculate rotated vector v
5979  hh = dotx(e,AM)/em;
5980 
5981  NETX (
5982  pp[0] = rr[0]*(AM[0]-hh*e[0])*e[0]; ,
5983  pp[1] = rr[1]*(AM[1]-hh*e[1])*e[1]; ,
5984  pp[2] = rr[2]*(AM[2]-hh*e[2])*e[2]; ,
5985  pp[3] = rr[3]*(AM[3]-hh*e[3])*e[3]; ,
5986  pp[4] = rr[4]*(AM[4]-hh*e[4])*e[4]; ,
5987  pp[5] = rr[5]*(AM[5]-hh*e[5])*e[5]; ,
5988  pp[6] = rr[6]*(AM[6]-hh*e[6])*e[6]; ,
5989  pp[7] = rr[7]*(AM[7]-hh*e[7])*e[7]; )
5990 
5991  gg = dotx(v,AM)/em;
5992  hh*= 2.;
5993  NETX (
5994  qq[0] = rr[0]*((hh*e[0]-AM[0])*v[0]+e[0]*e[0]*gg); ,
5995  qq[1] = rr[1]*((hh*e[1]-AM[1])*v[1]+e[1]*e[1]*gg); ,
5996  qq[2] = rr[2]*((hh*e[2]-AM[2])*v[2]+e[2]*e[2]*gg); ,
5997  qq[3] = rr[3]*((hh*e[3]-AM[3])*v[3]+e[3]*e[3]*gg); ,
5998  qq[4] = rr[4]*((hh*e[4]-AM[4])*v[4]+e[4]*e[4]*gg); ,
5999  qq[5] = rr[5]*((hh*e[5]-AM[5])*v[5]+e[5]*e[5]*gg); ,
6000  qq[6] = rr[6]*((hh*e[6]-AM[6])*v[6]+e[6]*e[6]*gg); ,
6001  qq[7] = rr[7]*((hh*e[7]-AM[7])*v[7]+e[7]*e[7]*gg); )
6002 
6003  co = dotx(qq,qq)/vm+dotx(pp,pp)/em+1.e-24; // cos term
6004  si = dotx(pp,qq); // sin term
6005  if(!eDisbalance) {co=1.;si=0.;}
6006  em = rotx(e,co,v,si/vm,e); // calculate final vector
6007  hh = dotx(e,AM,ee); // GW amplitude
6008  La = hh*hh/em;
6009  cc = La-dotx(ee,ee)/em;
6010  Lo+= La;
6011  Co+= cc;
6012  Lp+= La*cc*int(cc>0)/(Et-La+1+cc);
6013  mulx(e,hh/em,XI);
6014  }
6015 
6016 //++++++++++++++++elliptical case++++++++++++++++++++++
6017 // calculate elliptical likelihood and coherent energy
6018 //++++++++++++++++elliptical case++++++++++++++++++++++
6019 
6020  if(ISG) {
6021 
6022  Lp=Lo=Co=0.;
6023 
6024  for(j=0; j<V; j++) { // loop over selected pixels
6025 
6026  Fp = Fplus.data+j*NIFO;
6027  Fx = Fcros.data+j*NIFO;
6028  um = rotx(Fp,1+cO,Fx, sI,u); // rotate by 2*polarization angle
6029  vm = rotx(Fx,1+cO,Fp,-sI,v); // rotate by 2*polarization angle
6030  gp = dotx(u,u)+1.e-12; // fp^2
6031  gx = dotx(v,v)+1.e-12; // fx^2
6032  gg = gp + aa*aa*gx; // network sensitivity
6033 
6034  am = am00.data+j*NIFO;
6035  xi = xi00.data+j*NIFO;
6036  um = dotx(xi,xi)+1.e-6;
6037  hh = dotx(xi,am,pp);
6038  xp = dotx(u,xi);
6039  xx = dotx(v,xi)*aa;
6040  bb = (xp*xp+xx*xx)/(um*gg*um);
6041  La = hh*hh*bb;
6042  cc = bb*dotx(pp,pp);
6043 
6044  AM = am90.data+j*NIFO;
6045  XI = xi90.data+j*NIFO;
6046  vm = dotx(XI,XI)+1.e-6;
6047  HH = dotx(XI,AM,qq);
6048  XP = dotx(u,XI);
6049  XX = dotx(v,XI)*aa;
6050  bb = (XP*XP+XX*XX)/(vm*gg*vm);
6051  La+= HH*HH*bb;
6052  cc+= bb*dotx(qq,qq);
6053 
6054  bb = 2*(xp*XX-xx*XP)/(um*gg*vm);
6055  La+= hh*HH*bb;
6056  cc+= bb*dotx(pp,qq);
6057  cc = La-cc;
6058  Co+= cc;
6059  Lo+= La;
6060  Et = dotx(am,am)+dotx(AM,AM);
6061  Lp+= La*cc*int(cc>0)/(Et-La+2+cc);
6062  }
6063  }
6064 
6065 // final detection statistics
6066 
6067  cc = EE>0 ? Co/(EE-Lo+II+fabs(Co)) : 0.;
6068  stat = isgr ? Lp/EE : Lo*cc/EE;
6069  inet/= EE;
6070 
6071 
6072  if(stat>=STAT) { m=l; STAT=stat; AA=aa; CO=cO; SI=sI; Lm=Lo/2.; }
6073 
6074  if(ID) { // fill skymaps
6075  for(j=0; j<V; j++) { // loop over selected pixels
6076  Fp = Fplus.data+j*NIFO;
6077  Fx = Fcros.data+j*NIFO;
6078  Et = dotx(pa00,j,pa00,j);
6079  gp = dotx(Fp,Fp)+1.e-12; // fp^2
6080  gx = dotx(Fx,Fx)+1.e-12; // fx^2
6081  gI = dotx(Fp,Fx); // fp*fx
6082  gr = (gp+gx)/2;
6083  gR = (gp-gx)/2;
6084  gc = sqrt(gR*gR+gI*gI); // norm of complex antenna pattern
6085  gP+= (gr+gc); // average + sensitivity
6086  gX+= (gr-gc); // average x sensitivity
6087  }
6088 
6089  this->nAntenaPrior.set(l, gP/V);
6090  this->nSensitivity.set(l, gP/V);
6091  this->nAlignment.set(l, gX/V);
6092  this->nLikelihood.set(l, Lo/2);
6093  this->nNullEnergy.set(l, (EE-Lo)/2.);
6094  this->nCorrEnergy.set(l, Co/2);
6095  this->nCorrelation.set(l, cc);
6096  this->nSkyStat.set(l, stat);
6097  this->nProbability.set(l, skyProb.data[l]);
6098  this->nDisbalance.set(l, fabs(L00-L90)/fabs(L00+L90));
6099  this->nEllipticity.set(l, aa);
6100  this->nPolarisation.set(l, atan2(sI,cO));
6101  this->nNetIndex.set(l, inet);
6102  }
6103  }
6104 
6105  if(STAT<0.001 && ind<0) {
6106  this->wc_List[n].ignore(id); // reject cluster
6107  continue;
6108  }
6109 
6110 //============================================================
6111 // final calculation of likelihood for selected sky location
6112 //============================================================
6113 
6114  l = ind<0 ? m : ind;
6115 
6116  NETX (
6117  pa00[0] = a00[0].data + m0[l]*V; ,
6118  pa00[1] = a00[1].data + m1[l]*V; ,
6119  pa00[2] = a00[2].data + m2[l]*V; ,
6120  pa00[3] = a00[3].data + m3[l]*V; ,
6121  pa00[4] = a00[4].data + m4[l]*V; ,
6122  pa00[5] = a00[5].data + m5[l]*V; ,
6123  pa00[6] = a00[6].data + m6[l]*V; ,
6124  pa00[7] = a00[7].data + m7[l]*V; )
6125  NETX (
6126  pa90[0] = a90[0].data + m0[l]*V; ,
6127  pa90[1] = a90[1].data + m1[l]*V; ,
6128  pa90[2] = a90[2].data + m2[l]*V; ,
6129  pa90[3] = a90[3].data + m3[l]*V; ,
6130  pa90[4] = a90[4].data + m4[l]*V; ,
6131  pa90[5] = a90[5].data + m5[l]*V; ,
6132  pa90[6] = a90[6].data + m6[l]*V; ,
6133  pa90[7] = a90[7].data + m7[l]*V; )
6134 
6135  Lo=0;
6136 
6137  for(j=0; j<V; j++) { // select pixels and get dot ptoducts
6138 
6139  pix = this->wc_List[n].getPixel(id,pI[j]);
6140  pix->theta = nLikelihood.getTheta(l);
6141  pix->phi = nLikelihood.getPhi(l);
6142  pix->ellipticity = ISG ? AA : 0.;
6143  pix->polarisation = ISG ? atan2(SI,CO)/4. : 0.;
6144 
6145  E00=E90=gp=gx=gI=xp=xx=XP=XX = 0.;
6146  U = 1;
6147 
6148 
6149  Fp = Fplus.data+j*NIFO;
6150  Fx = Fcros.data+j*NIFO;
6151  am = am00.data+j*NIFO;
6152  AM = am90.data+j*NIFO;
6153  for(i=0; i<nIFO; i++) {
6154  Fp[i] = fp[i][l]*nr[i][j];
6155  Fx[i] = fx[i][l]*nr[i][j];
6156  am[i] = pa00[i][j];
6157  AM[i] = pa90[i][j];
6158  E00 += am[i]*am[i];
6159  E90 += AM[i]*AM[i];
6160 
6161  gp += Fp[i]*Fp[i]+1.e-12;
6162  gx += Fx[i]*Fx[i]+1.e-12;
6163  gI += Fp[i]*Fx[i];
6164  xp += Fp[i]*am[i];
6165  xx += Fx[i]*am[i];
6166  XP += Fp[i]*AM[i];
6167  XX += Fx[i]*AM[i];
6168 
6169  pix->setdata(am[i],'S',i);
6170  pix->setdata(AM[i],'P',i);
6171  xi00.data[i] = 0.;
6172  xi90.data[i] = 0.;
6173 
6174  }
6175 
6176  gr = (gp+gx)*soft;
6177  gR = (gp-gx)/2.;
6178  gc = sqrt(gR*gR+gI*gI); // norm of complex antenna pattern
6179 
6180 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6181 // condition 00 phase
6182 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6183 // find weak vector
6184 
6185  uc = (xp*gx - xx*gI); // u cos of rotation to PCF
6186  us = (xx*gp - xp*gI); // u sin of rotation to PCF
6187  vc = gp*uc + gI*us; // (u*f+)/|u|^2 - 'cos' for v
6188  vs = gx*us + gI*uc; // (u*fx)/|u|^2 - 'sin' for v
6189  um = rotx(Fp,uc,Fx,us,u); // calculate new response vector
6190  vm = rotx(Fx,-vc,Fp,vs,v)+1.e-24; // calculate complementary vector
6191  hh = dotx(u,am,e);
6192  cc = dotx(e,e);
6193 
6194  if((hh*hh-cc)/um<=0. || E00<Eo) U=0;
6195 
6196 // regulator
6197 
6198  ii = netx(u,um,v,vm,GAMMA);
6199  if(ii<N_2 && gamma<0.) U=0; // superclean selection cut
6200 
6201  uc += xp*gr; // u cos of rotation to PCF
6202  us += xx*gr; // u sin of rotation to PCF
6203 
6204  if(ii<N_1 && gamma!=0) {
6205  uc = xp*(gc+gR)+xx*gI;
6206  us = xx*(gc-gR)+xp*gI;
6207  }
6208 
6209  vc = gp*uc + gI*us; // (u*f+)/|u|^2 - 'cos' for v
6210  vs = gx*us + gI*uc; // (u*fx)/|u|^2 - 'sin' for v
6211  um = rotx(Fp,uc,Fx,us,u); // calculate new response vector
6212  vm = rotx(Fx,-vc,Fp,vs,v)+1.e-24; // calculate complementary vector
6213 
6214 // normalize u and v vectors
6215 
6216  um = sqrt(um);
6217  vm = sqrt(vm);
6218 
6219  hh = gg = 0.;
6220  for(i=0; i<nIFO; i++) {
6221  u[i] = u[i]/um;
6222  v[i] = v[i]/vm;
6223  hh += u[i]*am[i]; // (u*X) - solution
6224  gg += v[i]*am[i]; // (v*X) - solution
6225  }
6226 
6227 // calculate energy disbalance vectors
6228 
6229  co=si=0.;
6230  for(i=0; i<nIFO; i++) { // disbalance vectors
6231  cc = local ? am[i]/(am[i]*am[i]+2.) : 1.;
6232  pp[i] = cc*(am[i]-hh*u[i])*u[i];
6233  qq[i] = cc*((2.*hh*u[i]-am[i])*v[i] + u[i]*u[i]*gg);
6234  co += pp[i]*pp[i] + qq[i]*qq[i]; // cos (version 1)
6235  si += pp[i]*qq[i]; // sin
6236  }
6237  cc = sqrt(si*si+co*co)+1.e-24;
6238  co = co/cc;
6239  si = si/cc;
6240  if(!eDisbalance) {co=1.;si=0.;}
6241 
6242 // corrected likelihood
6243 
6244  hh = gg = 0.;
6245  for(i=0; i<nIFO; i++) { // solution for h(t,f)
6246  e[i] = u[i]*co + v[i]*si; // final projection vector
6247  v[i] = v[i]*co - u[i]*si; // orthogonal v vector
6248  u[i] = e[i];
6249  hh += u[i]*am[i]; // solution for hu(t,f)
6250  gg += v[i]*am[i]; // solution for hv(t,f)
6251  }
6252 
6253 // second iteration
6254 
6255  co=si=0.;
6256  for(i=0; i<nIFO; i++) { // disbalance vectors
6257  cc = local ? am[i]/(am[i]*am[i]+2.) : 1.;
6258  pp[i] = cc*(am[i]-hh*u[i])*u[i];
6259  qq[i] = cc*((2.*hh*u[i]-am[i])*v[i] + u[i]*u[i]*gg);
6260  co += pp[i]*pp[i] + qq[i]*qq[i]; // cos (version 1)
6261  si += pp[i]*qq[i]; // sin
6262  }
6263  cc = sqrt(si*si+co*co)+1.e-24;
6264  co = co/cc;
6265  si = si/cc;
6266  if(!eDisbalance) {co=1.;si=0.;}
6267 
6268  hh = 0.;
6269  for(i=0; i<nIFO; i++) { // corrected u vector for 00 amplitude
6270  u[i] = u[i]*co + v[i]*si;
6271  e[i] = am[i]*u[i];
6272  hh += e[i]*U;
6273  }
6274 
6275  La = hh*hh;
6276  wp = wx = 0.;
6277  for(i=0; i<nIFO; i++) { // detector response for 00 data
6278  pix->setdata(u[i]*hh/sqrt(nv[i][j]),'W',i);
6279  wp += Fp[i]*u[i]*hh;
6280  wx += Fx[i]*u[i]*hh;
6281  }
6282 
6283 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6284 // condition 90 phase
6285 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6286 // find weak vector
6287 
6288  U = 1;
6289  uc = XP*gx - XX*gI; // u cos of rotation to PCF
6290  us = XX*gp - XP*gI; // u sin of rotation to PCF
6291  vc = gp*uc + gI*us; // (u*f+)/|u|^2 - 'cos' for v
6292  vs = gx*us + gI*uc; // (u*fx)/|u|^2 - 'sin' for v
6293  um = rotx(Fp,uc,Fx,us,u); // calculate new response vector
6294  vm = rotx(Fx,-vc,Fp,vs,v)+1.e-24; // calculate complementary vector
6295  hh = dotx(u,AM,e);
6296  cc = dotx(e,e);
6297 
6298  if((hh*hh-cc)/um<=0. || E90<Eo) U=0;
6299 
6300 // sky regulator
6301 
6302  ii = netx(u,um,v,vm,GAMMA);
6303  if(ii<N_2 && gamma<0.) U=0; // superclean selection cut
6304 
6305  uc += XP*gr; // u cos of rotation to PCF
6306  us += XX*gr; // u sin of rotation to PCF
6307 
6308  if(ii<N_1 && gamma!=0) {
6309  uc = XP*(gc+gR)+XX*gI;
6310  us = XX*(gc-gR)+XP*gI;
6311  }
6312 
6313  vc = gp*uc + gI*us; // (u*f+)/|u|^2 - 'cos' for v
6314  vs = gx*us + gI*uc; // (u*fx)/|u|^2 - 'sin' for v
6315  um = rotx(Fp,uc,Fx,us,u); // calculate new response vector
6316  vm = rotx(Fx,-vc,Fp,vs,v)+1.e-24; // calculate complementary vector
6317 
6318 // normalize u and v vectors
6319 
6320  um = sqrt(um);
6321  vm = sqrt(vm);
6322 
6323  hh = gg = 0.;
6324  for(i=0; i<nIFO; i++) {
6325  u[i] = u[i]/um;
6326  v[i] = v[i]/vm;
6327  hh += u[i]*AM[i]; // (u*X) - solution
6328  gg += v[i]*AM[i]; // (v*X) - solution
6329  }
6330 
6331 // calculate energy disbalance vectors
6332 
6333  co=si=0.;
6334  for(i=0; i<nIFO; i++) { // disbalance vectors
6335  cc = local ? AM[i]/(AM[i]*AM[i]+2.) : 1.;
6336  pp[i] = cc*(AM[i]-hh*u[i])*u[i];
6337  qq[i] = cc*((2.*hh*u[i]-AM[i])*v[i] + u[i]*u[i]*gg);
6338  co += pp[i]*pp[i] + qq[i]*qq[i]; // cos (version 1)
6339  si += pp[i]*qq[i]; // sin
6340  }
6341  cc = sqrt(si*si+co*co)+1.e-24;
6342  co = co/cc;
6343  si = si/cc;
6344  if(!eDisbalance) {co=1.;si=0.;}
6345 
6346 // corrected likelihood
6347 
6348  hh = gg = 0.;
6349  for(i=0; i<nIFO; i++) { // solution for h(t,f)
6350  e[i] = u[i]*co + v[i]*si; // final projection vector
6351  v[i] = v[i]*co - u[i]*si; // orthogonal v vector
6352  u[i] = e[i];
6353  hh += u[i]*AM[i]; // solution for hu(t,f)
6354  gg += v[i]*AM[i]; // solution for hv(t,f)
6355  }
6356 
6357 // second iteration
6358 
6359  co=si=0.;
6360  for(i=0; i<nIFO; i++) { // disbalance vectors
6361  cc = local ? AM[i]/(AM[i]*AM[i]+2.) : 1.;
6362  pp[i] = cc*(AM[i]-hh*u[i])*u[i];
6363  qq[i] = cc*((2.*hh*u[i]-AM[i])*v[i] + u[i]*u[i]*gg);
6364  co += pp[i]*pp[i] + qq[i]*qq[i]; // cos (version 1)
6365  si += pp[i]*qq[i]; // sin
6366  }
6367  cc = sqrt(si*si+co*co)+1.e-24;
6368  co = co/cc;
6369  si = si/cc;
6370  if(!eDisbalance) {co=1.;si=0.;}
6371 
6372 
6373  hh = 0.;
6374  for(i=0; i<nIFO; i++) { // corrected u vector for 00 amplitude
6375  u[i] = u[i]*co + v[i]*si;
6376  e[i] = AM[i]*u[i];
6377  hh += e[i]*U;
6378  }
6379 
6380  La+= hh*hh; // 90 likelihood
6381  WP = WX = 0.;
6382  for(i=0; i<nIFO; i++) { // detector response for 90 data
6383  pix->setdata(u[i]*hh/sqrt(nv[i][j]),'U',i);
6384  WP += Fp[i]*u[i]*hh;
6385  WX += Fx[i]*u[i]*hh;
6386  }
6387 
6388  if(ISG) {
6389  ap = (1+AA*AA);
6390  cc = (1-AA*AA);
6391  as = SI*cc;
6392  ac = CO*cc;
6393  gg = (gp+gx)*ap + (gp-gx)*ac + 2*gI*as;
6394  hp = (wp*(ap+ac) + 2*AA*WX + wx*as)/gg;
6395  hx = (wx*(ap-ac) - 2*AA*WP + wp*as)/gg;
6396  HP = (WP*(ap+ac) - 2*AA*wx + WX*as)/gg;
6397  HX = (WX*(ap-ac) + 2*AA*wp + WP*as)/gg;
6398  La = rotx(Fp,hp,Fx,hx,e)+rotx(Fp,HP,Fx,HX,e);
6399 
6400  for(i=0; i<nIFO; i++) {
6401  pix->setdata((hp*fp[i][l]+hx*fx[i][l])/GG.data[j],'W',i); // 00 detector respose
6402  pix->setdata((HP*fp[i][l]+HX*fx[i][l])/GG.data[j],'U',i); // 90 detector respose
6403  }
6404  }
6405 
6406  pix->likelihood = La/2.;
6407  Lo += La/2;
6408 
6409  if(!core) pix->core = (E00<Eo && E90<Eo) ? false : true;
6410  if(ID) {
6411  this->pixeLHood.data[pix->time] = La/2.;
6412  this->pixeLNull.data[pix->time] = (E00+E90-La)/2+1.;
6413  }
6414 
6415  count++;
6416  }
6417 
6418 // fill in backward delay configuration
6419 
6420  vtof->clear();
6421  NETX (
6422  vtof->push_back(int(M/2)-int(m0[l])); ,
6423  vtof->push_back(int(M/2)-int(m1[l])); ,
6424  vtof->push_back(int(M/2)-int(m2[l])); ,
6425  vtof->push_back(int(M/2)-int(m3[l])); ,
6426  vtof->push_back(int(M/2)-int(m4[l])); ,
6427  vtof->push_back(int(M/2)-int(m5[l])); ,
6428  vtof->push_back(int(M/2)-int(m6[l])); ,
6429  vtof->push_back(int(M/2)-int(m7[l])); )
6430 
6431 // calculation of error regions
6432 
6433  skyProb *= Em/IIm;
6434  T = cTo.data[k]+getifo(0)->TFmap.start(); // trigger time
6435  if(iID<=0 && type!='E') getSkyArea(id,n,T); // calculate error regions
6436 
6437  if(fabs(Lm-Lo)/Lo>1.e-4)
6438  cout<<"likelihood warning: "<<Lm<<" "<<Lo<<endl;
6439 
6440  if(Em>0 && ID) {
6441  cout<<"max value: "<<STAT<<" at (theta,phi) = ("<<nLikelihood.getTheta(l)
6442  <<","<<nLikelihood.getPhi(l)<<") Likelihood: loop: "
6443  <<Lm<<", final: "<<Lo<<", sky: "<<LPm/2<<", energy: "<<Em/2<<endl;
6444  break;
6445  }
6446 
6447  if (mdcListSize() && n==0) { // only for lag=0 && simulation mode
6448  if (this->getwave(id, 0, 'W')) {
6449  //if (this->getwave(id, 0, 'S')) {
6450  detector* pd;
6451  size_t M = this->ifoList.size();
6452  for(int i=0; i<(int)M; i++) { // loop over detectors
6453  pd = this->getifo(i);
6454  pd->RWFID.push_back(id); // save cluster ID
6455 
6456  // save reconstructed waveform
6457 
6458  double gps = this->getifo(0)->getTFmap()->start();
6459  double wfStart = gps + pd->waveForm.start();
6460  //double wfRate = pd->waveForm.rate();
6461  //double wfSize = pd->waveForm.size();
6462 
6464  *wf = pd->waveForm;
6465  wf->start(wfStart);
6466  pd->RWFP.push_back(wf);
6467  }
6468  }
6469  }
6470 
6471  if(ID && !EFEC) {
6472  this->nSensitivity.gps = T;
6473  this->nAlignment.gps = T;
6474  this->nDisbalance.gps = T;
6475  this->nLikelihood.gps = T;
6476  this->nNullEnergy.gps = T;
6477  this->nCorrEnergy.gps = T;
6478  this->nCorrelation.gps = T;
6479  this->nSkyStat.gps = T;
6480  this->nEllipticity.gps = T;
6481  this->nPolarisation.gps = T;
6482  this->nNetIndex.gps = T;
6483  }
6484  } // end of loop over clusters
6485  if(ID) break;
6486  } // end of loop over time shifts
6487  return count;
6488 }
6489 
6490 //**************************************************************************
6491 //: initialize network data matrix NDM, works with likelihoodB()
6492 //**************************************************************************
6493 
6494 bool network::setndm(size_t ID, size_t lag, bool core, int type)
6495 {
6496  int ii;
6497  size_t j,n,m,k,K,V,id;
6498  size_t N = this->ifoList.size(); // number of detectors
6499  int N_1 = N>2 ? int(N)-1 : 2;
6500  int N_2 = N>2 ? int(N)-2 : 1;
6501  if(!N) return false;
6502 
6503  wavearray<double> cid; // cluster ID
6504  wavearray<double> rat; // cluster rate
6505  wavearray<double> lik; // likelihood
6506  vector<wavearray<double> > snr(N); // data stream snr
6507  vector<wavearray<double> > nul(N); // biased null stream
6508  netpixel* pix;
6509  wavecomplex gC;
6510  detector* pd;
6511 
6512  std::vector<int>* vi;
6513  std::vector<wavecomplex> A; // antenna patterns
6514  vectorD esnr; esnr.resize(N); // SkSk snr
6515  vectorD xsnr; xsnr.resize(N); // XkSk snr
6516  vectorD am; am.resize(N); // amplitude vector
6517  vectorD pp; pp.resize(N); // energy disbalance vector
6518  vectorD qq; qq.resize(N); // complementary disbalance vector
6519  vectorD ee; ee.resize(N); // temporary
6520  vectorD Fp; Fp.resize(N); // + antenna pattern
6521  vectorD Fx; Fx.resize(N); // x antenna pattern
6522  vectorD u; u.resize(N); // PCF u vector
6523  vectorD v; v.resize(N); // PCF v vector
6524  vectorD e; e.resize(N); // PCF final vector
6525  vectorD r; r.resize(N); // PCF final vector
6526 
6527  double um,vm,cc,hh,gr,gc,gI,Et,E,Xp,Xx,gp,gx;
6528  double gg,co,si,uc,us,vc,vs,gR,a,nr;
6529  double S_NDM = 0.;
6530  double S_NUL = 0.;
6531  double S_NIL = 0.;
6532  double S_SNR = 0.;
6533  double x_SNR = 0.;
6534  double e_SNR = 0.;
6535  double bIAS = 0.;
6536  double response = 0.;
6537  size_t count = 0;
6538 
6539 // regulators hard <- soft <0> weak -> hard
6540 // gamma = -1 <- 0 -> 1
6541 
6542  double soft = delta>0. ? delta : 0.;
6543  double GAMMA = 1.-gamma*gamma; // network regulator
6544  bool status = false;
6545 
6546  this->gNET = this->aNET = this->eCOR = E = 0.;
6547  A.resize(N);
6548 
6549  for(n=0; n<N; n++) {
6550  nul[n] = this->wc_List[lag].get((char*)"null",n+1,'W',type);
6551  snr[n] = this->wc_List[lag].get((char*)"energy",n+1,'S',type);
6552  this->getifo(n)->sSNR = 0.;
6553  this->getifo(n)->xSNR = 0.;
6554  this->getifo(n)->ekXk = 0.;
6555  this->getifo(n)->null = 0.;
6556  for(m=0; m<NIFO; m++) { this->getifo(n)->ED[m] = 0.; }
6557  for(m=0; m<N; m++) { NDM[n][m] = 0.; }
6558  esnr[n] = xsnr[n] = 0.;
6559  }
6560 
6561  if(!this->wc_List[lag].size()) return status;
6562 
6563  cid = this->wc_List[lag].get((char*)"ID",0,'S',type);
6564  rat = this->wc_List[lag].get((char*)"rate",0,'S',type);
6565  lik = this->wc_List[lag].get((char*)"like",0,'S',type);
6566  K = cid.size();
6567 
6568  for(k=0; k<K; k++) { // loop over clusters
6569 
6570  id = size_t(cid[k]+0.1);
6571  if(id != ID) continue;
6572 
6573  vi = &(this->wc_List[lag].cList[ID-1]);
6574  V = vi->size();
6575  if(!V) continue;
6576 
6577 // normalization of antenna patterns
6578 // calculation of the rotation angles
6579 // calculation of the likelihood matrix
6580 
6581  for(j=0; j<V; j++) {
6582 
6583  pix = this->wc_List[lag].getPixel(ID,j);
6584  if(!pix) {
6585  cout<<"network::setndm() error: NULL pointer"<<endl;
6586  exit(1);
6587  }
6588  if(!pix->core && core) continue;
6589  if(pix->rate != rat.data[k]) continue;
6590 
6591  count++;
6592  gr=Et=gg=Xp=Xx = 0.;
6593  gC=0.;
6594 
6595  for(n=0; n<N; n++) { // calculate noise normalization
6596  nr = pix->getdata('N',n); // noise rms
6597  gg += 1./(nr*nr);
6598  }
6599  gg = sqrt(gg);
6600 
6601  for(n=0; n<N; n++) { // calculate patterns
6602  am[n] = pix->getdata('S',n); // snr amplitude
6603  nr = pix->getdata('N',n)*gg; // noise rms
6604  Et += am[n]*am[n];
6605  pd = this->getifo(n);
6606  Fp[n] = pd->mFp.get(pix->theta,pix->phi)/nr;
6607  Fx[n] = pd->mFx.get(pix->theta,pix->phi)/nr;
6608 
6609  A[n].set(Fp[n],Fx[n]);
6610 
6611  gr += A[n].abs()/2.;
6612  gC += A[n]*A[n];
6613  Xp += am[n]*Fp[n];
6614  Xx += am[n]*Fx[n];
6615  }
6616  E += Et;
6617  gc = gC.mod()/2.;
6618  gR = gC.real()/2.;
6619  gI = gC.imag()/2.;
6620  gp = gr+gR+1.e-12;
6621  gx = gr-gR+1.e-12;
6622 
6623  this->gNET += (gr+gc)*Et;
6624  this->aNET += (gr-gc)*Et;
6625 
6626 // find weak vector
6627 
6628  uc = Xp*gx - Xx*gI; // u cos of rotation to PCF
6629  us = Xx*gp - Xp*gI; // u sin of rotation to PCF
6630  vc = gp*uc + gI*us; // cos of rotation to PCF for v
6631  vs = gx*us + gI*uc; // sin of rotation to PCF for v
6632 
6633  um = vm = hh = cc = 0.;
6634  for(n=0; n<N; n++) {
6635  u[n] = Fp[n]*uc + Fx[n]*us; // u - weak vector
6636  v[n] = Fp[n]*vs - Fx[n]*vc; // v - orthogonal to u
6637  um += u[n]*u[n];
6638  vm += v[n]*v[n];
6639  hh += u[n]*am[n];
6640  cc += u[n]*am[n]*u[n]*am[n];
6641  }
6642  vm += 1.e-24; // H1H2 regulator
6643 
6644  if((hh*hh-cc)/um <= 0.) continue; // negative correlated energy
6645 
6646 // regulator
6647 
6648  ii = 0;
6649  for(n=0; n<N; n++) {
6650  if(u[n]*u[n]/um > 1-GAMMA) ii++;
6651  if(u[n]*u[n]/um+v[n]*v[n]/vm > GAMMA) ii--;
6652  }
6653  this->iNET += ii*Et;
6654 
6655  if(ii<N_2 && gamma<0.) continue; // superclean set
6656 
6657  gg = (gp+gx)*soft;
6658  uc = Xp*(gx+gg) - Xx*gI; // u cos of rotation to PCF
6659  us = Xx*(gp+gg) - Xp*gI; // u sin of rotation to PCF
6660 
6661  if(ii<N_1 && gamma!=0) {
6662  uc = Xp*(gc+gR)+Xx*gI;
6663  us = Xx*(gc-gR)+Xp*gI;
6664  }
6665 
6666  vc = gp*uc + gI*us; // (u*f+)/|u|^2 - 'cos' for v
6667  vs = gx*us + gI*uc; // (u*fx)/|u|^2 - 'sin' for v
6668  um = vm = 0.;
6669  for(n=0; n<N; n++) {
6670  u[n] = Fp[n]*uc + Fx[n]*us;
6671  v[n] = Fp[n]*vs - Fx[n]*vc;
6672  um += u[n]*u[n]; // calculate u and return its norm
6673  vm += v[n]*v[n]; // calculate u and return its norm
6674  }
6675  vm += 1.e-24; // H1H2 regulator
6676 
6677 // calculate unity vectors in PCF
6678 
6679  hh = gg = 0.;
6680  for(n=0; n<N; n++) {
6681  u[n] /=sqrt(um);
6682  v[n] /=sqrt(vm); // unity vectors in PCF
6683  hh += u[n]*am[n]; // (u*X) - solution
6684  gg += v[n]*am[n]; // (v*X) - solution
6685  }
6686 
6687 // calculate energy disbalance vectors
6688 
6689  co = si = 0.;
6690  for(n=0; n<N; n++) { // disbalance vectors
6691  cc = local ? am[n]/(am[n]*am[n]+2.) : 1.;
6692  qq[n] = cc*((2*hh*u[n]-am[n])*v[n]+u[n]*u[n]*gg); // complementary energy disbalance
6693  pp[n] = cc*(am[n]-hh*u[n])*u[n]; // energy disbalance
6694  co += pp[n]*pp[n] + qq[n]*qq[n]; // cos
6695  si += pp[n]*qq[n]; // sin
6696  }
6697  cc = atan2(si,co+1.e-24); // rotation angle
6698  co = cos(cc); // cos(psi)
6699  si = sin(cc); // sin(psi)
6700  if(!eDisbalance) {co=1.;si=0.;}
6701 
6702  hh = gg = 0.;
6703  for(n=0; n<N; n++) {
6704  e[n] = u[n]*co+v[n]*si; // final projection vector
6705  r[n] = v[n]*co-u[n]*si;
6706  hh += e[n]*am[n];
6707  gg += r[n]*am[n];
6708  }
6709 
6710 // second iteration
6711 
6712  co = si = 0.;
6713  for(n=0; n<N; n++) { // disbalance vectors
6714  cc = local ? am[n]/(am[n]*am[n]+2.) : 1.;
6715  pp[n] = cc*(am[n]-hh*e[n])*e[n]; // energy disbalance
6716  qq[n] = cc*((2*hh*e[n]-am[n])*r[n]+e[n]*e[n]*gg); // complementary energy disbalance
6717  co += pp[n]*pp[n] + qq[n]*qq[n]; // cos (version 1)
6718  si += pp[n]*qq[n]; // sin
6719  }
6720  cc = atan2(si,co+1.e-24); // rotation angle
6721  co = cos(cc); // cos(psi)
6722  si = sin(cc); // sin(psi)
6723  if(!eDisbalance) {co=1.;si=0.;}
6724 
6725  for(n=0; n<N; n++) {
6726  e[n] = e[n]*co+r[n]*si; // final projection vector
6727  }
6728 
6729 // likelihood matrix
6730 
6731  for(n=0; n<N; n++) { // loop over NDM elements
6732  response = 0.;
6733  this->getifo(n)->null += e[n]*e[n]; // bias
6734 
6735  for(m=0; m<N; m++) {
6736  gg = e[n]*am[n]*e[m]*am[m]; // en*an * em*am
6737  NDM[n][m] += gg;
6738  response += e[n]*e[m]*am[m]; // detector response
6739  if(n!=m) this->eCOR += gg; // correlated energy
6740  status = true;
6741  }
6742 
6743  esnr[n] += response*response; // reconstructed SNR: Sk*Sk
6744  xsnr[n] += am[n]*response; // reconstructed SNR: Xk*Sk
6745  e_SNR += response*response; // total reconstructed SNR: sum Sk*Sk
6746  x_SNR += am[n]*response; // total reconstructed SNR: sum Xk*Sk
6747  this->getifo(n)->ED[3] += fabs(response*(am[n]-response));
6748  this->getifo(n)->ED[4] += fabs(response*(am[n]-response));
6749  }
6750  }
6751 
6752 // check normalization
6753 
6754  this->norm = x_SNR/e_SNR; // norm factor
6755  if(fabs(this->norm-1) > 1.e-4)
6756  cout<<"network::setndm(): incorrect likelihood normalization: "<<this->norm<<endl;
6757 
6758  for(n=0; n<N; n++) {
6759  bIAS += this->getifo(n)->null;
6760  this->getifo(n)->null += nul[n].data[k]; // detector unbiased null stream
6761  this->getifo(n)->sSNR = esnr[n]; // s-energy of the detector response
6762  this->getifo(n)->xSNR = xsnr[n]; // x-energy of the detector response
6763  S_NUL += this->getifo(n)->null; // total unbiased null stream
6764  S_NIL += nul[n].data[k]; // biased null stream
6765  S_SNR += snr[n].data[k]; // total energy
6766 
6767  this->getifo(n)->ED[0] = (esnr[n]-xsnr[n]);
6768  this->getifo(n)->ED[1] = fabs(esnr[n]-xsnr[n]);
6769  this->getifo(n)->ED[2] = fabs(esnr[n]-xsnr[n]);
6770 
6771  for(m=0; m<N; m++) S_NDM += NDM[n][m];
6772 
6773  }
6774 
6775  if(count) { this->gNET /= E; this->aNET /= E; this->iNET /= E;}
6776 
6777  a = S_NDM - lik.data[k];
6778  if(fabs(a)/S_SNR>1.e-6)
6779  cout<<"ndm-likelihood mismatch: "<<a<<" "<<S_NDM<<" "<<lik.data[k]<<" "<<norm<<endl;
6780  a = fabs(1 - (S_NDM+S_NIL)/S_SNR)/count;
6781  if(a>1.e-5)
6782  cout<<"biased energy disbalance: "<<a<<" "<<S_SNR-S_NDM<<" "<<S_NIL<<" size="<<count<<endl;
6783 
6784  if(status) break;
6785  }
6786  return status;
6787 }
6788 
6789 
6790 //**************************************************************************
6791 //: initialize network data matrix (NDM), works with likelihoodI
6792 //**************************************************************************
6793 bool network::SETNDM(size_t ID, size_t lag, bool core, int type)
6794 {
6795  int ii;
6796  size_t j,n,m,k,K,V;
6797  size_t N = this->ifoList.size(); // number of detectors
6798  int N_1 = N>2 ? int(N)-1 : 2;
6799  int N_2 = N>2 ? int(N)-2 : 1;
6800  if(!N) return false;
6801 
6802  wavearray<double> cid; // cluster ID
6803  wavearray<double> rat; // cluster rate
6804  wavearray<double> lik; // likelihood
6805  vector<wavearray<double> > snr(N); // data stream snr
6806  vector<wavearray<double> > nul(N); // biased null stream
6807  vector<wavearray<double> > SNR(N); // data stream snr
6808  vector<wavearray<double> > NUL(N); // biased null stream
6809  netpixel* pix;
6810  wavecomplex gC,Z;
6811  detector* pd;
6812 
6813  std::vector<int>* vint;
6814  std::vector<wavecomplex> A; // patterns in DPF
6815  vectorD esnr; esnr.resize(N); // SkSk snr
6816  vectorD xsnr; xsnr.resize(N); // XkSk snr
6817  vectorD ssnr; ssnr.resize(N); // total energy of non shifted detector output
6818  vectorD SSNR; SSNR.resize(N); // total energy of phase shifted detector output
6819  vectorD h00; h00.resize(N); // unmodeled 00 response vector
6820  vectorD h90; h90.resize(N); // unmodeled 00 response vector
6821  vectorD u00; u00.resize(N); // unmodeled 00 unit response vector
6822  vectorD u90; u90.resize(N); // unmodeled 90 unit response vector
6823  vectorD am; am.resize(N); // 00 phase response
6824  vectorD AM; AM.resize(N); // 90 phase response
6825  vectorD qq; qq.resize(N); // energy disbalance vector
6826  vectorD pp; pp.resize(N); // energy disbalance vector
6827  vectorD ee; pp.resize(N); // temporary
6828  vectorD Fp; Fp.resize(N); // + antenna pattern
6829  vectorD Fx; Fx.resize(N); // x antenna pattern
6830  vectorD u; u.resize(N); // unity vector
6831  vectorD v; v.resize(N); // unity vector
6832  vectorD e; e.resize(N); // unity vector
6833 
6834  double a,b,aa,psi,gg,gr,gc,gI,gR,E90,E00,E,fp,fx,vc,vs;
6835  double xx,xp,XX,XP,uc,us,co,hh,gp,gx,xi00,xi90,o00,o90;
6836  double hgw,HGW,wp,WP,wx,WX,HH,um,vm,si,cc;
6837  double S_NDM = 0.;
6838  double S_NUL = 0.;
6839  double s_snr = 0.;
6840  double S_SNR = 0.;
6841  size_t count = 0;
6842 
6843 // regulator soft <- weak -> hard
6844 // gamma = -1 <- 0 -> 1
6845 
6846  double soft = delta>0. ? delta : 0.;
6847  double GAMMA = 1.-gamma*gamma; // network regulator
6848  double Eo = this->acor*this->acor*N;
6849 
6850  double nC = this->MRA ? 1. : 2.; // NDM normalization Coefficient
6851 
6852  bool status = false;
6853  bool ISG = false;
6854 
6855  if(tYPe=='I' || tYPe=='S' || tYPe=='G') ISG = true;
6856  if(tYPe=='i' || tYPe=='s' || tYPe=='g') ISG = true;
6857 
6858  A.resize(N);
6859 
6860  this->gNET = 0.;
6861  this->aNET = 0.;
6862  this->iNET = 0.;
6863  this->eCOR = 0.;
6864  E = 0.;
6865 
6866  for(n=0; n<N; n++) {
6867  nul[n] = this->wc_List[lag].get((char*)"null",n+1,'W',type);
6868  NUL[n] = this->wc_List[lag].get((char*)"null",n+1,'U',type);
6869  snr[n] = this->wc_List[lag].get((char*)"energy",n+1,'S',type);
6870  SNR[n] = this->wc_List[lag].get((char*)"energy",n+1,'P',type);
6871  this->getifo(n)->sSNR = 0.;
6872  this->getifo(n)->xSNR = 0.;
6873  this->getifo(n)->ekXk = 0.;
6874  this->getifo(n)->null = 0.;
6875  for(m=0; m<5; m++) { this->getifo(n)->ED[m] = 0.; }
6876  for(m=0; m<N; m++) { NDM[n][m] = 0.; }
6877  esnr[n]=xsnr[n]=ssnr[n]=SSNR[n]=0.;
6878  }
6879 
6880  if(!this->wc_List[lag].size()) return false;
6881 
6882  cid = this->wc_List[lag].get((char*)"ID",0,'S',type);
6883  rat = this->wc_List[lag].get((char*)"rate",0,'S',type);
6884  lik = this->wc_List[lag].get((char*)"like",0,'S',type);
6885  K = cid.size();
6886 
6887  for(k=0; k<K; k++) { // loop over clusters
6888 
6889  if(size_t(cid[k]+0.1) != ID) continue;
6890 
6891  vint = &(this->wc_List[lag].cList[ID-1]);
6892  V = vint->size();
6893  if(!V) continue;
6894 
6895  // normalization of antenna patterns
6896  // calculation of the rotation angles
6897  // calculation of the likelihood matrix
6898 
6899  for(j=0; j<V; j++) {
6900 
6901  pix = this->wc_List[lag].getPixel(ID,j);
6902  if(!pix) {
6903  cout<<"network::SETNDM() error: NULL pointer"<<endl;
6904  exit(1);
6905  }
6906  if(!pix->core && core) continue;
6907  if((pix->rate != rat.data[k]) && type) continue;
6908 
6909 
6910  psi = 2*pix->polarisation; // polarisation rotation angle
6911  Z.set(cos(psi),-sin(psi));
6912 
6913  count++;
6914  gr=gg=xp=xx=XP=XX=E00=E90 = 0.;
6915  o00 = o90 = 1.;
6916  gC = 0.;
6917 
6918  for(n=0; n<N; n++) {
6919  b = pix->getdata('N',n); // noise rms
6920  gg += 1./b/b; // noise normalization
6921  }
6922  gg = sqrt(gg);
6923 
6924  for(n=0; n<N; n++) { // calculate patterns
6925  am[n] = pix->getdata('S',n); // snr amplitude
6926  AM[n] = pix->getdata('P',n); // snr 90 degrees amplitude
6927  E00 += am[n]*am[n];
6928  E90 += AM[n]*AM[n];
6929  b = pix->getdata('N',n)*gg; // noise rms
6930  pd = this->getifo(n);
6931  fp = pd->mFp.get(pix->theta,pix->phi);
6932  fx = pd->mFx.get(pix->theta,pix->phi);
6933  A[n].set(fp/b,fx/b);
6934  A[n] *= Z; // rotate patterns
6935  Fp[n] = A[n].real();
6936  Fx[n] = A[n].imag();
6937  gr += A[n].abs()/2.;
6938  gC += A[n]*A[n];
6939  xp += Fp[n]*am[n];
6940  xx += Fx[n]*am[n];
6941  XP += Fp[n]*AM[n];
6942  XX += Fx[n]*AM[n];
6943  }
6944 
6945  E += E00+E90;
6946  gc = gC.mod()/2.;
6947  gR = gC.real()/2.;
6948  gI = gC.imag()/2.;
6949  gp = gr+gR+1.e-12;
6950  gx = gr-gR+1.e-12;
6951  aa = pix->ellipticity;
6952 
6953  this->norm = aa; // save to store in root file as norm
6954  this->gNET += (gr+gc)*(E00+E90);
6955  this->aNET += (gr-gc)*(E00+E90);
6956 
6957 //====================================================
6958 // calculate unity vectors in PCF for 00 degree phase
6959 //====================================================
6960 
6961 // find weak vector
6962 
6963  uc = xp*gx - xx*gI; // u cos of rotation to PCF
6964  us = xx*gp - xp*gI; // u sin of rotation to PCF
6965  vc = gp*uc + gI*us; // cos of rotation to PCF for v
6966  vs = gx*us + gI*uc; // sin of rotation to PCF for v
6967 
6968  um = vm = hh = cc = 0.;
6969  for(n=0; n<N; n++) {
6970  u[n] = Fp[n]*uc + Fx[n]*us;
6971  v[n] = Fp[n]*vs - Fx[n]*vc;
6972  um += u[n]*u[n];
6973  vm += v[n]*v[n];
6974  hh += u[n]*am[n];
6975  cc += u[n]*am[n]*u[n]*am[n];
6976  }
6977  vm += 1.e-24; // H1H2 regulator
6978 
6979  if((hh*hh-cc)/um<=0. || E00<Eo) o00=0.;
6980 
6981 // sky regulator
6982 
6983  ii = 0;
6984  for(n=0; n<N; n++) {
6985  if(u[n]*u[n]/um > 1-GAMMA) ii++;
6986  if(u[n]*u[n]/um+v[n]*v[n]/vm > GAMMA) ii--;
6987  }
6988  this->iNET += ii*E00;
6989  if(ii<N_2 && gamma<0.) o00=0.; // superclean selection cut
6990 
6991  gg = (gp+gx)*soft;
6992  uc = xp*(gx+gg) - xx*gI; // u cos of rotation to PCF
6993  us = xx*(gp+gg) - xp*gI; // u sin of rotation to PCF
6994 
6995  if(ii<N_1 && gamma!=0) {
6996  uc = xp*(gc+gR)+xx*gI;
6997  us = xx*(gc-gR)+xp*gI;
6998  }
6999 
7000  vc = gp*uc + gI*us; // (u*f+)/|u|^2 - 'cos' for v
7001  vs = gx*us + gI*uc; // (u*fx)/|u|^2 - 'sin' for v
7002  um = vm = 0.;
7003  for(n=0; n<N; n++) {
7004  u[n] = Fp[n]*uc + Fx[n]*us;
7005  v[n] = Fp[n]*vs - Fx[n]*vc;
7006  um += u[n]*u[n]; // calculate u and return its norm
7007  vm += v[n]*v[n]; // calculate u and return its norm
7008  }
7009  vm += 1.e-24; // H1H2 regulator
7010 
7011 // calculate unity vectors in PCF
7012 
7013  hh = gg = 0.;
7014  for(n=0; n<N; n++) {
7015  u[n] /=sqrt(um);
7016  v[n] /=sqrt(vm); // unity vectors in PCF
7017  hh += u[n]*am[n]; // (u*X) - solution
7018  gg += v[n]*am[n]; // (v*X) - solution
7019  }
7020 
7021 // calculate energy disbalance vectors
7022 
7023  co=si=0.;
7024  for(n=0; n<N; n++) { // disbalance vectors
7025  cc = local ? am[n]/(am[n]*am[n]+2.) : 1.;
7026  pp[n] = cc*(am[n]-hh*u[n])*u[n];
7027  qq[n] = cc*((2.*hh*u[n]-am[n])*v[n] + u[n]*u[n]*gg);
7028  co += pp[n]*pp[n] + qq[n]*qq[n]; // cos (version 1)
7029  si += pp[n]*qq[n]; // sin
7030  }
7031  cc = sqrt(si*si+co*co)+1.e-24;
7032  co = co/cc;
7033  si = si/cc;
7034  if(!eDisbalance) {co=1.;si=0.;}
7035 
7036 // corrected likelihood
7037 
7038  hh = gg = 0.;
7039  for(n=0; n<N; n++) { // solution for h(t,f)
7040  e[n] = u[n]*co + v[n]*si; // final projection vector
7041  v[n] = v[n]*co - u[n]*si; // orthogonal v vector
7042  u[n] = e[n];
7043  hh += u[n]*am[n]; // solution for hu(t,f)
7044  gg += v[n]*am[n]; // solution for hv(t,f)
7045  }
7046 
7047 // second iteration
7048 
7049  co=si=0.;
7050  for(n=0; n<N; n++) { // disbalance vectors
7051  cc = local ? am[n]/(am[n]*am[n]+2.) : 1.;
7052  pp[n] = cc*(am[n]-hh*u[n])*u[n];
7053  qq[n] = cc*((2.*hh*u[n]-am[n])*v[n] + u[n]*u[n]*gg);
7054  co += pp[n]*pp[n] + qq[n]*qq[n]; // cos (version 1)
7055  si += pp[n]*qq[n]; // sin
7056  }
7057  cc = sqrt(si*si+co*co)+1.e-24;
7058  co = co/cc;
7059  si = si/cc;
7060  if(!eDisbalance) {co=1.;si=0.;}
7061 
7062  hh = wp = wx = 0.;
7063  for(n=0; n<N; n++) {
7064  u[n] = u[n]*co+v[n]*si; // final projection vector
7065  hh += u[n]*am[n];
7066  wp += Fp[n]*u[n];
7067  wx += Fx[n]*u[n]*aa;
7068  }
7069  for(n=0; n<N; n++) {
7070  h00[n] = u[n]*am[n]*o00;
7071  u00[n] = u[n]*o00;
7072  am[n] = hh*u[n]*o00; // 90 detector response
7073  }
7074 
7075 //==============================================
7076 // calculate unity vectors in PCF for 90 phase
7077 //==============================================
7078 
7079 // find weak vector
7080 
7081  uc = XP*gx - XX*gI; // u cos of rotation to PCF
7082  us = XX*gp - XP*gI; // u sin of rotation to PCF
7083  vc = gp*uc + gI*us; // cos of rotation to PCF for v
7084  vs = gx*us + gI*uc; // sin of rotation to PCF for v
7085 
7086  um = vm = hh = cc = 0.;
7087  for(n=0; n<N; n++) {
7088  u[n] = Fp[n]*uc + Fx[n]*us;
7089  v[n] = Fp[n]*vs - Fx[n]*vc;
7090  um += u[n]*u[n];
7091  vm += v[n]*v[n];
7092  hh += u[n]*AM[n];
7093  cc += u[n]*AM[n]*u[n]*AM[n];
7094  }
7095  vm += 1.e-24; // H1H2 regulator
7096 
7097  if((hh*hh-cc)/um<=0. || E90<Eo) o90=0.;
7098 
7099 // sky regulator
7100 
7101  ii = 0;
7102  for(n=0; n<N; n++) {
7103  if(u[n]*u[n]/um > 1-GAMMA) ii++;
7104  if(u[n]*u[n]/um+v[n]*v[n]/vm > GAMMA) ii--;
7105  }
7106  this->iNET += ii*E90;
7107  if(ii<N_2 && gamma<0.) o90=0.; // superclean selection cut
7108 
7109  gg = (gp+gx)*soft;
7110  uc = XP*(gx+gg) - XX*gI; // u cos of rotation to PCF
7111  us = XX*(gp+gg) - XP*gI; // u sin of rotation to PCF
7112 
7113  if(ii<N_1 && gamma!=0) {
7114  uc = XP*(gc+gR)+XX*gI;
7115  us = XX*(gc-gR)+XP*gI;
7116  }
7117 
7118  vc = gp*uc + gI*us; // (u*f+)/|u|^2 - 'cos' for v
7119  vs = gx*us + gI*uc; // (u*fx)/|u|^2 - 'sin' for v
7120  um = vm = 0.;
7121  for(n=0; n<N; n++) {
7122  u[n] = Fp[n]*uc + Fx[n]*us;
7123  v[n] = Fp[n]*vs - Fx[n]*vc;
7124  um += u[n]*u[n]; // calculate u and return its norm
7125  vm += v[n]*v[n]; // calculate u and return its norm
7126  }
7127  vm += 1.e-24; // H1H2 regulator
7128 
7129 // calculate unity vectors in PCF
7130 
7131  hh = gg = 0.;
7132  for(n=0; n<N; n++) {
7133  u[n] /=sqrt(um);
7134  v[n] /=sqrt(vm); // unity vectors in PCF
7135  hh += u[n]*AM[n]; // (u*X) - solution
7136  gg += v[n]*AM[n]; // (v*X) - solution
7137  }
7138 
7139 // calculate energy disbalance vectors
7140 
7141  co=si=0.;
7142  for(n=0; n<N; n++) { // disbalance vectors
7143  cc = local ? AM[n]/(AM[n]*AM[n]+2.) : 1.;
7144  pp[n] = cc*(AM[n]-hh*u[n])*u[n];
7145  qq[n] = cc*((2.*hh*u[n]-AM[n])*v[n] + u[n]*u[n]*gg);
7146  co += pp[n]*pp[n] + qq[n]*qq[n]; // cos (version 1)
7147  si += pp[n]*qq[n]; // sin
7148  }
7149  cc = sqrt(si*si+co*co)+1.e-24;
7150  co = co/cc;
7151  si = si/cc;
7152  if(!eDisbalance) {co=1.;si=0.;}
7153 
7154 // corrected likelihood
7155 
7156  hh=gg = 0.;
7157  for(n=0; n<N; n++) { // solution for h(t,f)
7158  e[n] = u[n]*co + v[n]*si; // final projection vector
7159  v[n] = v[n]*co - u[n]*si; // orthogonal v vector
7160  u[n] = e[n];
7161  hh += u[n]*AM[n]; // solution for hu(t,f)
7162  gg += v[n]*AM[n]; // solution for hv(t,f)
7163  }
7164 
7165 // second iteration
7166 
7167  co=si=0.;
7168  for(n=0; n<N; n++) { // disbalance vectors
7169  cc = local ? AM[n]/(AM[n]*AM[n]+2.) : 1.;
7170  pp[n] = cc*(AM[n]-hh*u[n])*u[n];
7171  qq[n] = cc*((2.*hh*u[n]-AM[n])*v[n] + u[n]*u[n]*gg);
7172  co += pp[n]*pp[n] + qq[n]*qq[n]; // cos (version 1)
7173  si += pp[n]*qq[n]; // sin
7174  }
7175  cc = sqrt(si*si+co*co)+1.e-24;
7176  co = co/cc;
7177  si = si/cc;
7178  if(!eDisbalance) {co=1.;si=0.;}
7179 
7180  HH = WP = WX = 0.;
7181  for(n=0; n<N; n++) {
7182  u[n] = u[n]*co+v[n]*si; // final projection vector
7183  HH += u[n]*AM[n];
7184  WP += Fp[n]*u[n];
7185  WX += Fx[n]*u[n]*aa;
7186  }
7187  for(n=0; n<N; n++) {
7188  h90[n] = u[n]*AM[n]*o90;
7189  u90[n] = u[n]*o90;
7190  AM[n] = HH*u[n]*o90; // 90 detector response
7191  }
7192 
7193  gg = gp + aa*aa*gx; // inverse network sensitivity
7194  cc = ISG ? (wp*WX-wx*WP)/gg : 0.0; // cross term
7195  hh = ISG ? (wp*wp+wx*wx)/gg/nC : 1./nC; // 00 L term
7196  HH = ISG ? (WP*WP+WX*WX)/gg/nC : 1./nC; // 90 L term
7197 
7198 //==============================================
7199 // likelihood matrix
7200 //==============================================
7201 
7202  hgw = HGW = 0.;
7203 
7204  for(n=0; n<N; n++) {
7205  hgw += (am[n]*Fp[n] + aa*AM[n]*Fx[n])/gg; // h(0 deg)
7206  HGW += (AM[n]*Fp[n] - aa*am[n]*Fx[n])/gg; // h(90 deg)
7207  }
7208 
7209  for(n=0; n<N; n++) { // loop over NDM elements
7210  xi00 = 0.;
7211  xi90 = 0.;
7212 
7213  for(m=0; m<N; m++) {
7214 
7215  a = h00[n]*h00[m]*hh
7216  + h90[n]*h90[m]*HH
7217  + h00[n]*h90[m]*cc;
7218 
7219  xi00 += u00[n]*h00[m]; // unmodeled 00 response
7220  xi90 += u90[n]*h90[m]; // unmodeled 90 response
7221 
7222  NDM[n][m] += a;
7223  if(n!=m) this->eCOR += a; // correlated energy
7224 
7225  a = h00[n]*h00[m] - h90[n]*h90[m]; // unmodeled diff
7226  this->getifo(n)->ED[3] += a;
7227  status = true;
7228  }
7229 
7230  a = u00[n]*u00[n]*hh + u90[n]*u90[n]*HH; // bias
7231  this->getifo(n)->null += a;
7232 
7233  xx = pix->getdata('S',n); // 0-phase
7234  if(ISG) xi00 = hgw*Fp[n]-aa*HGW*Fx[n]; // 0-phase response
7235  esnr[n] += xi00*xi00; // reconstructed SNR: Sk*Sk
7236  xsnr[n] += xx*xi00; // reconstructed SNR: Xk*Sk
7237  ssnr[n] += xx*xx; // total energy of non shifted output
7238  this->getifo(n)->ED[1] += xi00*(xx-xi00);
7239  this->getifo(n)->ED[4] += fabs(xi00*(xx-xi00));
7240 
7241  XX = pix->getdata('P',n); // 90-phase
7242  if(ISG) xi90 = HGW*Fp[n]+aa*hgw*Fx[n]; // 90-phase response
7243  esnr[n] += xi90*xi90; // reconstructed SNR: Sk*Sk
7244  xsnr[n] += XX*xi90; // reconstructed SNR: Xk*Sk
7245  SSNR[n] += XX*XX; // total energy of phase shifted output
7246  this->getifo(n)->ED[2] += xi90*(XX-xi90);
7247  this->getifo(n)->ED[4] += fabs(xi90*(XX-xi90));
7248 
7249  }
7250  }
7251 
7252 // take into account norm-factor
7253 
7254  for(n=0; n<N; n++) {
7255 
7256  b = (SSNR[n]+ssnr[n] - esnr[n])/nC;
7257  this->getifo(n)->null += b; // detector biased null stream
7258  this->getifo(n)->sSNR = esnr[n]/nC; // s-energy of the detector response
7259  this->getifo(n)->xSNR = xsnr[n]/nC; // x-energy of the detector response
7260  S_NUL += b; // total biased null stream
7261  s_snr += ssnr[n]; // total energy
7262  S_SNR += SSNR[n]; // total energy of phase shifted stream
7263 
7264  for(m=0; m<N; m++) S_NDM += NDM[n][m];
7265 
7266  if(fabs(ssnr[n]-snr[n].data[k])/ssnr[n] > 1.e-6 || fabs(SSNR[n]-SNR[n].data[k])/SSNR[n]>1.e-6)
7267  cout<<"SETNDM()-likelihoodI() SNR mismatch: "<<n<<" "<<ID<<" "
7268  <<ssnr[n]<<":"<<snr[n].data[k]<<" "<<SSNR[n]<<":"<<SNR[n].data[k]<<endl;
7269  }
7270 
7271  if(count) { this->gNET /= E; this->aNET /= E; this->iNET /= E; }
7272 
7273  a = S_NDM - lik.data[k];
7274  if(fabs(a)/S_NDM>1.e-6)
7275  cout<<"NDM-likelihood mismatch: "<<a<<" "<<S_NDM<<" "<<lik.data[k]<<endl;
7276 
7277  a = fabs(1 - nC*(S_NDM+S_NUL)/(s_snr+S_SNR))/count;
7278  if(a>1.e-5)
7279  cout<<"biased energy disbalance: "<<a<<" "<<S_NDM+S_NUL<<" "<<(s_snr+S_SNR)/nC<<endl;
7280 
7281  if(status) break;
7282  }
7283  return status;
7284 }
7285 
7286 
7287 //**************************************************************************
7288 //: set parameters for time shift analysis
7289 //**************************************************************************
7291  size_t lagOff, size_t lagMax,
7292  const char* fname, const char* fmode, size_t* lagSite) {
7293  netcluster wc;
7294  size_t nIFO = this->ifoList.size();
7295  this->wc_List.clear(); this->livTime.clear();
7296 
7297  if(lagStep<=0.) {
7298  cout << "network::setTimeShifts : lagStep must be positive" << endl;
7299  exit(1);
7300  }
7301 
7302  if(lagSize<1) lagSize=1;
7303 
7304  if(strcmp(fmode,"r") && strcmp(fmode,"w") && strcmp(fmode,"s")) {
7305  cout << "network::setTimeShifts : bad fmode : must be r/w/s" << endl;
7306  exit(1);
7307  }
7308 
7309  if(fname) { if(strlen(fname)<1) fname = NULL; } // check file name
7310 
7311  TRandom3 rnd;
7312  size_t n,m,k;
7313  size_t nList = 0;
7314  size_t maxList;
7315  size_t lagIDS = lagOff;
7316  int* lagList[NIFO];
7317  int lagL[NIFO];
7318  int lagH[NIFO];
7319  int N[NIFO];
7320  int id[NIFO];
7321  int ID[NIFO];
7322  int maxIter = 10000000;
7323  detector* pd = NULL;
7324 
7325  for(n=0;n<NIFO;n++) {
7326  lagL[n] = kMinInt;
7327  lagH[n] = kMaxInt;
7328  N[n] = 0;
7329  id[n] = 0;
7330  ID[n] = 0;
7331  }
7332 
7333 // default lag list
7334 
7335  if(lagMax==0) {
7336 
7337  lagIDS += int(getifo(0)->sHIFt/lagStep);
7338  maxList = lagSize+lagIDS;
7339 
7340  for(n=0; n<nIFO; n++) lagList[n] = new int[maxList];
7341  for(m=0; m<maxList; m++) {
7342  for(n=0; n<nIFO; n++) {
7343  pd = this->getifo(n);
7344  lagList[n][m] = n==0 ? m : int(pd->sHIFt/lagStep);
7345  }
7346  }
7347  nList=maxList;
7348  goto final;
7349  }
7350 
7351 // read list of lags from file fname fmode="r" or from string fname fmode="s"
7352 
7353  if(fname && (!strcmp(fmode,"r") || !strcmp(fmode,"s"))) {
7354  if(!strcmp(fmode,"r")) { // read from file
7355 
7356  ifstream in;
7357  in.open(fname, ios::in);
7358  if(!in.good()) {
7359  cout << "network::setTimeShifts : Error Opening File : " << fname << endl;
7360  exit(1);
7361  }
7362 
7363  char str[1024];
7364  int fpos=0;
7365  maxList=0;
7366  while(true) {
7367  in.getline(str,1024);
7368  if (!in.good()) break;
7369  if(str[0] != '#') maxList++;
7370  }
7371 
7372  for(n=0; n<nIFO; n++) lagList[n] = new int[maxList];
7373  in.clear(ios::goodbit);
7374  in.seekg(0, ios::beg);
7375  while(true) {
7376  fpos=in.tellg();
7377  in.getline(str,1024);
7378  if(str[0] == '#') continue;
7379  in.seekg(fpos, ios::beg);
7380  fpos=in.tellg();
7381  in >> m;
7382  for(n=0; n<nIFO; n++) in >> lagList[n][m];
7383  if (!in.good()) break;
7384  }
7385 
7386  in.close();
7387  }
7388 
7389  if(!strcmp(fmode,"s")) { // read from string
7390 
7391  stringstream in;
7392  in << fname; // when fmode='s' then fname contains the lag list
7393 
7394  char str[1024];
7395  int fpos=0;
7396  maxList=0;
7397  while(true) {
7398  in.getline(str,1024);
7399  if (!in.good()) break;
7400  if(str[0] != '#') maxList++;
7401  }
7402 
7403  for(n=0; n<nIFO; n++) lagList[n] = new int[maxList];
7404  in.clear(ios::goodbit);
7405  in.seekg(0, ios::beg);
7406  while(true) {
7407  fpos=in.tellg();
7408  in.getline(str,1024);
7409  if(str[0] == '#') continue;
7410  in.seekg(fpos, ios::beg);
7411  fpos=in.tellg();
7412  in >> m;
7413  for(n=0; n<nIFO; n++) in >> lagList[n][m];
7414  if (!in.good()) break;
7415  }
7416  }
7417 
7418 // check boundaries
7419 
7420  int lagP=0;
7421  for (n=0; n<nIFO; n++) {lagL[n]=0;lagH[n]=lagMax;}
7422  for(m=0; m<maxList; m++){
7423  bool check=true;
7424  for (n=0; n<nIFO; n++) id[n]=lagList[n][m];
7425 
7426 // Lags must be in the range 0:lagMax
7427 
7428  for (n=0; n<nIFO; n++) if(id[n]<0||id[n]>int(lagMax)) check=false;
7429 
7430 // Difference between 2 lags belonging to different detectors must be <= lagMax
7431 
7432  for (int i=nIFO-1;i>=0;i--) {
7433  for (int j=i-1;j>=0;j--) {
7434  if (!(((id[i]-id[j])>=(lagL[i]-lagH[j]))&&
7435  ((id[i]-id[j])<=(lagH[i]-lagL[j])))) check=false;
7436  }
7437  }
7438  if (check) lagP++;
7439  }
7440 
7441  if(lagP==0) {
7442  cout << "network::setTimeShifts : no lags in the list" << endl;
7443  cout << "lagP : " << lagP << " " << lagSize << endl;
7444  exit(1);
7445  }
7446  if(lagP!=int(maxList)) {
7447  cout << "network::setTimeShifts : lags out of lagMax" << endl;
7448  cout << "lagP : " << lagP << " " << lagSize << endl;
7449  exit(1);
7450  }
7451  nList=maxList;
7452  goto final;
7453  }
7454 
7455 // extended lags list
7456 
7457  if(lagSite!=NULL) for(n=0; n<nIFO; n++) {
7458  if(lagSite[n] >= nIFO) {
7459  cout << "network::setTimeShifts : Error lagSite - value out of range " << endl;
7460  exit(-1);
7461  }
7462  }
7463 
7464  for(n=1; n<nIFO; n++) N[n]=lagMax;
7465  for(n=0; n<nIFO; n++) {lagL[n]=0;lagH[n]=lagMax;}
7466 
7467  maxList=lagOff+lagSize;
7468  for(n=0; n<nIFO; n++) lagList[n] = new int[maxList];
7469  for(n=0; n<nIFO; n++) lagList[n][nList]=0;
7470  nList++;
7471 
7472  rnd.SetSeed(13);
7473  for (int k=0;k<maxIter;k++) {
7474  for(n=0; n<nIFO; n++) ID[n] = TMath::Nint(rnd.Uniform(-(N[n]+0.5),N[n]+0.5));
7475  for(n=0; n<nIFO; n++) id[n] = (lagSite==NULL) ? ID[n] : ID[lagSite[n]];
7476  bool check=true;
7477  for(int i=nIFO-1;i>=0;i--) {
7478  for(int j=i-1;j>=0;j--) {
7479  if(!(((id[i]-id[j])>=(lagL[i]-lagH[j]))&&
7480  ((id[i]-id[j])<=(lagH[i]-lagL[j])))) check=false;
7481  if(lagSite!=NULL) {
7482  if(lagSite[i]!=lagSite[j] && id[i]==id[j]) check=false;
7483  } else {
7484  if(id[i]==id[j]) check=false;
7485  }
7486  }
7487  }
7488 // check if lag is already in the list
7489  if(check) {
7490  for(m=0;m<nList;m++) {
7491  bool pass=true;
7492  for(n=0; n<nIFO; n++) if(lagList[n][m]!=id[n]) pass=false;
7493  if(pass) check=false;
7494  }
7495  }
7496  if(check) {
7497  if(NETX(id[0]||,id[1]||,id[2]||,id[3]||,id[4]||,id[5]||,id[6]||,id[7]||) false) { // skip zero lag
7498  for(n=0; n<nIFO; n++) lagList[n][nList]=id[n];
7499  nList++;
7500  }
7501  }
7502  if (nList>=maxList) break;
7503  }
7504 
7505 // shift lags with respect to the first detector
7506 // negative lags are converted into positive
7507 
7508 final: // extract selected lags from the extended lag list
7509 
7510  for(m=0; m<nList; m++) {
7511  int lagMin = kMaxInt;
7512  for(n=0; n<nIFO; n++) if (lagList[n][m]<lagMin) lagMin=lagList[n][m];
7513  for(n=0; n<nIFO; n++) lagList[n][m]-=lagMin;
7514  }
7515 
7516  if(lagIDS+lagSize>nList) {
7517  cout << "network::setTimeShifts : lagOff+lagSize > nList of lags : " << nList << endl;
7518  exit(1);
7519  }
7520 
7521  for(n=0; n<nIFO; n++){
7522  pd = this->getifo(n);
7523  m = pd->lagShift.size();
7524  if(m!=lagSize) pd->lagShift.resize(lagSize);
7525  pd->lagShift = 0.;
7526  }
7527 
7528 // write in the final list those lags which are inside the segment boundaries
7529 // compute segment lenght
7530 
7531  double R = this->getifo(0)->getTFmap()->rate();
7532  double segLen = this->getifo(0)->getTFmap()->size();
7533  double edge = this->Edge;
7534  size_t selSize=0;
7535  size_t lagMaxSeg=0;
7536  double zero = 0.;
7537 
7538 // check boundaries
7539 
7540  segLen = (segLen/R-2*edge)/lagStep;
7541  lagMaxSeg = int(segLen)-1;
7542 
7543  for(n=0; n<nIFO; n++) {
7544  lagL[n] = 0;
7545  lagH[n] = lagMaxSeg;
7546  }
7547 
7548  for(m=0; m<lagSize; m++) {
7549  bool check = true;
7550  for (n=0; n<nIFO; n++) id[n]=lagList[n][m+lagIDS];
7551 
7552 // Lags must be in the range 0:lagMax
7553  for(n=0; n<nIFO; n++) if(id[n]<0||id[n]>int(lagMaxSeg)) check=false;
7554 
7555 // Difference between 2 lags belonging to diffent detectors must be <= lagMax
7556  for(int i=nIFO-1; i>=0; i--) {
7557  for(int j=i-1; j>=0; j--) {
7558  if (!(((id[i]-id[j])>=(lagL[i]-lagH[j]))&&
7559  ((id[i]-id[j])<=(lagH[i]-lagL[j])))) check=false;
7560  }
7561  }
7562 
7563 // lag is within the boundaries -> store in lagShift
7564 
7565  if (check) {
7566  if(lagMax) { // extended lags
7567  for(n=0; n<nIFO; n++) {
7568  k = lagList[n][m+lagIDS];
7569  if(k) check = false; // check if zero lag is present
7570  this->getifo(n)->lagShift.data[selSize] = k*lagStep;
7571  }
7572  }
7573  else {
7574  k = lagList[0][m+lagIDS];
7575  this->getifo(0)->lagShift.data[selSize] = k*lagStep;
7576  zero = 0;
7577  for(n=1; n<nIFO; n++) {
7578  pd = this->getifo(n);
7579  zero += fabs(pd->sHIFt-k*lagStep);
7580  pd->lagShift.data[selSize] = pd->sHIFt;
7581  }
7582  if(zero>0.1) check = false; // check if zero lag is present
7583  }
7584  wc.shift = check ? 0 : m+lagOff;
7585  wc_List.push_back(wc);
7586  livTime.push_back(0.);
7587  selSize++;
7588  }
7589  }
7590 
7591  if(selSize==0) {
7592  cout << "network::setTimeShifts error: no lag was selected" << endl;
7593  exit(0);
7594  }
7595 
7596  for(n=0; n<nIFO; n++) {
7597  m = this->getifo(n)->lagShift.size();
7598  if(m!=selSize) this->getifo(n)->lagShift.resize(selSize);
7599  }
7600 
7601 // dump lags list
7602 
7603  if(fname && !strcmp(fmode,"w") && lagMax) {
7604 
7605  FILE *fP=NULL;
7606  if((fP = fopen(fname, "w")) == NULL) {
7607  cout << "network::setTimeShifts error: cannot open file " << fname << endl;
7608  exit(1);
7609  }
7610 
7611  // write header
7612  fprintf(fP,"#");for (n=0;n<=nIFO;n++) fprintf(fP,"--------------");fprintf(fP,"\n");
7613  fprintf(fP,"#total %10d lags \n",int(nList));
7614  fprintf(fP,"#");for (n=0;n<=nIFO;n++) fprintf(fP,"--------------");fprintf(fP,"\n");
7615  fprintf(fP,"#%13s%14s%14s\n"," nIFO","lagStep"," lagMax");
7616  fprintf(fP,"#%13d%14.3f%14d\n",int(nIFO),lagStep,int(lagMax));
7617  fprintf(fP,"#");for (n=0;n<=nIFO;n++) fprintf(fP,"--------------");fprintf(fP,"\n");
7618  fprintf(fP,"#%13s","lagId");
7619  for(n=0; n<nIFO; n++) fprintf(fP,"%12s-%1d","lagShift",int(n));
7620  fprintf(fP,"\n");
7621  fprintf(fP,"#");for (n=0;n<=nIFO;n++) fprintf(fP,"--------------");fprintf(fP,"\n");
7622 
7623  // write lags
7624  for(m=0; m<nList; m++){
7625  fprintf(fP,"%14d", int(m));
7626  for (n=0; n<nIFO; n++) fprintf(fP,"%14d",lagList[n][m]);
7627  fprintf(fP,"\n");
7628  }
7629 
7630  if(fP!=NULL) fclose(fP);
7631  }
7632 
7633 // free memory
7634 
7635  for(n=0; n<nIFO; n++) delete [] lagList[n];
7636 
7637 // print selected lags
7638 
7639  printf("%8s ","lag");
7640  for(n=0; n<nIFO; n++) printf("%12.12s%2s","ifo",getifo(n)->Name);
7641  printf("\n");
7642  for(m=0; m<selSize; m++){
7643  printf("%8d ",(int)wc_List[m].shift);
7644  for(n=0; n<nIFO; n++) printf("%14.5f",this->getifo(n)->lagShift.data[m]);
7645  printf("\n");
7646  }
7647 
7648  nLag=selSize; Step=lagStep;
7649  return selSize;
7650 }
7651 
7652 //***************************************************************
7653 // set delay filter for a network:
7654 // time delay convention: + - shift TS right
7655 // - - shift TS left
7656 ///***************************************************************
7658 {
7659  this->filter.clear();
7660  std::vector<delayFilter>().swap(this->filter); // release memory
7661 
7662  if(!d) d = this->getifo(0); // reference detector
7663  double rate = d->getTFmap()->rate(); // data rate
7664 
7665  if(ifoList.size()<2 || !d || rate==0.) {
7666  cout<<"network::setFilter() error: incomplete network initialization"<<endl;
7667  return 0;
7668  }
7669 
7670  double T = this->getDelay((char*)"MAX")+0.002; // maximum delay
7671  delayFilter v = d->filter[0]; // delay filter
7672 
7673  int i,j,k,n,m;
7674  int M = int(d->nDFL); // number of wavelet layers
7675  int K = int(v.index.size()); // delay filter length
7676  int N = int(d->nDFS); // number of filter delays
7677  int J = int((fabs(T)*rate*N)/M+0.5); // total delay in samples
7678 
7679  if(N<M) { cout<<"network::setFilter() error"<<endl; return 0; }
7680  if(!K) return 0;
7681 
7682  this->getifo(0)->nDFS = N; // store number of filter delays in ref detector
7683  this->filter.reserve((2*J-1)*M); // allocate memory for filter
7684 
7685  for(i=0; i<M; i++) {
7686  for(j=-(J-1); j<J; j++) { // loop over delays
7687  m = j>0 ? (j+N/2-1)/N : (j-N/2)/N; // delay in wavelet pixels
7688  n = j - m*N; // n - delay in samples
7689  if(n <= 0) n = -n; // filter index for negative delays
7690  else n = N-n; // filter index for positive delays
7691  v = d->filter[n*M+i];
7692  for(k=0; k<K; k++) v.index[k] -= m*M;
7693  this->filter.push_back(v);
7694  }
7695  }
7696 
7697  return 2*J-1;
7698 }
7699 
7700 //***************************************************************
7701 // set 0-phase delay filter for a network from detector:
7702 // used in cWB script with wat-4.7.0 and earlier
7703 // time delay convention: + - shift TS right
7704 // - - shift TS left
7705 ///***************************************************************
7707 {
7708  size_t N = this->ifoList.size();
7709  if(N < 2) return;
7710  if(d) this->getifo(0)->setFilter(*d);
7711  this->setFilter(this->getifo(0));
7712  this->getifo(0)->clearFilter();
7713  return;
7714 }
7715 
7716 //***************************************************************
7717 // set delay filters for a network from detector filter files
7718 // time delay convention: + - shift TS right
7719 // - - shift TS left
7720 ///***************************************************************
7721 void network::setDelayFilters(char* fname, char* gname)
7722 {
7723  size_t N = this->ifoList.size();
7724 
7725  if(N < 2) return;
7726  if(gname) {
7727  this->getifo(0)->readFilter(gname);
7728  this->setFilter(this->getifo(0));
7729  this->filter90.clear();
7730  std::vector<delayFilter>().swap(this->filter90); // release memory
7731  this->filter90 = this->filter;
7732  }
7733  this->getifo(0)->readFilter(fname);
7734  this->setFilter(this->getifo(0));
7735  this->getifo(0)->clearFilter();
7736  return;
7737 }
7738 
7739 //***************************************************************
7740 // set delay filters for a network from a network filter file
7741 // gname defines the phase shifted filter
7742 ///***************************************************************
7743 void network::setFilter(char* fname, char* gname)
7744 {
7745  size_t N = this->ifoList.size();
7746  if(N < 2) return;
7747  if(gname) {
7748  this->readFilter(gname);
7749  this->filter90 = this->filter;
7750  }
7751  this->readFilter(fname);
7752  return;
7753 }
7754 
7755 //***************************************************************
7756 // Dumps network filter to file *fname in binary format.
7757 //***************************************************************
7758 void network::writeFilter(const char *fname)
7759 {
7760  size_t i,j,k;
7761  FILE *fp;
7762 
7763  if ( (fp=fopen(fname, "wb")) == NULL ) {
7764  cout << " network::writeFilter() error : cannot open file " << fname <<". \n";
7765  return ;
7766  }
7767 
7768  size_t M = size_t(getifo(0)->TFmap.maxLayer()+1); // number of wavelet layers
7769  size_t N = size_t(filter.size()/M); // number of delays
7770  size_t K = size_t(filter[0].index.size()); // delay filter length
7771  size_t n = K * sizeof(float);
7772  size_t m = K * sizeof(short);
7773 
7776 
7777  fwrite(&K, sizeof(size_t), 1, fp); // write filter length
7778  fwrite(&M, sizeof(size_t), 1, fp); // number of layers
7779  fwrite(&N, sizeof(size_t), 1, fp); // number of delays
7780 
7781  for(i=0; i<M; i++) { // loop over wavelet layers
7782  for(j=0; j<N; j++) { // loop over delays
7783  for(k=0; k<K; k++) { // loop over filter coefficients
7784  value.data[k] = filter[i*N+j].value[k];
7785  index.data[k] = filter[i*N+j].index[k];
7786  }
7787  fwrite(value.data, n, 1, fp);
7788  fwrite(index.data, m, 1, fp);
7789  }
7790  }
7791  fclose(fp);
7792 }
7793 
7794 //***************************************************************
7795 // Read network filter from file *fname.
7796 //***************************************************************
7797 void network::readFilter(const char *fname)
7798 {
7799  size_t i,j,k;
7800  FILE *fp;
7801 
7802  if ( (fp=fopen(fname, "rb")) == NULL ) {
7803  cout << " network::readFilter() error : cannot open file " << fname <<". \n";
7804  exit(1);
7805  }
7806 
7807  size_t M; // number of wavelet layers
7808  size_t N; // number of delays
7809  size_t K; // delay filter length
7810 
7811  fread(&K, sizeof(size_t), 1, fp); // read filter length
7812  fread(&M, sizeof(size_t), 1, fp); // read number of layers
7813  fread(&N, sizeof(size_t), 1, fp); // read number of delays
7814 
7815  size_t n = K * sizeof(float);
7816  size_t m = K * sizeof(short);
7819  delayFilter v;
7820 
7821  v.value.clear(); v.value.reserve(K);
7822  v.index.clear(); v.index.reserve(K);
7823  filter.clear(); filter.reserve(N*M);
7824 
7825  for(k=0; k<K; k++) { // loop over filter coefficients
7826  v.value.push_back(0.);
7827  v.index.push_back(0);
7828  }
7829 
7830  for(i=0; i<M; i++) { // loop over wavelet layers
7831  for(j=0; j<N; j++) { // loop over delays
7832  fread(value.data, n, 1, fp);
7833  fread(index.data, m, 1, fp);
7834  for(k=0; k<K; k++) { // loop over filter coefficients
7835  v.value[k] = value.data[k];
7836  v.index[k] = index.data[k];
7837  }
7838  filter.push_back(v);
7839  }
7840  }
7841  fclose(fp);
7842 }
7843 
7844 // extract accurate timr delay amplitudes for a given sky location
7845 void network::updateTDamp(int l, float** v00, float** v90) {
7846 // parameter 1 - sky location index
7847 // parameter 2 - 0-phase array for time-delayed amplitudes
7848 // parameter 3 - 90-phase array for time-delayed amplitudes
7849 // Algorithm: for a given pixel set extract TF data from the sparse maps.
7850 // Obtain time domain data for each resolution, time-shift
7851 // detectors for a given sky location l. Reproduce time-shifted TF maps and
7852 // extract time-shifted amplitudes. Update time delay arrays - only one sky
7853 // location is updated
7854 
7855  int nres = this->wdmList.size(); // number of resolutions
7856  int nIFO = this->ifoList.size(); // number of detectors
7857  int V = int(this->pList.size()); // number of pixels
7858  int layers;
7859 
7860  WSeries<double> WW;
7862  netpixel* pix;
7863  detector* pd;
7864 
7865  for(int i=0; i<nres; i++) {
7866  for(int k=0; k<nIFO; k++) {
7867  pd = this->getifo(k);
7868  pd->vSS[i].Expand(false); // expand sparse map
7869 
7870  WW = pd->vSS[i]; // copy TF map
7871  pd->vSS[i].Inverse(); // 0-phase TS
7872  WW.Inverse(-2); // 90-phase TS
7873  pd->vSS[i].getLayer(x,0); // get I time series
7874  WW.getLayer(y,0); // get Q time series
7875  x+=y; x*=0.5; // prepare time series
7876  x.delay(pd->index[l]/this->rTDF); // time shift data in x
7877  pd->vSS[i].Forward(x); // prepare TF map
7878  layers = pd->vSS[i].maxLayer()+1; // number of WDM layers
7879 
7880  for(int j=0; j<V; j++) { // loop over pixels
7881  pix = this->pList[j];
7882  if(pix->layers != layers) continue; // skip wrong resolution
7883  int ind = int(pix->data[k].index); // index in TF array
7884  v00[k][j] = pd->vSS[i].GetMap00(ind); // update 00 amplitude
7885  v90[k][j] = pd->vSS[i].GetMap90(ind); // update 00 amplitude
7886  }
7887 
7888  pd->vSS[i].Shrink(); // shrink TF map
7889  }
7890  }
7891 }
7892 
7893 //***************************************************************
7894 // delay detectors in the network with respect to reference
7895 // to match sky location theta and phi
7896 // index array should be setup
7897 ///***************************************************************
7898 void network::delay(double theta, double phi)
7899 {
7900  size_t m;
7901  size_t N = this->ifoList.size(); // number of detectors
7902  size_t k = this->getIndex(theta,phi); // sky index
7903  detector* d;
7904 
7905  for(size_t n=1; n<N; n++){
7906  d = this->getifo(n);
7907  m = d->index.data[k]; // delay index
7908  this->delay(d,m);
7909  }
7910  return;
7911 }
7912 
7913 //***************************************************************
7914 // delay detector in a network:
7915 // m - is the delay index
7916 ///***************************************************************
7917 void network::delay(detector* d, size_t m)
7918 {
7919  double R = d->getTFmap()->rate();
7920 
7921  size_t i,j,k;
7922  size_t N = d->getTFmap()->size();
7923  size_t I = d->TFmap.maxLayer()+1;
7924  size_t M = this->filter.size()/I; // total number of delays
7925  size_t K = this->filter[0].index.size(); // filter length
7926  size_t jB = size_t(this->Edge*R/I)*I; // number of samples in the edges
7927  size_t jS;
7928 
7929  slice S;
7930  delayFilter* pv;
7931 
7932 // buffer for wavelet layer delay filter
7933  double* F = (double*)malloc(K*sizeof(double));
7934  int* J = (int*)malloc(K*sizeof(int));
7935 
7936  N -= jB; // correction for left boundary
7937 
7938  WSeries<double> temp = d->TFmap;
7939  d->TFmap=0.;
7940 
7941 // cout<<"m="<<m<<" N="<<N<<" R="<<R<<" I="<<I<<" M="<<M<<" K="<<K<<endl;
7942 
7943  double* p1 = temp.data;
7944  double* b0 = temp.data;
7945 
7946  for(i=0; i<I; i++) { // loop over wavelet layers
7947 
7948 // set filter array for this layer and delay index
7949  pv = &(filter[i*M+m]);
7950  for(k=0; k<K; k++){
7951  F[k] = double(pv->value[k]);
7952  J[k] = int(pv->index[k]);
7953  }
7954 
7955  S = d->getTFmap()->getSlice(i);
7956  jS = S.start()+jB;
7957 
7958  for(j=jS; j<N; j+=I) { // loop over samples in the layer
7959  p1=b0+j;
7960  d->TFmap.data[j] = dot32(F,p1,J); // apply delay filter
7961  }
7962  }
7963  free(F);
7964  free(J);
7965 }
7966 
7967 //***************************************************************
7968 //:set index array for delayed amplitudes
7969 // used with wavelet delay filters
7970 // time delay convention: t+tau - arrival time at the center of Earth
7971 // ta1-tau0 - how much det1 should be delayed to be sinchronized with det0
7972 ///***************************************************************
7974 {
7975  double t;
7976  int i,ii;
7977  size_t n,m,l,k;
7978  size_t N = ifoList.size(); // number of detectors
7979 
7980  double tt[NIFO][NIFO];
7981  double TT[NIFO];
7982  int mm[NIFO][NIFO];
7983 
7984  if(N<2) {
7985  cout<<"network::setDelayIndex(): invalid network\n";
7986  return;
7987  }
7988 
7989  detector* dr[NIFO];
7990  for(n=0; n<N; n++) dr[n] = ifoList[n];
7991 
7992  size_t I = dr[0]->nDFL; // number of wavelet layers
7993  size_t K = this->filter.size()/I; // number of delays
7994  size_t L = dr[0]->tau.size(); // skymap size
7995 
7996  double rate = dr[0]->getTFmap()->rate(); // data rate
7997  rate *= dr[0]->nDFS/I; // up-sample rate
7998 
7999  if(pOUT) cout<<"filter size="<<this->filter.size()
8000  <<" layers="<<I<<" delays="<<K<<" samples="<<dr[0]->nDFS<<endl;
8001 
8002  if(!(K&1) || rate == 0.) {
8003  cout<<"network::setDelayIndex(): invalid network\n";
8004  return;
8005  }
8006 
8007  for(n=0; n<N; n++) {
8008  if(dr[n]->index.size() != L) {
8009  dr[n]->index.resize(L);
8010  }
8011  }
8012 
8013 // calculate time interval the di detector is delayed to be
8014 // sinchronized with dr
8015 // time delay > 0 - shift di right (future)
8016 // time delay < 0 - shift di left (past)
8017 
8018  this->nPenalty = dr[0]->tau;
8019 
8020  for(l=0; l<L; l++){
8021 
8022 // calculate time delay matrix
8023 // 0 d01 d02
8024 // d10 0 d12
8025 // d20 d21 0
8026 
8027  for(n=0; n<N; n++) {
8028  for(m=0; m<N; m++) {
8029  t = dr[n]->tau.get(l)-dr[m]->tau.get(l);
8030  i = int(t*rate+2*K+0.5) - 2*K;
8031  mm[n][m] = i;
8032  tt[n][m] = t*rate;
8033  }
8034  }
8035 
8036  for(n=0; n<N; n++) {
8037  TT[n] = 0.; // max delay for n-th configuration
8038  for(m=0; m<N; m++) {
8039  for(k=0; k<N; k++) {
8040  t = fabs(mm[n][k]-mm[n][m]-tt[m][k]);
8041  if(TT[n] < t) TT[n] = t;
8042  }
8043  }
8044  }
8045 
8046  t = 20.; i = N;
8047  for(m=0; m<N; m++) {
8048  if(t>TT[m]) { t = TT[m]; k = m; } // first best configuration
8049  }
8050  this->nPenalty.set(l,double(t));
8051 
8052  t = dr[k]->tau.get(l);
8053  i = mIFO<9 ? mm[k][this->mIFO] : int(t*rate+2*K+0.5)-2*K;
8054 
8055 // 0 d01 d02 0 d01 d02
8056 // d10 0 d12 -> 0 d'01 d'02
8057 // d20 d21 0 0 d"01 d"02
8058 
8059  for(m=0; m<N; m++) {
8060  ii = (K/2+mm[k][m])-i; // convert to time delay with respect to master IFO
8061  dr[m]->index.data[l] = ii;
8062  if(ii < 0) cout<<"network::setDelayIndex error: sky index<0: "<<k<<endl;
8063  }
8064  }
8065  return;
8066 }
8067 
8068 //***************************************************************
8069 //:set theta, phi index array
8070 //:will not work on 32 bit with the option other than 0,2,4
8071 //***************************************************************
8073 {
8074  detector* dr = ifoList[0];
8075 
8076  if(ifoList.size()<2 || !dr->tau.size()) {
8077  cout<<"network::setIndex() - invalid network"<<endl;
8078  return 0;
8079  }
8080 
8081  size_t i,j,n,m;
8082  size_t L = dr->tau.size();
8083  size_t N = ifoList.size();
8084  size_t I = mode ? dr->nDFL : 1; // number of wavelet layers
8085  // TO BE FIXED !!! works only for 1G
8086  // for 2G only mode=0 works !!!
8087  size_t K = this->filter.size()/I; // number of delays
8088  size_t J = 0; // counter for rejected locations
8089  size_t M = mIFO<9 ? mIFO : 0; // reference detector
8090  long long ll;
8091 
8092  if(this->index.size()!=L) this->index.resize(L);
8093  if(this->skyMask.size()!=L) this->skyMask.resize(L);
8094  if(this->skyHole.size()!=L) { this->skyHole.resize(L); this->skyHole = 1.; }
8095  for(j=0; j<L; j++) {
8096  index.data[j] = j;
8097  skyMask.data[j] = size_t(skyHole.data[j]+0.1);
8098  }
8099  if(!mode) return 0;
8100 
8101  if(mode==2 || mode==4) {
8102  dr->tau.downsample(skyMask,mode);
8103  return 0;
8104  }
8105 
8106  wavearray<long long> delay(L);
8107  long long **pp = (long long**)malloc(L*sizeof(long long*));
8108  skymap* sm = &nSkyStat;
8109 
8110  for(n=0; n<N; n++) {
8111  if(!this->getifo(n)->index.size()) {
8112  cout<<"network::setIndex() - invalid network"<<endl;
8113  return 0;
8114  }
8115  }
8116 
8117  for(i=0; i<L; i++){
8118  delay.data[i] = 0;
8119  pp[i] = delay.data+i;
8120  m = 0;
8121  for(n=0; n<N; n++) {
8122  if(n == M) continue;
8123  ll = this->getifo(n)->index.data[i];
8124  if(this->mIFO==99) ll += K/2 - this->getifo(0)->index.data[i];
8125  delay.data[i] += ll<<(m*12);
8126  m++;
8127  }
8128  }
8129 
8130  delay.waveSort(pp,0,L-1);
8131  ll = *(pp[0]);
8132  for(i=1; i<L; i++) {
8133  j = pp[i] - delay.data;
8134  if(ll == *(pp[i])) {
8135  skyMask.data[j] = 0; // remove duplicate delay configurations
8136  J++;
8137  if(pOUT) cout<<" "<<j<<"|"<<sm->getTheta(j)<<"|"<<sm->getPhi(j);
8138  }
8139  else {
8140  ll = *(pp[i]);
8141  if(pOUT) cout<<"\n ll="<<ll<<" "<<j<<"|"<<sm->getTheta(j)<<"|"<<sm->getPhi(j);
8142  }
8143  }
8144 
8145  free(pp);
8146  return J;
8147 }
8148 
8149 void
8151 
8152  // print detector's info
8153  int nIFO = ifoListSize();
8154  for(int n=0; n<nIFO; n++) getifo(n)->print();
8155 
8156  // print MDC log infos
8157 
8158  cout << "----------------------------------------------" << endl;
8159  cout << " INJECTIONS : " << this->mdcListSize() << endl;
8160  cout << "----------------------------------------------" << endl;
8161  for(size_t k=0;k<this->mdcListSize();k++) {
8162  string str(this->getmdcList(k));
8163  cout << endl << str.c_str() << endl;
8164  }
8165 
8166  return;
8167 }
8168 
wavearray< double > t(hp.size())
std::vector< char * > ifoName
Definition: network.hh:591
double sHIFt
Definition: detector.hh:317
static float _sse_abs_ps(__m128 *_a)
Definition: watsse.hh:119
double pc
Definition: DrawEBHH.C:15
double rho
double netCC
Definition: network.hh:578
char cut[512]
virtual void resize(unsigned int)
Definition: wseries.cc:883
double sTARt
virtual size_t size() const
Definition: wavearray.hh:127
static const double C
Definition: GNGen.cc:10
char val[20]
#define NIFO
Definition: wat.hh:56
double imag() const
Definition: wavecomplex.hh:52
float phi
Definition: netpixel.hh:99
double getWFfreq(char atype='S')
Definition: detector.cc:1750
size_t nLag
Definition: network.hh:555
std::vector< vector_int > cRate
Definition: netcluster.hh:380
void printwc(size_t)
Definition: network.cc:2627
double start
Definition: network.hh:37
double lagStep
Definition: test_config1.C:53
gnetwork * gNET
double duration
std::vector< netcluster > wc_List
Definition: network.hh:592
par[0] value
wavearray< double > getMRAwave(network *net, int ID, size_t n, char atype='S', int mode=0)
Definition: netcluster.cc:2880
detector D
Definition: TestBandPass.C:15
size_t add(detector *)
param: detector structure return number of detectors in the network
Definition: network.cc:2528
tuple f
Definition: cwb_online.py:91
void setFpFx(double, double=0., double=180., double=0., double=360.)
param - step on phi and theta param - theta begin param - theta end param - phi begin param - phi end...
Definition: detector.cc:692
printf("total live time: non-zero lags = %10.1f \n", liveTot)
TString live
size_t readMDClog(char *, double=0., int=11, int=12)
param: MDC log file param: approximate gps time
Definition: network.cc:3339
static float _avx_dpf_ps(double **Fp, double **Fx, int l, std::vector< float * > &pAPN, std::vector< float * > &pAVX, int I)
Definition: watavx.hh:65
size_t clusterID
Definition: netpixel.hh:91
fprintf(stdout,"start=%f duration=%f rate=%f\n", x.start(), x.size()/x.rate(), x.rate())
int offset
Definition: TestSTFT_2.C:19
virtual void rate(double r)
Definition: wavearray.hh:123
double delta
std::vector< wavearray< float > > tdAmp
Definition: netpixel.hh:105
virtual ~network()
Definition: network.cc:52
double sSNR
Definition: detector.hh:320
#define _ALIGNED
Definition: wat.hh:53
bool getwave(size_t, size_t, char='W')
param: cluster ID param: delay index param: time series type return: true if time series are extracte...
Definition: network.cc:3545
float * rank
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
double getWFtime(char atype='S')
Definition: detector.cc:1735
par[0] name
size_t * lagSite
Definition: test_config1.C:58
long getNetworkPixels(int LAG, double Eo, double DD=1., TH1F *hist=NULL)
Definition: network.cc:60
static void _sse_add4_ps(__m128 *_a, __m128 *_b, __m128 _c)
Definition: watsse.hh:244
double Gamma(double r)
Definition: watfun.hh:175
int n
Definition: cwb_net.C:10
static __m128 _sse_abs4_ps(__m128 *_p)
Definition: watsse.hh:139
static void _sse_zero_ps(__m128 *_p)
Definition: watsse.hh:26
static __m128 _sse_ed4_ps(__m128 *_p, __m128 *_q, __m128 _L)
Definition: watsse.hh:855
std::vector< vectorD > NDM
Definition: network.hh:585
void getSkyArea(size_t id, size_t lag, double T)
param: cluster id param: lag param: cluster time
Definition: network.cc:4224
std::vector< int > neighbors
Definition: netpixel.hh:106
double iGamma(double r, double p)
Definition: watfun.hh:187
size_t nRun
Definition: network.hh:554
wavearray< double > fx
Definition: detector.hh:346
size_t setIndexMode(size_t=0)
Definition: network.cc:8072
int ID
Definition: TestMDC.C:70
static __m128 _sse_dot4_ps(__m128 *_p, __m128 *_q)
Definition: watsse.hh:205
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
std::vector< delayFilter > filter
Definition: detector.hh:343
wavearray< double > HRSS
Definition: detector.hh:353
std::vector< wavearray< double > * > RWFP
Definition: detector.hh:364
static void _sse_cpf4_ps(__m128 *_aa, __m128 *_pp)
Definition: watsse.hh:299
bool optim
float theta
size_t nDFS
Definition: detector.hh:324
WDM< double > wdm(nLAYERS, nLAYERS, 6, 10)
void add(const wavearray< DataType_t > &, int=0, int=0, int=0)
Definition: wavearray.cc:728
std::vector< vector_float > sArea
Definition: netcluster.hh:383
netpixel pix(nifo)
UChar_t VETO[100]
netcluster * pwc
Definition: cwb_job_obj.C:20
TH2F * ph
virtual size_t initwc(double, double)
param: cluster start time relative to segment start param: cluster duration return cluster list size ...
Definition: network.cc:3696
double get_SS()
Definition: detector.hh:291
wavearray< short > index
Definition: detector.hh:350
wavearray< int > sI
TRandom3 P
Definition: compare_bkg.C:296
size_t setSkyMask(double f, char *fname)
Definition: network.cc:3182
double min()
Definition: skymap.cc:441
int layers
std::vector< std::string > mdcType
Definition: network.hh:595
double real() const
Definition: wavecomplex.hh:51
size_t mIFO
Definition: network.hh:557
STL namespace.
double getTheta(size_t i)
Definition: skymap.hh:206
size_t lagOff
Definition: test_config1.C:54
void setAntenna()
Definition: network.cc:2842
std::slice getSlice(double n)
Definition: wseries.hh:134
waveform wf
double getThetaStep(size_t i)
Definition: skymap.hh:224
static void _sse_cpf_ps(float *a, __m128 *_p)
Definition: watsse.hh:289
double theta_1
Definition: skymap.hh:303
Long_t size
NET segList
Definition: cwb_net.C:276
wavearray< double > hp
Definition: DrawInspiral.C:43
WSeries< double > waveBand
Definition: detector.hh:338
void test_sse(int, int)
Definition: network.cc:238
watplot p1(const_cast< char * >("TFMap1"))
#define M
Definition: UniqSLagsList.C:3
size_t setFilter(detector *=NULL)
param: detector
Definition: network.cc:7657
size_t layers
Definition: netpixel.hh:94
int m
Definition: cwb_net.C:10
double getPhiStep(size_t i)
Definition: skymap.hh:164
std::vector< vector_int > cList
Definition: netcluster.hh:379
virtual void start(double s)
Definition: wavearray.hh:119
double max()
Definition: skymap.cc:420
std::vector< size_t > mdc__ID
Definition: network.hh:597
void downsample(wavearray< short > &, size_t=4)
Definition: skymap.cc:518
int j
Definition: cwb_net.C:10
static void _sse_rotm_ps(__m128 *u, float *c, __m128 *v, float *s, __m128 *a)
Definition: watsse.hh:406
bool getMRAwave(size_t ID, size_t lag, char atype='S', int mode=0, bool tof=false)
Definition: network.cc:3635
i drho i
void updateTDamp(int, float **, float **)
Definition: network.cc:7845
TRandom3 rnd(1)
std::vector< double > mdcTime
Definition: network.hh:596
long subNetCut(int lag, float subnet=0.6, float subcut=0.33, TH2F *hist=NULL)
Definition: network.cc:983
long coherence(double, double=0., double=0.)
param: threshold on lognormal pixel energy (in units of noise rms) param: threshold on total pixel en...
Definition: network.cc:3784
skymap tau
Definition: detector.hh:328
std::vector< double > vectorD
Definition: network.hh:33
long likelihood2G(char mode, int lag, int ID, TH2F *hist=NULL)
Definition: network.cc:1356
std::vector< detector * > ifoList
Definition: network.hh:590
double get_XX()
Definition: detector.hh:292
#define N
double netCC
Definition: test_config1.C:33
tuple ff
Definition: cwb_online.py:394
bool core
Definition: netpixel.hh:102
std::vector< vector_float > p_Map
Definition: netcluster.hh:384
double Edge
Definition: network.hh:560
double theta_2
Definition: skymap.hh:304
cout<< "Selected Pixels : "<< nPix<< endl;wc.cluster(1, 1);SSeries< double > ss
network()
Definition: network.cc:28
nT
Definition: cbc_plots.C:659
void writeFilter(const char *fname)
Definition: network.cc:7758
static float _avx_loadata_ps(float **p, float **q, float **u, float **v, float En, std::vector< float * > &pAVX, int I)
Definition: watavx.hh:412
#define PI
Definition: watfun.hh:14
skymap mFx
Definition: detector.hh:330
void clean(int cID=0)
Definition: netcluster.hh:433
double aNET
Definition: network.hh:562
bool optim
Definition: network.hh:572
size_t mode
wavearray< double > w
Definition: Test1.C:27
#define nIFO
void wrate(double r)
Definition: wseries.hh:102
wavearray< double > ffp
Definition: detector.hh:347
float M1
int getLevel()
Definition: wseries.hh:91
float phi
size_t size()
Definition: netpixel.hh:71
double precision
Definition: network.hh:575
double factor
double ra
Definition: ConvertGWGC.C:46
char str[1024]
size_t wavecount(double x, int n=0)
Definition: wavearray.hh:286
long likelihoodWP(char mode, int lag, int ID, TH2F *hist=NULL)
Definition: network.cc:275
float psi
double getlow() const
Definition: wseries.hh:111
wavearray< double > xx
Definition: TestFrame1.C:11
static __m256 _avx_noise_ps(float **p, float **q, std::vector< float * > &pAVX, int I)
Definition: watavx.hh:1054
double setVeto(double=5.)
param: time window around injections
Definition: network.cc:3456
double shift
Definition: netcluster.hh:364
int _sse_MRA_ps(network *net, float *amp, float *AMP, float Eo, int K)
void set(double x, double y)
Definition: wavecomplex.hh:56
waveSegment SEG
std::vector< double > livTime
Definition: network.hh:593
TGraph * gr
wavearray< double > hx
Definition: DrawInspiral.C:44
int pattern
size_t size() const
Definition: wslice.hh:71
Definition: monster.hh:12
bool local
Definition: network.hh:571
wavearray< double > * px
TCanvas * c1
wavearray< double > TIME
Definition: detector.hh:357
r setFilter(10)
i() int(T_cor *100))
static __m256 _avx_stat_ps(float **x, float **X, float **s, float **S, std::vector< float * > &pAVX, int I)
Definition: watavx.hh:906
static __m128 _sse_ecoh4_ps(__m128 *_p, __m128 *_q, __m128 _L)
Definition: watsse.hh:760
float polarisation
Definition: netpixel.hh:101
wavearray< double > * getHoT()
param: no parameters
Definition: detector.hh:157
int getOrder()
Definition: skymap.hh:296
gwavearray< double > * gx
void setDelayIndex(double rate)
param: MDC log file
Definition: network.cc:2865
std::vector< std::string > mdcList
Definition: network.hh:594
bool log
Definition: WaveMDC.C:41
double * tmp
Definition: testWDM_5.C:31
double getDelay(const char *c="")
Definition: network.cc:2787
double eCOR
Definition: network.hh:564
static __m128 _sse_ind4_ps(__m128 *_p, __m128 _L)
Definition: watsse.hh:791
bool EFEC
wavearray< double > fpx
Definition: detector.hh:349
WSeries< double > pTF[nRES]
Definition: revMonster.cc:8
wavearray< double > fp
Definition: detector.hh:345
double get_XS()
Definition: detector.hh:294
double start
Definition: netcluster.hh:361
double gNET
Definition: network.hh:561
int getLayer(wavearray< DataType_t > &w, double n)
param: n - layer number
Definition: wseries.cc:175
static void _avx_free_ps(std::vector< float * > &v)
Definition: watavx.hh:21
std::vector< vector_int > p_Ind
Definition: netcluster.hh:385
static double tau
Definition: geodesics.cc:8
char fname[1024]
segLen
Definition: cwb_eced.C:7
std::vector< int > RWFID
Definition: detector.hh:363
Definition: Wavelet.hh:31
static void _sse_pol4_ps(__m128 *_fp, __m128 *_fx, __m128 *_v, double *r, double *a)
Definition: watsse.hh:1068
static float _avx_setAMP_ps(float **p, float **q, std::vector< float * > &pAVX, int I)
Definition: watavx.hh:734
double precision
static void _avx_loadNULL_ps(float **n, float **N, float **d, float **D, float **h, float **H, int I)
Definition: watavx.hh:485
double Step
Definition: network.hh:559
double acor
bool eDisbalance
int k
m1
Definition: cbc_plots.C:606
std::vector< waveSegment > segList
Definition: network.hh:598
int _sse_mra_ps(network *NET, float *amp, float *AMP, float Eo, int K)
static void _sse_rot4m_ps(__m128 *_u, __m128 *_c, __m128 *_v, __m128 *_s, __m128 *_a)
Definition: watsse.hh:454
double THRESHOLD(double bpp)
param: selected fraction of LTF pixels assuming Gaussian noise
Definition: network.cc:2584
double mchirp(int ID, double=2.5, double=1.e20, double=0)
Definition: netcluster.cc:1405
static double A
Definition: geodesics.cc:8
void readFilter(const char *)
Definition: network.cc:7797
double acor
Definition: network.hh:567
x *double Et
Definition: ComputeSNR.C:40
double F
size_t time
Definition: netpixel.hh:92
void setDelay(const char *="L1")
Definition: network.cc:2736
static float _avx_ort_ps(float **p, float **q, std::vector< float * > &pAVX, int I)
Definition: watavx.hh:813
static float _avx_GW_ps(float **p, float **q, std::vector< float * > &pAPN, float *rr, std::vector< float * > &pAVX, int II)
Definition: watavx.hh:232
Definition: skymap.hh:45
wavearray< double > lagShift
Definition: detector.hh:351
double e2or
Definition: network.hh:566
double e
void setLevel(size_t n)
Definition: wseries.hh:94
long likelihood(char='E', double=sqrt(2.), int=0, size_t=0, int=-1, bool=false)
Definition: network.cc:4415
static void _avx_cpf_ps(float **p, float **q, float **u, float **v, int I)
Definition: watavx.hh:30
WSeries< double > ww
Definition: Regression_H1.C:33
long likelihoodI(char='P', double=sqrt(2.), int=0, size_t=0, int=-1, bool=false)
Definition: network.cc:5265
double phi2RA(double ph, double gps)
Definition: skymap.hh:194
#define STAT
Definition: FrDisplay.cc:110
netpixel * getPixel(size_t n, size_t i)
Definition: netcluster.hh:395
int npix
double gethigh() const
Definition: wseries.hh:118
virtual void FFTW(int=1)
Definition: wavearray.cc:878
FILE * fP
regression r
Definition: Regression_H1.C:44
s s
Definition: cwb_net.C:137
int index
Definition: network.hh:36
char filter[1024]
wavearray< double > ffm
Definition: detector.hh:348
double getPhi(size_t i)
Definition: skymap.hh:146
WSeries< double > TFmap
Definition: detector.hh:336
bool wfsave
Definition: network.hh:582
double gps
double pSigma
Definition: network.hh:576
float ellipticity
Definition: netpixel.hh:100
void print()
Definition: network.cc:8150
double T
Definition: testWDM_4.C:11
virtual void waveSort(DataType_t **pp, size_t l=0, size_t r=0) const
Definition: wavearray.cc:1403
ifstream in
std::vector< int > sCuts
Definition: netcluster.hh:374
WSeries< double > waveForm
Definition: detector.hh:337
watplot p2(const_cast< char * >("TFMap2"))
WSeries< double > * getTFmap()
param: no parameters
Definition: detector.hh:161
wavearray< int > index
double xSNR
Definition: detector.hh:321
float theta
Definition: netpixel.hh:98
virtual void delay(double T)
Definition: wavearray.cc:578
Definition: Meyer.hh:18
char Name[16]
Definition: detector.hh:309
virtual void stop(double s)
Definition: wavearray.hh:121
skymap mFp
Definition: detector.hh:329
double fabs(const Complex &x)
Definition: numpy.cc:37
string file
Definition: cwb_online.py:385
double norm
Definition: network.hh:565
double gamma
Definition: network.hh:574
#define GPS
double get_NN()
Definition: detector.hh:293
std::vector< short > index
Definition: detector.hh:27
void Forward(int n=-1)
param: wavelet - n is number of steps (-1 means full decomposition)
Definition: wseries.cc:228
Meyer< double > S(1024, 2)
double df
int l
Definition: cbc_plots.C:434
static __m128 _sse_sum_ps(__m128 **_p)
Definition: watsse.hh:497
sprintf(tfres,"(1/%g)x(%g) (sec)x(Hz)", 2 *df, df)
DataType_t get(size_t i)
Definition: wavearray.hh:265
std::vector< clusterdata > cData
Definition: netcluster.hh:373
double netRHO
Definition: test_config1.C:32
static void _sse_point_ps(__m128 **_p, float **p, short **m, int l, int n)
Definition: watsse.hh:484
float CC[4]
Definition: monster.hh:12
void setDelayFilters(detector *=NULL)
Definition: network.cc:7706
TCanvas * c2
Definition: slag.C:207
double phi_2
Definition: skymap.hh:306
static void _sse_mul_ps(__m128 *_a, float b)
Definition: watsse.hh:38
double getwave(int, netcluster &, char, size_t)
param: no parameters
Definition: detector.cc:544
DataType_t * data
Definition: wavearray.hh:301
float M2
double null
Definition: detector.hh:318
long nSky
Definition: network.hh:556
netcluster wc
Long_t id
enum WAVETYPE m_WaveType
Definition: Wavelet.hh:88
TH1 * t1
double phi_1
Definition: skymap.hh:305
double iGamma1G(double r, double p)
Definition: watfun.hh:228
double get(size_t i)
param: sky index
Definition: skymap.cc:681
WaveDWT< DataType_t > * pWavelet
Definition: wseries.hh:438
double dT
Definition: testWDM_5.C:12
size_t netcut(double, char='L', size_t=0, int=1)
param: threshold param: minimum cluster size processed by the corrcut param: cluster type return: num...
Definition: network.cc:2967
long nSky
void delay(double theta, double phi)
Definition: network.cc:7898
snr * snr
Definition: ComputeSNR.C:71
long likelihoodB(char='E', double=sqrt(2.), int=0, size_t=0, int=-1, bool=false)
param: maximized statistic: param: threshold to define core pixels (in units of noise rms) ...
Definition: network.cc:4439
bool save
static float _sse_maxE_ps(__m128 *_a, __m128 *_A)
Definition: watsse.hh:536
cout<< "live time after cat 2 : "<< detSegs_ctime<< endl;if(detSegs_ctime< segTHR){cout<< "job segment live time after cat2 < "<< segTHR<< " sec, job terminated !!!"<< endl;exit(1);}double Tb=detSegs[0].start;double Te=detSegs[0].stop;double dT=Te-Tb;char file[512], tdf00[512], tdf90[512], buFFer[1024];int rnID=int(gRandom->Rndm(13)*1.e9);if(simulation){i=NET.readMDClog(injectionList, double(long(Tb))-mdcShift);printf("GPS: %16.6f saved, injections: %d\n", double(long(Tb)), i);frTB[nIFO].shiftBurstMDCLog(NET.mdcList, ifos, mdcShift);for(int i=0;i< NET.mdcTime.size();i++) NET.mdcTime[i]+=mdcShift;vector< waveSegment > mdcSegs(NET.mdcTime.size());for(int k=0;k< NET.mdcTime.size();k++){mdcSegs[k].start=NET.mdcTime[k]-gap;mdcSegs[k].stop=NET.mdcTime[k]+gap;}vector< waveSegment > mdcSegs_dq2=slagTB.mergeSegLists(detSegs_dq2, mdcSegs);double mdcSegs_ctime=slagTB.getTimeSegList(mdcSegs_dq2);cout<< "live time in zero lag after cat2+inj : "<< mdcSegs_ctime<< endl;if(mdcSegs_ctime==0){cout<< "job segment with zero cat2+inj live time in zero lag, job terminated !!!"<< endl;exit(1);}}if(dump_infos_and_exit) exit(0);if(mask >0.) NET.setSkyMask(mask, skyMaskFile);for(i=0;i< nIFO;i++){frTB[i].readFrames(FRF[i], channelNamesRaw[i], x);x.start(x.start()+dataShift[i]);x.start(x.start()-segLen *(segID[i]-segID[0]));if(singleDetector) TB.resampleToPowerOfTwo(x);sprintf(file,"%s/%s_%d_%s_%d_%d.dat", nodedir, ifo[i], int(Tb), data_label, runID, rnID);if(dump_sensitivity_and_exit){sprintf(file,"%s/sensitivity_%s_%d_%s_job%d.txt", dump_dir, ifo[i], int(Tb), data_label, runID);cout<< endl<< "Dump Sensitivity : "<< file<< endl<< endl;TB.makeSpectrum(file, x);continue;}if(dcCal[i]>0.) x *=dcCal[i];if(fResample >0){x.FFT(1);x.resize(fResample/x.rate()*x.size());x.FFT(-1);x.rate(fResample);}pTF[i]=pD[i]-> getTFmap()
fclose(ftrig)
float rate
Definition: netpixel.hh:95
std::vector< SSeries< double > > vSS
Definition: detector.hh:334
static void _sse_minSNE_ps(__m128 *_pE, __m128 **_pe, __m128 *_es)
Definition: watsse.hh:522
network & operator=(const network &)
Definition: network.cc:2480
size_t size()
Definition: skymap.hh:118
WSeries< double > waveNull
Definition: detector.hh:339
double getdata(char type='R', size_t n=0)
Definition: netpixel.hh:56
size_t setRank(double, double=0.)
Definition: network.cc:3085
static __m128 _sse_like4_ps(__m128 *_f, __m128 *_a, __m128 *_A)
Definition: watsse.hh:980
static void _sse_rot4p_ps(__m128 *_u, __m128 *_c, __m128 *_v, __m128 *_s, __m128 *_a)
Definition: watsse.hh:424
double shift[NIFO_MAX]
std::vector< float > value
Definition: detector.hh:28
static void _sse_rotp_ps(__m128 *u, float *c, __m128 *v, float *s, __m128 *a)
Definition: watsse.hh:398
virtual void resize(unsigned int)
Definition: wavearray.cc:445
bool MRA
Definition: network.hh:581
int check
size_t readSEGlist(char *, int=1)
param: segment list file param: start time collumn number
Definition: network.cc:3415
int setTimeShifts(size_t=1, double=1., size_t=0, size_t=0, const char *=NULL, const char *="w", size_t *=NULL)
param number of time lags param time shift step in seconds param first lag ID param maximum lag ID pa...
Definition: network.cc:7290
double penalty
Definition: network.hh:577
void Inverse(int n=-1)
param: n - number of steps (-1 means full reconstruction)
Definition: wseries.cc:273
virtual void waveSplit(DataType_t **pp, size_t l, size_t r, size_t m) const
Definition: wavearray.cc:1481
wavearray< double > y
Definition: Test10.C:31
size_t ifoID
Definition: detector.hh:310
double stop
Definition: network.hh:38
double delta
Definition: network.hh:573
void putLayer(wavearray< DataType_t > &, double n)
param: n - layer number
Definition: wseries.cc:201
static float _avx_packet_ps(float **p, float **q, std::vector< float * > &pAVX, int I)
Definition: watavx.hh:532
char c3[8]
double netRHO
Definition: network.hh:579
bool setndm(size_t, size_t, bool=true, int=1)
param: cluster ID param: lag index param: statistic identificator param: resolution idenificator retu...
Definition: network.cc:6494
double frequency(int l)
Definition: wseries.cc:99
static void _sse_dpf4_ps(__m128 *_Fp, __m128 *_Fx, __m128 *_fp, __m128 *_fx)
Definition: watsse.hh:613
#define SNR
Definition: DrawNRI.C:36
bool SETNDM(size_t, size_t, bool=true, int=1)
Definition: network.cc:6793
float null
Definition: netpixel.hh:97
static void _sse_pnp4_ps(__m128 *_fp, __m128 *_fx, __m128 *_am, __m128 *_AM, __m128 *_u, __m128 *_v)
Definition: watsse.hh:623
wavearray< double > ISNR
Definition: detector.hh:354
size_t start() const
Definition: wslice.hh:67
size_t nDFL
Definition: detector.hh:325
int maxLayer()
Definition: wseries.hh:121
bool EFEC
Definition: network.hh:569
detector ** pD
double mod() const
Definition: wavecomplex.hh:55
double iNET
Definition: network.hh:563
size_t lagMax
Definition: test_config1.C:55
void setTau(double, double=0., double=180., double=0., double=360.)
param - step on phi and theta param - theta begin param - theta end param - phi begin param - phi end...
Definition: detector.cc:637
static void _sse_ort4_ps(__m128 *_u, __m128 *_v, __m128 *_s, __m128 *_c)
Definition: watsse.hh:554
std::vector< vector_int > nTofF
Definition: netcluster.hh:386
void setSkyMaps(double, double=0., double=180., double=0., double=360.)
param: sky map granularity step, degrees param: theta begin, degrees param: theta end...
Definition: network.cc:2656
exit(0)
void cpf(const wavearray< DataType_t > &, int=0, int=0, int=0)
Definition: wavearray.cc:699
void clean()
Definition: netpixel.hh:81
bool setdata(double a, char type='R', size_t n=0)
Definition: netpixel.hh:40
double enrg
Definition: detector.hh:319
#define GAMMA(TYPE)
Definition: xroot.hh:5
double threshold(double, double)
param: selected fraction of LTF pixels assuming Gaussian noise param: maximum time delay between dete...
Definition: network.cc:2613
double avr
size_t healpix
m2
Definition: cbc_plots.C:607
size_t lagSize
Definition: test_config1.C:52