LAL  7.5.0.1-08ee4f4
CoherentEstimation.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007 Jolien Creighton, Julien Sylvestre
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19 
20 #include <lal/CoherentEstimation.h>
21 #include <lal/DetResponse.h>
22 #include <lal/TimeDelay.h>
23 #include <lal/AVFactories.h>
24 #include <strings.h>
25 #include <math.h>
26 
27 #define EPS 1.0e-7
28 
29 #define Cosh(x) cosh(x)
30 #define ACosh(x) acosh(x)
31 
32 double cosh(double);
33 double acosh(double);
34 
35 static INT4 jacobi(float **a, int n, float d[], float **v, int *nrot);
36 
37 void
40  CoherentEstimation *params,
41  DetectorsData *in) {
42  /*
43  NOTES:
44  o destroys input (in)
45  o order of in must be same as order of params->filters
46  o output time wrt center of Earth
47  */
48 
49  INT4 /* Sret, */
50  i, j, k, /* counters */
51  iPad, ePad, /* used for padding */
52  del; /* integer time delay */
53  REAL4 y; /* dummy */
54  REAL8 p1,p2; /* weights in interpolation */
55  REAL8 *tDelays; /* time delays wrt Earth center */
56  REAL8 mDelay; /* max of time delays */
57  REAL8 tmid; /* mid time point */
58  LALDetAMResponse *F; /* response functions */
59  LALPlaceAndGPS pGPS; /* for time delays */
60  LALDetAndSource dAs; /* for responses */
61  LALSource source; /* for responses */
62  LIGOTimeGPS t0; /* start time of data */
63 
64  REAL8 *alpha; /* scale factor */
65  INT4 nrot;
66  REAL8 maxLambda, tmpLambda;
67  REAL4 *lambda;
68  REAL4 **Hmat;
69  REAL4 **v;
70  REAL8 **Cmat;
71 
72  /*
73  {REAL8 tmp = Cosh(ACosh((double)3.02993)/3.0);
74  printf("%g\n",tmp);}
75  */
76 
77  /***********************************************************************/
78  /* initialize status & validate input */
79  /***********************************************************************/
80  INITSTATUS(stat);
81  ATTATCHSTATUSPTR( stat );
82 
83 
87 
89 
90  for(i=0;i<(INT4)in->Ndetectors;i++) {
92  }
93 
94  t0 = in->data[0].epoch;
95 
96  for(i=1;i<(INT4)in->Ndetectors;i++) {
97  ASSERT ( in->data[i].epoch.gpsSeconds == t0.gpsSeconds &&
99  }
100 
106 
107  /***********************************************************************/
108  /* if params->preProcessed is 0, need to pre-processed by applying the */
109  /* IIR filters twice */
110  /***********************************************************************/
111  if(!(params->preProcessed) && params->nPreProcessed) {
112 
113  REAL8Vector *tmpR8 = NULL;
114  UINT4 jind;
115 
116  for(i=0;i<(INT4)in->Ndetectors;i++) {
118  }
119 
120  /* loop over all detectors, and filter twice */
121  for(i=0; i<(INT4)params->Ndetectors; i++) {
122 
123  TRY ( LALDCreateVector( stat->statusPtr,
124  &tmpR8,
125  in->data[i].data->length ), stat );
126 
127  for(jind = 0; jind<in->data[i].data->length; jind++) {
128  tmpR8->data[jind] = (REAL8)(in->data[i].data->data[jind]);
129  }
130 
131  for(j=0; j<params->nPreProcessed; j++) {
133  tmpR8,
134  params->filters[i]), stat );
135  }
136 
137  for(jind = 0; jind<in->data[i].data->length; jind++) {
138  in->data[i].data->data[jind] = (REAL4)(tmpR8->data[jind]);
139  }
140 
141  TRY ( LALDDestroyVector ( stat->statusPtr,
142  &tmpR8 ) , stat );
143 
144  /* set first 1/16 s to zero to avoid transient */
145  memset(in->data[i].data->data, 0, sizeof(REAL4) * (UINT4)ceil(0.0635 / in->data[i].deltaT));
146 
147  }
148 
149  params->preProcessed = 1;
150 
151  }
152 
153 
154  /* update output parameters */
155  output->epoch = in->data[0].epoch;
156  output->deltaT = in->data[0].deltaT;
157  output->f0 = in->data[0].f0;
158  memcpy(&(output->sampleUnits), &(in->data[0].sampleUnits), sizeof(LALUnit));
159 
160  /* make sure output is zero */
161  memset(output->data->data, 0, output->data->length * sizeof(REAL4));
162 
163 
164 
165  /***********************************************************************/
166  /* Compute time delays and response functions */
167  /***********************************************************************/
168  if(!(tDelays = (REAL8 *)LALMalloc(params->Ndetectors * sizeof(REAL8)))) {
170  }
171 
172  /* delays are computed wrt to center of data stretch */
173  pGPS.p_gps = &t0;
174  tmid = 0.5 * (REAL8)(in->data[0].data->length) * in->data[0].deltaT;
175  pGPS.p_gps->gpsSeconds += (INT4)floor(tmid);
176  pGPS.p_gps->gpsNanoSeconds += (INT4)floor(1E9*(tmid-floor(tmid)));
177  if(pGPS.p_gps->gpsNanoSeconds >= 1000000000) {
178  pGPS.p_gps->gpsSeconds += (INT4)floor((REAL8)(pGPS.p_gps->gpsNanoSeconds) / 1E9);
179  pGPS.p_gps->gpsNanoSeconds -= 1000000000 * (INT4)floor((REAL8)(pGPS.p_gps->gpsNanoSeconds) / 1E9);
180  }
181 
182 
183  if(!(F = (LALDetAMResponse *)LALMalloc(params->Ndetectors * sizeof(LALDetAMResponse)))) {
185  }
186 
187  dAs.pSource = &source;
188  source.equatorialCoords = *(params->position);
189  source.orientation = params->polAngle;
190 
191  for(i=0; i<(INT4)params->Ndetectors; i++) {
192 
193  pGPS.p_detector = dAs.pDetector = params->detectors + i;
194 
195  /* tDelays = arrival time at detector - arrival time a center of Earth */
196  tDelays[i] = XLALTimeDelayFromEarthCenter(params->detectors[i].location, params->position->longitude, params->position->latitude, &t0);
197 
198  /* JC: isnan is not allowed
199  if(isnan(tDelays[i])) {
200  ABORT ( stat, COHERENTESTIMATIONH_ENUM, COHERENTESTIMATIONH_MSGENUM );
201  }
202  */
203 
205  F + i,
206  &dAs,
207  pGPS.p_gps ), stat );
208 
209  /* JC: isnan is not allowed
210  if(isnan(F[i].cross) || isnan(F[i].plus)) {
211  ABORT ( stat, COHERENTESTIMATIONH_ENUM, COHERENTESTIMATIONH_MSGENUM );
212  }
213  */
214  }
215 
216  /***********************************************************************/
217  /* Compute and store estimated data */
218  /***********************************************************************/
219  /* set time origine on detector with largest delay */
220  /*
221  mDelay = tDelays[0];
222  for(i=1; i<params->Ndetectors; i++) {
223  if(tDelays[i] > mDelay) {
224  mDelay = tDelays[i];
225  }
226  }
227  */
228  mDelay = tDelays[0];
229 
230  for(i=0; i<(INT4)params->Ndetectors; i++) {
231  tDelays[i] -= mDelay;
232  }
233 
234 
235  alpha = (REAL8 *)LALMalloc(params->Ndetectors * sizeof(REAL8));
236  if(!alpha) {
238  }
239 
240  lambda = (REAL4 *)LALMalloc(params->Ndetectors * sizeof(REAL4));
241  if(!lambda) {
243  }
244 
245  Hmat = (REAL4 **)LALMalloc(params->Ndetectors * sizeof(REAL4 *));
246  if(!Hmat) {
248  }
249  for(i=0; i<(INT4)params->Ndetectors; i++) {
250  Hmat[i] = (REAL4 *)LALMalloc(params->Ndetectors * sizeof(REAL4));
251  if(!(Hmat[i])) {
253  }
254  }
255 
256  v = (REAL4 **)LALMalloc(params->Ndetectors * sizeof(REAL4 *));
257  if(!v) {
259  }
260  for(i=0; i<(INT4)params->Ndetectors; i++) {
261  v[i] = (REAL4 *)LALMalloc(params->Ndetectors * sizeof(REAL4));
262  if(!(v[i])) {
264  }
265  }
266 
267  Cmat = params->CMat;
268 
269  for(i=0; i<(INT4)params->Ndetectors; i++) {
270  for(j=0; j<(INT4)params->Ndetectors; j++) {
271 
272  Hmat[i][j] = (F[i].plus*F[j].plus*params->plus2cross + (F[i].plus*F[j].cross + F[j].plus*F[i].cross)*params->plusDotcross + F[i].cross*F[j].cross/params->plus2cross) / Cmat[i][i];
273 
274  }
275  }
276 
277  if(jacobi(Hmat, params->Ndetectors, lambda, v, &nrot)) {
279  }
280  /*
281  printf("%g\t%g\t%g\n",lambda[0],lambda[1],lambda[2]);
282  */
283  maxLambda = -1e30;
284  for(k=0;k<(INT4)params->Ndetectors;k++) {
285 
286  tmpLambda = 0.0;
287 
288  for(i=0; i<(INT4)params->Ndetectors; i++) {
289  for(j=0; j<(INT4)params->Ndetectors; j++) {
290  tmpLambda += v[i][k]*v[j][k]*(F[i].plus*F[j].plus*params->plus2cross + (F[i].plus*F[j].cross + F[j].plus*F[i].cross)*params->plusDotcross + F[i].cross*F[j].cross/params->plus2cross);
291  }
292  }
293 
294  if(tmpLambda > maxLambda) {
295  for(i=0; i<(INT4)params->Ndetectors; i++) {
296  alpha[i] = v[i][k];
297  }
298  maxLambda = tmpLambda;
299  }
300 /*
301  printf("%u\t%g\t%g\t%g\t%g\n",k,lambda[k],alpha[0],alpha[1],alpha[2]);
302  */
303  }
304 
305  /* loop */
306  for(i=0; i<(INT4)params->Ndetectors; i++) {
307 
308  /* setup padding and weights */
309  if(tDelays[i] < 0.0) {
310  /* need padding at beginning */
311  iPad = (INT4)floor(-tDelays[i]/output->deltaT);
312  ePad = 0;
313 
314  /* set integer delay (for p1 weight) */
315  del = -iPad;
316 
317  /* set weights */
318  p1 = ceil(tDelays[i] / output->deltaT) - tDelays[i] / output->deltaT;
319  p2 = 1.0 - p1;
320  } else {
321  /* need padding at end */
322  iPad = 0;
323  ePad = (INT4)ceil(tDelays[i]/output->deltaT);
324 
325  /* integer delay */
326  del = ePad;
327 
328  /* weights */
329  p1 = ceil(tDelays[i] / output->deltaT) - tDelays[i] / output->deltaT;
330  p2 = 1.0 - p1;
331  }
332 
333 
334  /* interpolate using time delays */
335  for(j=iPad+1; j<(INT4)output->data->length - (INT4)ePad; j++) {
336 
337  y = p1 * in->data[i].data->data[del+j-1] + p2 * in->data[i].data->data[del+j];
338 
339  output->data->data[j] += y * alpha[i];
340  }
341  }
342 
343  /*
344  {
345  FILE *out;
346  out = fopen("test.dat","w");
347  for(j=0;j<output->data->length;j++) {
348  fprintf(out,"%g\t%g\n",output->data->data[j].re,output->data->data[j].im);
349  }
350  fclose(out);
351 
352  exit(0);
353  }
354  */
355 
356  /***********************************************************************/
357  /* clean up and normal return */
358  /***********************************************************************/
359  LALFree(tDelays);
360  LALFree(F);
361 
362  LALFree(alpha);
363  LALFree(lambda);
364 
365  for(i=0; i<(INT4)params->Ndetectors; i++) {
366  LALFree(Hmat[i]);
367  LALFree(v[i]);
368  }
369  LALFree(Hmat);
370  LALFree(v);
371 
372  DETATCHSTATUSPTR( stat );
373  RETURN( stat );
374 
375 }
376 
377 
378 void
380  LALStatus *stat,
381  DetectorsData *dat
382  ) {
383 
384  UINT4 i;
385 
386  INITSTATUS(stat);
387  ATTATCHSTATUSPTR( stat );
388 
389  if(!dat) {
391  }
392 
393  for(i=0; i<dat->Ndetectors; i++) {
394  if(dat->data[i].data) {
395  TRY ( LALDestroyVector(stat->statusPtr, &(dat->data[i].data)), stat );
396  }
397  }
398 
399  LALFree(dat->data);
400 
401  DETATCHSTATUSPTR( stat );
402  RETURN( stat );
403 
404 }
405 
406 
407 
408 void
410  LALStatus *stat,
411  CoherentEstimation *dat
412  ) {
413 
414  UINT4 i;
415 
416  INITSTATUS(stat);
417  ATTATCHSTATUSPTR( stat );
418 
419  if(!dat) {
421  }
422 
423  LALFree(dat->detectors);
424 
425  for(i=0; i<dat->Ndetectors; i++) {
426  if(dat->filters[i]) {
427  TRY ( LALDestroyREAL8IIRFilter(stat->statusPtr, dat->filters + i), stat );
428  }
429  LALFree(dat->CMat[i]);
430  }
431 
432  LALFree(dat->filters);
433 
434  LALFree(dat->CMat);
435 
436  DETATCHSTATUSPTR( stat );
437  RETURN( stat );
438 
439 }
440 
441 
442 #define ROTATE(a,i,j,k,l) g=a[i][j];h=a[k][l];a[i][j]=g-s*(h+g*tau);\
443  a[k][l]=h+s*(g-h*tau);
444 
445 int jacobi(float **a, int n, float d[], float **v, int *nrot)
446 {
447  int j,iq,ip,i/*,k*/;
448  float tresh,theta,tau,t,sm,s,h,g,c,*b,*z;
449 
450  b = (REAL4 *)LALMalloc(n * sizeof(REAL4));
451  if(!b) {
452  return 1;
453  }
454  b -= 1;
455 
456  z = (REAL4 *)LALMalloc(n * sizeof(REAL4));
457  if(!z) {
458  return 1;
459  }
460  z -= 1;
461 
462  d -= 1;
463 
464  for(i=0;i<n;i++) {
465  v[i] -= 1;
466  a[i] -= 1;
467  }
468  v -= 1;
469  a -= 1;
470 
471  for (ip=1;ip<=n;ip++) {
472  for (iq=1;iq<=n;iq++) v[ip][iq]=0.0;
473  v[ip][ip]=1.0;
474  }
475  for (ip=1;ip<=n;ip++) {
476  b[ip]=d[ip]=a[ip][ip];
477  z[ip]=0.0;
478  }
479  *nrot=0;
480  for (i=1;i<=50;i++) {
481  sm=0.0;
482  for (ip=1;ip<=n-1;ip++) {
483  for (iq=ip+1;iq<=n;iq++)
484  sm += fabs(a[ip][iq]);
485  }
486  if (sm == 0.0) {
487  LALFree(z + 1);
488  LALFree(b + 1);
489  d += 1;
490  a += 1;
491  v += 1;
492  for(i=0;i<n;i++) {
493  v[i] += 1;
494  a[i] += 1;
495  }
496  return 0;
497  }
498  if (i < 4)
499  tresh=0.2*sm/(n*n);
500  else
501  tresh=0.0;
502  for (ip=1;ip<=n-1;ip++) {
503  for (iq=ip+1;iq<=n;iq++) {
504  g=100.0*fabs(a[ip][iq]);
505  if (i > 4 && (float)(fabs(d[ip])+g) == (float)fabs(d[ip])
506  && (float)(fabs(d[iq])+g) == (float)fabs(d[iq]))
507  a[ip][iq]=0.0;
508  else if (fabs(a[ip][iq]) > tresh) {
509  h=d[iq]-d[ip];
510  if ((float)(fabs(h)+g) == (float)fabs(h))
511  t=(a[ip][iq])/h;
512  else {
513  theta=0.5*h/(a[ip][iq]);
514  t=1.0/(fabs(theta)+sqrt(1.0+theta*theta));
515  if (theta < 0.0) t = -t;
516  }
517  c=1.0/sqrt(1+t*t);
518  s=t*c;
519  tau=s/(1.0+c);
520  h=t*a[ip][iq];
521  z[ip] -= h;
522  z[iq] += h;
523  d[ip] -= h;
524  d[iq] += h;
525  a[ip][iq]=0.0;
526  for (j=1;j<=ip-1;j++) {
527  ROTATE(a,j,ip,j,iq)
528  }
529  for (j=ip+1;j<=iq-1;j++) {
530  ROTATE(a,ip,j,j,iq)
531  }
532  for (j=iq+1;j<=n;j++) {
533  ROTATE(a,ip,j,iq,j)
534  }
535  for (j=1;j<=n;j++) {
536  ROTATE(v,j,ip,j,iq)
537  }
538  ++(*nrot);
539  }
540  }
541  }
542  for (ip=1;ip<=n;ip++) {
543  b[ip] += z[ip];
544  d[ip]=b[ip];
545  z[ip]=0.0;
546  }
547  }
548 
549  fprintf(stderr,"Too many iterations in routine jacobi");
550  return 1;
551 }
552 #undef ROTATE
553 
void LALDoCoherentEstimation(LALStatus *stat, REAL4TimeSeries *output, CoherentEstimation *params, DetectorsData *in)
double cosh(double)
void LALClearCoherentData(LALStatus *stat, DetectorsData *dat)
#define ROTATE(a, i, j, k, l)
static INT4 jacobi(float **a, int n, float d[], float **v, int *nrot)
double acosh(double)
void LALClearCoherentInfo(LALStatus *stat, CoherentEstimation *dat)
#define COHERENTESTIMATIONH_EDST
#define COHERENTESTIMATIONH_EUIMP
#define COHERENTESTIMATIONH_MSGENUM
#define COHERENTESTIMATIONH_ENULL
#define COHERENTESTIMATIONH_EICE
#define COHERENTESTIMATIONH_MSGEDST
#define COHERENTESTIMATIONH_MSGEUIMP
#define COHERENTESTIMATIONH_ENUM
#define COHERENTESTIMATIONH_EMEM
#define COHERENTESTIMATIONH_MSGEMEM
#define COHERENTESTIMATIONH_MSGE0DEC
#define COHERENTESTIMATIONH_MSGEICE
#define COHERENTESTIMATIONH_MSGENULL
#define COHERENTESTIMATIONH_E0DEC
#define LALMalloc(n)
Definition: LALMalloc.h:93
#define LALFree(p)
Definition: LALMalloc.h:96
#define ABORT(statusptr, code, mesg)
#define TRY(func, statusptr)
#define ATTATCHSTATUSPTR(statusptr)
#define ASSERT(assertion, statusptr, code, mesg)
#define DETATCHSTATUSPTR(statusptr)
#define INITSTATUS(statusptr)
#define RETURN(statusptr)
#define fprintf
void LALDestroyREAL8IIRFilter(LALStatus *stat, REAL8IIRFilter **input)
Deprecated.
void LALComputeDetAMResponse(LALStatus *status, LALDetAMResponse *pResponse, const LALDetAndSource *pDetAndSrc, const LIGOTimeGPS *gps)
Definition: DetResponse.c:401
void LALIIRFilterREAL8Vector(LALStatus *status, REAL8Vector *vector, REAL8IIRFilter *filter)
WARNING: THIS FUNCTION IS OBSOLETE.
double REAL8
Double precision real floating-point number (8 bytes).
uint32_t UINT4
Four-byte unsigned integer.
int32_t INT4
Four-byte signed integer.
float REAL4
Single precision real floating-point number (4 bytes).
static const INT4 a
Definition: Random.c:79
double XLALTimeDelayFromEarthCenter(const double detector_earthfixed_xyz_metres[3], double source_right_ascension_radians, double source_declination_radians, const LIGOTimeGPS *gpstime)
Compute difference in arrival time of the same signal at detector and at center of Earth-fixed frame.
Definition: TimeDelay.c:83
void LALDestroyVector(LALStatus *, REAL4Vector **)
void LALDCreateVector(LALStatus *, REAL8Vector **, UINT4)
void LALDDestroyVector(LALStatus *, REAL8Vector **)
REAL8IIRFilter ** filters
LALDetector * detectors
SkyPosition * position
REAL4TimeSeries * data
This structure encapsulates the detector AM (beam pattern) coefficients for one source at one instanc...
Definition: DetResponse.h:140
REAL4 plus
Detector response to -polarized gravitational radiation
Definition: DetResponse.h:141
REAL4 cross
Detector response to -polarized gravitational radiation.
Definition: DetResponse.h:142
This structure aggregates a pointer to a LALDetector and a LALSource.
Definition: DetResponse.h:128
LALSource * pSource
Pointer to LALSource object containing information about the source.
Definition: DetResponse.h:130
const LALDetector * pDetector
Pointer to LALDetector object containing information about the detector.
Definition: DetResponse.h:129
REAL8 location[3]
The three components, in an Earth-fixed Cartesian coordinate system, of the position vector from the ...
Definition: LALDetectors.h:279
This structure stores pointers to a LALDetector and a LIGOTimeGPS.
Definition: Date.h:102
LIGOTimeGPS * p_gps
Pointer to a GPS time structure.
Definition: Date.h:104
const LALDetector * p_detector
pointer to a detector
Definition: Date.h:103
This structure contains gravitational wave source position (in Equatorial coördinates),...
Definition: DetResponse.h:105
SkyPosition equatorialCoords
equatorial coordinates of source, in decimal RADIANS
Definition: DetResponse.h:107
REAL8 orientation
Orientation angle ( ) of source: counter-clockwise angle -axis makes with a line perpendicular to mer...
Definition: DetResponse.h:108
LAL status structure, see The LALStatus structure for more details.
Definition: LALDatatypes.h:947
struct tagLALStatus * statusPtr
Pointer to the next node in the list; NULL if this function is not reporting a subroutine error.
Definition: LALDatatypes.h:954
This structure stores units in the mksA system (plus Kelvin, Strain, and ADC Count).
Definition: LALDatatypes.h:498
Epoch relative to GPS epoch, see LIGOTimeGPS type for more details.
Definition: LALDatatypes.h:458
INT4 gpsSeconds
Seconds since 0h UTC 6 Jan 1980.
Definition: LALDatatypes.h:459
INT4 gpsNanoSeconds
Residual nanoseconds.
Definition: LALDatatypes.h:460
Time series of REAL4 data, see DATATYPE-TimeSeries types for more details.
Definition: LALDatatypes.h:570
REAL4Sequence * data
The sequence of sampled data.
Definition: LALDatatypes.h:576
LALUnit sampleUnits
The physical units of the quantity being sampled.
Definition: LALDatatypes.h:575
REAL8 deltaT
The time step between samples of the time series in seconds.
Definition: LALDatatypes.h:573
LIGOTimeGPS epoch
The start time of the time series.
Definition: LALDatatypes.h:572
REAL8 f0
The heterodyning frequency, in Hertz (zero if not heterodyned).
Definition: LALDatatypes.h:574
REAL4 * data
Pointer to the data array.
Definition: LALDatatypes.h:150
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:149
Vector of type REAL8, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:154
REAL8 * data
Pointer to the data array.
Definition: LALDatatypes.h:159
REAL8 longitude
The longitudinal coordinate (in radians), as defined above.
REAL8 latitude
The latitudinal coordinate (in radians), as defined above.
void output(int gps_sec, int output_type)
Definition: tconvert.c:440