Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALPulsar 7.1.1.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
BinaryPulsarTiming.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Jolien Creighton, Matt Pitkin
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/**
21 * \author Matt Pitkin
22 * \date 2006
23 * \file
24 * \ingroup lalpulsar_general
25 * \brief Functions to calculate binary system time delays and read TEMPO pulsar parameter files
26 *
27 * Functions for calculating the timing delay to a signal from a pulsar in a
28 * binary system and reading pulsar parameters from TEMPO .par
29 * files.
30 * Models are taken from Taylor and Weisberg (1989) and use the
31 * naming conventions therein and used by TEMPO .
32 *
33 * ### Prototypes ###
34 *
35 *
36 * ### Description ###
37 *
38 * The main function computes the time delay of a signal from a pulsar in a
39 * binary system due to doppler shifts and relativistic delays,
40 * \f{equation}{
41 * \Delta{}t = t_\textrm{Roemer} + t_\textrm{Shapiro} + t_\textrm{Einstein} + t_\textrm{
42 * Abberation},
43 * \f}
44 * where \f$ t_\textrm{Roemer} \f$ is the light travel time, \f$ t_\textrm{Shapiro} \f$ is the
45 * General relativistic time delay, \f$ t_\textrm{Einstein} \f$ is the special
46 * relativistic time delay, and \f$ t_\textrm{Abberation} \f$ is the delay caused by the
47 * pulsars' rotation. There are several models of the binary systems, described
48 * in \cite TaylorWeisberg1989 , of which the four most common are so far
49 * implemented. The four models are the Blandford-Teukolsky model (BT)
50 * \cite BlandfordTeukolsky1976 , the low ellipticity model (ELL1)
51 * \cite ChLangeetal2001 , Damour-Deruelle model (DD) \cite DamourDeruelle1985 ,
52 * and the main sequence system model (MSS) \cite Wex1998 .
53 * These four models all use the five main binary parameters: the longitude of
54 * periastron \f$ \omega_0 \f$ , the eccentricity of the orbit \f$ e \f$ , the orbital period
55 * \f$ P \f$ , the time of periastron/or the time of ascension of the first node
56 * \f$ T_0 \f$ / \f$ T_{\textrm{asc}} \f$ , and the projected semi-major axis \f$ a\sin{}i \f$ . The are
57 * also many other model dependent parameters. These routines closely follow
58 * those used in the radio astronomy package TEMPO. A further model from TEMPO2
59 * called T2 is also implemented in a basic form. The model is generally based
60 * on the DD model, but will convert to ELL1 if the \c eps parameters are set.
61 * At the moment this (T2) does not include multiple companions in the orbit,
62 * but does encompass the DDS model. It also can include Kopeikin terms that
63 * take account of the effect of the binary orbit on the parallax.
64 *
65 * Radio astronomers fit pulsar parameters using TEMPO which will output
66 * the parameters in a <tt>.par</tt> file. The values allowed in this file can be
67 * found in the TEMPO documentation. A function is included to extract these
68 * parameters from the <tt>.par</tt> files and put them into a
69 * \c BinaryPulsarParams structure, it will set any unused parameters to
70 * zero or \c NULL. All parameters are in the units used by TEMPO with any
71 * conversion to SI units occuring within the binary timing routines. A function
72 * is also included which converts a string containing the right ascension or
73 * declination in the format <tt>ddd/hh:mm:ss.s</tt> or <tt>ddd/hhmmss.s</tt>
74 * (as is given in the <tt>.par</tt> file) into a \c REAL8 value in
75 * radians.
76 *
77 * ### Notes ###
78 *
79 */
80
81/* Matt Pitkin 29/04/04 */
82
83#include <lal/BinaryPulsarTiming.h>
84
85#include <string.h>
86#include <math.h>
87#include <lal/LALConstants.h>
88#include <lal/LALStdlib.h>
89#include <lal/LALString.h>
90#include <lal/SSBtimes.h>
91
92#ifdef __GNUC__
93#define UNUSED __attribute__ ((unused))
94#else
95#define UNUSED
96#endif
97
98#define AULTSC 499.00478364 /* number of light seconds in AU (from tempo2.h) */
99
100/**
101 * XLAL function to compute the eccentric anomaly iteratively from Kelper's
102 * equation.
103 */
105{
106 REAL8 du;
107
108 *u = phase + ecc * sin( phase ) / sqrt( 1.0 - 2.*ecc * cos( phase ) + ecc * ecc );
109 do {
110 du = ( phase - ( *u - ecc * sin( *u ) ) ) / ( 1.0 - ecc * cos( *u ) );
111 ( *u ) += du;
112 } while ( fabs( du ) > 1.e-14 );
113}
114
115
116/**
117 * XLAL function to compute Kopeikin terms that include the effect of
118 * binary orbital parameters of parallax
119 */
123{
124 REAL8 sini, cosi, tani;
125 REAL8 sin_delta, cos_delta, sin_alpha, cos_alpha;
126 REAL8 delta_i0, delta_j0;
127 REAL8 sin_omega, cos_omega;
128 REAL8 ca, sa, cd, sd;
129 REAL8 delt;
130 REAL8 posPulsar[3], velPulsar[3], psrPos[3];
131 REAL8 tt0;
132 REAL8 dpara; /* parallax */
133 REAL8 x;
134
135 sini = sin( params->kin );
136 cosi = cos( params->kin );
137 tani = sini / cosi;
138
139 sin_omega = sin( params->kom );
140 cos_omega = cos( params->kom );
141
142 /* ki_dot is set in tempo2 function, but not used */
143 /* ki_dot = -params.pmra * sin_omega + params.pmdec*cos_omega; */
144 /* Equation 8 in Kopeikin 1996 */
145 // (*x) += ((*x)*ki_dot/tani)*tt0;
146 /* Equation 9 in Kopeikin 1996 */
147 //(*omz) += (pmra*cos_omega+pmdec*sin_omega)/sini*tt0;
148
149 /* Now modify x and omega due to the annual-orbital parallax term
150 * as described in Kopeikin 1995
151 *
152 * Require knowledge of the barycentric earth position vector - earth_ssb
153 */
154
155 /* get pulsar vector */
156 ca = cos( params->ra );
157 sa = sin( params->ra );
158 cd = cos( params->dec );
159 sd = sin( params->dec );
160
161 posPulsar[0] = ca * cd;
162 posPulsar[1] = sa * cd;
163 posPulsar[2] = sd;
164
165 velPulsar[0] = -params->pmra / cos( params->dec ) * sa * cd - params->pmdec * ca * sd;
166 velPulsar[1] = params->pmra / cos( params->dec ) * ca * cd - params->pmdec * sa * sd;
167 velPulsar[2] = params->pmdec * cd;
168
169 delt = in->tb - params->posepoch;
170 /* add proper motion onto the pulsar position */
171 for ( UINT4 i = 0; i < 3; i++ ) {
172 psrPos[i] = posPulsar[i] + delt * velPulsar[i];
173 }
174
175 /* Obtain vector pointing at the pulsar */
176 sin_delta = psrPos[2];
177 cos_delta = cos( asin( sin_delta ) );
178 sin_alpha = psrPos[1] / cos_delta;
179 cos_alpha = psrPos[0] / cos_delta;
180
181 /* Equation 15 in Kopeikin 1995 */
182 delta_i0 = -in->earth.posNow[0] / AULTSC * sin_alpha +
183 in->earth.posNow[1] / AULTSC * cos_alpha;
184 /* Equation 16 in Kopeikin 1995 */
185 delta_j0 = -in->earth.posNow[0] / AULTSC * sin_delta * cos_alpha -
186 in->earth.posNow[1] / AULTSC * sin_delta * sin_alpha +
187 in->earth.posNow[2] / AULTSC * cos_delta;
188
189 dpara = params->px;
190 x = params->x;
191
192 /* xpr and ypr are set in tempo2 function, but not used */
193 /* xpr = delta_i0*sin_omega - delta_j0*cos_omega;
194 ypr = delta_i0*cos_omega + delta_j0*sin_omega; */
195
196 /* Equations 18 and 19 in Kopeikin 1995 */
197 if ( params->daopset ) {
198 REAL8 daop = params->daop;
199
200 kop->DK011 = - x / daop / sini * delta_i0 * sin_omega;
201 kop->DK012 = - x / daop / sini * delta_j0 * cos_omega;
202 kop->DK013 = - x / daop / sini * delta_i0 * cos_omega;
203 kop->DK014 = x / daop / sini * delta_j0 * sin_omega;
204
205 kop->DK021 = x / daop / tani * delta_i0 * cos_omega;
206 kop->DK022 = -x / daop / tani * delta_j0 * sin_omega;
207 kop->DK023 = x / daop / tani * delta_i0 * sin_omega;
208 kop->DK024 = x / daop / tani * delta_j0 * cos_omega;
209 } else {
210 kop->DK011 = -x * dpara / sini * delta_i0 * sin_omega;
211 kop->DK012 = -x * dpara / sini * delta_j0 * cos_omega;
212 kop->DK013 = -x * dpara / sini * delta_i0 * cos_omega;
213 kop->DK014 = x * dpara / sini * delta_j0 * sin_omega;
214
215 kop->DK021 = x * dpara / tani * delta_i0 * cos_omega;
216 kop->DK022 = -x * dpara / tani * delta_j0 * sin_omega;
217 kop->DK023 = x * dpara / tani * delta_i0 * sin_omega;
218 kop->DK024 = x * dpara / tani * delta_j0 * cos_omega;
219 }
220
221 if ( params->T0 != 0. ) {
222 tt0 = in->tb - params->T0;
223 } else if ( params->Tasc != 0. ) {
224 tt0 = in->tb - params->Tasc;
225 } else {
226 XLALPrintError( "%s: Neither T0 or Tasc is defined!\n", __func__ );
228 }
229
230 kop->DK031 = x * tt0 / sini * params->pmra * sin_omega;
231 kop->DK032 = x * tt0 / sini * params->pmdec * cos_omega;
232 kop->DK033 = x * tt0 / sini * params->pmra * cos_omega;
233 kop->DK034 = -x * tt0 / sini * params->pmdec * sin_omega;
234
235 kop->DK041 = x * tt0 / tani * params->pmra * cos_omega;
236 kop->DK042 = -x * tt0 / tani * params->pmdec * sin_omega;
237 kop->DK043 = -x * tt0 / tani * params->pmra * sin_omega;
238 kop->DK044 = -x * tt0 / tani * params->pmdec * cos_omega;
239}
240
241
245{
246 REAL8 sini, cosi, tani;
247 REAL8 sin_delta, cos_delta, sin_alpha, cos_alpha;
248 REAL8 delta_i0, delta_j0;
249 REAL8 sin_omega, cos_omega;
250 REAL8 ca, sa, cd, sd;
251 REAL8 delt;
252 REAL8 posPulsar[3], velPulsar[3], psrPos[3];
253 REAL8 tt0;
254 REAL8 dpara; /* parallax */
255 REAL8 x;
256
257 REAL8 kin = PulsarGetREAL8ParamOrZero( params, "KIN" );
258 sini = sin( kin );
259 cosi = cos( kin );
260 tani = sini / cosi;
261
262 REAL8 kom = PulsarGetREAL8ParamOrZero( params, "KOM" );
263 sin_omega = sin( kom );
264 cos_omega = cos( kom );
265
266 /* ki_dot is set in tempo2 function, but not used */
267 /* ki_dot = -params.pmra * sin_omega + params.pmdec*cos_omega; */
268 /* Equation 8 in Kopeikin 1996 */
269 // (*x) += ((*x)*ki_dot/tani)*tt0;
270 /* Equation 9 in Kopeikin 1996 */
271 //(*omz) += (pmra*cos_omega+pmdec*sin_omega)/sini*tt0;
272
273 /* Now modify x and omega due to the annual-orbital parallax term
274 * as described in Kopeikin 1995
275 *
276 * Require knowledge of the barycentric earth position vector - earth_ssb
277 */
278
279 REAL8 dec = 0.;
280 REAL8 ra = 0.;
281 if ( PulsarCheckParam( params, "RAJ" ) ) {
282 ra = PulsarGetREAL8Param( params, "RAJ" );
283 } else if ( PulsarCheckParam( params, "RA" ) ) {
284 ra = PulsarGetREAL8Param( params, "RA" );
285 }
286
287 if ( PulsarCheckParam( params, "DECJ" ) ) {
288 dec = PulsarGetREAL8Param( params, "DECJ" );
289 } else if ( PulsarCheckParam( params, "DEC" ) ) {
290 dec = PulsarGetREAL8Param( params, "DEC" );
291 }
292
293 /* get pulsar vector */
294 ca = cos( ra );
295 sa = sin( ra );
296 cd = cos( dec );
297 sd = sin( dec );
298
299 posPulsar[0] = ca * cd;
300 posPulsar[1] = sa * cd;
301 posPulsar[2] = sd;
302
303 REAL8 pmra = PulsarGetREAL8ParamOrZero( params, "PMRA" );
304 REAL8 pmdec = PulsarGetREAL8ParamOrZero( params, "PMDEC" );
305 velPulsar[0] = -pmra / cos( dec ) * sa * cd - pmdec * ca * sd;
306 velPulsar[1] = pmra / cos( dec ) * ca * cd - pmdec * sa * sd;
307 velPulsar[2] = pmdec * cd;
308
309 delt = in->tb - PulsarGetREAL8ParamOrZero( params, "POSEPOCH" );
310 /* add proper motion onto the pulsar position */
311 for ( UINT4 i = 0; i < 3; i++ ) {
312 psrPos[i] = posPulsar[i] + delt * velPulsar[i];
313 }
314
315 /* Obtain vector pointing at the pulsar */
316 sin_delta = psrPos[2];
317 cos_delta = cos( asin( sin_delta ) );
318 sin_alpha = psrPos[1] / cos_delta;
319 cos_alpha = psrPos[0] / cos_delta;
320
321 /* Equation 15 in Kopeikin 1995 */
322 delta_i0 = -in->earth.posNow[0] / AULTSC * sin_alpha +
323 in->earth.posNow[1] / AULTSC * cos_alpha;
324 /* Equation 16 in Kopeikin 1995 */
325 delta_j0 = -in->earth.posNow[0] / AULTSC * sin_delta * cos_alpha -
326 in->earth.posNow[1] / AULTSC * sin_delta * sin_alpha +
327 in->earth.posNow[2] / AULTSC * cos_delta;
328
329 dpara = PulsarGetREAL8ParamOrZero( params, "PX" );
331
332 /* xpr and ypr are set in tempo2 function, but not used */
333 /* xpr = delta_i0*sin_omega - delta_j0*cos_omega;
334 ypr = delta_i0*cos_omega + delta_j0*sin_omega; */
335
336 /* Equations 18 and 19 in Kopeikin 1995 */
337 if ( PulsarCheckParam( params, "D_AOP" ) ) {
338 REAL8 daop = PulsarGetREAL8Param( params, "D_AOP" );
339
340 kop->DK011 = - x / daop / sini * delta_i0 * sin_omega;
341 kop->DK012 = - x / daop / sini * delta_j0 * cos_omega;
342 kop->DK013 = - x / daop / sini * delta_i0 * cos_omega;
343 kop->DK014 = x / daop / sini * delta_j0 * sin_omega;
344
345 kop->DK021 = x / daop / tani * delta_i0 * cos_omega;
346 kop->DK022 = -x / daop / tani * delta_j0 * sin_omega;
347 kop->DK023 = x / daop / tani * delta_i0 * sin_omega;
348 kop->DK024 = x / daop / tani * delta_j0 * cos_omega;
349 } else {
350 kop->DK011 = -x * dpara / sini * delta_i0 * sin_omega;
351 kop->DK012 = -x * dpara / sini * delta_j0 * cos_omega;
352 kop->DK013 = -x * dpara / sini * delta_i0 * cos_omega;
353 kop->DK014 = x * dpara / sini * delta_j0 * sin_omega;
354
355 kop->DK021 = x * dpara / tani * delta_i0 * cos_omega;
356 kop->DK022 = -x * dpara / tani * delta_j0 * sin_omega;
357 kop->DK023 = x * dpara / tani * delta_i0 * sin_omega;
358 kop->DK024 = x * dpara / tani * delta_j0 * cos_omega;
359 }
360
362 REAL8 Tasc = PulsarGetREAL8ParamOrZero( params, "TASC" );
363 if ( T0 != 0. ) {
364 tt0 = in->tb - T0;
365 } else if ( Tasc != 0. ) {
366 tt0 = in->tb - Tasc;
367 } else {
368 XLALPrintError( "%s: Neither T0 or Tasc is defined!\n", __func__ );
370 }
371
372 kop->DK031 = x * tt0 / sini * pmra * sin_omega;
373 kop->DK032 = x * tt0 / sini * pmdec * cos_omega;
374 kop->DK033 = x * tt0 / sini * pmra * cos_omega;
375 kop->DK034 = -x * tt0 / sini * pmdec * sin_omega;
376
377 kop->DK041 = x * tt0 / tani * pmra * cos_omega;
378 kop->DK042 = -x * tt0 / tani * pmdec * sin_omega;
379 kop->DK043 = -x * tt0 / tani * pmra * sin_omega;
380 kop->DK044 = -x * tt0 / tani * pmdec * cos_omega;
381}
382
383
384
385/**
386 * Calculate the binary system time delay using the pulsar parameters in
387 * \c params
388 */
389void
392 BinaryPulsarInput *input,
394{
397
398 /* Check input arguments */
399 ASSERT( input != ( BinaryPulsarInput * )NULL, status,
401
402 ASSERT( output != ( BinaryPulsarOutput * )NULL, status,
404
405 ASSERT( params != ( BinaryPulsarParams * )NULL, status,
407
408 ASSERT( ( !strcmp( params->model, "BT" ) ) ||
409 ( !strcmp( params->model, "BT1P" ) ) ||
410 ( !strcmp( params->model, "BT2P" ) ) ||
411 ( !strcmp( params->model, "BTX" ) ) ||
412 ( !strcmp( params->model, "ELL1" ) ) ||
413 ( !strcmp( params->model, "DD" ) ) ||
414 ( !strcmp( params->model, "DDS" ) ) ||
415 ( !strcmp( params->model, "MSS" ) ) ||
416 ( !strcmp( params->model, "T2" ) ), status,
419
421
423 RETURN( status );
424}
425
426
427/**
428 * XLAL function to compute the binary time delay
429 */
430void
432 BinaryPulsarInput *input,
434{
435 REAL8 dt = 0.; /* binary pulsar deltaT */
436 REAL8 x, xdot; /* x = asini/c */
437 REAL8 w = 0; /* longitude of periastron */
438 REAL8 e, edot; /* eccentricity */
439 REAL8 eps1, eps2;
440 REAL8 eps1dot, eps2dot;
441 REAL8 w0, wdot;
442 REAL8 Pb, pbdot;
443 REAL8 xpbdot;
444 REAL8 T0, Tasc, tb = 0.; /* time parameters */
445
446 REAL8 s, r; /* Shapiro shape and range params */
447 REAL8 lal_gamma; /* time dilation and grav redshift */
448 REAL8 dr, dth;
449 REAL8 shapmax; /* Shapiro max parameter for DDS model */
450 REAL8 a0, b0; /* abberation parameters */
451
452 REAL8 m2;
453 const REAL8 c3 = ( REAL8 )LAL_C_SI * ( REAL8 )LAL_C_SI * ( REAL8 )LAL_C_SI;
454
455 CHAR *model = params->model;
456
457 /* Check input arguments */
458 if ( input == ( BinaryPulsarInput * )NULL ) {
460 }
461
462 if ( output == ( BinaryPulsarOutput * )NULL ) {
464 }
465
466 if ( params == ( BinaryPulsarParams * )NULL ) {
468 }
469
470 if ( ( !strcmp( params->model, "BT" ) ) &&
471 ( !strcmp( params->model, "BT1P" ) ) &&
472 ( !strcmp( params->model, "BT2P" ) ) &&
473 ( !strcmp( params->model, "BTX" ) ) &&
474 ( !strcmp( params->model, "ELL1" ) ) &&
475 ( !strcmp( params->model, "DD" ) ) &&
476 ( !strcmp( params->model, "DDS" ) ) &&
477 ( !strcmp( params->model, "MSS" ) ) &&
478 ( !strcmp( params->model, "T2" ) ) ) {
480 }
481
482 /* convert certain params to SI units */
483 w0 = params->w0;
484 wdot = params->wdot; /* wdot in rads/s */
485
486 Pb = params->Pb; /* period in secs */
487 pbdot = params->Pbdot;
488
489 T0 = params->T0; /* these should be in TDB in seconds */
490 Tasc = params->Tasc;
491
492 e = params->e;
493 edot = params->edot;
494 eps1 = params->eps1;
495 eps2 = params->eps2;
496 eps1dot = params->eps1dot;
497 eps2dot = params->eps2dot;
498
499 x = params->x;
500 xdot = params->xdot;
501 xpbdot = params->xpbdot;
502
503 lal_gamma = params->gamma;
504 s = params->s; /* sin i */
505 dr = params->dr;
506 dth = params->dth;
507 shapmax = params->shapmax;
508
509 a0 = params->a0;
510 b0 = params->b0;
511
512 m2 = params->m2;
513
514 /* Shapiro range parameter r defined as Gm2/c^3 (secs) */
515 r = LAL_G_SI * m2 / c3;
516
517 /* if T0 is not defined, but Tasc is */
518 if ( T0 == 0.0 && Tasc != 0.0 && eps1 == 0.0 && eps2 == 0.0 ) {
519 REAL8 fe, uasc, Dt; /* see TEMPO tasc2t0.f */
520
521 fe = sqrt( ( 1.0 - e ) / ( 1.0 + e ) );
522 uasc = 2.0 * atan( fe * tan( w0 / 2.0 ) );
523 Dt = ( Pb / LAL_TWOPI ) * ( uasc - e * sin( uasc ) );
524
525 T0 = Tasc + Dt;
526 }
527
528 /* set time at which to calculate the binary time delay */
529 tb = input->tb;
530
531 /* for BT, BT1P and BT2P models (and BTX model, but only for one orbit) */
532 if ( strstr( model, "BT" ) != NULL ) {
533 REAL8 tt0;
534 REAL8 orbits = 0.;
535 INT4 norbits = 0.;
536 REAL8 phase; /* same as mean anomaly */
537 REAL8 u = 0.0; /* eccentric anomaly */
538
539 INT4 nplanets = 1; /* number of orbiting bodies in system */
540 INT4 i = 1, j = 1;
541 REAL8 fac = 1.; /* factor in front of fb coefficients */
542
543 REAL8 su = 0., cu = 0.;
544 REAL8 sw = 0., cw = 0.;
545
546 /* work out number of orbits i.e. have we got a BT1P or BT2P model */
547 if ( !strcmp( model, "BT1P" ) ) {
548 nplanets = 2;
549 }
550 if ( !strcmp( model, "BT2P" ) ) {
551 nplanets = 3;
552 }
553
554 for ( i = 1 ; i < nplanets + 1 ; i++ ) {
555
556 /* set some vars for bnrybt.f (TEMPO) method */
557 /*REAL8 tt;
558 REAL8 som;
559 REAL8 com;
560 REAL8 alpha, beta;*/
561 /*REAL8 q, r, s;*/
562
563 /*fprintf(stderr, "You are using the Blandford-Teukolsky (BT) binary
564 model.\n");*/
565
566 if ( i == 2 ) {
567 T0 = params->T02;
568 w0 = params->w02;
569 x = params->x2;
570 e = params->e2;
571 Pb = params->Pb2;
572 } else if ( i == 3 ) {
573 T0 = params->T03;
574 w0 = params->w03;
575 x = params->x3;
576 e = params->e3;
577 Pb = params->Pb3;
578 }
579
580 tt0 = tb - T0;
581
582 /* only do relativistic corrections for first orbit */
583 if ( i == 1 ) {
584 x = x + xdot * tt0;
585 e = e + edot * tt0;
586 w = w0 + wdot * tt0; /* calculate w */
587
588 if ( !strcmp( model, "BTX" ) ) {
589 fac = 1.;
590 for ( j = 1 ; j < params->nfb + 1; j++ ) {
591 fac /= ( REAL8 )j;
592 orbits += fac * params->fb[j - 1] * pow( tt0, j );
593 }
594 } else {
595 orbits = tt0 / Pb - 0.5 * ( pbdot + xpbdot ) * ( tt0 / Pb ) * ( tt0 / Pb );
596 }
597 } else {
598 orbits = tt0 / Pb;
599 }
600
601 norbits = ( INT4 )orbits;
602
603 if ( orbits < 0. ) {
604 norbits--;
605 }
606
607 phase = LAL_TWOPI * ( orbits - ( REAL8 )norbits ); /* called phase in TEMPO */
608
609 /* compute eccentric anomaly */
611
612 su = sin( u );
613 cu = cos( u );
614
615 /*fprintf(stderr, "Eccentric anomaly = %f, phase = %f.\n", u, phase);*/
616 sw = sin( w );
617 cw = cos( w );
618
619 /* see eq 5 of Taylor and Weisberg (1989) */
620 /**********************************************************/
621 if ( !strcmp( model, "BTX" ) ) {
622 /* dt += (x*sin(w)*(cos(u)-e) + (x*cos(w)*sqrt(1.0-e*e) +
623 lal_gamma)*sin(u))*(1.0 - params->fb[0]*(x*cos(w)*sqrt(1.0 -
624 e*e)*cos(u) - x*sin(w)*sin(u))/(1.0 - e*cos(u))); */
625 dt += ( x * sw * ( cu - e ) + ( x * cw * sqrt( 1.0 - e * e ) +
626 lal_gamma ) * su ) * ( 1.0 - LAL_TWOPI * params->fb[0] * ( x * cw * sqrt( 1.0 -
627 e * e ) * cu - x * sw * su ) / ( 1.0 - e * cu ) );
628 } else {
629 /* dt += (x*sin(w)*(cos(u)-e) + (x*cos(w)*sqrt(1.0-e*e) +
630 lal_gamma)*sin(u))*(1.0 - (LAL_TWOPI/Pb)*(x*cos(w)*sqrt(1.0 -
631 e*e)*cos(u) - x*sin(w)*sin(u))/(1.0 - e*cos(u))); */
632 dt += ( x * sw * ( cu - e ) + ( x * cw * sqrt( 1.0 - e * e ) +
633 lal_gamma ) * su ) * ( 1.0 - ( LAL_TWOPI / Pb ) * ( x * cw * sqrt( 1.0 -
634 e * e ) * cu - x * sw * su ) / ( 1.0 - e * cu ) );
635 }
636 /**********************************************************/
637 }
638
639 /* use method from Taylor etal 1976 ApJ Lett and used in bnrybt.f */
640 /**********************************************************/
641 /*tt = 1.0-e*e;
642 som = sin(w);
643 com = cos(w);
644 alpha = x*som;
645 beta = x*com*sqrt(tt);
646 q = alpha*(cos(u)-e) + (beta+lal_gamma)*sin(u);
647 r = -alpha*sin(u) + beta*cos(u);
648 s = 1.0/(1.0-e*cos(u));
649 dt = -(-q+(LAL_TWOPI/Pb)*q*r*s);*/
650 /**********************************************************/
651 /* There appears to be NO difference between either method */
652
653 output->deltaT = -dt;
654 }
655
656 /* for ELL1 model (low eccentricity orbits so use eps1 and eps2) */
657 /* see Appendix A, Ch. Lange etal, MNRAS (2001) (also accept T2 model if
658 eps values are set - this will include Kopeikin terms if necessary) */
659 if ( !strcmp( model, "ELL1" ) || ( !strcmp( model, "T2" ) && eps1 != 0. ) ) {
660 REAL8 nb;
661 REAL8 tt0;
662 REAL8 w_int; /* omega internal to this model */
663 REAL8 orbits, phase;
664 INT4 norbits;
665 REAL8 e1, e2, ecc;
666 REAL8 DRE, DREp, DREpp; /* Roemer and Einstein delays (cf DD) */
667 REAL8 dlogbr;
668 REAL8 DS, DA; /* Shapiro delay and Abberation delay terms */
669 REAL8 Dbb;
670 REAL8 DAOP, DSR; /* Kopeikin delay terms */
671 REAL8 fac = 1.; /* factor in front of fb coefficients */
672
673 KopeikinTerms kt;
674 REAL8 Ck, Sk;
675
676 REAL8 sp = 0., cp = 0., s2p = 0., c2p = 0.;
677
678 /* fprintf(stderr, "You are using the ELL1 low eccentricity orbit model.\n");*/
679
680 /*********************************************************/
681 /* CORRECT CODE (as in TEMPO bnryell1.f) FROM HERE */
682
683 ecc = sqrt( eps1 * eps1 + eps2 * eps2 );
684
685 /* if Tasc is not defined convert T0 */
686 if ( Tasc == 0.0 && T0 != 0.0 ) {
687 REAL8 fe, uasc, Dt; /* see TEMPO tasc2t0.f */
688
689 fe = sqrt( ( 1.0 - ecc ) / ( 1.0 + ecc ) );
690 uasc = 2.0 * atan( fe * tan( w0 / 2.0 ) );
691 Dt = ( Pb / LAL_TWOPI ) * ( uasc - ecc * sin( uasc ) );
692
693 /* rearrange from what's in tasc2t0.f */
694 Tasc = T0 - Dt;
695 }
696
697 tt0 = tb - Tasc;
698
699 /* handle higher orbital frequency derivatives if present */
700 if ( params->nfb > 0 ) {
701 /* set period from first orbital frequency value */
702 Pb = 1. / params->fb[0];
703 orbits = tt0 / Pb;
704
705 fac = 1.;
706 for ( UINT4 j = 1 ; j < ( UINT4 )params->nfb; j++ ) {
707 fac /= ( REAL8 )( j + 1 );
708 orbits += fac * params->fb[j] * pow( tt0, j + 1 );
709 }
710 } else {
711 orbits = tt0 / Pb - 0.5 * ( pbdot + xpbdot ) * ( tt0 / Pb ) * ( tt0 / Pb );
712 }
713
714 nb = LAL_TWOPI / Pb;
715
716 norbits = ( INT4 )orbits;
717 if ( orbits < 0.0 ) {
718 norbits--;
719 }
720
721 phase = LAL_TWOPI * ( orbits - ( REAL8 )norbits );
722
723 x = x + xdot * tt0;
724
725 /* depending on whether we have eps derivs or w time derivs calculate e1 and e2 accordingly */
726 if ( params->nEll == 0 ) {
727 e1 = eps1 + eps1dot * tt0;
728 e2 = eps2 + eps2dot * tt0;
729 } else {
730 ecc = sqrt( eps1 * eps1 + eps2 * eps2 );
731 ecc += edot * tt0;
732 w_int = atan2( eps1, eps2 );
733 w_int = w_int + wdot * tt0;
734
735 e1 = ecc * sin( w_int );
736 e2 = ecc * cos( w_int );
737 }
738
739 //sin_cos_LUT(&sp, &cp, phase);
740 //sin_cos_LUT(&s2p, &c2p, 2.*phase);
741 sp = sin( phase );
742 cp = cos( phase );
743 s2p = sin( 2.*phase );
744 c2p = cos( 2.*phase );
745
746 /* this timing delay (Roemer + Einstein) should be most important in most cases */
747 /* DRE = x*(sin(phase)-0.5*(e1*cos(2.0*phase)-e2*sin(2.0*phase)));
748 DREp = x*cos(phase);
749 DREpp = -x*sin(phase); */
750 DRE = x * ( sp - 0.5 * ( e1 * c2p - e2 * s2p ) );
751 DREp = x * cp;
752 DREpp = -x * sp;
753
754 /* these params will normally be negligable */
755 dlogbr = log( 1.0 - s * sp );
756 DS = -2.0 * r * dlogbr;
757 DA = a0 * sp + b0 * cp;
758
759 /* compute Kopeikin terms */
760 if ( params->kinset && params->komset && ( params->pmra != 0. ||
761 params->pmdec != 0. ) ) {
762 XLALComputeKopeikinTerms( &kt, params, input );
763
764 Ck = sp - 0.5 * ( e1 * c2p - e2 * s2p );
765 Sk = cp + 0.5 * ( e2 * c2p + e1 * s2p );
766
767 DAOP = ( kt.DK011 + kt.DK012 ) * Ck - ( kt.DK021 + kt.DK022 ) * Sk;
768 DSR = ( kt.DK031 + kt.DK032 ) * Ck + ( kt.DK041 + kt.DK042 ) * Sk;
769 } else {
770 DAOP = 0.;
771 DSR = 0.;
772 }
773
774 Dbb = DRE * ( 1.0 - nb * DREp + ( nb * DREp ) * ( nb * DREp ) + 0.5 * nb * nb * DRE * DREpp ) + DS + DA
775 + DAOP + DSR;
776
777 output->deltaT = -Dbb;
778 /********************************************************/
779 }
780
781 /* for DD model - code partly adapted from TEMPO bnrydd.f */
782 /* also used for MSS model (Wex 1998) - main sequence star orbit - this only has two lines
783 different than DD model - TEMPO bnrymss.f */
784 /* also DDS model and (partial) T2 model (if EPS params not set) from TEMPO2 T2model.C */
785 if ( !strcmp( model, "DD" ) || !strcmp( model, "MSS" ) || !strcmp( model, "DDS" ) || ( !strcmp( model, "T2" ) && eps1 == 0. ) ) {
786 REAL8 u; /* new eccentric anomaly */
787 REAL8 Ae; /* eccentricity parameter */
788 REAL8 DRE; /* Roemer delay + Einstein delay */
789 REAL8 DREp, DREpp; /* see DD eqs 48 - 50 */
790 REAL8 DS; /* Shapiro delay */
791 REAL8 DA; /* aberation caused by pulsar rotation delay */
792 REAL8 DAOP, DSR; /* Kopeikin term delays */
793
794 REAL8 tt0;
795 /* various variable use during calculation */
796 REAL8 er, eth, an, k;
797 REAL8 orbits, phase;
798 INT4 norbits;
799 REAL8 onemecu, cae, sae;
800 REAL8 alpha, beta, bg;
801 REAL8 anhat, sqr1me2, cume, brace, dlogbr;
802 REAL8 Dbb; /* Delta barbar in DD eq 52 */
803
804 REAL8 xi; /* parameter for MSS model - the only other one needed */
805 REAL8 sdds = 0.; /* parameter for DDS model */
806
807 REAL8 su = 0., cu = 0.;
808 REAL8 sw = 0., cw = 0.;
809
810 KopeikinTerms kt;
811 REAL8 Ck, Sk;
812
813 /* fprintf(stderr, "You are using the Damour-Deruelle (DD) binary model.\n");*/
814
815 /* part of code adapted from TEMPO bnrydd.f */
816 an = LAL_TWOPI / Pb;
817 k = wdot / an;
818 xi = xdot / an; /* MSS parameter */
819
820 tt0 = tb - T0;
821 /* x = x + xdot*tt0; */
822
823 /* following DDmodel.C from TEMPO2 just set dth, dr, a0 and b0 to 0 */
824 if ( !strcmp( model, "DD" ) ) {
825 dr = 0.;
826 dth = 0.;
827 a0 = 0.;
828 b0 = 0.;
829 }
830
831 e = e + edot * tt0;
832 er = e * ( 1.0 + dr );
833 eth = e * ( 1.0 + dth );
834
835 orbits = ( tt0 / Pb ) - 0.5 * ( pbdot + xpbdot ) * ( tt0 / Pb ) * ( tt0 / Pb );
836 norbits = ( INT4 )orbits;
837
838 if ( orbits < 0.0 ) {
839 norbits--;
840 }
841
842 phase = LAL_TWOPI * ( orbits - ( REAL8 )norbits );
843
844 /* compute eccentric anomaly */
846
847 su = sin( u );
848 cu = cos( u );
849
850 /* compute Ae as in TEMPO bnrydd.f */
851 onemecu = 1.0 - e * cu;
852 cae = ( cu - e ) / onemecu;
853 sae = sqrt( 1.0 - e * e ) * su / onemecu;
854
855 Ae = atan2( sae, cae );
856
857 if ( Ae < 0.0 ) {
858 Ae = Ae + LAL_TWOPI;
859 }
860
861 Ae = LAL_TWOPI * orbits + Ae - phase;
862
863 w = w0 + k * Ae; /* add corrections to omega */ /* MSS also uses (om2dot, but not defined) */
864
865 /* small difference between MSS and DD */
866 if ( !strcmp( model, "MSS" ) ) {
867 x = x + xi * Ae; /* in bnrymss.f they also include a second time derivative of x (x2dot), but
868this isn't defined for either of the two pulsars currently using this model */
869 } else {
870 x = x + xdot * tt0;
871 }
872
873 /* now compute time delays as in DD eqs 46 - 52 */
874
875 /* calculate Einstein and Roemer delay */
876 sw = sin( w );
877 cw = cos( w );
878 alpha = x * sw;
879 beta = x * sqrt( 1.0 - eth * eth ) * cw;
880 bg = beta + lal_gamma;
881 DRE = alpha * ( cu - er ) + bg * su;
882 DREp = -alpha * su + bg * cu;
883 DREpp = -alpha * cu - bg * su;
884 anhat = an / onemecu;
885
886 /* calculate Shapiro and abberation delays DD eqs 26, 27 */
887 sqr1me2 = sqrt( 1.0 - e * e );
888 cume = cu - e;
889 if ( !strcmp( model, "DDS" ) ) {
890 sdds = 1. - exp( -1.*shapmax );
891 brace = onemecu - sdds * ( sw * cume + sqr1me2 * cw * su );
892 } else {
893 brace = onemecu - s * ( sw * cume + sqr1me2 * cw * su );
894 }
895 dlogbr = log( brace );
896 DS = -2.0 * r * dlogbr;
897
898 /* this abberation delay is prob fairly small */
899 DA = a0 * ( sin( w + Ae ) + e * sw ) + b0 * ( cos( w + Ae ) + e * cw );
900
901 /* compute Kopeikin terms */
902 if ( params->kinset && params->komset && ( params->pmra != 0. ||
903 params->pmdec != 0. ) ) {
904 XLALComputeKopeikinTerms( &kt, params, input );
905
906 Ck = cw * ( cu - er ) - sqrt( 1. - eth * eth ) * sw * su;
907 Sk = sw * ( cu - er ) + sqrt( 1. - eth * eth ) * cw * su;
908
909 DAOP = ( kt.DK011 + kt.DK012 ) * Ck - ( kt.DK021 + kt.DK022 ) * Sk;
910 DSR = ( kt.DK031 + kt.DK032 ) * Ck + ( kt.DK041 + kt.DK042 ) * Sk;
911 } else {
912 DAOP = 0.;
913 DSR = 0.;
914 }
915
916 /* timing difference */
917 Dbb = DRE * ( 1.0 - anhat * DREp + anhat * anhat * DREp * DREp + 0.5 * anhat * anhat * DRE * DREpp -
918 0.5 * e * su * anhat * anhat * DRE * DREp / onemecu ) + DS + DA + DAOP + DSR;
919
920 output->deltaT = -Dbb;
921 }
922
923 /* for DDGR model */
924
925 /* for Epstein-Haugan (EH) model - see Haugan, ApJ (1985) eqs 69 and 71 */
926
927 /* check that the returned value is not a NaN */
928 if ( isnan( output->deltaT ) ) {
930 }
931}
932
933
934void
936 BinaryPulsarInput *input,
938{
939 REAL8 dt = 0.; /* binary pulsar deltaT */
940 REAL8 x, xdot; /* x = asini/c */
941 REAL8 w = 0; /* longitude of periastron */
942 REAL8 e, edot; /* eccentricity */
943 REAL8 eps1, eps2;
944 REAL8 eps1dot, eps2dot;
945 REAL8 w0, wdot;
946 REAL8 Pb, pbdot;
947 REAL8 xpbdot;
948 REAL8 T0, Tasc, tb = 0.; /* time parameters */
949
950 REAL8 s, r; /* Shapiro shape and range params */
951 REAL8 lal_gamma; /* time dilation and grav redshift */
952 REAL8 dr, dth;
953 REAL8 shapmax; /* Shapiro max parameter for DDS model */
954 REAL8 a0, b0; /* abberation parameters */
955 REAL8 pmra, pmdec; /* proper motion parameters */
956
957 REAL8 m2;
958 const REAL8 c3 = ( REAL8 )LAL_C_SI * ( REAL8 )LAL_C_SI * ( REAL8 )LAL_C_SI;
959
960 const CHAR *model = PulsarGetStringParam( params, "BINARY" );
961
962 /* Check input arguments */
963 if ( input == ( BinaryPulsarInput * )NULL ) {
965 }
966
967 if ( output == ( BinaryPulsarOutput * )NULL ) {
969 }
970
971 if ( params == ( PulsarParameters * )NULL ) {
973 }
974
975 if ( ( !strcmp( model, "BT" ) ) &&
976 ( !strcmp( model, "BT1P" ) ) &&
977 ( !strcmp( model, "BT2P" ) ) &&
978 ( !strcmp( model, "BTX" ) ) &&
979 ( !strcmp( model, "ELL1" ) ) &&
980 ( !strcmp( model, "DD" ) ) &&
981 ( !strcmp( model, "DDS" ) ) &&
982 ( !strcmp( model, "MSS" ) ) &&
983 ( !strcmp( model, "T2" ) ) ) {
985 }
986
987 /* convert certain params to SI units */
988 w0 = PulsarGetREAL8ParamOrZero( params, "OM" );
989 wdot = PulsarGetREAL8ParamOrZero( params, "OMDOT" ); /* wdot in rads/s */
990
991 Pb = PulsarGetREAL8ParamOrZero( params, "PB" ); /* period in secs */
992 pbdot = PulsarGetREAL8ParamOrZero( params, "PBDOT" );
993
994 T0 = PulsarGetREAL8ParamOrZero( params, "T0" ); /* these should be in TDB in seconds */
995 Tasc = PulsarGetREAL8ParamOrZero( params, "TASC" );
996
998 edot = PulsarGetREAL8ParamOrZero( params, "EDOT" );
999 eps1 = PulsarGetREAL8ParamOrZero( params, "EPS1" );
1000 eps2 = PulsarGetREAL8ParamOrZero( params, "EPS2" );
1001 eps1dot = PulsarGetREAL8ParamOrZero( params, "EPS1DOT" );
1002 eps2dot = PulsarGetREAL8ParamOrZero( params, "EPS2DOT" );
1003
1005 xdot = PulsarGetREAL8ParamOrZero( params, "XDOT" );
1006 xpbdot = PulsarGetREAL8ParamOrZero( params, "XPBDOT" );
1007
1008 lal_gamma = PulsarGetREAL8ParamOrZero( params, "GAMMA" );
1009 s = PulsarGetREAL8ParamOrZero( params, "SINI" ); /* sin i */
1010 dr = PulsarGetREAL8ParamOrZero( params, "DR" );
1011 dth = PulsarGetREAL8ParamOrZero( params, "DTHETA" );
1012 shapmax = PulsarGetREAL8ParamOrZero( params, "SHAPMAX" );
1013
1014 a0 = PulsarGetREAL8ParamOrZero( params, "A0" );
1016
1018
1019 pmra = PulsarGetREAL8ParamOrZero( params, "PMRA" );
1020 pmdec = PulsarGetREAL8ParamOrZero( params, "PMDEC" );
1021
1022 /* Shapiro range parameter r defined as Gm2/c^3 (secs) */
1023 r = LAL_G_SI * m2 / c3;
1024
1025 /* if T0 is not defined, but Tasc is */
1026 if ( T0 == 0.0 && Tasc != 0.0 && eps1 == 0.0 && eps2 == 0.0 ) {
1027 REAL8 fe, uasc, Dt; /* see TEMPO tasc2t0.f */
1028
1029 fe = sqrt( ( 1.0 - e ) / ( 1.0 + e ) );
1030 uasc = 2.0 * atan( fe * tan( w0 / 2.0 ) );
1031 Dt = ( Pb / LAL_TWOPI ) * ( uasc - e * sin( uasc ) );
1032
1033 T0 = Tasc + Dt;
1034 }
1035
1036 /* set time at which to calculate the binary time delay */
1037 tb = input->tb;
1038
1039 /* for BT, BT1P and BT2P models (and BTX model, but only for one orbit) */
1040 if ( strstr( model, "BT" ) != NULL ) {
1041 REAL8 tt0;
1042 REAL8 orbits = 0.;
1043 INT4 norbits = 0;
1044 REAL8 phase; /* same as mean anomaly */
1045 REAL8 u = 0.0; /* eccentric anomaly */
1046
1047 INT4 nplanets = 1; /* number of orbiting bodies in system */
1048 INT4 i = 1, j = 1;
1049 REAL8 fac = 1.; /* factor in front of fb coefficients */
1050
1051 REAL8 su = 0., cu = 0.;
1052 REAL8 sw = 0., cw = 0.;
1053
1054 /* work out number of orbits i.e. have we got a BT1P or BT2P model */
1055 if ( !strcmp( model, "BT1P" ) ) {
1056 nplanets = 2;
1057 }
1058 if ( !strcmp( model, "BT2P" ) ) {
1059 nplanets = 3;
1060 }
1061
1062 for ( i = 1 ; i < nplanets + 1 ; i++ ) {
1063
1064 /* set some vars for bnrybt.f (TEMPO) method */
1065 /*REAL8 tt;
1066 REAL8 som;
1067 REAL8 com;
1068 REAL8 alpha, beta;*/
1069 /*REAL8 q, r, s;*/
1070
1071 /*fprintf(stderr, "You are using the Blandford-Teukolsky (BT) binary model.\n");*/
1072
1073 if ( i == 2 ) {
1074 T0 = PulsarGetREAL8ParamOrZero( params, "T0_2" );
1075 w0 = PulsarGetREAL8ParamOrZero( params, "OM_2" );
1076 x = PulsarGetREAL8ParamOrZero( params, "A1_2" );
1077 e = PulsarGetREAL8ParamOrZero( params, "ECC_2" );
1078 Pb = PulsarGetREAL8ParamOrZero( params, "PB_2" );
1079 } else if ( i == 3 ) {
1080 T0 = PulsarGetREAL8ParamOrZero( params, "T0_3" );
1081 w0 = PulsarGetREAL8ParamOrZero( params, "OM_3" );
1082 x = PulsarGetREAL8ParamOrZero( params, "A1_3" );
1083 e = PulsarGetREAL8ParamOrZero( params, "ECC_3" );
1084 Pb = PulsarGetREAL8ParamOrZero( params, "PB_3" );
1085 }
1086
1087 tt0 = tb - T0;
1088
1089 /* only do relativistic corrections for first orbit */
1090 if ( i == 1 ) {
1091 x = x + xdot * tt0;
1092 e = e + edot * tt0;
1093 w = w0 + wdot * tt0; /* calculate w */
1094
1095 if ( !strcmp( model, "BTX" ) && PulsarCheckParam( params, "FB" ) ) {
1096 const REAL8Vector *fb = PulsarGetREAL8VectorParam( params, "FB" );
1097
1098 fac = 1.;
1099 for ( j = 1 ; j < ( INT4 )fb->length + 1; j++ ) {
1100 fac /= ( REAL8 )j;
1101 orbits += fac * fb->data[j - 1] * pow( tt0, j );
1102 }
1103 } else {
1104 orbits = tt0 / Pb - 0.5 * ( pbdot + xpbdot ) * ( tt0 / Pb ) * ( tt0 / Pb );
1105 }
1106 } else {
1107 orbits = tt0 / Pb;
1108 }
1109
1110 norbits = ( INT4 )orbits;
1111
1112 if ( orbits < 0. ) {
1113 norbits--;
1114 }
1115
1116 phase = LAL_TWOPI * ( orbits - ( REAL8 )norbits ); /* called phase in TEMPO */
1117
1118 /* compute eccentric anomaly */
1120
1121 su = sin( u );
1122 cu = cos( u );
1123
1124 /*fprintf(stderr, "Eccentric anomaly = %f, phase = %f.\n", u, phase);*/
1125 sw = sin( w );
1126 cw = cos( w );
1127
1128 /* see eq 5 of Taylor and Weisberg (1989) */
1129 /**********************************************************/
1130 if ( !strcmp( model, "BTX" ) ) {
1131 REAL8 fb0 = 0.;
1132 if ( PulsarCheckParam( params, "FB" ) ) {
1133 const REAL8Vector *fb = PulsarGetREAL8VectorParam( params, "FB" );
1134 fb0 = fb->data[0];
1135 }
1136 /* dt += (x*sin(w)*(cos(u)-e) + (x*cos(w)*sqrt(1.0-e*e) +
1137 lal_gamma)*sin(u))*(1.0 - params->fb[0]*(x*cos(w)*sqrt(1.0 -
1138 e*e)*cos(u) - x*sin(w)*sin(u))/(1.0 - e*cos(u))); */
1139 dt += ( x * sw * ( cu - e ) + ( x * cw * sqrt( 1.0 - e * e ) +
1140 lal_gamma ) * su ) * ( 1.0 - LAL_TWOPI * fb0 * ( x * cw * sqrt( 1.0 -
1141 e * e ) * cu - x * sw * su ) / ( 1.0 - e * cu ) );
1142 } else {
1143 /* dt += (x*sin(w)*(cos(u)-e) + (x*cos(w)*sqrt(1.0-e*e) +
1144 lal_gamma)*sin(u))*(1.0 - (LAL_TWOPI/Pb)*(x*cos(w)*sqrt(1.0 -
1145 e*e)*cos(u) - x*sin(w)*sin(u))/(1.0 - e*cos(u))); */
1146 dt += ( x * sw * ( cu - e ) + ( x * cw * sqrt( 1.0 - e * e ) +
1147 lal_gamma ) * su ) * ( 1.0 - ( LAL_TWOPI / Pb ) * ( x * cw * sqrt( 1.0 -
1148 e * e ) * cu - x * sw * su ) / ( 1.0 - e * cu ) );
1149 }
1150 /**********************************************************/
1151 }
1152
1153 /* use method from Taylor etal 1976 ApJ Lett and used in bnrybt.f */
1154 /**********************************************************/
1155 /*tt = 1.0-e*e;
1156 som = sin(w);
1157 com = cos(w);
1158 alpha = x*som;
1159 beta = x*com*sqrt(tt);
1160 q = alpha*(cos(u)-e) + (beta+lal_gamma)*sin(u);
1161 r = -alpha*sin(u) + beta*cos(u);
1162 s = 1.0/(1.0-e*cos(u));
1163 dt = -(-q+(LAL_TWOPI/Pb)*q*r*s);*/
1164 /**********************************************************/
1165 /* There appears to be NO difference between either method */
1166
1167 output->deltaT = -dt;
1168 }
1169
1170 /* for ELL1 model (low eccentricity orbits so use eps1 and eps2) */
1171 /* see Appendix A, Ch. Lange etal, MNRAS (2001) (also accept T2 model if
1172 eps values are set - this will include Kopeikin terms if necessary) */
1173 if ( !strcmp( model, "ELL1" ) || ( !strcmp( model, "T2" ) && eps1 != 0. ) ) {
1174 REAL8 nb;
1175 REAL8 tt0;
1176 REAL8 w_int; /* omega internal to this model */
1177 REAL8 orbits, phase;
1178 INT4 norbits;
1179 REAL8 e1, e2, ecc;
1180 REAL8 DRE, DREp, DREpp; /* Roemer and Einstein delays (cf DD) */
1181 REAL8 dlogbr;
1182 REAL8 DS, DA; /* Shapiro delay and Abberation delay terms */
1183 REAL8 Dbb;
1184 REAL8 DAOP, DSR; /* Kopeikin delay terms */
1185 REAL8 fac = 1.; /* factor in front of fb coefficients */
1186
1187 KopeikinTerms kt;
1188 REAL8 Ck, Sk;
1189
1190 REAL8 sp = 0., cp = 0., s2p = 0., c2p = 0.;
1191
1192 /* fprintf(stderr, "You are using the ELL1 low eccentricity orbit model.\n");*/
1193
1194 /*********************************************************/
1195 /* CORRECT CODE (as in TEMPO bnryell1.f) FROM HERE */
1196
1197 ecc = sqrt( eps1 * eps1 + eps2 * eps2 );
1198
1199 /* if Tasc is not defined convert T0 */
1200 if ( Tasc == 0.0 && T0 != 0.0 ) {
1201 REAL8 fe, uasc, Dt; /* see TEMPO tasc2t0.f */
1202
1203 fe = sqrt( ( 1.0 - ecc ) / ( 1.0 + ecc ) );
1204 uasc = 2.0 * atan( fe * tan( w0 / 2.0 ) );
1205 Dt = ( Pb / LAL_TWOPI ) * ( uasc - ecc * sin( uasc ) );
1206
1207 /* rearrange from what's in tasc2t0.f */
1208 Tasc = T0 - Dt;
1209 }
1210
1211 tt0 = tb - Tasc;
1212
1213 /* handle higher orbital frequency derivatives if present */
1214 if ( PulsarCheckParam( params, "FB" ) ) {
1215 const REAL8Vector *fb = PulsarGetREAL8VectorParam( params, "FB" );
1216
1217 /* set period from first orbital frequency value */
1218 Pb = 1. / fb->data[0];
1219 orbits = tt0 / Pb;
1220
1221 fac = 1.;
1222 for ( UINT4 j = 1 ; j < fb->length; j++ ) {
1223 fac /= ( REAL8 )( j + 1 );
1224 orbits += fac * fb->data[j] * pow( tt0, j + 1 );
1225 }
1226 } else {
1227 orbits = tt0 / Pb - 0.5 * ( pbdot + xpbdot ) * ( tt0 / Pb ) * ( tt0 / Pb );
1228 }
1229
1230 nb = LAL_TWOPI / Pb;
1231
1232 norbits = ( INT4 )orbits;
1233 if ( orbits < 0.0 ) {
1234 norbits--;
1235 }
1236
1237 phase = LAL_TWOPI * ( orbits - ( REAL8 )norbits );
1238
1239 x = x + xdot * tt0;
1240
1241 /* depending on whether we have eps derivs or w time derivs calculate e1 and e2 accordingly */
1242 if ( eps1dot != 0. || eps2dot != 0. ) {
1243 e1 = eps1 + eps1dot * tt0;
1244 e2 = eps2 + eps2dot * tt0;
1245 } else {
1246 ecc = sqrt( eps1 * eps1 + eps2 * eps2 );
1247 ecc += edot * tt0;
1248 w_int = atan2( eps1, eps2 );
1249 w_int = w_int + wdot * tt0;
1250
1251 e1 = ecc * sin( w_int );
1252 e2 = ecc * cos( w_int );
1253 }
1254
1255 //sin_cos_LUT(&sp, &cp, phase);
1256 //sin_cos_LUT(&s2p, &c2p, 2.*phase);
1257 sp = sin( phase );
1258 cp = cos( phase );
1259 s2p = sin( 2.*phase );
1260 c2p = cos( 2.*phase );
1261
1262 /* this timing delay (Roemer + Einstein) should be most important in most cases */
1263 /* DRE = x*(sin(phase)-0.5*(e1*cos(2.0*phase)-e2*sin(2.0*phase)));
1264 DREp = x*cos(phase);
1265 DREpp = -x*sin(phase); */
1266 DRE = x * ( sp - 0.5 * ( e1 * c2p - e2 * s2p ) );
1267 DREp = x * cp;
1268 DREpp = -x * sp;
1269
1270 /* these params will normally be negligable */
1271 dlogbr = log( 1.0 - s * sp );
1272 DS = -2.0 * r * dlogbr;
1273 DA = a0 * sp + b0 * cp;
1274
1275 /* compute Kopeikin terms */
1276 if ( PulsarCheckParam( params, "KIN" ) && PulsarCheckParam( params, "KOM" ) && ( pmra != 0. || pmdec != 0. ) ) {
1277 XLALComputeKopeikinTermsNew( &kt, params, input );
1278
1279 Ck = sp - 0.5 * ( e1 * c2p - e2 * s2p );
1280 Sk = cp + 0.5 * ( e2 * c2p + e1 * s2p );
1281
1282 DAOP = ( kt.DK011 + kt.DK012 ) * Ck - ( kt.DK021 + kt.DK022 ) * Sk;
1283 DSR = ( kt.DK031 + kt.DK032 ) * Ck + ( kt.DK041 + kt.DK042 ) * Sk;
1284 } else {
1285 DAOP = 0.;
1286 DSR = 0.;
1287 }
1288
1289 Dbb = DRE * ( 1.0 - nb * DREp + ( nb * DREp ) * ( nb * DREp ) + 0.5 * nb * nb * DRE * DREpp ) + DS + DA
1290 + DAOP + DSR;
1291
1292 output->deltaT = -Dbb;
1293 /********************************************************/
1294 }
1295
1296 /* for DD model - code partly adapted from TEMPO bnrydd.f */
1297 /* also used for MSS model (Wex 1998) - main sequence star orbit - this only has two lines
1298 different than DD model - TEMPO bnrymss.f */
1299 /* also DDS model and (partial) T2 model (if EPS params not set) from TEMPO2 T2model.C */
1300 if ( !strcmp( model, "DD" ) || !strcmp( model, "MSS" ) || !strcmp( model, "DDS" ) || ( !strcmp( model, "T2" ) && eps1 == 0. ) ) {
1301 REAL8 u; /* new eccentric anomaly */
1302 REAL8 Ae; /* eccentricity parameter */
1303 REAL8 DRE; /* Roemer delay + Einstein delay */
1304 REAL8 DREp, DREpp; /* see DD eqs 48 - 50 */
1305 REAL8 DS; /* Shapiro delay */
1306 REAL8 DA; /* aberation caused by pulsar rotation delay */
1307 REAL8 DAOP, DSR; /* Kopeikin term delays */
1308
1309 REAL8 tt0;
1310 /* various variable use during calculation */
1311 REAL8 er, eth, an, k;
1312 REAL8 orbits, phase;
1313 INT4 norbits;
1314 REAL8 onemecu, cae, sae;
1315 REAL8 alpha, beta, bg;
1316 REAL8 anhat, sqr1me2, cume, brace, dlogbr;
1317 REAL8 Dbb; /* Delta barbar in DD eq 52 */
1318
1319 REAL8 xi; /* parameter for MSS model - the only other one needed */
1320 REAL8 sdds = 0.; /* parameter for DDS model */
1321
1322 REAL8 su = 0., cu = 0.;
1323 REAL8 sw = 0., cw = 0.;
1324
1325 KopeikinTerms kt;
1326 REAL8 Ck, Sk;
1327
1328 /* fprintf(stderr, "You are using the Damour-Deruelle (DD) binary model.\n");*/
1329
1330 /* part of code adapted from TEMPO bnrydd.f */
1331 an = LAL_TWOPI / Pb;
1332 k = wdot / an;
1333 xi = xdot / an; /* MSS parameter */
1334
1335 tt0 = tb - T0;
1336 /* x = x + xdot*tt0; */
1337
1338 /* following DDmodel.C from TEMPO2 just set dth, dr, a0 and b0 to 0 */
1339 if ( !strcmp( model, "DD" ) ) {
1340 dr = 0.;
1341 dth = 0.;
1342 a0 = 0.;
1343 b0 = 0.;
1344 }
1345
1346 e = e + edot * tt0;
1347 er = e * ( 1.0 + dr );
1348 eth = e * ( 1.0 + dth );
1349
1350 orbits = ( tt0 / Pb ) - 0.5 * ( pbdot + xpbdot ) * ( tt0 / Pb ) * ( tt0 / Pb );
1351 norbits = ( INT4 )orbits;
1352
1353 if ( orbits < 0.0 ) {
1354 norbits--;
1355 }
1356
1357 phase = LAL_TWOPI * ( orbits - ( REAL8 )norbits );
1358
1359 /* compute eccentric anomaly */
1361
1362 su = sin( u );
1363 cu = cos( u );
1364
1365 /* compute Ae as in TEMPO bnrydd.f */
1366 onemecu = 1.0 - e * cu;
1367 cae = ( cu - e ) / onemecu;
1368 sae = sqrt( 1.0 - e * e ) * su / onemecu;
1369
1370 Ae = atan2( sae, cae );
1371
1372 if ( Ae < 0.0 ) {
1373 Ae = Ae + LAL_TWOPI;
1374 }
1375
1376 Ae = LAL_TWOPI * orbits + Ae - phase;
1377
1378 w = w0 + k * Ae; /* add corrections to omega */ /* MSS also uses (om2dot, but not defined) */
1379
1380 /* small difference between MSS and DD */
1381 if ( !strcmp( model, "MSS" ) ) {
1382 x = x + xi * Ae; /* in bnrymss.f they also include a second time derivative of x (x2dot), but
1383this isn't defined for either of the two pulsars currently using this model */
1384 } else {
1385 x = x + xdot * tt0;
1386 }
1387
1388 /* now compute time delays as in DD eqs 46 - 52 */
1389
1390 /* calculate Einstein and Roemer delay */
1391 sw = sin( w );
1392 cw = cos( w );
1393 alpha = x * sw;
1394 beta = x * sqrt( 1.0 - eth * eth ) * cw;
1395 bg = beta + lal_gamma;
1396 DRE = alpha * ( cu - er ) + bg * su;
1397 DREp = -alpha * su + bg * cu;
1398 DREpp = -alpha * cu - bg * su;
1399 anhat = an / onemecu;
1400
1401 /* calculate Shapiro and abberation delays DD eqs 26, 27 */
1402 sqr1me2 = sqrt( 1.0 - e * e );
1403 cume = cu - e;
1404 if ( !strcmp( model, "DDS" ) ) {
1405 sdds = 1. - exp( -1.*shapmax );
1406 brace = onemecu - sdds * ( sw * cume + sqr1me2 * cw * su );
1407 } else {
1408 brace = onemecu - s * ( sw * cume + sqr1me2 * cw * su );
1409 }
1410 dlogbr = log( brace );
1411 DS = -2.0 * r * dlogbr;
1412
1413 /* this abberation delay is prob fairly small */
1414 DA = a0 * ( sin( w + Ae ) + e * sw ) + b0 * ( cos( w + Ae ) + e * cw );
1415
1416 /* compute Kopeikin terms */
1417 if ( PulsarCheckParam( params, "KIN" ) && PulsarCheckParam( params, "KOM" ) && ( pmra != 0. || pmdec != 0. ) ) {
1418 XLALComputeKopeikinTermsNew( &kt, params, input );
1419
1420 Ck = cw * ( cu - er ) - sqrt( 1. - eth * eth ) * sw * su;
1421 Sk = sw * ( cu - er ) + sqrt( 1. - eth * eth ) * cw * su;
1422
1423 DAOP = ( kt.DK011 + kt.DK012 ) * Ck - ( kt.DK021 + kt.DK022 ) * Sk;
1424 DSR = ( kt.DK031 + kt.DK032 ) * Ck + ( kt.DK041 + kt.DK042 ) * Sk;
1425 } else {
1426 DAOP = 0.;
1427 DSR = 0.;
1428 }
1429
1430 /* timing difference */
1431 Dbb = DRE * ( 1.0 - anhat * DREp + anhat * anhat * DREp * DREp + 0.5 * anhat * anhat * DRE * DREpp -
1432 0.5 * e * su * anhat * anhat * DRE * DREp / onemecu ) + DS + DA + DAOP + DSR;
1433
1434 output->deltaT = -Dbb;
1435 }
1436
1437 /* for DDGR model */
1438
1439 /* for Epstein-Haugan (EH) model - see Haugan, ApJ (1985) eqs 69 and 71 */
1440
1441 /* check that the returned value is not a NaN */
1442 if ( isnan( output->deltaT ) ) {
1444 }
1445
1446}
void XLALBinaryPulsarDeltaTNew(BinaryPulsarOutput *output, BinaryPulsarInput *input, PulsarParameters *params)
function to calculate the binary system delay using new parameter structure
void XLALComputeEccentricAnomaly(REAL8 phase, REAL8 ecc, REAL8 *u)
XLAL function to compute the eccentric anomaly iteratively from Kelper's equation.
void XLALComputeKopeikinTerms(KopeikinTerms *kop, BinaryPulsarParams *params, BinaryPulsarInput *in)
XLAL function to compute Kopeikin terms that include the effect of binary orbital parameters of paral...
#define AULTSC
void XLALComputeKopeikinTermsNew(KopeikinTerms *kop, PulsarParameters *params, BinaryPulsarInput *in)
void LALBinaryPulsarDeltaT(LALStatus *status, BinaryPulsarOutput *output, BinaryPulsarInput *input, BinaryPulsarParams *params)
Calculate the binary system time delay using the pulsar parameters in params.
void XLALBinaryPulsarDeltaT(BinaryPulsarOutput *output, BinaryPulsarInput *input, BinaryPulsarParams *params)
XLAL function to compute the binary time delay.
#define BINARYPULSARTIMINGH_ENAN
#define BINARYPULSARTIMINGH_MSGENULLPARAMS
#define BINARYPULSARTIMINGH_ENULLOUTPUT
#define BINARYPULSARTIMINGH_ENULLINPUT
#define BINARYPULSARTIMINGH_ENULLPARAMS
#define BINARYPULSARTIMINGH_MSGENULLOUTPUT
#define BINARYPULSARTIMINGH_ENULLBINARYMODEL
#define BINARYPULSARTIMINGH_MSGNULLBINARYMODEL
#define BINARYPULSARTIMINGH_MSGENULLINPUT
#define __func__
log an I/O error, i.e.
int j
int k
const double b0
#define ATTATCHSTATUSPTR(statusptr)
#define ASSERT(assertion, statusptr, code, mesg)
#define DETATCHSTATUSPTR(statusptr)
#define INITSTATUS(statusptr)
#define RETURN(statusptr)
const REAL8Vector * PulsarGetREAL8VectorParam(const PulsarParameters *pars, const CHAR *name)
Return a REAL8Vector parameter.
REAL8 PulsarGetREAL8ParamOrZero(const PulsarParameters *pars, const CHAR *name)
Return a REAL8 parameter if it exists, otherwise return zero.
int PulsarCheckParam(const PulsarParameters *pars, const CHAR *name)
Check for the existence of the parameter name in the PulsarParameters structure.
REAL8 PulsarGetREAL8Param(const PulsarParameters *pars, const CHAR *name)
Return a REAL8 parameter.
const CHAR * PulsarGetStringParam(const PulsarParameters *pars, const CHAR *name)
Return a string parameter.
double e
const double u
const double w
#define LAL_TWOPI
#define LAL_G_SI
double REAL8
char CHAR
uint32_t UINT4
int32_t INT4
static const INT4 r
#define XLAL_ERROR_VOID(...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_EINVAL
m2
def phase(point, coeffs, params, ignoreintcheck=False)
int T0
double alpha
structure containing the input parameters for the binary delay function
REAL8 tb
Time of arrival (TOA) at the SSB.
EarthState earth
The current Earth state (for e.g.
structure containing the output parameters for the binary delay function
A structure to contain all pulsar parameters and associated errors.
REAL8 posNow[3]
Cartesian coords of Earth's center at tgps, extrapolated from JPL DE405 ephemeris; units= sec.
structure containing the Kopeikin terms
The PulsarParameters structure to contain a set of pulsar parameters.
REAL8 * data
double ra
double dec
double m2