LALPulsar  6.1.0.1-89842e6
LISAspecifics.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006, 2007 Reinhard Prix
3  * Copyright (C) 2006, 2007, 2008 John T. Whelan
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with with program; see the file COPYING. If not, write to the
17  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  * MA 02110-1301 USA
19  */
20 
21 /**
22  * \author R. Prix, J. T. Whelan
23  * \file
24  * \brief
25  * LISA-specific implementations for Fstat/continuous-wave searches on LISA TDI observables.
26  *
27  */
28 
29 /*---------- INCLUDES ----------*/
30 #include <math.h>
31 #include <string.h>
32 
33 #include <lal/LISAspecifics.h>
34 #include <lal/LALError.h>
35 #include <lal/SinCosLUT.h>
36 
37 /*---------- local DEFINES ----------*/
38 #define TRUE (1==1)
39 #define FALSE (1==0)
40 
41 /*----- Macros ----- */
42 /** Simple Euklidean scalar product for two 3-dim vectors in cartesian coords */
43 #define SCALAR(u,v) ((u)[0]*(v)[0] + (u)[1]*(v)[1] + (u)[2]*(v)[2])
44 #define SQ(x) ( (x) * (x) )
45 #define GPS2REAL8(gps) (1.0 * (gps).gpsSeconds + 1.e-9 * (gps).gpsNanoSeconds )
46 #define LAL_SQRT1_3 0.5773502691896257645091487805019575 /**< 1/sqrt(3) */
47 /*----- SWITCHES -----*/
48 
49 /*---------- internal types ----------*/
50 
51 /*---------- Global variables ----------*/
52 
53 /*---------- internal prototypes ----------*/
54 int XLALgetLISAtwoArmRAAIFO( CmplxDetectorTensor *detT, const DetectorArm *armA, const DetectorArm *armB, const FreqSkypos_t *freq_skypos );
55 
56 static REAL4 safe_sinc( REAL4 x );
57 
58 /*==================== FUNCTION DEFINITIONS ====================*/
59 
60 
61 /**
62  * Return true if 'det' is a LISA \em LALDetector struct
63  */
64 BOOLEAN
66 {
67  return ( det != NULL ) && ( strncmp( det->frDetector.name, "LISA TDI ", 9 ) == 0 );
68 }
69 
70 /**
71  * Set up the \em LALDetector structs representing LISA X, Y, Z TDI observables.
72  * Detectors will be registered with prefixes beginning with 'prefixLetter'.
73  */
74 int
75 XLALregisterLISAdetectors( const CHAR prefixLetter )
76 {
77 
78  for ( CHAR channelNum = '1'; channelNum <= '9'; ++channelNum ) {
79  LALDetector XLAL_INIT_DECL( Detector1 );
80 
81  switch ( channelNum ) {
82  case '1':
83  strcpy( Detector1.frDetector.name, "LISA TDI X" );
84  break;
85  case '2':
86  strcpy( Detector1.frDetector.name, "LISA TDI Y" );
87  break;
88  case '3':
89  strcpy( Detector1.frDetector.name, "LISA TDI Z" );
90  break;
91  case '4':
92  strcpy( Detector1.frDetector.name, "LISA TDI Y-Z" );
93  break;
94  case '5':
95  strcpy( Detector1.frDetector.name, "LISA TDI Z-X" );
96  break;
97  case '6':
98  strcpy( Detector1.frDetector.name, "LISA TDI X-Y" );
99  break;
100  case '7':
101  strcpy( Detector1.frDetector.name, "LISA TDI A" );
102  break;
103  case '8':
104  strcpy( Detector1.frDetector.name, "LISA TDI E" );
105  break;
106  case '9':
107  strcpy( Detector1.frDetector.name, "LISA TDI T" );
108  break;
109  default:
110  XLAL_ERROR( XLAL_EINVAL, "Illegal LISA TDI index '%c': must be one of {'1', '2', '3', '4', '5', '6', '7', '8', '9'}.\n\n", channelNum );
111  break;
112  } /* switch (channelNum) */
113 
114  Detector1.frDetector.prefix[0] = prefixLetter;
115  Detector1.frDetector.prefix[1] = channelNum;
116 
117  /* fill frDetector with dummy numbers: meaningless for LISA */
118  Detector1.frDetector.vertexLongitudeRadians = 0;
119  Detector1.frDetector.vertexLatitudeRadians = 0;
120  Detector1.frDetector.vertexElevation = 0;
121  Detector1.frDetector.xArmAltitudeRadians = 0;
122  Detector1.frDetector.xArmAzimuthRadians = 0;
123  Detector1.frDetector.yArmAltitudeRadians = 0;
124  Detector1.frDetector.yArmAzimuthRadians = 0;
125 
126  Detector1.type = LALDETECTORTYPE_ABSENT;
127 
128  /* however: need to be careful to put some non-zero numbers for location
129  * otherwise XLALBarycenter() will spit out NaNs ...
130  */
131  Detector1.location[0] = 1;
132  Detector1.location[1] = 1;
133  Detector1.location[2] = 1;
134 
136 
137  }
138 
139  return XLAL_SUCCESS;
140 
141 } /* XLALregisterLISAdetectors() */
142 
143 
144 /**
145  * Precompute the arm-geometry for LISA, which is later used
146  * for assembling the RAA detector-tensor (which depends on
147  * frequency and skyposition
148  */
149 int
151 {
152  REAL4 x[3], y[3], z[3]; /* position x,y,z of spacecraft n */
153 
154  enum { SC1 = 0, SC2, SC3 }; /* translate TDI-conventions to C-indexing */
155  enum { I1 = 0, I2, I3 }; /* convenience indices */
156 
157  UINT4 send_l[3] = { SC3, SC1, SC2 }; /* canonical sender-spacecraft 's' for arm 'l' */
158  UINT4 rec_l [3] = { SC2, SC3, SC1 }; /* canonical receiver-spacecraft 'r' for arm 'l' */
159 
160  UINT4 arm;
161 
162  if ( !detState ) {
163  return -1;
164  }
165 
166  { /* determine space-craft positions [MLDC Challenge 1] */
167  REAL4 e = 0.00965; /* LISA eccentricity */
168  REAL4 ae = LAL_AU_SI * e / LAL_C_SI; /* in units of time */
169  REAL4 kappa = 0, lambda = 0; /* MLDC default */
170  REAL4 sin_alpha, cos_alpha;
171 
173  REAL8 alpha_t;
174  UINT4 i;
175  REAL8 tGPS = GPS2REAL8( detState->tGPS ) - LISA_TIME_ORIGIN;
176 
177  alpha_t = Om * tGPS + kappa;
178  XLAL_CHECK( XLALSinCosLUT( &sin_alpha, &cos_alpha, alpha_t ) == XLAL_SUCCESS, XLAL_EFUNC );
179 
180  for ( i = 0; i < 3; i ++ ) {
181  REAL4 beta = 2.0 * i * LAL_PI / 3.0 + lambda; /* relative orbital phase in constellation */
182  REAL4 sin_beta, cos_beta;
183  XLAL_CHECK( XLALSinCosLUT( &sin_beta, &cos_beta, beta ) == XLAL_SUCCESS, XLAL_EFUNC );
184 
185  x[i] = detState->earthState.posNow[0] + ae * ( sin_alpha * cos_alpha * sin_beta - ( 1.0f + SQ( sin_alpha ) ) * cos_beta );
186  y[i] = detState->earthState.posNow[1] + ae * ( sin_alpha * cos_alpha * cos_beta - ( 1.0f + SQ( cos_alpha ) ) * sin_beta );
187  z[i] = detState->earthState.posNow[2] - sqrt( 3.0f ) * ae * ( cos_alpha * cos_beta + sin_alpha * sin_beta );
188  } /* for i=[0:2] */
189 
190  } /* determine spacecraft positions */
191 
192  for ( arm = 0; arm < 3; arm ++ ) {
193  UINT4 send, rec;
194  REAL4 n[3], L_c, invL;
195 
196  /* get canonical (ie following TDI conventions) senders and receivers this arm */
197  send = send_l[arm];
198  rec = rec_l [arm];
199 
200  /* get un-normalized arm-vectors first */
201  n[0] = x[rec] - x[send];
202  n[1] = y[rec] - y[send];
203  n[2] = z[rec] - z[send];
204 
205  /* get armlength in seconds, and normalize */
206  L_c = sqrt( SCALAR( n, n ) );
207  detState->detArms[arm].armlength_c = L_c;
208  invL = 1.0f / L_c;
209 
210  n[0] *= invL;
211  n[1] *= invL;
212  n[2] *= invL;
213 
214  /* pre-compute the "basis tensor" n x n for this arm */
215  XLALTensorSquareVector3( &( detState->detArms[arm].basisT ), n );
216 
217  /* store arm unit-vector */
218  detState->detArms[arm].n[0] = n[0];
219  detState->detArms[arm].n[1] = n[1];
220  detState->detArms[arm].n[2] = n[2];
221 
222  } /* for arm = 0, 1, 2 */
223 
224  return 0;
225 
226 } /* XLALprecomputeLISAarms() */
227 
228 
229 /* Construct the long-wavelength-limit (LWL) detector tensor for LISA, given the prefix
230  * and the precomputed detector arms.
231  *
232  * RETURN 0 = OK, -1 = ERROR
233  */
234 int
235 XLALgetLISADetectorTensorLWL( SymmTensor3 *detT, /**< [out]: LISA LWL detector-tensor */
236  const Detector3Arms detArms, /**< [in] precomputed detector-arms */
237  CHAR channelNum ) /**< channel-number (as a char) '1', '2', '3' .. */
238 {
239  LISAarmT armA = 0, armB = 0;
240  CHAR chan1 = 0;
241  CHAR chan2 = 0;
242  SymmTensor3 detT1, detT2;
243 
244  if ( !detT ) {
245  return -1;
246  }
247 
248  /* we distinuish (currently) 3 different TDI observables: X (channel=1), Y (channel=2), Z (channel=3) */
249  switch ( channelNum ) {
250  case '1': /* TDI observable 'X' */
251  armA = LISA_ARM2;
252  armB = LISA_ARM3;
253  break;
254  case '2': /* TDI observable 'Y' */
255  armA = LISA_ARM3;
256  armB = LISA_ARM1;
257  break;
258  case '3': /* TDI observable 'Z' */
259  armA = LISA_ARM1;
260  armB = LISA_ARM2;
261  break;
262  case '4':
263  chan1 = '2';
264  chan2 = '3';
265  break;
266  case '5':
267  chan1 = '3';
268  chan2 = '1';
269  break;
270  case '6':
271  chan1 = '1';
272  chan2 = '2';
273  break;
274  case '7':
275  case '8':
276  case '9':
277  chan2 = 'X';
278  break;
279  default: /* unknown */
280  XLALPrintError( "\nInvalid channel-number '%c' for LISA \n\n", channelNum );
282  return -1;
283  break;
284  } /* switch channel[1] */
285 
286  if ( chan1 == 0 ) {
287  if ( chan2 == 0 ) {
288  XLALSubtractSymmTensor3s( detT, &( detArms[armA].basisT ), &( detArms[armB].basisT ) );
289  XLALScaleSymmTensor3( detT, detT, 0.5f ); /* (1/2)*(nA x nA - nB x nB ) */
290  } else {
291  REAL8 weight1, weight2, weight3;
292  SymmTensor3 detT3;
293 
294  if ( XLALgetLISADetectorTensorLWL( &detT1, detArms, '1' ) != 0 ) {
295  XLALPrintError( "\nXLALgetLISADetectorTensorLWL() failed !\n\n" );
297  return -1;
298  }
299  if ( XLALgetLISADetectorTensorLWL( &detT2, detArms, '2' ) != 0 ) {
300  XLALPrintError( "\nXLALgetLISADetectorTensorLWL() failed !\n\n" );
302  return -1;
303  }
304  if ( XLALgetLISADetectorTensorLWL( &detT3, detArms, '3' ) != 0 ) {
305  XLALPrintError( "\nXLALgetLISADetectorTensorLWL() failed !\n\n" );
307  return -1;
308  }
309  switch ( channelNum ) {
310  case '7':
311  weight1 = ( 2.0 / 3.0 );
312  weight2 = ( -1.0 / 3.0 );
313  weight3 = ( -1.0 / 3.0 );
314  break;
315  case '8':
316  weight1 = 0.0;
317  weight2 = ( -1.0 * LAL_SQRT1_3 );
318  weight3 = LAL_SQRT1_3;
319  break;
320  case '9':
321  /* Note that in the LWL this will give detT = 0 */
322  weight1 = ( LAL_SQRT2 / 3.0 );
323  weight2 = ( LAL_SQRT2 / 3.0 );
324  weight3 = ( LAL_SQRT2 / 3.0 );
325  break;
326  default:
327  /* should never get to default */
328  XLALPrintError( "\nInvalid channel-number '%c' for LISA \n\n", channelNum );
330  return -1;
331  break;
332  }
333 
334  /* Note that the following in-place operations *are* safe */
335 
336  if ( XLALScaleSymmTensor3( &detT1, &detT1, weight1 ) != 0 ) {
337  XLALPrintError( "\nXLALScaleSymmTensor3() failed !\n\n" );
339  return -1;
340  }
341  if ( XLALScaleSymmTensor3( &detT2, &detT2, weight2 ) != 0 ) {
342  XLALPrintError( "\nXLALScaleSymmTensor3() failed !\n\n" );
344  return -1;
345  }
346  if ( XLALScaleSymmTensor3( &detT3, &detT3, weight3 ) != 0 ) {
347  XLALPrintError( "\nXLALScaleSymmTensor3() failed !\n\n" );
349  return -1;
350  }
351  if ( XLALAddSymmTensor3s( &detT2, &detT2, &detT3 ) != 0 ) {
352  XLALPrintError( "\nXLALSumSymmTensor3s() failed !\n\n" );
354  return -1;
355  }
356  if ( XLALAddSymmTensor3s( detT, &detT1, &detT2 ) != 0 ) {
357  XLALPrintError( "\nXLALSumSymmTensor3s() failed !\n\n" );
359  return -1;
360  }
361  } /* if (chan2 != 0) */
362  } else {
363  if ( XLALgetLISADetectorTensorLWL( &detT1, detArms, chan1 ) != 0 ) {
364  XLALPrintError( "\nXLALgetLISADetectorTensorLWL() failed !\n\n" );
366  return -1;
367  }
368  if ( XLALgetLISADetectorTensorLWL( &detT2, detArms, chan2 ) != 0 ) {
369  XLALPrintError( "\nXLALgetLISADetectorTensorLWL() failed !\n\n" );
371  return -1;
372  }
373 
374  if ( XLALSubtractSymmTensor3s( detT, &detT1, &detT2 ) != 0 ) {
375  XLALPrintError( "\nXLALSubtractSymmTensor3s() failed !\n\n" );
377  return -1;
378  } /* d_X - d_Y etc */
379  } /* multi-channel "detector" such as 'X-Y' etc */
380 
381  return 0;
382 
383 } /* XLALgetLISADetectorTensorLWL() */
384 
385 
386 /* Construct the rigid-adiabatic-approximation (RAA) detector tensor for LISA, given the prefix,
387  * the precomputed arms, and the Frequency and skyposition.
388  *
389  * RETURN 0 = OK, -1 = ERROR
390  */
391 int
392 XLALgetLISADetectorTensorRAA( CmplxDetectorTensor *detT, /**< [out]: LISA LWL detector-tensor */
393  const Detector3Arms detArms, /**< [in] precomputed detector-arms */
394  CHAR channelNum, /**< [in] channel-number (as a char) '1', '2', '3' .. */
395  const FreqSkypos_t *freq_skypos /**< [in] precompute frequency and skypos info */
396  )
397 {
398  LISAarmT armA = 0, armB = 0;
399  CHAR chan1 = 0;
400  CHAR chan2 = 0;
401  CmplxDetectorTensor detT1, detT2;
402 
403  if ( !detT ) {
404  return -1;
405  }
406 
407  /* we distinuish (currently) 3 different TDI observables: X (channel=1), Y (channel=2), Z (channel=3) */
408  switch ( channelNum ) {
409  case '1': /* TDI observable 'X' */
410  armA = LISA_ARM2;
411  armB = LISA_ARM3;
412  break;
413  case '2': /* TDI observable 'Y' */
414  armA = LISA_ARM3;
415  armB = LISA_ARM1;
416  break;
417  case '3': /* TDI observable 'Z' */
418  armA = LISA_ARM1;
419  armB = LISA_ARM2;
420  break;
421  case '4':
422  chan1 = '2';
423  chan2 = '3';
424  break;
425  case '5':
426  chan1 = '3';
427  chan2 = '1';
428  break;
429  case '6':
430  chan1 = '1';
431  chan2 = '2';
432  break;
433  case '7':
434  case '8':
435  case '9':
436  chan2 = 'X';
437  break;
438  default: /* unknown */
439  XLALPrintError( "\nInvalid channel-number '%c' for LISA \n\n", channelNum );
441  return -1;
442  break;
443  } /* switch channel[1] */
444 
445  if ( chan1 == 0 ) {
446  if ( chan2 == 0 ) {
447  if ( XLALgetLISAtwoArmRAAIFO( detT, &( detArms[armA] ),
448  &( detArms[armB] ), freq_skypos )
449  != 0 ) {
450  XLALPrintError( "\nXLALgetLISAtwoArmRAAIFO() failed !\n\n" );
452  return -1;
453  }
454  } else {
455  REAL8 weight1, weight2, weight3;
456  CmplxDetectorTensor detT3;
457 
458  if ( XLALgetLISADetectorTensorRAA( &detT1, detArms, '1',
459  freq_skypos ) != 0 ) {
460  XLALPrintError( "\nXLALgetLISADetectorTensorRAA() failed !\n\n" );
462  return -1;
463  }
464  if ( XLALgetLISADetectorTensorRAA( &detT2, detArms, '2',
465  freq_skypos ) != 0 ) {
466  XLALPrintError( "\nXLALgetLISADetectorTensorRAA() failed !\n\n" );
468  return -1;
469  }
470  if ( XLALgetLISADetectorTensorRAA( &detT3, detArms, '3',
471  freq_skypos ) != 0 ) {
472  XLALPrintError( "\nXLALgetLISADetectorTensorRAA() failed !\n\n" );
474  return -1;
475  }
476  switch ( channelNum ) {
477  case '7':
478  weight1 = ( 2.0 / 3.0 );
479  weight2 = ( -1.0 / 3.0 );
480  weight3 = ( -1.0 / 3.0 );
481  break;
482  case '8':
483  weight1 = 0.0;
484  weight2 = ( -1.0 * LAL_SQRT1_3 );
485  weight3 = LAL_SQRT1_3;
486  break;
487  case '9':
488  /* Note that in the RAA this will give detT != 0 */
489  weight1 = ( LAL_SQRT2 / 3.0 );
490  weight2 = ( LAL_SQRT2 / 3.0 );
491  weight3 = ( LAL_SQRT2 / 3.0 );
492  break;
493  default:
494  /* should never get to default */
495  XLALPrintError( "\nInvalid channel-number '%c' for LISA \n\n", channelNum );
497  return -1;
498  break;
499  }
500 
501  /* Note that the following in-place operations *are* safe */
502 
503  if ( XLALScaleSymmTensor3( &detT1.re, &detT1.re, weight1 ) != 0 ) {
504  XLALPrintError( "\nXLALScaleSymmTensor3() failed !\n\n" );
506  return -1;
507  }
508  if ( XLALScaleSymmTensor3( &detT1.im, &detT1.im, weight1 ) != 0 ) {
509  XLALPrintError( "\nXLALScaleSymmTensor3() failed !\n\n" );
511  return -1;
512  }
513  if ( XLALScaleSymmTensor3( &detT2.re, &detT2.re, weight2 ) != 0 ) {
514  XLALPrintError( "\nXLALScaleSymmTensor3() failed !\n\n" );
516  return -1;
517  }
518  if ( XLALScaleSymmTensor3( &detT2.im, &detT2.im, weight2 ) != 0 ) {
519  XLALPrintError( "\nXLALScaleSymmTensor3() failed !\n\n" );
521  return -1;
522  }
523  if ( XLALScaleSymmTensor3( &detT3.re, &detT3.re, weight3 ) != 0 ) {
524  XLALPrintError( "\nXLALScaleSymmTensor3() failed !\n\n" );
526  return -1;
527  }
528  if ( XLALScaleSymmTensor3( &detT3.im, &detT3.im, weight3 ) != 0 ) {
529  XLALPrintError( "\nXLALScaleSymmTensor3() failed !\n\n" );
531  return -1;
532  }
533  if ( XLALAddSymmTensor3s( &detT2.re, &detT2.re, &detT3.re ) != 0 ) {
534  XLALPrintError( "\nXLALSumSymmTensor3s() failed !\n\n" );
536  return -1;
537  }
538  if ( XLALAddSymmTensor3s( &detT2.im, &detT2.im, &detT3.im ) != 0 ) {
539  XLALPrintError( "\nXLALSumSymmTensor3s() failed !\n\n" );
541  return -1;
542  }
543  if ( XLALAddSymmTensor3s( &detT->re, &detT1.re, &detT2.re ) != 0 ) {
544  XLALPrintError( "\nXLALSumSymmTensor3s() failed !\n\n" );
546  return -1;
547  }
548  if ( XLALAddSymmTensor3s( &detT->im, &detT1.im, &detT2.im ) != 0 ) {
549  XLALPrintError( "\nXLALSumSymmTensor3s() failed !\n\n" );
551  return -1;
552  }
553  } /* if (chan2 != 0) */
554  } else {
555  if ( XLALgetLISADetectorTensorRAA( &detT1, detArms, chan1, freq_skypos ) != 0 ) {
556  XLALPrintError( "\nXLALgetLISADetectorTensorRAA() failed !\n\n" );
558  return -1;
559  }
560  if ( XLALgetLISADetectorTensorRAA( &detT2, detArms, chan2, freq_skypos ) != 0 ) {
561  XLALPrintError( "\nXLALgetLISADetectorTensorRAA() failed !\n\n" );
563  return -1;
564  }
565  XLALSubtractSymmTensor3s( &detT->re, &detT1.re, &detT2.re );
566  XLALSubtractSymmTensor3s( &detT->im, &detT1.im, &detT2.im );
567  }
568 
569  return 0;
570 
571 } /* XLALgetCmplxLISADetectorTensor() */
572 
573 
574 /**
575  * return a rigid-adiabatic-approximation (RAA) two-arm IFO detector tensor for LISA, given 'armA' and 'armB'
576  * This implements LISA RAA-tensor using spacecraft-orbits described by Eq.(2.1) in LISA-MLCD
577  * 'challenge1.pdf' document, see http://astrogravs.nasa.gov/docs/mldc/round1.html
578  *
579  * RETURN 0 = OK, -1 = ERROR
580  *
581  * \note: armA=0 means "arm 1" in TDI notation, therefore the enums LISA_ARM1, LISA_ARM2, LISA_ARM3
582  * should be used to avoid confusion.
583  */
584 int
585 XLALgetLISAtwoArmRAAIFO( CmplxDetectorTensor *detT, /**< [out]: two-arm IFO detector-tensor */
586  const DetectorArm *detArmA, /**< [in] precomputed detector-arm 'A' */
587  const DetectorArm *detArmB, /**< [in] precomputed detector-arm 'B' */
588  const FreqSkypos_t *freq_skypos /**< [in] precomputed frequency and skypos info */
589  )
590 {
591  REAL4 L_c = 0.5f * ( detArmA->armlength_c + detArmB->armlength_c );
592  REAL4 pifL_c = LAL_PI * freq_skypos->Freq * L_c;
593  REAL4 pifL_3c = pifL_c / 3.0f;
594  REAL4 kdotnA, kdotnB;
595  REAL4 eta, sinpha, cospha;
596  REAL4 sinc_eta;
597  COMPLEX8 coeffAA, coeffBB;
598 
599  if ( !detT || !detArmA || !detArmB || !freq_skypos ) {
600  return -1;
601  }
602 
603  kdotnA = - SCALAR( freq_skypos->skyposV, ( detArmA->n ) );
604  kdotnB = - SCALAR( freq_skypos->skyposV, ( detArmB->n ) );
605 
606  /* ----- calculate complex coefficient in front of basis-tensor (1/2)*(nA x nA) ----- */
607 
608  /* first term */
609  XLAL_CHECK( XLALSinCosLUT( &sinpha, &cospha, pifL_3c * ( 3.0f - ( kdotnA + 2.0f * kdotnB ) ) ) == XLAL_SUCCESS, XLAL_EFUNC );
610 
611  eta = pifL_c * ( 1.0f + kdotnA );
612  sinc_eta = safe_sinc( eta );
613 
614  coeffAA = crectf( 0.25f * cospha * sinc_eta, 0.25f * sinpha * sinc_eta );
615 
616  /* second term */
617  XLAL_CHECK( XLALSinCosLUT( &sinpha, &cospha, pifL_3c * ( - 3.0f - ( kdotnA + 2.0f * kdotnB ) ) ) == XLAL_SUCCESS, XLAL_EFUNC );
618 
619  eta = pifL_c * ( 1.0f - kdotnA );
620  sinc_eta = safe_sinc( eta );
621 
622  coeffAA += crectf( 0.25f * cospha * sinc_eta, 0.25f * sinpha * sinc_eta );
623 
624  /* ----- calculate coefficient in front of (1/2)*(nB x nB) */
625 
626  /* first term */
627  XLAL_CHECK( XLALSinCosLUT( &sinpha, &cospha, pifL_3c * ( 3.0f + ( 2.0f * kdotnA + kdotnB ) ) ) == XLAL_SUCCESS, XLAL_EFUNC );
628 
629  eta = pifL_c * ( 1.0f - kdotnB );
630  sinc_eta = safe_sinc( eta );
631 
632  coeffBB = crectf( 0.25f * cospha * sinc_eta, 0.25f * sinpha * sinc_eta );
633 
634  /* second term */
635  XLAL_CHECK( XLALSinCosLUT( &sinpha, &cospha, pifL_3c * ( - 3.0f + ( 2.0f * kdotnA + kdotnB ) ) ) == XLAL_SUCCESS, XLAL_EFUNC );
636 
637  eta = pifL_c * ( 1.0f + kdotnB );
638  sinc_eta = safe_sinc( eta );
639 
640  coeffBB += crectf( 0.25f * cospha * sinc_eta, 0.25f * sinpha * sinc_eta );
641 
642  /* now we can express the detector tensor in the rigid adiabatic approximation (RAA):
643  * detT = coeffAA * basisA - coeffBB * basisB
644  */
645  {
646  SymmTensor3 tmpA, tmpB;
647  XLALScaleSymmTensor3( &tmpA, &detArmA->basisT, crealf( coeffAA ) );
648  XLALScaleSymmTensor3( &tmpB, &detArmB->basisT, crealf( coeffBB ) );
649  XLALSubtractSymmTensor3s( &detT->re, &tmpA, &tmpB );
650 
651  XLALScaleSymmTensor3( &tmpA, &detArmA->basisT, cimagf( coeffAA ) );
652  XLALScaleSymmTensor3( &tmpB, &detArmB->basisT, cimagf( coeffBB ) );
653  XLALSubtractSymmTensor3s( &detT->im, &tmpA, &tmpB );
654  }
655 
656  return 0;
657 
658 } /* XLALgetLISAtwoArmRAAIFO() */
659 
660 #define SINC_SAFETY 1e-5
661 /**
662  * Unnormalized sinc(x) = sin(x) / x. Correctly handle the limit x->0
663  * where sinc(x) = 1
664  */
666 {
667  REAL4 sinx, cosx;
668  if ( ( x > SINC_SAFETY ) || ( x < -SINC_SAFETY ) ) {
669  XLAL_CHECK( XLALSinCosLUT( &sinx, &cosx, x ) == XLAL_SUCCESS, XLAL_EFUNC );
670  return ( sinx / x );
671  } else {
672  return 1.0f;
673  }
674 
675 } /* sinc () */
int XLALregisterLISAdetectors(const CHAR prefixLetter)
Set up the LALDetector structs representing LISA X, Y, Z TDI observables.
Definition: LISAspecifics.c:75
int XLALgetLISAtwoArmRAAIFO(CmplxDetectorTensor *detT, const DetectorArm *armA, const DetectorArm *armB, const FreqSkypos_t *freq_skypos)
return a rigid-adiabatic-approximation (RAA) two-arm IFO detector tensor for LISA,...
static REAL4 safe_sinc(REAL4 x)
Unnormalized sinc(x) = sin(x) / x.
int XLALprecomputeLISAarms(DetectorState *detState)
Precompute the arm-geometry for LISA, which is later used for assembling the RAA detector-tensor (whi...
#define SINC_SAFETY
int XLALgetLISADetectorTensorRAA(CmplxDetectorTensor *detT, const Detector3Arms detArms, CHAR channelNum, const FreqSkypos_t *freq_skypos)
#define LAL_SQRT1_3
1/sqrt(3)
Definition: LISAspecifics.c:46
BOOLEAN XLALisLISAdetector(const LALDetector *det)
Return true if 'det' is a LISA LALDetector struct.
Definition: LISAspecifics.c:65
#define SCALAR(u, v)
Simple Euklidean scalar product for two 3-dim vectors in cartesian coords.
Definition: LISAspecifics.c:43
#define SQ(x)
Definition: LISAspecifics.c:44
int XLALgetLISADetectorTensorLWL(SymmTensor3 *detT, const Detector3Arms detArms, CHAR channelNum)
#define GPS2REAL8(gps)
Definition: LISAspecifics.c:45
LISAarmT
Translate TDI arm indices to C-indexing.
Definition: LISAspecifics.h:49
@ LISA_ARM2
Definition: LISAspecifics.h:51
@ LISA_ARM1
Definition: LISAspecifics.h:50
@ LISA_ARM3
Definition: LISAspecifics.h:52
#define LISA_TIME_ORIGIN
Definition: LISAspecifics.h:45
double e
int XLALTensorSquareVector3(SymmTensor3 *vxv, REAL4 v[3])
Compute the "squared-tensor" v x v for given vector v, the result is returned in a "detectorTensor" s...
int XLALAddSymmTensor3s(SymmTensor3 *sum, const SymmTensor3 *aT, const SymmTensor3 *bT)
Convenience function for adding two SymmTensor3s: aT + bT NOTE: it is safe to have sum point to the s...
int XLALSubtractSymmTensor3s(SymmTensor3 *diff, const SymmTensor3 *aT, const SymmTensor3 *bT)
Convenience function for subtracting two SymmTensor3s: aT - bT NOTE: it is safe to have diff point to...
int XLALScaleSymmTensor3(SymmTensor3 *mult, const SymmTensor3 *aT, REAL4 factor)
Convenience function for multiplying a SymmTensor3 by a scalar factor.
DetectorArm Detector3Arms[3]
used to allow functions some type/size checking
#define LAL_PI
#define LAL_YRSID_SI
#define LAL_TWOPI
#define LAL_SQRT2
unsigned char BOOLEAN
double REAL8
#define XLAL_INIT_DECL(var,...)
#define crectf(re, im)
char CHAR
uint32_t UINT4
float complex COMPLEX8
float REAL4
LALDETECTORTYPE_ABSENT
int XLALRegisterSpecialCWDetector(const LALDetector *specialDetector)
Register a special detector for use with CW codes.
Definition: SFTnaming.c:73
int XLALSinCosLUT(REAL4 *sinx, REAL4 *cosx, REAL8 x)
Calculate sin(x) and cos(x) to roughly 1e-7 precision using a lookup-table and Taylor-expansion.
Definition: SinCosLUT.c:83
#define xlalErrno
#define XLAL_ERROR(...)
#define XLAL_CHECK(assertion,...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_SUCCESS
XLAL_EFUNC
XLAL_EINVAL
list y
eta
n
The 'detector tensor' for a GW-detector: symmetric 3x3 matrix, storing only the upper triangle.
Definition: LISAspecifics.h:61
SymmTensor3 re
tensor holding real-parts of all components
Definition: LISAspecifics.h:62
SymmTensor3 im
tensor holding imaginary-parts of all components
Definition: LISAspecifics.h:63
Struct containing pre-computed quantites describing a single detector arm: unit-vector along detector...
SymmTensor3 basisT
arm "basis-tensor" (n x n)
REAL4 n[3]
unit vector pointing along this arm
REAL4 armlength_c
armlengths in seconds L / c
State-info about position, velocity and LMST of a detector together with corresponding EarthState.
EarthState earthState
EarthState information.
Detector3Arms detArms
include up to three arms to allow describing LISA
LIGOTimeGPS tGPS
GPS timestamps corresponding to this entry.
REAL8 posNow[3]
Cartesian coords of Earth's center at tgps, extrapolated from JPL DE405 ephemeris; units= sec.
Convenience container for precomputed pi f L/c and skyposition vector.
Definition: LISAspecifics.h:69
REAL8 skyposV[3]
unit vector pointing to skyposition of source
Definition: LISAspecifics.h:71
REAL4 Freq
signal frequency
Definition: LISAspecifics.h:70
LALFrDetector frDetector
CHAR name[LALNameLength]
A symmetric 3x3 tensor (such as detector-tensors), storing only the upper triangle.