00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <math.h>
00033
00034
00035 #include <gsl/gsl_block.h>
00036 #include <gsl/gsl_vector.h>
00037 #include <gsl/gsl_matrix.h>
00038 #include <gsl/gsl_linalg.h>
00039 #include <gsl/gsl_blas.h>
00040 #include <gsl/gsl_integration.h>
00041
00042 #include <lal/DetectorStates.h>
00043 #include <lal/PulsarTimes.h>
00044 #include <lal/FlatPulsarMetric.h>
00045
00046 NRCSID( FLATPULSARMETRICC, "$Id: FlatPulsarMetric.c,v 1.4 2008/04/30 18:53:06 kipp Exp $");
00047
00048
00049 #define TRUE (1==1)
00050 #define FALSE (1==0)
00051
00052
00053
00054
00055 typedef enum {
00056 COMP_RX = -2,
00057 COMP_RY = -1,
00058 COMP_S0,
00059 COMP_S1,
00060 COMP_S2,
00061 COMP_S3,
00062 COMP_LAST
00063 } component_t;
00064
00065 typedef struct {
00066 component_t comp1, comp2;
00067 component_t comp;
00068 const EphemerisData *edat;
00069 REAL8 refTime;
00070 REAL8 startTime;
00071 REAL8 Tspan;
00072 } cov_params_t;
00073
00074
00075 LALStatus empty_status;
00076
00077
00078
00079
00080
00081 double Phi_i ( double ti, void *params );
00082 double Phi_i_Phi_j ( double ti, void *params );
00083 REAL8 cov_Phi_ij ( const cov_params_t *params );
00084
00085
00086 REAL8
00087 cov_Phi_ij ( const cov_params_t *params )
00088 {
00089 gsl_function integrand;
00090 cov_params_t par;
00091 int stat;
00092 double epsabs = 1e-6;
00093 double epsrel = 1e-6;
00094 double abserr;
00095 size_t neval;
00096
00097 double av_ij, av_i, av_j;
00098
00099 par = (*params);
00100 integrand.params = (void*)∥
00101
00102
00103 integrand.function = &Phi_i_Phi_j;
00104 stat = gsl_integration_qng (&integrand, 0, 1, epsabs, epsrel, &av_ij, &abserr, &neval);
00105 if ( stat != 0 )
00106 {
00107 LALPrintError ( "\nGSL-integration 'gsl_integration_qng()' of <Phi_i Phi_j> failed!\n");
00108 XLAL_ERROR_REAL8( "cov_Phi_ij", XLAL_EFUNC );
00109 }
00110
00111
00112
00113
00114 integrand.function = &Phi_i;
00115 par.comp = par.comp1;
00116 stat = gsl_integration_qng (&integrand, 0, 1, epsabs, epsrel, &av_i, &abserr, &neval);
00117 if ( stat != 0 )
00118 {
00119 LALPrintError ( "\nGSL-integration 'gsl_integration_qng()' of <Phi_i> failed!\n");
00120 XLAL_ERROR_REAL8( "cov_Phi_ij", XLAL_EFUNC );
00121 }
00122
00123
00124
00125
00126 integrand.function = &Phi_i;
00127 par.comp = par.comp2;
00128 stat = gsl_integration_qng (&integrand, 0, 1, epsabs, epsrel, &av_j, &abserr, &neval);
00129 if ( stat != 0 )
00130 {
00131 LALPrintError ( "\nGSL-integration 'gsl_integration_qng()' of <Phi_j> failed!\n");
00132 XLAL_ERROR_REAL8( "cov_Phi_ij", XLAL_EFUNC );
00133 }
00134
00135
00136
00137
00138 return ( av_ij - av_i * av_j );
00139
00140 }
00141
00142
00143 double
00144 Phi_i_Phi_j ( double ti, void *params )
00145 {
00146 cov_params_t *par = (cov_params_t*)params;
00147
00148 double phi_i, phi_j;
00149
00150 par->comp = par->comp1;
00151 phi_i = Phi_i ( ti, params );
00152
00153 par->comp = par->comp2;
00154 phi_j = Phi_i ( ti, params );
00155
00156 return ( phi_i * phi_j );
00157
00158 }
00159
00160
00161
00162
00163
00164 double
00165 Phi_i ( double tt, void *params )
00166 {
00167 cov_params_t *par = (cov_params_t*)params;
00168 double ret;
00169 REAL8 ti = par->startTime + tt * par->Tspan;
00170 REAL8 sineps, coseps;
00171
00172 if ( par->edat->leap < 0 )
00173 {
00174 sineps = 0;
00175 coseps = 1;
00176 }
00177 else
00178 {
00179 sineps = SIN_EPS;
00180 coseps = COS_EPS;
00181 }
00182
00183 if ( par->comp < 0 )
00184 {
00185 LALStatus status = empty_status;
00186 EarthState earth;
00187 LIGOTimeGPS tGPS;
00188 REAL8 rOrb[3];
00189 REAL8 rX, rY;
00190 REAL8 Rorb = LAL_AU_SI / LAL_C_SI;
00191
00192 XLALGPSSetREAL8( &tGPS, ti );
00193 LALBarycenterEarth( &status, &earth, &tGPS, par->edat );
00194
00195 rX = earth.posNow[0] / Rorb;
00196 rY = ( coseps * earth.posNow[1] + sineps * earth.posNow[2] ) / Rorb ;
00197
00198 if ( par->comp == COMP_RX )
00199 ret = rX;
00200 else
00201 ret= rY;
00202 }
00203 else
00204 {
00205 int s = par->comp;
00206 ret = pow ( (ti - par->refTime)/par->Tspan, s + 1 );
00207 }
00208
00209 return ret;
00210
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 int
00227 XLALFlatMetricCW ( gsl_matrix *gij,
00228 LIGOTimeGPS refTime,
00229 LIGOTimeGPS startTime,
00230 REAL8 Tspan,
00231 const EphemerisData *edat
00232 )
00233 {
00234 UINT4 dim, numSpins, s, sp;
00235 REAL8 gg;
00236 cov_params_t params;
00237
00238 if ( !gij || ( gij->size1 != gij->size2 ) || !edat )
00239 return -1;
00240
00241 dim = gij->size1;
00242 if ( dim < 3 || dim > 6 )
00243 {
00244 LALPrintError ("\nMetric dimension must be 3 <= dim <= 6!\n\n");
00245 return -1;
00246 }
00247 numSpins = dim - 2;
00248
00249 params.edat = edat;
00250 params.refTime = XLALGPSGetREAL8 ( &refTime );
00251 params.startTime = XLALGPSGetREAL8 ( &startTime );
00252 params.Tspan = Tspan;
00253
00254
00255 params.comp1 = COMP_RX;
00256 params.comp2 = COMP_RX;
00257 gg = cov_Phi_ij ( ¶ms );
00258
00259 gsl_matrix_set (gij, 0, 0, gg);
00260
00261 params.comp1 = COMP_RY;
00262 params.comp2 = COMP_RY;
00263 gg = cov_Phi_ij ( ¶ms );
00264
00265 gsl_matrix_set (gij, 1, 1, gg);
00266
00267 params.comp1 = COMP_RX;
00268 params.comp2 = COMP_RY;
00269 gg = cov_Phi_ij ( ¶ms );
00270
00271 gsl_matrix_set (gij, 0, 1, gg);
00272 gsl_matrix_set (gij, 1, 0, gg);
00273
00274
00275 for ( s=0; s < numSpins; s ++ )
00276 {
00277 params.comp1 = COMP_RX;
00278 params.comp2 = s;
00279 gg = cov_Phi_ij ( ¶ms );
00280
00281 gsl_matrix_set (gij, 0, s+2, gg);
00282 gsl_matrix_set (gij, s+2, 0, gg);
00283
00284 params.comp1 = COMP_RY;
00285 params.comp2 = s;
00286 gg = cov_Phi_ij ( ¶ms );
00287
00288 gsl_matrix_set (gij, 1, s+2, gg);
00289 gsl_matrix_set (gij, s+2, 1, gg);
00290
00291 for ( sp = s; sp < numSpins; sp ++ )
00292 {
00293 params.comp1 = s;
00294 params.comp2 = sp;
00295 gg = cov_Phi_ij ( ¶ms );
00296
00297 gsl_matrix_set (gij, s+2, sp+2, gg);
00298 gsl_matrix_set (gij, sp+2, s+2, gg);
00299 }
00300
00301 }
00302
00303
00304 gsl_matrix_swap_rows (gij, 0, 2);
00305 gsl_matrix_swap_rows (gij, 1, 2);
00306 gsl_matrix_swap_columns (gij, 0, 2);
00307 gsl_matrix_swap_columns (gij, 1, 2);
00308
00309
00310 return 0;
00311
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 void
00338 LALFlatPulsarMetric ( LALStatus *status,
00339 REAL8Vector **metric,
00340 LIGOTimeGPS startTime,
00341 REAL8 duration,
00342 const LALDetector *site
00343 )
00344 {
00345 REAL8Vector *ret = NULL;
00346
00347 PulsarTimesParamStruc zero_phases;
00348 REAL8 lat, lon;
00349
00350 UINT4 spinOrder = 3;
00351 UINT4 dim = 2 + spinOrder;
00352 UINT4 s0, s1;
00353
00354
00355 REAL8 phi_o_0, phi_s_0;
00356 REAL8 phi_o_1, phi_s_1;
00357 REAL8 delta_phi_o, delta_phi_s;
00358 REAL8 omega_o, omega_s;
00359 REAL8 REX, REY;
00360
00361
00362 REAL8 rX_av, rY_av;
00363 REAL8 rX_2_av, rY_2_av;
00364 REAL8 rX_rY_av;
00365 REAL8 cosLambda;
00366 REAL8 cosEps;
00367
00368
00369 INITSTATUS( status, "LALFlatPulsarMetric", FLATPULSARMETRICC );
00370 ATTATCHSTATUSPTR (status);
00371
00372
00373 lon = site->frDetector.vertexLongitudeRadians;
00374 lat = site->frDetector.vertexLatitudeRadians;
00375
00376
00377 TRY ( LALDCreateVector( status->statusPtr, &ret, dim * (dim+1) / 2 ), status);
00378
00379
00380
00381 {
00382 UINT4 s0fact = 1, s1fact = 1;
00383
00384 for ( s0 = 0; s0 < spinOrder; s0 ++ )
00385 {
00386 s0fact *= (s0 ? s0 : 1);
00387 s1fact = 1;
00388 for ( s1 = s0; s1 < spinOrder; s1 ++ )
00389 {
00390 UINT4 tmp;
00391 REAL8 gs0s1;
00392
00393 s1fact *= (s1 ? s1 : 1);
00394
00395 tmp = s0fact * s1fact * (s0 + 2) * (s1 + 2) * (s0 + s1 + 3);
00396 gs0s1 = 1.0 / tmp;
00397
00398 ret->data[ PMETRIC_INDEX (s0+2, s1+2) ] = gs0s1;
00399
00400 }
00401 }
00402
00403 }
00404
00405
00406
00407
00408 cosLambda = cos(lat);
00409 cosEps = cos(LAL_IEARTH);
00410 REX = LAL_REARTH_SI * cosLambda / LAL_AU_SI;
00411 REY = REX * cosEps;
00412
00413
00414 omega_s = LAL_TWOPI / LAL_DAYSID_SI;
00415 omega_o = LAL_TWOPI / LAL_YRSID_SI;
00416
00417
00418 zero_phases.epoch = startTime;
00419 TRY (LALGetEarthTimes( status->statusPtr, &zero_phases), status);
00420 phi_o_0 = LAL_TWOPI - zero_phases.tAutumn/LAL_YRSID_SI*LAL_TWOPI;
00421 phi_s_0 = LAL_TWOPI - zero_phases.tMidnight/LAL_DAYSID_SI*LAL_TWOPI + lon;
00422
00423
00424 delta_phi_o = omega_o * duration;
00425 delta_phi_s = omega_s * duration;
00426 phi_o_1 = phi_o_0 + delta_phi_o;
00427 phi_s_1 = phi_s_0 + delta_phi_s;
00428
00429
00430 rX_av =
00431 1.0 * ( sin(phi_o_1) - sin(phi_o_0) ) / delta_phi_o +
00432 REX * ( sin(phi_s_1) - sin(phi_s_0) ) / delta_phi_s;
00433
00434 rY_av =
00435 1.0 * (-cos(phi_o_1) + cos(phi_o_0) ) / delta_phi_o +
00436 REY * (-cos(phi_s_1) + cos(phi_s_0) ) / delta_phi_s;
00437
00438
00439 {
00440
00441 REAL8 cos_o_2_av = 0.5 + (0.25 / delta_phi_o) * ( sin(2.0*phi_o_1) - sin(2.0*phi_o_0) );
00442 REAL8 cos_s_2_av = 0.5 + (0.25 / delta_phi_s) * ( sin(2.0*phi_s_1) - sin(2.0*phi_s_0) );
00443
00444 REAL8 sin_o_2_av = 0.5 - (0.25 / delta_phi_o) * ( sin(2.0*phi_o_1) - sin(2.0*phi_o_0) );
00445 REAL8 sin_s_2_av = 0.5 - (0.25 / delta_phi_s) * ( sin(2.0*phi_s_1) - sin(2.0*phi_s_0) );
00446
00447 REAL8 cos_o_cos_s_av =
00448 ( 0.5 / (delta_phi_s + delta_phi_o) ) * ( sin(phi_s_1 + phi_o_1) - sin(phi_s_0 + phi_o_0) ) +
00449 ( 0.5 / (delta_phi_s - delta_phi_o) ) * ( sin(phi_s_1 - phi_o_1) - sin(phi_s_0 - phi_o_0) );
00450
00451 REAL8 sin_o_sin_s_av =
00452 (-0.5 / (delta_phi_s + delta_phi_o) ) * ( sin(phi_s_1 + phi_o_1) - sin(phi_s_0 + phi_o_0) ) +
00453 ( 0.5 / (delta_phi_s - delta_phi_o) ) * ( sin(phi_s_1 - phi_o_1) - sin(phi_s_0 - phi_o_0) );
00454
00455 REAL8 cos_o_sin_o_av = (-0.25 / delta_phi_o) * ( cos(2.0*phi_o_1) - cos(2.0*phi_o_0) );
00456 REAL8 cos_s_sin_s_av = (-0.25 / delta_phi_s) * ( cos(2.0*phi_s_1) - cos(2.0*phi_s_0) );
00457
00458 REAL8 cos_o_sin_s_av =
00459 (-0.5 / (delta_phi_s + delta_phi_o) ) * ( cos(phi_s_1 + phi_o_1) - cos(phi_s_0 + phi_o_0) ) +
00460 (-0.5 / (delta_phi_s - delta_phi_o) ) * ( cos(phi_s_1 - phi_o_1) - cos(phi_s_0 - phi_o_0) );
00461
00462
00463 REAL8 cos_s_sin_o_av =
00464 (-0.5 / (delta_phi_o + delta_phi_s) ) * ( cos(phi_o_1 + phi_s_1) - cos(phi_o_0 + phi_s_0) ) +
00465 (-0.5 / (delta_phi_o - delta_phi_s) ) * ( cos(phi_o_1 - phi_s_1) - cos(phi_o_0 - phi_s_0) );
00466
00467
00468
00469 rX_2_av = cos_o_2_av + REX*REX * cos_s_2_av + 2.0 * REX * cos_o_cos_s_av;
00470 rY_2_av = sin_o_2_av + REY*REY * sin_s_2_av + 2.0 * REY * sin_o_sin_s_av;
00471
00472 rX_rY_av= cos_o_sin_o_av + REX*REY*cos_s_sin_s_av + REX*cos_s_sin_o_av + REY*cos_o_sin_s_av;
00473 }
00474
00475
00476 ret->data[ PMETRIC_INDEX(0,0) ] = rX_2_av - rX_av * rX_av;
00477 ret->data[ PMETRIC_INDEX(1,1) ] = rY_2_av - rY_av * rY_av;
00478 ret->data[ PMETRIC_INDEX(0,1) ] = rX_rY_av - rX_av * rY_av;
00479
00480
00481 {
00482 REAL8 t_1_cos_o_av = (1.0 / pow(delta_phi_o,2)) *
00483 ( delta_phi_o * sin(phi_o_1) + cos(phi_o_1) - cos(phi_o_0) );
00484 REAL8 t_1_cos_s_av = (1.0 / pow(delta_phi_s,2)) *
00485 ( delta_phi_s * sin(phi_s_1) + cos(phi_s_1) - cos(phi_s_0) );
00486
00487 REAL8 t_1_sin_o_av = (1.0 / pow(delta_phi_o,2)) *
00488 (-delta_phi_o * cos(phi_o_1) + sin(phi_o_1) - sin(phi_o_0) );
00489 REAL8 t_1_sin_s_av = (1.0 / pow(delta_phi_s,2)) *
00490 (-delta_phi_s * cos(phi_s_1) + sin(phi_s_1) - sin(phi_s_0) );
00491
00492 REAL8 t_1_rX_av = t_1_cos_o_av + REX * t_1_cos_s_av;
00493 REAL8 t_1_rY_av = t_1_sin_o_av + REY * t_1_sin_s_av;
00494
00495 REAL8 t_1_av = 1.0 / 2.0;
00496
00497 ret->data[ PMETRIC_INDEX(0,2) ] = t_1_rX_av - t_1_av * rX_av;
00498 ret->data[ PMETRIC_INDEX(1,2) ] = t_1_rY_av - t_1_av * rY_av;
00499 }
00500 {
00501 REAL8 t_2_cos_o_av = (1.0 / pow(delta_phi_o,3)) *
00502 ( (pow(delta_phi_o,2) - 2.0) * sin(phi_o_1) + 2.0*delta_phi_o * cos(phi_o_1) + 2.0*sin(phi_o_0));
00503 REAL8 t_2_cos_s_av = (1.0 / pow(delta_phi_s,3)) *
00504 ( (pow(delta_phi_s,2) - 2.0) * sin(phi_s_1) + 2.0*delta_phi_s * cos(phi_s_1) + 2.0*sin(phi_s_0));
00505
00506 REAL8 t_2_sin_o_av = (1.0 / pow(delta_phi_o,3)) *
00507 (-(pow(delta_phi_o,2) - 2.0) * cos(phi_o_1) + 2.0*delta_phi_o * sin(phi_o_1) - 2.0*cos(phi_o_0));
00508 REAL8 t_2_sin_s_av = (1.0 / pow(delta_phi_s,3)) *
00509 (-(pow(delta_phi_s,2) - 2.0) * cos(phi_s_1) + 2.0*delta_phi_s * sin(phi_s_1) - 2.0*cos(phi_s_0));
00510
00511
00512 REAL8 t_2_rX_av = t_2_cos_o_av + REX * t_2_cos_s_av;
00513 REAL8 t_2_rY_av = t_2_sin_o_av + REY * t_2_sin_s_av;
00514
00515 REAL8 t_2_av = 1.0 / 3.0;
00516
00517 ret->data[ PMETRIC_INDEX(0,3) ] = t_2_rX_av - t_2_av * rX_av;
00518 ret->data[ PMETRIC_INDEX(1,3) ] = t_2_rY_av - t_2_av * rY_av;
00519 }
00520 {
00521 REAL8 t_3_cos_o_av = (1.0 / pow(delta_phi_o,4)) *
00522 ( (pow(delta_phi_o,3) - 6.0*delta_phi_o) * sin(phi_o_1)
00523 + (3.0*pow(delta_phi_o,2)-6.0) * cos(phi_o_1) + 6.0*cos(phi_o_0) );
00524 REAL8 t_3_cos_s_av = (1.0 / pow(delta_phi_s,4)) *
00525 ( (pow(delta_phi_s,3) - 6.0*delta_phi_s) * sin(phi_s_1)
00526 + (3.0*pow(delta_phi_s,2)-6.0) * cos(phi_s_1) + 6.0*cos(phi_s_0) );
00527
00528 REAL8 t_3_sin_o_av = (1.0 / pow(delta_phi_o,4)) *
00529 (-(pow(delta_phi_o,3) - 6.0*delta_phi_o) * cos(phi_o_1)
00530 + (3.0*pow(delta_phi_o,2)-6.0) * sin(phi_o_1) + 6.0*sin(phi_o_0) );
00531 REAL8 t_3_sin_s_av = (1.0 / pow(delta_phi_s,4)) *
00532 (-(pow(delta_phi_s,3) - 6.0*delta_phi_s) * cos(phi_s_1)
00533 + (3.0*pow(delta_phi_s,2)-6.0) * sin(phi_s_1) + 6.0*sin(phi_s_0) );
00534
00535 REAL8 t_3_rX_av = t_3_cos_o_av + REX * t_3_cos_s_av;
00536 REAL8 t_3_rY_av = t_3_sin_o_av + REY * t_3_sin_s_av;
00537
00538 REAL8 t_3_av = 1.0 / 4.0;
00539
00540 ret->data[ PMETRIC_INDEX(0,4) ] = t_3_rX_av - t_3_av * rX_av;
00541 ret->data[ PMETRIC_INDEX(1,4) ] = t_3_rY_av - t_3_av * rY_av;
00542 }
00543
00544
00545 (*metric) = ret;
00546
00547 DETATCHSTATUSPTR (status);
00548 RETURN(status);
00549
00550 }
00551