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
LALBarycenter.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2012 Miroslav Shaltev, R Prix
3* Copyright (C) 2007 Curt Cutler, Jolien Creighton, Reinhard Prix, Teviet Creighton
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#include <lal/Date.h>
22#include <lal/LALBarycenter.h>
23
24#define OBLQ 0.40909280422232891e0; /* obliquity of ecliptic at JD 245145.0* in radians */;
25
26/// ---------- internal buffer type for optimized Barycentering function ----------
27typedef struct tagfixed_sky {
28 REAL8 sinAlpha; /// sin(alpha)
29 REAL8 cosAlpha; /// cos(alpha)
30 REAL8 sinDelta; /// sin(delta)
31 REAL8 cosDelta; /// cos(delta)
32 REAL8 n[3]; /// unit vector pointing from SSB to the source, in J2000 Cartesian coords, 0=x,1=y,2=z
34
35typedef struct tagfixed_site {
36 REAL8 rd; /// distance 'rd' from center of Earth, in light seconds
37 REAL8 longitude; /// geocentric (not geodetic!!) longitude of detector vertex
38 REAL8 latitude; /// geocentric latitude of detector vertex
39 REAL8 sinLat; /// sin(latitude)
40 REAL8 cosLat; /// cos(latitude);
41 REAL8 rd_sinLat; /// rd * sin(latitude)
42 REAL8 rd_cosLat; /// rd * cos(latitude)
44
46 REAL8 alpha; /// buffered sky-location: right-ascension in rad
47 REAL8 delta; /// buffered sky-location: declination in rad
48 fixed_sky_t fixed_sky; /// fixed-sky buffered quantities
49
50 LALDetector site; /// buffered detector site
51 fixed_site_t fixed_site; /// fixed-site buffered quantities
52
53 BOOLEAN active; /// switch set on TRUE of buffer has been filled
54}; // struct tagBarycenterBuffer
55
56/* Internal functions */
57static void precessionMatrix( REAL8 prn[3][3], REAL8 mjd, REAL8 dpsi, REAL8 deps );
58static void observatoryEarth( REAL8 obsearth[3], const LALDetector det, const LIGOTimeGPS *tgps, REAL8 gmst, REAL8 dpsi, REAL8 deps );
59
60/// \addtogroup LALBarycenter_h
61/// @{
62
63/**
64 * \author Curt Cutler
65 * \brief Computes the position and orientation of the Earth, at some arrival time
66 * \f$ t_a \f$ , specified <tt>LIGOTimeGPS</tt> input structure.
67 *
68 * The Einstein delay is also calculated. The results are stored in the
69 * <tt>EarthState</tt> output structure, which can then be fed as input to
70 * <tt>LALBarycenter()</tt>.
71 * The idea is that <tt>LALBarycenterEarth()</tt> calculates quantities that
72 * are independent of the source location and detector position
73 * on Earth. Thus this function is called ONCE for every desired
74 * arrival time; the results are then re-used as one steps around the
75 * sky (and/or changes detector) at that time.
76 */
77int
78XLALBarycenterEarth( EarthState *earth, /**< [out] the earth's state at time tGPS */
79 const LIGOTimeGPS *tGPS, /**< [in] GPS time tgps */
80 const EphemerisData *edat ) /**< [in] ephemeris-files */
81{
82 REAL8 tgps[2]; /*I convert from two-integer representation to
83 two REAL8s (just because I initially wrote my code for
84 REAL8s). GPS time(sec) = tgps[0] + 1.e-9*tgps[1] */
85
86 /*int ihour; most recent hour to current time, tGPS,
87 in look-up table */
88 /*REAL8 t0,t0hr; */
89
90 REAL8 t0e; /*time since first entry in Earth ephem. table */
91 INT4 ientryE; /*entry in look-up table closest to current time, tGPS */
92
93 REAL8 tinitE; /*time (GPS) of first entry in Earth ephem table*/
94 REAL8 tdiffE; /*current time tGPS minus time of nearest entry
95 in Earth ephem look-up table */
96 REAL8 tdiff2E; /*tdiff2=tdiffE*tdiffE */
97 /*next entries are same as above, but for Sun table */
98 REAL8 t0s;
99 INT4 ientryS;
100 REAL8 tinitS;
101 REAL8 tdiffS;
102 REAL8 tdiff2S;
103
104 INT4 j; /*dummy index */
105
106 earth->ttype = TIMECORRECTION_ORIGINAL; /* using the original XLALBarycenterEarth function */
107
108 /* check input */
109 if ( !earth || !tGPS || !edat || !edat->ephemE || !edat->ephemS ) {
110 XLALPrintError( "%s: invalid NULL input 'earth', 'tGPS', 'edat', 'edat->ephemE' or 'edat->ephemS'\n", __func__ );
112 }
113
114 tgps[0] = ( REAL8 )tGPS->gpsSeconds; /*convert from INT4 to REAL8 */
115 tgps[1] = ( REAL8 )tGPS->gpsNanoSeconds;
116
117 tinitE = edat->ephemE[0].gps;
118 tinitS = edat->ephemS[0].gps;
119
120 t0e = tgps[0] - tinitE;
121 ientryE = floor( ( t0e / edat->dtEtable ) + 0.5e0 ); /*finding Earth table entry
122 closest to arrival time*/
123 t0s = tgps[0] - tinitS;
124 ientryS = floor( ( t0s / edat->dtStable ) + 0.5e0 ); /*finding Sun table entry
125 closest to arrival time*/
126
127 /*Making sure tgps is within earth and sun ephemeris arrays*/
128
129 if ( ( ientryE < 0 ) || ( ientryE >= edat->nentriesE ) ) {
130 XLALPrintError( "%s: input GPS time %f outside of Earth ephem range [%f, %f]\n", __func__, tgps[0], tinitE, tinitE + edat->nentriesE * edat->dtEtable );
132 }
133 if ( ( ientryS < 0 ) || ( ientryS >= edat->nentriesS ) ) {
134 XLALPrintError( "%s: input GPS time %f outside of Sun ephem range [%f, %f]\n", __func__, tgps[0], tinitS, tinitS + edat->nentriesS * edat->dtStable );
136 }
137
138 tdiffE = t0e - edat->dtEtable * ientryE + tgps[1] * 1.e-9; /*tdiff is arrival
139 time minus closest Earth table entry; tdiff can be pos. or neg. */
140 tdiff2E = tdiffE * tdiffE;
141
142 tdiffS = t0s - edat->dtStable * ientryS + tgps[1] * 1.e-9; /*same for Sun*/
143 tdiff2S = tdiffS * tdiffS;
144
145
146 /********************************************************************
147 *Calucate position and vel. of center of Earth.
148 *We extrapolate from a table produced using JPL DE405 ephemeris.
149 *---------------------------------------------------------------------
150 */
151 {
152
153 REAL8 *pos = edat->ephemE[ientryE].pos; /*Cartesian coords of center of Earth
154 from DE405 ephem, in sec. 0=x,1=y,2=z */
155 REAL8 *vel = edat->ephemE[ientryE].vel;
156 REAL8 *acc = edat->ephemE[ientryE].acc;
157
158 for ( j = 0; j < 3; j++ ) {
159 earth->posNow[j] = pos[j] + vel[j] * tdiffE + 0.5 * acc[j] * tdiff2E;
160 earth->velNow[j] = vel[j] + acc[j] * tdiffE;
161 }
162 }
163
164 /********************************************************************
165 * Now calculating Earth's rotational state.
166 *---------------------------------------------------------------------
167 */
168 {
169 INT2 leapsSince2000; /*number of leap secs added to UTC calendar since
170 Jan 1, 2000 00:00:00 UTC; leap is a NEGATIVE number
171 for dates before Jan 1, 2000. */
172
173 REAL8 tu0JC; /*time elapsed on UT1 clock (in Julian centuries)
174 between Jan 1.5 2000 (= J2000 epoch)
175 and midnight before gps[0,j] */
176
177 REAL8 tuJC; /*time elapsed on UT1 clock (in Julian centuries)
178 between Jan 1.5 2000 (= J2000 epoch)
179 and the present time (tGPS) */
180
181 INT4 tuInt; /*number of full seconds (integer) on elapsed
182 on UT1 clock from Jan 1, 2000 00:00:00 UTC to present*/
183 REAL8 dtu; /*see comments below*/
184
185 REAL8 gmst; /*Greenwich mean sidereal time at present (tGPS), in sec */
186 REAL8 gmst0; /*Greenwich mean sidereal time at prev. midnight, in sec */
187 REAL8 gmstRad; /*gmst, but in radians*/
188
189 INT4 ut1secSince1Jan2000, fullUt1days;
190 REAL8 daysSinceJ2000;
191 REAL8 eps0 = OBLQ; /*obliquity of ecliptic at JD 245145.0*/
192
193 leapsSince2000 = 0; /*right # for Jan. 1, 2000 */
194 leapsSince2000 = XLALGPSLeapSeconds( tGPS->gpsSeconds ) - 13;
195 {
197 if ( err != XLAL_SUCCESS ) {
198 XLALPrintError( "%s: XLALGPSLeapSeconds (%d) failed.\n", __func__, tGPS->gpsSeconds );
200 }
201 }
202
203 tuInt = tGPS->gpsSeconds - 630720013; /*first subtract off value
204 of gps clock at Jan 1, 2000 00:00:00 UTC */
205
206 ut1secSince1Jan2000 = tuInt - leapsSince2000; /*next subtract
207 off # leap secs added to UTC calendar since Jan 1, 2000 00:00:00 UTC */
208 tuJC = ( ut1secSince1Jan2000 + tgps[1] * 1.e-9 - 43200 ) / ( 8.64e4 * 36525 );
209 /*UT1 time elapsed, in Julian centuries, since Jan 1.5 2000
210 (= J2000 epoch) and pulse arrival time*/
211
212 fullUt1days = floor( ut1secSince1Jan2000 / 8.64e4 );/*full days on ut1 clock
213 since Jan 1, 2000 00:00:00 UTC */
214
215
216 tu0JC = ( fullUt1days - 0.5e0 ) / 36525.0; /* UT1 time elapsed,
217 in Julian centuries between Jan 1.5 2000 (= J2000 epoch)
218 and midnight before gps[0,j] */
219
220 dtu = tuJC - tu0JC; /*time, in Jul. centuries, between pulse arrival time and previous midnight (UT1) */
221
222 daysSinceJ2000 = ( tuInt - 43200 ) / 8.64e4; /*days(not int) on GPS
223 (or TAI,etc.) clock since J2000 */
224
225 /*----------------------------------------------------------------------
226 *in below formula for gmst0 & gmst, on rhs we SHOULD use time elapsed
227 * in UT1, but instead we insert elapsed in UTC. This will lead to
228 * errors in tdb of order 1 microsec.
229 *----------------------------------------------------------------------
230 */
231
232 gmst0 = 24110.54841e0 + tu0JC * ( 8640184.812866e0 + tu0JC * ( 0.093104e0
233 - tu0JC * 6.2e-6 ) ); /*formula for Greenwich mean sidereal time
234 on p.50 of Explanatory Supp. to Ast Alm. ...
235 gmst unit is sec, where 2pi rad = 24*60*60sec */
236
237 /*-----------------------------------------------------------------------
238 *Explan of tu0JC*8640184.812866e0 term: when tu0JC0=0.01 Julian centuries
239 *(= 1 year), Earth has spun an extra 86401.84 sec (approx one revolution)
240 *with respect to the stars.
241 *
242 *Note: this way of organizing calc of gmst was stolen from TEMPO;
243 *see subroutine lmst (= local mean sidereal time) .
244 *------------------------------------------------------------------------
245 */
246
247
248 gmst = gmst0 + dtu * ( 8.64e4 * 36525 + 8640184.812866e0
249 + 0.093104e0 * ( tuJC + tu0JC )
250 - 6.2e-6 * ( tuJC * tuJC + tuJC * tu0JC + tu0JC * tu0JC ) );
251
252 gmstRad = gmst * LAL_PI / 43200;
253
254 earth->gmstRad = gmstRad;
255
256 /*------------------------------------------------------------------------
257 *Now calculating 3 terms, describing lunisolar precession;
258 *see Eqs. 3.212 on pp. 104-5 in Explanatory Supp.
259 *-------------------------------------------------------------------------
260 */
261
262 earth->tzeA = tuJC * ( 2306.2181e0 + ( 0.30188e0 + 0.017998e0 * tuJC ) * tuJC )
263 * LAL_PI / 6.48e5;
264
265 earth->zA = tuJC * ( 2306.2181e0 + ( 1.09468e0 + 0.018203e0 * tuJC ) * tuJC )
266 * LAL_PI / 6.48e5;
267
268 earth->thetaA = tuJC * ( 2004.3109e0 - ( 0.42665e0 + 0.041833 * tuJC ) * tuJC )
269 * LAL_PI / 6.48e5;
270
271 /*--------------------------------------------------------------------------
272 * Now adding approx nutation (= short-period,forced motion, by definition).
273 * These two dominant terms, with periods 18.6 yrs (big term) and
274 * 0.500 yrs (small term),respp., give nutation to around 1 arc sec; see
275 * p. 120 of Explan. Supp. The forced nutation amplitude
276 * is around 17 arcsec.
277 *
278 * Note the unforced motion or Chandler wobble (called ``polar motion''
279 * in Explanatory Supp) is not included here. However its amplitude is
280 * order of (and a somewhat less than) 1 arcsec; see plot on p. 270 of
281 * Explanatory Supplement to Ast. Alm.
282 *--------------------------------------------------------------------------
283 */
284 /* define variables for storing sin/cos of deltaE, eps0 etc */
285
286 earth->delpsi = ( -0.0048e0 * LAL_PI / 180.e0 ) *
287 sin( ( 125.e0 - 0.05295e0 * daysSinceJ2000 ) * LAL_PI / 180.e0 )
288 - ( 4.e-4 * LAL_PI / 180.e0 ) *
289 sin( ( 200.9e0 + 1.97129e0 * daysSinceJ2000 ) * LAL_PI / 180.e0 );
290
291
292 earth->deleps = ( 0.0026e0 * LAL_PI / 180.e0 ) *
293 cos( ( 125.e0 - 0.05295e0 * daysSinceJ2000 ) * LAL_PI / 180.e0 )
294 + ( 2.e-4 * LAL_PI / 180.e0 ) *
295 cos( ( 200.9e0 + 1.97129e0 * daysSinceJ2000 ) * LAL_PI / 180.e0 );
296
297 earth->gastRad = gmstRad + earth->delpsi * cos( eps0 );
298 /* ``equation of the equinoxes''*/
299
300 }
301 /**********************************************************************
302 *Now calculating Einstein delay. This is just difference between
303 *TDB and TDT.
304 *We steal from TEMPO the approx 20 biggest terms in an expansion.
305 *-----------------------------------------------------------------------
306 * jedtdt is Julian date (TDT) MINUS 2451545.0 (TDT);
307 * -7300.5 = 2444244.5 (Julian date when gps clock started)
308 * - 2451545.0 TDT (approx. J2000.0);
309 * Note the 51.184 s difference between TDT and GPS
310 *-----------------------------------------------------------------------
311 */
312 {
313 REAL8 jedtdt = -7300.5e0 + ( tgps[0] + 51.184e0 + tgps[1] * 1.e-9 ) / 8.64e4;
314 REAL8 jt = jedtdt / 3.6525e5; /*converting to TEMPO expansion param
315 = Julian millenium, NOT Julian century */
316 earth->einstein = 1.e-6 * (
317 1656.674564e0 * sin( 6283.075849991e0 * jt + 6.240054195e0 ) +
318 22.417471e0 * sin( 5753.384884897e0 * jt + 4.296977442e0 ) +
319 13.839792e0 * sin( 12566.151699983e0 * jt + 6.196904410e0 ) +
320 4.770086e0 * sin( 529.690965095e0 * jt + 0.444401603e0 ) +
321 4.676740e0 * sin( 6069.776754553e0 * jt + 4.021195093e0 ) +
322 2.256707e0 * sin( 213.299095438e0 * jt + 5.543113262e0 ) +
323 1.694205e0 * sin( -3.523118349e0 * jt + 5.025132748e0 ) +
324 1.554905e0 * sin( 77713.771467920e0 * jt + 5.198467090e0 ) +
325 1.276839e0 * sin( 7860.419392439e0 * jt + 5.988822341e0 ) +
326 1.193379e0 * sin( 5223.693919802e0 * jt + 3.649823730e0 ) +
327 1.115322e0 * sin( 3930.209696220e0 * jt + 1.422745069e0 ) +
328 0.794185e0 * sin( 11506.769769794e0 * jt + 2.322313077e0 ) +
329 0.447061e0 * sin( 26.298319800e0 * jt + 3.615796498e0 ) +
330 0.435206e0 * sin( -398.149003408e0 * jt + 4.349338347e0 ) +
331 0.600309e0 * sin( 1577.343542448e0 * jt + 2.678271909e0 ) +
332 0.496817e0 * sin( 6208.294251424e0 * jt + 5.696701824e0 ) +
333 0.486306e0 * sin( 5884.926846583e0 * jt + 0.520007179e0 ) +
334 0.432392e0 * sin( 74.781598567e0 * jt + 2.435898309e0 ) +
335 0.468597e0 * sin( 6244.942814354e0 * jt + 5.866398759e0 ) +
336 0.375510e0 * sin( 5507.553238667e0 * jt + 4.103476804e0 )
337 );
338
339 /* now adding NEXT biggest (2nd-tier) terms from Tempo */
340 earth->einstein = earth->einstein + 1.e-6 * (
341 0.243085 * sin( -775.522611324 * jt + 3.651837925 ) +
342 0.173435 * sin( 18849.227549974 * jt + 6.153743485 ) +
343 0.230685 * sin( 5856.477659115 * jt + 4.773852582 ) +
344 0.203747 * sin( 12036.460734888 * jt + 4.333987818 ) +
345 0.143935 * sin( -796.298006816 * jt + 5.957517795 ) +
346 0.159080 * sin( 10977.078804699 * jt + 1.890075226 ) +
347 0.119979 * sin( 38.133035638 * jt + 4.551585768 ) +
348 0.118971 * sin( 5486.777843175 * jt + 1.914547226 ) +
349 0.116120 * sin( 1059.381930189 * jt + 0.873504123 ) +
350 0.137927 * sin( 11790.629088659 * jt + 1.135934669 ) +
351 0.098358 * sin( 2544.314419883 * jt + 0.092793886 ) +
352 0.101868 * sin( -5573.142801634 * jt + 5.984503847 ) +
353 0.080164 * sin( 206.185548437 * jt + 2.095377709 ) +
354 0.079645 * sin( 4694.002954708 * jt + 2.949233637 ) +
355 0.062617 * sin( 20.775395492 * jt + 2.654394814 ) +
356 0.075019 * sin( 2942.463423292 * jt + 4.980931759 ) +
357 0.064397 * sin( 5746.271337896 * jt + 1.280308748 ) +
358 0.063814 * sin( 5760.498431898 * jt + 4.167901731 ) +
359 0.048042 * sin( 2146.165416475 * jt + 1.495846011 ) +
360 0.048373 * sin( 155.420399434 * jt + 2.251573730 )
361 );
362
363
364 /* below, I've just taken derivative of above expression for einstein,
365 then commented out terms that contribute less than around 10^{-12}
366 to tDotBary */
367
368 earth->deinstein = 1.e-6 * (
369 1656.674564e0 * 6283.075849991e0 *
370 cos( 6283.075849991e0 * jt + 6.240054195e0 ) +
371
372 22.417471e0 * 5753.384884897e0 *
373 cos( 5753.384884897e0 * jt + 4.296977442e0 ) +
374
375 13.839792e0 * 12566.151699983e0 *
376 cos( 12566.151699983e0 * jt + 6.196904410e0 ) +
377
378 /* neglect next term
379 4.770086e0*529.690965095e0*
380 cos(529.690965095e0*jt + 0.444401603e0 ) +
381 */
382 4.676740e0 * 6069.776754553e0 *
383 cos( 6069.776754553e0 * jt + 4.021195093e0 ) +
384
385 /* neglect next 2 terms
386 2.256707e0*213.299095438e0*
387 cos(213.299095438e0*jt + 5.543113262e0 ) +
388
389 1.694205e0*-3.523118349e0*
390 cos(-3.523118349e0*jt + 5.025132748e0 ) +
391 */
392
393 1.554905e0 * 77713.771467920e0 *
394 cos( 77713.771467920e0 * jt + 5.198467090e0 )
395
396 /* neglect all the rest
397 + 1.276839e0*7860.419392439e0*
398 cos(7860.419392439e0*jt + 5.988822341e0 ) +
399
400 1.193379e0*5223.693919802e0*
401 cos(5223.693919802e0*jt + 3.649823730e0 ) +
402
403 1.115322e0*3930.209696220e0*
404 cos(3930.209696220e0*jt + 1.422745069e0 ) +
405
406 0.794185e0*11506.769769794e0*
407 cos(11506.769769794e0 *jt + 2.322313077e0 ) +
408
409 0.447061e0*26.298319800e0*
410 cos(26.298319800e0*jt + 3.615796498e0 ) +
411
412 0.435206e0*-398.149003408e0*
413 cos(-398.149003408e0*jt + 4.349338347e0 ) +
414
415 0.600309e0*1577.343542448e0*
416 cos(1577.343542448e0*jt + 2.678271909e0 ) +
417
418 0.496817e0*6208.294251424e0*
419 cos(6208.294251424e0*jt + 5.696701824e0 ) +
420
421 0.486306e0*5884.926846583e0*
422 cos(5884.926846583e0*jt + 0.520007179e0 ) +
423
424 0.432392e0*74.781598567e0*
425 cos(74.781598567e0*jt + 2.435898309e0 ) +
426
427 0.468597e0*6244.942814354e0*
428 cos(6244.942814354e0*jt + 5.866398759e0 ) +
429
430 0.375510e0*5507.553238667e0*
431 cos(5507.553238667e0*jt + 4.103476804e0 )
432 */
433
434 ) / ( 8.64e4 * 3.6525e5 );
435
436 /*Note I don't bother adding 2nd-tier terms to deinstein_tempo either */
437 }
438
439 /********************************************************************
440 *Now calculating Earth-Sun separation vector, as needed
441 *for Shapiro delay calculation.
442 *--------------------------------------------------------------------
443 */
444 {
445 REAL8 rse2;
446 REAL8 *sunPos = edat->ephemS[ientryS].pos;
447 REAL8 *sunVel = edat->ephemS[ientryS].vel;
448 REAL8 *sunAcc = edat->ephemS[ientryS].acc;
449 REAL8 sunPosNow[3], sunVelNow[3];
450
451 rse2 = earth->drse = 0.0;
452 for ( j = 0; j < 3; j++ ) {
453 sunPosNow[j] = sunPos[j] + sunVel[j] * tdiffS + 0.5 * sunAcc[j] * tdiff2S;
454 sunVelNow[j] = sunVel[j] + sunAcc[j] * tdiffS;
455
456 earth->se[j] = earth->posNow[j] - sunPosNow[j];
457 earth->dse[j] = earth->velNow[j] - sunVelNow[j];
458 rse2 += earth->se[j] * earth->se[j];
459 earth->drse += earth->se[j] * earth->dse[j];
460 }
461 earth->rse = sqrt( rse2 );
462 earth->drse = earth->drse / earth->rse;
463 /* Curt: make sure rse, b, (rse +seDotN) aren't zero */
464 }
465
466 return XLAL_SUCCESS;
467
468} /* XLALBarycenterEarth() */
469
470
471/**
472 * \brief Computes the position and orientation of the Earth, at some arrival
473 * time, but unlike \c XLALBarycenterEarth uses look-up tables for the Einstein
474 * delay calculation.
475 *
476 * The function replicates the functionality of \c XLALBarycenterEarth, but (as
477 * in the pulsar timing software TEMPO2) will use a look-up table to compute
478 * the Einstein delay term. This function will also allow the final solar
479 * system barycentre correction to be in either Barycentric Dynamical Time
480 * (TDB), as used previously in \c XLALBarycenterEarth, or in Coordinate
481 * Barycentric Time (TCB), as is the default for TEMPO2.
482 *
483 * The function can revert to using the original \c XLALBarycenterEarth code by
484 * supplying \c TIMECORRECTION_ORIGINAL as the \c ttype input.
485 */
486int
487XLALBarycenterEarthNew( EarthState *earth, /**< [out] the earth's state at time tGPS */
488 const LIGOTimeGPS *tGPS, /**< [in] GPS time tgps */
489 const EphemerisData *edat, /**< [in] ephemeris-files */
490 const TimeCorrectionData *tdat, /**< [in] time correction file data */
491 TimeCorrectionType ttype /**< [in] time correction type */
492 )
493{
494 earth->ttype = ttype; /* set TimeCorrectionType */
495
496 /* if wanted ORIGNAL version of the code just use XLALBarycenterEarth */
497 if ( ttype == TIMECORRECTION_ORIGINAL ) {
498 return XLALBarycenterEarth( earth, tGPS, edat );
499 }
500
501 /* start off doing the same as XLALBarycenterEarth() */
502 REAL8 tgps[2]; /*I convert from two-integer representation to
503 two REAL8s (just because I initially wrote my code for
504 REAL8s). GPS time(sec) = tgps[0] + 1.e-9*tgps[1] */
505
506 /*int ihour; most recent hour to current time, tGPS,
507 in look-up table */
508 /*REAL8 t0,t0hr; */
509
510 REAL8 t0e; /*time since first entry in Earth ephem. table */
511 INT4 ientryE; /*entry in look-up table closest to current time, tGPS */
512
513 REAL8 tinitE; /*time (GPS) of first entry in Earth ephem table*/
514 REAL8 tdiffE; /*current time tGPS minus time of nearest entry
515 in Earth ephem look-up table */
516 REAL8 tdiff2E; /*tdiff2=tdiffE*tdiffE */
517 /*next entries are same as above, but for Sun table */
518 REAL8 t0s;
519 INT4 ientryS;
520 REAL8 tinitS;
521 REAL8 tdiffS;
522 REAL8 tdiff2S;
523
524 static REAL8 scorr; /* SI second/metre correction factor */
525
526 INT4 j; /*dummy index */
527
528 /* check input */
529 if ( !earth || !tGPS || !edat || !edat->ephemE || !edat->ephemS || !tdat || !tdat->timeCorrs ) {
530 XLALPrintError( "%s: invalid NULL input 'earth', 'tGPS', 'edat', 'edat->ephemE', 'edat->ephemS', 'tdat' or 'tdat->timeCorrs'\n", __func__ );
532 }
533 tgps[0] = ( REAL8 )tGPS->gpsSeconds; /*convert from INT4 to REAL8 */
534 tgps[1] = ( REAL8 )tGPS->gpsNanoSeconds;
535
536 tinitE = edat->ephemE[0].gps;
537 tinitS = edat->ephemS[0].gps;
538
539 t0e = tgps[0] - tinitE;
540 ientryE = floor( ( t0e / edat->dtEtable ) + 0.5e0 ); /*finding Earth table entry
541 closest to arrival time*/
542 t0s = tgps[0] - tinitS;
543 ientryS = floor( ( t0s / edat->dtStable ) + 0.5e0 ); /*finding Sun table entry
544 closest to arrival time*/
545 /*Making sure tgps is within earth and sun ephemeris arrays*/
546 if ( ( ientryE < 0 ) || ( ientryE >= edat->nentriesE ) ) {
547 XLALPrintError( "%s: input GPS time %f outside of Earth ephem range [%f, %f]\n", __func__, tgps[0], tinitE, tinitE + edat->nentriesE * edat->dtEtable );
549 }
550 if ( ( ientryS < 0 ) || ( ientryS >= edat->nentriesS ) ) {
551 XLALPrintError( "%s: input GPS time %f outside of Sun ephem range [%f, %f]\n", __func__, tgps[0], tinitS, tinitS + edat->nentriesS * edat->dtStable );
553 }
554
555 tdiffE = t0e - edat->dtEtable * ientryE + tgps[1] * 1.e-9; /*tdiff is arrival
556 time minus closest Earth table entry; tdiff can be pos. or neg. */
557 tdiff2E = tdiffE * tdiffE;
558
559 tdiffS = t0s - edat->dtStable * ientryS + tgps[1] * 1.e-9; /*same for Sun*/
560 tdiff2S = tdiffS * tdiffS;
561
562 /* in the TCB system the gravitational potential well of the solar system is
563 * removed, so clocks run slightly faster than the SI second by a small
564 * correction factor */
565 if ( ttype == TIMECORRECTION_TEMPO2 || ttype == TIMECORRECTION_TCB ) {
566 scorr = IFTE_K;
567 } else {
568 scorr = 1.;
569 }
570 /********************************************************************
571 *Calculate position and vel. of center of Earth.
572 *We extrapolate from a table produced using a JPL ephemeris.
573 *---------------------------------------------------------------------
574 */
575 {
576 REAL8 *pos = edat->ephemE[ientryE].pos; /*Cartesian coords of center of Earth
577 from ephem, in sec. 0=x,1=y,2=z */
578 REAL8 *vel = edat->ephemE[ientryE].vel;
579 REAL8 *acc = edat->ephemE[ientryE].acc;
580
581 for ( j = 0; j < 3; j++ ) {
582 earth->posNow[j] = scorr * ( pos[j] + vel[j] * tdiffE + 0.5 * acc[j] * tdiff2E );
583 earth->velNow[j] = scorr * ( vel[j] + acc[j] * tdiffE );
584 }
585 }
586
587 /********************************************************************
588 * Now calculating Earth's rotational state.
589 *---------------------------------------------------------------------
590 */
591 {
592 INT2 leapsSince2000; /*number of leap secs added to UTC calendar since
593 Jan 1, 2000 00:00:00 UTC; leap is a NEGATIVE number
594 for dates before Jan 1, 2000. */
595
596 REAL8 tu0JC; /*time elapsed on UT1 clock (in Julian centuries)
597 between Jan 1.5 2000 (= J2000 epoch)
598 and midnight before gps[0,j] */
599
600 REAL8 tuJC; /*time elapsed on UT1 clock (in Julian centuries)
601 between Jan 1.5 2000 (= J2000 epoch)
602 and the present time (tGPS) */
603
604 INT4 tuInt; /*number of full seconds (integer) on elapsed
605 on UT1 clock from Jan 1, 2000 00:00:00 UTC to present*/
606 REAL8 dtu; /*see comments below*/
607
608 REAL8 gmst; /*Greenwich mean sidereal time at present (tGPS), in sec */
609 REAL8 gmst0; /*Greenwich mean sidereal time at prev. midnight, in sec */
610 REAL8 gmstRad; /*gmst, but in radians*/
611
612 INT4 ut1secSince1Jan2000, fullUt1days;
613 REAL8 daysSinceJ2000;
614 REAL8 eps0 = OBLQ; /*obliquity of ecliptic at JD 245145.0*/
615
616 leapsSince2000 = 0; /*right # for Jan. 1, 2000 */
617 leapsSince2000 = XLALGPSLeapSeconds( tGPS->gpsSeconds ) - 13;
618 {
620 if ( err != XLAL_SUCCESS ) {
621 XLALPrintError( "%s: XLALGPSLeapSeconds (%d) failed.\n", __func__, tGPS->gpsSeconds );
623 }
624 }
625
626 tuInt = tGPS->gpsSeconds - 630720013; /*first subtract off value
627 of gps clock at Jan 1, 2000 00:00:00 UTC */
628
629 ut1secSince1Jan2000 = tuInt - leapsSince2000; /*next subtract
630 off # leap secs added to UTC calendar since Jan 1, 2000 00:00:00 UTC */
631 tuJC = ( ut1secSince1Jan2000 + tgps[1] * 1.e-9 - 43200 ) / ( 8.64e4 * 36525 );
632 /*UT1 time elapsed, in Julian centuries, since Jan 1.5 2000
633 (= J2000 epoch) and pulse arrival time*/
634
635 fullUt1days = floor( ut1secSince1Jan2000 / 8.64e4 );/*full days on ut1 clock
636 since Jan 1, 2000 00:00:00 UTC */
637
638 tu0JC = ( fullUt1days - 0.5e0 ) / 36525.0; /* UT1 time elapsed,
639 in Julian centuries between Jan 1.5 2000 (= J2000 epoch)
640 and midnight before gps[0,j] */
641
642 dtu = tuJC - tu0JC; /*time, in Jul. centuries, between pulse arrival time and previous midnight (UT1) */
643
644 daysSinceJ2000 = ( tuInt - 43200. ) / 8.64e4; /*days(not int) on GPS
645 (or TAI,etc.) clock since J2000 */
646
647 /*----------------------------------------------------------------------
648 * in below formula for gmst0 & gmst, on rhs we SHOULD use time elapsed
649 * in UT1, but instead we insert elapsed in UTC. This will lead to
650 * errors in tdb of order 1 microsec.
651 *----------------------------------------------------------------------
652 */
653
654 gmst0 = 24110.54841e0 + tu0JC * ( 8640184.812866e0 + tu0JC * ( 0.093104e0 - tu0JC * 6.2e-6 ) );
655 /*formula for Greenwich mean sidereal time
656 on p.50 of Explanatory Supp. to Ast Alm. ...
657 gmst unit is sec, where 2pi rad = 24*60*60sec */
658
659 /*-----------------------------------------------------------------------
660 * Explan of tu0JC*8640184.812866e0 term: when tu0JC0=0.01 Julian centuries
661 * (= 1 year), Earth has spun an extra 86401.84 sec (approx one revolution)
662 * with respect to the stars.
663 *
664 * Note: this way of organizing calc of gmst was stolen from TEMPO;
665 * see subroutine lmst (= local mean sidereal time) .
666 *------------------------------------------------------------------------
667 */
668
669 gmst = gmst0 + dtu * ( 8.64e4 * 36525. + 8640184.812866e0
670 + 0.093104e0 * ( tuJC + tu0JC )
671 - 6.2e-6 * ( tuJC * tuJC + tuJC * tu0JC + tu0JC * tu0JC ) );
672
673 gmstRad = gmst * LAL_PI / 43200.;
674
675 earth->gmstRad = gmstRad;
676
677 /*------------------------------------------------------------------------
678 * Now calculating 3 terms, describing lunisolar precession;
679 * see Eqs. 3.212 on pp. 104-5 in Explanatory Supp.
680 *-------------------------------------------------------------------------
681 */
682
683 earth->tzeA = tuJC * ( 2306.2181e0 + ( 0.30188e0 + 0.017998e0 * tuJC ) * tuJC )
684 * LAL_PI / 6.48e5;
685
686 earth->zA = tuJC * ( 2306.2181e0 + ( 1.09468e0 + 0.018203e0 * tuJC ) * tuJC )
687 * LAL_PI / 6.48e5;
688
689 earth->thetaA = tuJC * ( 2004.3109e0 - ( 0.42665e0 + 0.041833 * tuJC ) * tuJC )
690 * LAL_PI / 6.48e5;
691
692 /*--------------------------------------------------------------------------
693 * Now adding approx nutation (= short-period,forced motion, by definition).
694 * These two dominant terms, with periods 18.6 yrs (big term) and
695 * 0.500 yrs (small term),respp., give nutation to around 1 arc sec; see
696 * p. 120 of Explan. Supp. The forced nutation amplitude
697 * is around 17 arcsec.
698 *
699 * Note the unforced motion or Chandler wobble (called ``polar motion''
700 * in Explanatory Supp) is not included here. However its amplitude is
701 * order of (and a somewhat less than) 1 arcsec; see plot on p. 270 of
702 * Explanatory Supplement to Ast. Alm.
703 *--------------------------------------------------------------------------
704 */
705 /* define variables for storing sin/cos of deltaE, eps0 etc */
706 earth->delpsi = ( -0.0048e0 * LAL_PI / 180.e0 ) *
707 sin( ( 125.e0 - 0.05295e0 * daysSinceJ2000 ) * LAL_PI / 180.e0 )
708 - ( 4.e-4 * LAL_PI / 180.e0 ) *
709 sin( ( 200.9e0 + 1.97129e0 * daysSinceJ2000 ) * LAL_PI / 180.e0 );
710
711 earth->deleps = ( 0.0026e0 * LAL_PI / 180.e0 ) *
712 cos( ( 125.e0 - 0.05295e0 * daysSinceJ2000 ) * LAL_PI / 180.e0 )
713 + ( 2.e-4 * LAL_PI / 180.e0 ) *
714 cos( ( 200.9e0 + 1.97129e0 * daysSinceJ2000 ) * LAL_PI / 180.e0 );
715
716 earth->gastRad = gmstRad + earth->delpsi * cos( eps0 );
717 /* ``equation of the equinoxes''*/
718 }
719 /**********************************************************************
720 * Now calculating Einstein delay using the look-up table and linearly
721 * interpolating between points. Depending on the ephemeris type this is
722 * either the difference between TDB and TDT, or TCB and TDT. The
723 * TCB calculation includes a linear drift term correcting the SSB time
724 * to be outside the solar systems gravitational potential. These
725 * calculations are taken from the TEMPO2 tt2tdb.C file.
726 *
727 * Note the 51.184 s difference between TDT and GPS
728 *-----------------------------------------------------------------------
729 */
730 {
731 /* get deltaT from the look-up table */
732 INT4 cidx = floor( ( ( tgps[0] + tgps[1] * 1.e-9 ) - tdat->timeCorrStart ) / tdat->dtTtable );
733
734 if ( cidx < 0 || cidx > ( INT4 )tdat->nentriesT - 2 ) {
735 XLALPrintError( "%s: input GPS time %f outside of time ephem range\n", __func__, tgps[0] );
737 }
738
739 REAL8 dtidx = ( tgps[0] + tgps[1] * 1.e-9 ) - ( tdat->timeCorrStart + ( REAL8 )cidx * tdat->dtTtable );
740 REAL8 grad = ( tdat->timeCorrs[cidx + 1] - tdat->timeCorrs[cidx] ) / tdat->dtTtable;
741
742 REAL8 deltaT = tdat->timeCorrs[cidx] + grad * dtidx;
743
744 REAL8 correctionTT_Teph;
745
746 correctionTT_Teph = IFTE_TEPH0 + deltaT / ( 1.0 - IFTE_LC );
747 /* the observatory term (obsTerm) correction from TEMPO2's tt2tdb.C code
748 is added in XLALBarycenter */
749 if ( ttype == TIMECORRECTION_TEMPO || ttype == TIMECORRECTION_TDB ) { /* conversion for TDT to TDB using lookup table */
750 /* add correction offset as in TEMPO2 tt2tdb.C to
751 * account for its readdition in correctionTT_Teph */
752 correctionTT_Teph -= IFTE_TEPH0 / ( 1.0 - IFTE_LC );
753 earth->einstein = correctionTT_Teph;
754 earth->deinstein = 0.;
755 }
756 /* conversion for TDT to TCB using lookup table */
757 else if ( ttype == TIMECORRECTION_TEMPO2 || ttype == TIMECORRECTION_TCB ) {
758 /* GPS time in MJD */
759 REAL8 mjdtt = 44244. + ( ( tgps[0] + tgps[1] * 1.e-9 ) + 51.184 ) / 86400.;
760
761 earth->einstein = IFTE_KM1 * ( mjdtt - IFTE_MJD0 ) * 86400.0 /* linear drift term */
762 + IFTE_K * ( correctionTT_Teph - ( long double )IFTE_TEPH0 );
763 earth->deinstein = IFTE_KM1; /* account for the drift in the derivative */
764 }
765
766 /* now get the time derivative using Curt's method: NOTE: this really should be
767 checked as the differences may not be negligble */
768 REAL8 jedtdt = -7300.5e0 + ( tgps[0] + 51.184e0 + tgps[1] * 1.e-9 ) / 8.64e4;
769 REAL8 jt = jedtdt / 3.6525e5; /*converting to TEMPO expansion param
770 = Julian millenium, NOT Julian century */
771
772 /* below, I've just taken derivative of above expression for einstein,
773 then commented out terms that contribute less than around 10^{-12}
774 to tDotBary */
775 earth->deinstein += 1.e-6 * (
776 1656.674564e0 * 6283.075849991e0 * cos( 6283.075849991e0 * jt + 6.240054195e0 ) +
777 22.417471e0 * 5753.384884897e0 * cos( 5753.384884897e0 * jt + 4.296977442e0 ) +
778 13.839792e0 * 12566.151699983e0 * cos( 12566.151699983e0 * jt + 6.196904410e0 ) +
779 4.676740e0 * 6069.776754553e0 * cos( 6069.776754553e0 * jt + 4.021195093e0 ) +
780 1.554905e0 * 77713.771467920e0 * cos( 77713.771467920e0 * jt + 5.198467090e0 )
781 ) / ( 8.64e4 * 3.6525e5 );
782 }
783
784 /********************************************************************
785 *Now calculating Earth-Sun separation vector, as needed
786 *for Shapiro delay calculation.
787 *--------------------------------------------------------------------
788 */
789 {
790 REAL8 rse2;
791 REAL8 *sunPos = edat->ephemS[ientryS].pos;
792 REAL8 *sunVel = edat->ephemS[ientryS].vel;
793 REAL8 *sunAcc = edat->ephemS[ientryS].acc;
794 REAL8 sunPosNow[3], sunVelNow[3];
795
796 rse2 = earth->drse = 0.0;
797 for ( j = 0; j < 3; j++ ) {
798 sunPosNow[j] = scorr * ( sunPos[j] + sunVel[j] * tdiffS + 0.5 * sunAcc[j] * tdiff2S );
799 sunVelNow[j] = scorr * ( sunVel[j] + sunAcc[j] * tdiffS );
800
801 earth->se[j] = earth->posNow[j] - sunPosNow[j];
802 earth->dse[j] = earth->velNow[j] - sunVelNow[j];
803 rse2 += earth->se[j] * earth->se[j];
804 earth->drse += earth->se[j] * earth->dse[j];
805 }
806 earth->rse = sqrt( rse2 );
807 earth->drse = earth->drse / earth->rse;
808 /* Curt: make sure rse, b, (rse +seDotN) aren't zero */
809 }
810
811 return XLAL_SUCCESS;
812
813} /* XLALBarycenterEarthNew() */
814
815
816/**
817 * \author Curt Cutler
818 * \brief Transforms from detector arrival time \f$ t_a \f$ in GPS (as specified in the
819 * LIGOTimeGPS structure) to pulse emission time \f$ t_e \f$ , in TDB.
820 *
821 * Actually, the returned \f$ t_e \f$ is
822 * the emission time plus the constant light-travel-time from
823 * source to SSB.) The inputs to XLALBarycenter(), through
824 * the BarycenterInput structure, are the source location,
825 * detector site identifier, and GPS arrival time.
826 * The function returns the emission time \f$ t_e(t_a) \f$ , the
827 * derivative \f$ d t_e/d t_a \f$ , and the difference
828 * \f$ t_e(t_a) - t_a \f$ through the EmissionTime structure.
829 * The emission time \f$ t_e(t_a) \f$ is returned in the LIGOTimeGPS format,
830 * while the other two quantities are REAL8's.
831 */
832int
833XLALBarycenter( EmissionTime *emit, /**< [out] emission-time information */
834 const BarycenterInput *baryinput, /**< [in] info about detector and source-location */
835 const EarthState *earth ) /**< [in] earth-state (from XLALBarycenterEarth()) */
836{
837 REAL8 longitude, latitude, rd; /*geocentric (not geodetic!!) longitude
838 and latitude of detector vertex, and
839 dist. rd from center of Earth (sec). */
840 REAL8 OMEGA = 7.29211510e-5; /*ang. vel. of Earth (rad/sec)*/
841
842 REAL8 alpha, delta; /* RA and DEC (radians) in
843 ICRS realization of J2000 coords.*/
844
845 REAL8 sinTheta; /* sin(theta) = sin(pi/2 - delta) */
846
847 REAL8 tgps[2]; /*I convert from two-integer representation to
848 two REAL8s (just because I initially wrote my code for
849 REAL8s). GPS time(sec) = tgps[0] + 1.e-9*tgps[1] */
850
851 REAL8 roemer, droemer; /*Roemer delay and its time derivative*/
852 REAL8 erot, derot; /*delay from center-of-Earth to detector (sec),
853 and its time deriv */
854 REAL8 shapiro, dshapiro; /*Shapiro delay due to Sun, and its time deriv. */
855 REAL8 finiteDistCorr, dfiniteDistCorr; /*correction to Roemer delay due
856 to finite dist D to source;
857 important for D < 100pc */
858 REAL8 s[3]; /*unit vector pointing at source, in J2000 Cartesian coords */
859 INT4 j; /*dummy index */
860
861 /* check input */
862 if ( !emit || !baryinput || !earth ) {
863 XLALPrintError( "%s: invalid NULL input 'baryinput, 'emit' or 'earth'\n", __func__ );
865 }
866
867 tgps[0] = ( REAL8 )baryinput->tgps.gpsSeconds; /*convert from INT4 to REAL8 */
868 tgps[1] = ( REAL8 )baryinput->tgps.gpsNanoSeconds;
869
870 alpha = baryinput->alpha;
871 delta = baryinput->delta;
872
873 /* check that alpha and delta are in reasonable range */
874 if ( ( fabs( alpha ) > LAL_TWOPI ) || ( fabs( delta ) > LAL_PI_2 ) ) {
875 XLALPrintError( "%s: alpha = %f outside of [-2pi,2pi] or delta = %f outside of [-pi/2,pi/2]\n", __func__, alpha, delta );
877 }
878
879 sinTheta = sin( LAL_PI / 2.0 - delta );
880 s[2] = cos( LAL_PI / 2.0 - delta ); /* s is vector that points towards source */
881 s[1] = sinTheta * sin( alpha ); /* in Cartesian coords based on J2000 */
882 s[0] = sinTheta * cos( alpha ); /* 0=x,1=y,2=z */
883
884 rd = sqrt( baryinput->site.location[0] * baryinput->site.location[0]
885 + baryinput->site.location[1] * baryinput->site.location[1]
886 + baryinput->site.location[2] * baryinput->site.location[2] );
887 if ( rd == 0.0 ) {
888 latitude = LAL_PI_2;
889 } else {
890 latitude = LAL_PI_2 - acos( baryinput->site.location[2] / rd );
891 }
892 longitude = atan2( baryinput->site.location[1], baryinput->site.location[0] );
893
894 /********************************************************************
895 *Calucate Roemer delay for detector at center of Earth.
896 *We extrapolate from a table produced using JPL DE405 ephemeris.
897 *---------------------------------------------------------------------
898 */
899 {
900 roemer = droemer = 0.0;
901 for ( j = 0; j < 3; j++ ) {
902 roemer += s[j] * earth->posNow[j];
903 droemer += s[j] * earth->velNow[j];
904 }
905 emit->roemer = roemer;
906 emit->droemer = droemer;
907 }
908
909 /* get the observatory term (if not using the original XLALBarycenterEarth function) */
910 REAL8 obsTerm = 0; /* observatory term correction from TEMPO2 tt2tdb.C */
911 if ( earth->ttype != TIMECORRECTION_ORIGINAL ) {
912 REAL8 obsEarth[3];
913 observatoryEarth( obsEarth, baryinput->site, &baryinput->tgps, earth->gmstRad, earth->delpsi, earth->deleps );
914
915 for ( j = 0; j < 3; j++ ) {
916 obsTerm += obsEarth[j] * earth->velNow[j];
917 }
918
919 obsTerm /= ( 1.0 - IFTE_LC ) * ( REAL8 )IFTE_K;
920 }
921
922 /********************************************************************
923 * Now including Earth's rotation
924 *---------------------------------------------------------------------
925 */
926 {
927
928 REAL8 eps0 = OBLQ;/*obliquity of ecliptic at JD 245145.0,
929 in radians. NOT! to be confused with
930 LAL_EPSILON0_SI = permittivity of free
931 space; value from Explan. Supp.
932 to Astronom. Almanac */
933 /* REAL8 eps0= (23.e0 + 26.e0/60 + 21.448e0/3.6e3)*LAL_PI/180; */
934
935 REAL8 NdotD;
936 REAL8 cosDeltaSinAlphaMinusZA, cosDeltaCosAlphaMinusZA, sinDelta;
937 /* above used in calculating effect of luni-solar precession*/
938
939 REAL8 delXNut, delYNut, delZNut, NdotDNut; /* used in calculating effect
940 of forced nutation */
941
942 cosDeltaSinAlphaMinusZA = sin( alpha + earth->tzeA ) * cos( delta );
943
944 cosDeltaCosAlphaMinusZA = cos( alpha + earth->tzeA ) * cos( earth->thetaA )
945 * cos( delta ) - sin( earth->thetaA ) * sin( delta );
946
947 sinDelta = cos( alpha + earth->tzeA ) * sin( earth->thetaA ) * cos( delta )
948 + cos( earth->thetaA ) * sin( delta );
949
950 /*now taking NdotD, including lunisolar precession, using
951 Eqs. 3.212-2 of Explan. Supp.
952 Basic idea for incorporating luni-solar precession
953 is to change the (alpha,delta) of source to compensate for
954 Earth's time-changing spin axis.
955 */
956
957 NdotD = sin( latitude ) * sinDelta + cos( latitude ) * (
958 cos( earth->gastRad + longitude - earth->zA ) * cosDeltaCosAlphaMinusZA
959 + sin( earth->gastRad + longitude - earth->zA ) * cosDeltaSinAlphaMinusZA );
960
961 erot = rd * NdotD;
962
963 derot = OMEGA * rd * cos( latitude ) * (
964 - sin( earth->gastRad + longitude - earth->zA ) * cosDeltaCosAlphaMinusZA
965 + cos( earth->gastRad + longitude - earth->zA ) * cosDeltaSinAlphaMinusZA );
966
967
968 /*--------------------------------------------------------------------------
969 * Now adding approx nutation (= short-period,forced motion, by definition).
970 * These two dominant terms, with periods 18.6 yrs (big term) and
971 * 0.500 yrs (small term),resp., give nutation to around 1 arc sec; see
972 * p. 120 of Explan. Supp. The forced nutation amplitude
973 * is around 17 arcsec.
974 *
975 * Note the unforced motion or Chandler wobble (called ``polar motion''
976 * in Explanatory Supp) is not included here. However its amplitude is
977 * order of (and a somewhat less than) 1 arcsec; see plot on p. 270 of
978 * Explanatory Supplement to Ast. Alm.
979 *
980 *Below correction for nutation from Eq.3.225-2 of Explan. Supp.
981 *Basic idea is to change the (alpha,delta) of source to
982 *compensate for Earth's time-changing spin axis.
983 *--------------------------------------------------------------------------
984 */
985
986 delXNut = -( earth->delpsi ) * ( cos( delta ) * sin( alpha ) * cos( eps0 )
987 + sin( delta ) * sin( eps0 ) );
988
989 delYNut = cos( delta ) * cos( alpha ) * cos( eps0 ) * ( earth->delpsi )
990 - sin( delta ) * ( earth->deleps );
991
992 delZNut = cos( delta ) * cos( alpha ) * sin( eps0 ) * ( earth->delpsi )
993 + cos( delta ) * sin( alpha ) * ( earth->deleps );
994
995
996 NdotDNut = sin( latitude ) * delZNut
997 + cos( latitude ) * cos( earth->gastRad + longitude ) * delXNut
998 + cos( latitude ) * sin( earth->gastRad + longitude ) * delYNut;
999
1000 erot = erot + rd * NdotDNut;
1001
1002 derot = derot + OMEGA * rd * (
1003 -cos( latitude ) * sin( earth->gastRad + longitude ) * delXNut
1004 + cos( latitude ) * cos( earth->gastRad + longitude ) * delYNut );
1005
1006 emit->erot = erot;
1007 emit->derot = derot;
1008 /* Note erot has a periodic piece (P=one day) AND a constant piece,
1009 since z-component (parallel to North pole) of vector from
1010 Earth-center to detector is constant */
1011
1012 }
1013
1014 /********************************************************************
1015 *Now adding Shapiro delay. Note according to J. Taylor review article
1016 *on pulsar timing, max value of Shapiro delay (when rays just graze sun)
1017 *is 120 microsec.
1018 *
1019 *Here we calculate Shapiro delay
1020 *for a detector at the center of the Earth.
1021 *Causes errors of order 10^{-4}sec * 4 * 10^{-5} = 4*10^{-9} sec
1022 *--------------------------------------------------------------------
1023 */
1024 {
1025 REAL8 seDotN, dseDotN, b, db;
1026 REAL8 rsun = 2.322e0; /*radius of sun in sec */
1027 seDotN = earth->se[2] * sin( delta ) + ( earth->se[0] * cos( alpha )
1028 + earth->se[1] * sin( alpha ) ) * cos( delta );
1029 dseDotN = earth->dse[2] * sin( delta ) + ( earth->dse[0] * cos( alpha )
1030 + earth->dse[1] * sin( alpha ) ) * cos( delta );
1031
1032 b = sqrt( earth->rse * earth->rse - seDotN * seDotN );
1033 db = ( earth->rse * earth->drse - seDotN * dseDotN ) / b;
1034
1035
1036 if ( ( b < rsun ) && ( seDotN < 0.e0 ) ) { /*if gw travels thru interior of Sun*/
1037 shapiro = 9.852e-6 * log( ( LAL_AU_SI / LAL_C_SI ) /
1038 ( seDotN + sqrt( rsun * rsun + seDotN * seDotN ) ) )
1039 + 19.704e-6 * ( 1.e0 - b / rsun );
1040 dshapiro = - 19.704e-6 * db / rsun;
1041 } else { /*else the usual expression*/
1042 shapiro = 9.852e-6 * log( ( LAL_AU_SI / LAL_C_SI ) / ( earth->rse + seDotN ) );
1043 dshapiro = -9.852e-6 * ( earth->drse + dseDotN ) / ( earth->rse + seDotN );
1044 }
1045
1046 emit->shapiro = shapiro;
1047 emit->dshapiro = dshapiro;
1048 }
1049 /********************************************************************
1050 *Now correcting Roemer delay for finite distance to source.
1051 *Timing corrections are order 10 microsec
1052 *for sources closer than about 100 pc = 10^10 sec.
1053 *--------------------------------------------------------------------
1054 */
1055 {
1056 REAL8 r2 = 0.e0; /*squared dist from SSB to center of earth, in sec^2 */
1057 REAL8 dr2 = 0.e0; /*time deriv of r2 */
1058 if ( baryinput->dInv > 1.0e-11 ) { /*implement if corr. > 1 microsec*/
1059 for ( j = 0; j < 3; j++ ) {
1060 r2 += earth->posNow[j] * earth->posNow[j];
1061 dr2 += 2.e0 * earth->posNow[j] * earth->velNow[j];
1062 }
1063 finiteDistCorr = -0.5e0 * ( r2 - roemer * roemer ) * baryinput->dInv;
1064 dfiniteDistCorr = -( 0.5e0 * dr2 - roemer * droemer ) * baryinput->dInv;
1065 } else {
1066 finiteDistCorr = 0.e0;
1067 dfiniteDistCorr = 0.e0;
1068 }
1069 }
1070 /*-----------------------------------------------------------------------
1071 *Now adding it all up.
1072 *emit.te is pulse emission time in TDB coords
1073 *(up to a constant roughly equal to ligh travel time from source to SSB).
1074 *emit->deltaT = emit.te - tgps.
1075 *-----------------------------------------------------------------------
1076 */
1077 {
1078
1079 INT4 deltaTint; /* floor of deltaT */
1080
1081 emit->deltaT = roemer + erot + obsTerm + earth->einstein - shapiro + finiteDistCorr;
1082
1083 emit->tDot = 1.e0 + droemer + derot + earth->deinstein - dshapiro + dfiniteDistCorr;
1084
1085 deltaTint = ( INT4 )floor( emit->deltaT );
1086
1087 if ( ( 1.e-9 * tgps[1] + emit->deltaT - deltaTint ) >= 1.e0 ) {
1088 emit->te.gpsSeconds = baryinput->tgps.gpsSeconds + deltaTint + 1;
1089 emit->te.gpsNanoSeconds = ( INT4 )floor( 1.e9 * ( tgps[1] * 1.e-9
1090 + emit->deltaT - deltaTint - 1.e0 ) );
1091 } else {
1092 emit->te.gpsSeconds = baryinput->tgps.gpsSeconds + deltaTint;
1093 emit->te.gpsNanoSeconds = ( INT4 )floor( 1.e9 * ( tgps[1] * 1.e-9
1094 + emit->deltaT - deltaTint ) );
1095 }
1096
1097 {
1098 for ( j = 0; j < 3; j++ ) {
1099 emit->rDetector[j] = earth->posNow[j];
1100 emit->vDetector[j] = earth->velNow[j];
1101 }
1102 /*Now adding Earth's rotation to rDetector and
1103 vDetector, but NOT yet including effects of
1104 lunisolar prec. or nutation (though DO use gast instead of gmst)
1105 For next 10 years, will give rDetector to 10 microsec and
1106 v/c to 10^-9 */
1107 emit->rDetector[0] += rd * cos( latitude ) * cos( longitude + earth->gastRad );
1108 emit->vDetector[0] += -OMEGA * rd * cos( latitude ) *
1109 sin( longitude + earth->gastRad );
1110 emit->rDetector[1] += rd * cos( latitude ) * sin( longitude + earth->gastRad );
1111 emit->vDetector[1] += OMEGA * rd * cos( latitude ) *
1112 cos( longitude + earth->gastRad );
1113 emit->rDetector[2] += rd * sin( latitude );
1114 /*no change to emit->vDetector[2] = component along spin axis,
1115 if ignore prec. and nutation */
1116 }
1117
1118 }
1119
1120 return XLAL_SUCCESS;
1121
1122} /* XLALBarycenter() */
1123
1124/**
1125 * \author Curt Cutler, Miroslav Shaltev, R Prix
1126 * \brief Speed optimized version of XLALBarycenter(),
1127 * should be fully equivalent except for the additional buffer argument.
1128 * The 'buffer' is used to keep sky-specific and detector-specific values that can can potentially be re-used
1129 * across subsequent calls to this function.
1130 *
1131 * NOTE: The 'buffer' argument is a pointer to a buffer-pointer, which is allowed to be buffer==NULL (=> no buffering),
1132 * otherwise a given non-NULL (*buffer) is re-used, or if (*buffer==NULL) we create a new one and return in (*buffer).
1133 *
1134 */
1135int
1136XLALBarycenterOpt( EmissionTime *emit, /**< [out] emission-time information */
1137 const BarycenterInput *baryinput, /**< [in] info about detector and source-location */
1138 const EarthState *earth, /**< [in] earth-state (from XLALBarycenterEarth()) */
1139 BarycenterBuffer **buffer /**< [in/out] internal buffer for speed optimization */
1140 )
1141{
1142 /* ---------- check input sanity ---------- */
1143 XLAL_CHECK( emit != NULL, XLAL_EINVAL, "Invalid input: emit == NULL" );
1144 XLAL_CHECK( baryinput != NULL, XLAL_EINVAL, "Invalid input: baryinput == NULL" );
1145 XLAL_CHECK( earth != NULL, XLAL_EINVAL, "Invalid input: earth == NULL" );
1146 XLAL_CHECK( buffer != NULL, XLAL_EINVAL, "Invalid input: buffer == NULL" );
1147
1148 // physical constants used by Curt (slightly different from LAL's Constants, but kept for binary-equivalence with XLALBarycenter()
1149 const REAL8 OMEGA = 7.29211510e-5; /* ang. vel. of Earth (rad/sec)*/
1150 // REAL8 eps0 = 0.40909280422232891; /* obliquity of ecliptic at JD 245145.0, in radians. Value from Explan. Supp. to Astronom. Almanac */
1151 const REAL8 sinEps0 = 0.397777155931914; // sin ( eps0 );
1152 const REAL8 cosEps0 = 0.917482062069182; // cos ( eps0 );
1153
1154 REAL8 tgps[2];
1155 tgps[0] = baryinput->tgps.gpsSeconds;
1156 tgps[1] = baryinput->tgps.gpsNanoSeconds;
1157
1158 // ---------- sky-position dependent quantities: compute or re-use from buffer is applicable
1159 REAL8 alpha, delta; /* RA and DEC (radians) in ICRS realization of J2000 coords.*/
1160 alpha = baryinput->alpha;
1161 delta = baryinput->delta;
1162
1163 REAL8 sinAlpha, cosAlpha, sinDelta, cosDelta;
1164 REAL8 n[3]; /*unit vector pointing from SSB to the source, in J2000 Cartesian coords, 0=x,1=y,2=z */
1165
1166 // ---------- handle buffering of recurring computed quantities
1167 // 3 possible scenarios:
1168 // i) caller gave as an initialized buffer: we use that one
1169 // ii) caller gave as a pointer to a NULL-initialized buffer-pointer: allocate buffer, initialize and pass back to caller
1170 // iii) caller gave as a NULL pointer: use buffer internally, but destroy at the end of this function
1171 BarycenterBuffer *myBuffer = NULL;
1172 if ( ( buffer ) && ( *buffer ) ) { // caller gave as an allocated buffer
1173 myBuffer = ( *buffer );
1174 } else { // we need to create a buffer
1175 XLAL_CHECK( ( myBuffer = XLALCalloc( 1, sizeof( *myBuffer ) ) ) != NULL, XLAL_ENOMEM, "Failed to XLALCalloc(1,sizeof(*myBuffer))\n" );
1176 }
1177
1178 // now we're (basically) guaranteed to have a valid buffer in 'myBuffer'
1179
1180 // use buffered sky-quantities if same sky-position as stored in buffer
1181 if ( myBuffer->active && ( alpha == myBuffer->alpha ) && ( delta == myBuffer->delta ) ) {
1182 sinDelta = myBuffer->fixed_sky.sinDelta;
1183 cosDelta = myBuffer->fixed_sky.cosDelta;
1184 sinAlpha = myBuffer->fixed_sky.sinAlpha;
1185 cosAlpha = myBuffer->fixed_sky.cosAlpha;
1186 n[0] = myBuffer->fixed_sky.n[0];
1187 n[1] = myBuffer->fixed_sky.n[1];
1188 n[2] = myBuffer->fixed_sky.n[2];
1189 } else { // not buffered, recompute sky-dependent quantities
1190 /* check that alpha and delta are in reasonable range */
1191 XLAL_CHECK( fabs( alpha ) <= LAL_TWOPI, XLAL_EDOM, "alpha = %f outside of allowed range [-2pi,2pi]\n", alpha );
1192 XLAL_CHECK( fabs( delta ) <= LAL_PI_2, XLAL_EDOM, "delta = %f outside of allowed range [-pi/2,pi/2]\n", delta );
1193
1194 sinDelta = cos( LAL_PI / 2.0 - delta ); // this weird way of computing it is required to stay binary identical to Curt's function
1195 cosDelta = sin( LAL_PI / 2.0 - delta );
1196 sinAlpha = sin( alpha );
1197 cosAlpha = cos( alpha );
1198
1199 n[0] = cosDelta * cosAlpha;
1200 n[1] = cosDelta * sinAlpha;
1201 n[2] = sinDelta;
1202
1203 // ... and store them in the myBuffer
1204 myBuffer->alpha = alpha;
1205 myBuffer->delta = delta;
1206 myBuffer->fixed_sky.sinDelta = sinDelta;
1207 myBuffer->fixed_sky.cosDelta = cosDelta;
1208 myBuffer->fixed_sky.sinAlpha = sinAlpha;
1209 myBuffer->fixed_sky.cosAlpha = cosAlpha;
1210 myBuffer->fixed_sky.n[0] = n[0];
1211 myBuffer->fixed_sky.n[1] = n[1];
1212 myBuffer->fixed_sky.n[2] = n[2];
1213 myBuffer->active = 1;
1214 } // if not re-using sky-buffered quantities
1215
1216 // ---------- detector site-position dependent quantities: compute or re-use from buffer is applicable
1217 REAL8 rd; /* distance 'rd' of detector from center of Earth, in light seconds */
1218 REAL8 longitude, latitude; /* geocentric (not geodetic!!) longitude and latitude of detector vertex */
1219 REAL8 sinLat, cosLat;
1220 REAL8 rd_sinLat, rd_cosLat; // shortcuts for 'rd * sin(latitude)' and 'rd * cos(latitude)' respectively
1221
1222 // use buffered site-quantities if same site as stored in myBuffer
1223 if ( myBuffer->active && ( memcmp( &baryinput->site, &myBuffer->site, sizeof( myBuffer->site ) ) == 0 ) ) {
1224 rd = myBuffer->fixed_site.rd;
1225 longitude = myBuffer->fixed_site.longitude;
1226 latitude = myBuffer->fixed_site.latitude;
1227 sinLat = myBuffer->fixed_site.sinLat;
1228 cosLat = myBuffer->fixed_site.cosLat;
1229 rd_sinLat = myBuffer->fixed_site.rd_sinLat;
1230 rd_cosLat = myBuffer->fixed_site.rd_cosLat;
1231 } else {
1232 rd = sqrt( + baryinput->site.location[0] * baryinput->site.location[0]
1233 + baryinput->site.location[1] * baryinput->site.location[1]
1234 + baryinput->site.location[2] * baryinput->site.location[2] );
1235
1236 longitude = atan2( baryinput->site.location[1], baryinput->site.location[0] );
1237 if ( rd == 0.0 ) {
1238 latitude = LAL_PI_2; // avoid division by 0, for detector at center of earth
1239 } else {
1240 latitude = LAL_PI_2 - acos( baryinput->site.location[2] / rd );
1241 }
1242
1243 sinLat = sin( latitude );
1244 cosLat = cos( latitude );
1245 rd_sinLat = rd * sinLat;
1246 rd_cosLat = rd * cosLat;
1247
1248 // ... and store them in the myBuffer
1249 memcpy( &myBuffer->site, &baryinput->site, sizeof( myBuffer->site ) );
1250 myBuffer->fixed_site.rd = rd;
1251 myBuffer->fixed_site.longitude = longitude;
1252 myBuffer->fixed_site.latitude = latitude;
1253 myBuffer->fixed_site.sinLat = sinLat;
1254 myBuffer->fixed_site.cosLat = cosLat;
1255 myBuffer->fixed_site.rd_sinLat = rd_sinLat;
1256 myBuffer->fixed_site.rd_cosLat = rd_cosLat;
1257 myBuffer->active = 1;
1258 } // if not re-using site-buffered quantities
1259
1260 /*---------------------------------------------------------------------
1261 * Calucate Roemer delay for detector at center of Earth.
1262 * We extrapolate from a table produced using JPL DE405 ephemeris.
1263 *---------------------------------------------------------------------
1264 */
1265 /*Roemer delay and its time derivative*/
1266 emit->roemer = 0;
1267 emit->droemer = 0;
1268 for ( UINT4 j = 0; j < 3; j++ ) {
1269 emit->roemer += n[j] * earth->posNow[j];
1270 emit->droemer += n[j] * earth->velNow[j];
1271 }
1272
1273 /* get the observatory term (if in TDB) */
1274 REAL8 obsTerm = 0; /* observatory term correction from TEMPO2 tt2tb.C */
1275 if ( earth->ttype != TIMECORRECTION_ORIGINAL ) {
1276 REAL8 obsEarth[3];
1277 observatoryEarth( obsEarth, baryinput->site, &baryinput->tgps, earth->gmstRad, earth->delpsi, earth->deleps );
1278
1279 for ( UINT4 j = 0; j < 3; j++ ) {
1280 obsTerm += obsEarth[j] * earth->velNow[j];
1281 }
1282
1283 obsTerm /= ( 1.0 - IFTE_LC ) * ( REAL8 )IFTE_K;
1284 }
1285
1286 /*---------------------------------------------------------------------
1287 * Now including Earth's rotation
1288 *---------------------------------------------------------------------
1289 */
1290 /* calculating effect of luni-solar precession */
1291 REAL8 sinAlphaMinusZA = sin( alpha + earth->tzeA );
1292 REAL8 cosAlphaMinusZA = cos( alpha + earth->tzeA );
1293 REAL8 cosThetaA = cos( earth->thetaA );
1294 REAL8 sinThetaA = sin( earth->thetaA );
1295
1296 REAL8 cosDeltaSinAlphaMinusZA = sinAlphaMinusZA * cosDelta;
1297
1298 REAL8 cosDeltaCosAlphaMinusZA = cosAlphaMinusZA * cosThetaA * cosDelta - sinThetaA * sinDelta;
1299
1300 REAL8 sinDeltaCurt = cosAlphaMinusZA * sinThetaA * cosDelta + cosThetaA * sinDelta;
1301
1302 /* now taking NdotD, including lunisolar precession, using
1303 Eqs. 3.212-2 of Explan. Supp.
1304 Basic idea for incorporating luni-solar precession
1305 is to change the (alpha,delta) of source to compensate for
1306 Earth's time-changing spin axis.
1307 */
1308 REAL8 cosGastZA = cos( earth->gastRad + longitude - earth->zA );
1309 REAL8 sinGastZA = sin( earth->gastRad + longitude - earth->zA );
1310
1311 REAL8 rd_NdotD = rd_sinLat * sinDeltaCurt + rd_cosLat * ( cosGastZA * cosDeltaCosAlphaMinusZA + sinGastZA * cosDeltaSinAlphaMinusZA );
1312
1313 /* delay from center-of-Earth to detector (sec), and its time deriv */
1314 emit->erot = rd_NdotD;
1315 emit->derot = OMEGA * rd_cosLat * ( - sinGastZA * cosDeltaCosAlphaMinusZA + cosGastZA * cosDeltaSinAlphaMinusZA );
1316
1317 /*--------------------------------------------------------------------------
1318 * Now adding approx nutation (= short-period,forced motion, by definition).
1319 * These two dominant terms, with periods 18.6 yrs (big term) and
1320 * 0.500 yrs (small term),resp., give nutation to around 1 arc sec; see
1321 * p. 120 of Explan. Supp. The forced nutation amplitude
1322 * is around 17 arcsec.
1323 *
1324 * Note the unforced motion or Chandler wobble (called ``polar motion''
1325 * in Explanatory Supp) is not included here. However its amplitude is
1326 * order of (and a somewhat less than) 1 arcsec; see plot on p. 270 of
1327 * Explanatory Supplement to Ast. Alm.
1328 *
1329 * Below correction for nutation from Eq.3.225-2 of Explan. Supp.
1330 * Basic idea is to change the (alpha,delta) of source to
1331 * compensate for Earth's time-changing spin axis.
1332 *--------------------------------------------------------------------------
1333 */
1334 REAL8 delXNut = - earth->delpsi * ( cosDelta * sinAlpha * cosEps0 + sinDelta * sinEps0 );
1335
1336 REAL8 delYNut = cosDelta * cosAlpha * cosEps0 * earth->delpsi - sinDelta * earth->deleps;
1337
1338 REAL8 delZNut = cosDelta * cosAlpha * sinEps0 * earth->delpsi + cosDelta * sinAlpha * earth->deleps;
1339
1340 REAL8 cosGastLong = cos( earth->gastRad + longitude );
1341 REAL8 sinGastLong = sin( earth->gastRad + longitude );
1342
1343 REAL8 rd_NdotDNut = rd_sinLat * delZNut + rd_cosLat * cosGastLong * delXNut + rd_cosLat * sinGastLong * delYNut;
1344
1345 emit->erot += rd_NdotDNut;
1346 emit->derot += OMEGA * ( - rd_cosLat * sinGastLong * delXNut + rd_cosLat * cosGastLong * delYNut );
1347
1348 /* Note erot has a periodic piece (P=one day) AND a constant piece,
1349 since z-component (parallel to North pole) of vector from
1350 Earth-center to detector is constant
1351 */
1352
1353 /*--------------------------------------------------------------------
1354 * Now adding Shapiro delay. Note according to J. Taylor review article
1355 * on pulsar timing, max value of Shapiro delay (when rays just graze sun)
1356 * is 120 microsec.
1357 *
1358 * Here we calculate Shapiro delay
1359 * for a detector at the center of the Earth.
1360 * Causes errors of order 10^{-4}sec * 4 * 10^{-5} = 4*10^{-9} sec
1361 *--------------------------------------------------------------------
1362 */
1363 REAL8 rsun = 2.322; /*radius of sun in sec */
1364 REAL8 seDotN = earth->se[2] * sinDelta + ( earth->se[0] * cosAlpha + earth->se[1] * sinAlpha ) * cosDelta;
1365 REAL8 dseDotN = earth->dse[2] * sinDelta + ( earth->dse[0] * cosAlpha + earth->dse[1] * sinAlpha ) * cosDelta;
1366
1367 REAL8 b = sqrt( earth->rse * earth->rse - seDotN * seDotN );
1368 REAL8 db = ( earth->rse * earth->drse - seDotN * dseDotN ) / b;
1369
1370 /* if gw travels thru interior of Sun*/
1371 if ( ( b < rsun ) && ( seDotN < 0 ) ) {
1372 emit->shapiro = 9.852e-6 * log( ( LAL_AU_SI / LAL_C_SI ) / ( seDotN + sqrt( rsun * rsun + seDotN * seDotN ) ) ) + 19.704e-6 * ( 1.0 - b / rsun );
1373 emit->dshapiro = - 19.704e-6 * db / rsun;
1374 } else { /* else the usual expression*/
1375 emit->shapiro = 9.852e-6 * log( ( LAL_AU_SI / LAL_C_SI ) / ( earth->rse + seDotN ) );
1376 emit->dshapiro = -9.852e-6 * ( earth->drse + dseDotN ) / ( earth->rse + seDotN );
1377 }
1378
1379 /*--------------------------------------------------------------------
1380 * Now correcting Roemer delay for finite distance to source.
1381 * Timing corrections are order 10 microsec
1382 * for sources closer than about 100 pc = 10^10 sec.
1383 *--------------------------------------------------------------------
1384 */
1385 REAL8 r2 = 0; /* squared dist from SSB to center of earth, in sec^2 */
1386 REAL8 dr2 = 0; /* time deriv of r2 */
1387 REAL8 finiteDistCorr, dfiniteDistCorr; /*correction to Roemer delay due to finite dist D to source; important for D < 100pc */
1388
1389 if ( baryinput->dInv > 1.0e-11 ) { /* implement if corr. > 1 microsec */
1390 for ( UINT4 j = 0; j < 3; j++ ) {
1391 r2 += earth->posNow[j] * earth->posNow[j];
1392 dr2 += 2.0 * earth->posNow[j] * earth->velNow[j];
1393 }
1394 finiteDistCorr = - 0.5 * ( r2 - emit->roemer * emit->roemer ) * baryinput->dInv;
1395 dfiniteDistCorr = - ( 0.5 * dr2 - emit->roemer * emit->droemer ) * baryinput->dInv;
1396 } else {
1397 finiteDistCorr = 0;
1398 dfiniteDistCorr = 0;
1399 }
1400
1401 /* -----------------------------------------------------------------------
1402 * Now adding it all up.
1403 * emit.te is pulse emission time in TDB coords
1404 * (up to a constant roughly equal to ligh travel time from source to SSB).
1405 * emit->deltaT = emit.te - tgps.
1406 * -----------------------------------------------------------------------
1407 */
1408 emit->deltaT = emit->roemer + emit->erot + earth->einstein - emit->shapiro + finiteDistCorr + obsTerm;
1409 emit->tDot = 1.0 + emit->droemer + emit->derot + earth->deinstein - emit->dshapiro + dfiniteDistCorr;
1410
1411 INT4 deltaTint = floor( emit->deltaT );
1412
1413 if ( ( 1e-9 * tgps[1] + emit->deltaT - deltaTint ) >= 1.e0 ) {
1414 emit->te.gpsSeconds = baryinput->tgps.gpsSeconds + deltaTint + 1;
1415 emit->te.gpsNanoSeconds = floor( 1e9 * ( tgps[1] * 1e-9 + emit->deltaT - deltaTint - 1.0 ) );
1416 } else {
1417 emit->te.gpsSeconds = baryinput->tgps.gpsSeconds + deltaTint;
1418 emit->te.gpsNanoSeconds = floor( 1e9 * ( tgps[1] * 1e-9 + emit->deltaT - deltaTint ) );
1419 }
1420
1421 for ( UINT4 j = 0; j < 3; j++ ) {
1422 emit->rDetector[j] = earth->posNow[j];
1423 emit->vDetector[j] = earth->velNow[j];
1424 }
1425
1426 /* Now adding Earth's rotation to rDetector and
1427 vDetector, but NOT yet including effects of
1428 lunisolar prec. or nutation (though DO use gast instead of gmst)
1429 For next 10 years, will give rDetector to 10 microsec and
1430 v/c to 10^-9
1431 */
1432 emit->rDetector[0] += rd_cosLat * cosGastLong;
1433 emit->vDetector[0] += - OMEGA * rd_cosLat * sinGastLong;
1434 emit->rDetector[1] += rd_cosLat * sinGastLong;
1435 emit->vDetector[1] += OMEGA * rd_cosLat * cosGastLong;
1436 emit->rDetector[2] += rd_sinLat;
1437 /*no change to emit->vDetector[2] = component along spin axis, if ignore prec. and nutation */
1438
1439 // finish buffer handling
1440 // *) if user passed a pointer to NULL, return our internal buffer
1441 if ( buffer && ( *buffer == NULL ) ) {
1442 ( *buffer ) = myBuffer;
1443 }
1444 // *) if passed NULL as 'buffer', then we destroy the internal buffer now
1445 if ( buffer == NULL ) {
1446 XLALFree( myBuffer );
1447 }
1448
1449 return XLAL_SUCCESS;
1450
1451} /* XLALBarycenterOpt() */
1452
1453/**
1454 * Function to calculate the precession matrix give Earth nutation values
1455 * depsilon and dpsi for a given MJD time.
1456 *
1457 * This function is a slightly modified version of the TEMPO2 function
1458 * get_precessionMatrix in get_ObsCoord.C (itself translated from the
1459 * TEMPO FORTRAN functions for precession and nutation).
1460 */
1461void precessionMatrix( REAL8 prn[3][3], /**< [out] The precession matrix */
1462 REAL8 mjd, /**< [in] The UT1 local mean siderial time (in MJD format) */
1463 REAL8 dpsi, /**< [in] The dpsi value for the Earth nutation */
1464 REAL8 deps ) /**< [in] The deps value for the Earth nutation */
1465{
1466 INT4 i, j;
1467
1468 /* For precession */
1469 REAL8 t, trad, zeta, z, theta;
1470 static const REAL8 par_zeta[3] = {2306.2181, 0.30188, 0.017998};
1471 static const REAL8 par_z[3] = {2306.2181, 1.09468, 0.018203};
1472 static const REAL8 par_theta[3] = {2004.3109, -0.42665, -0.041833};
1473 static const REAL8 seconds_per_rad = 3600.0 / LAL_PI_180;
1474
1475 REAL8 czeta, szeta, cz, sz, ctheta, stheta;
1476
1477 REAL8 nut[3][3], prc[3][3];
1478
1479 /* cosine and sine of the obliquity of the ecliptic */
1480 const REAL8 ceps = 0.917482062069182;
1481 const REAL8 seps = 0.397777155931914;
1482
1483 t = ( mjd - 51544.5 ) / 36525.0;
1484 trad = t / seconds_per_rad;
1485
1486 zeta = trad * ( par_zeta[0] + t * ( par_zeta[1] + t * par_zeta[2] ) );
1487 z = trad * ( par_z[0] + t * ( par_z[1] + t * par_z[2] ) );
1488 theta = trad * ( par_theta[0] + t * ( par_theta[1] + t * par_theta[2] ) );
1489
1490 czeta = cos( zeta );
1491 szeta = sin( zeta );
1492 cz = cos( z );
1493 sz = sin( z );
1494 ctheta = cos( theta );
1495 stheta = sin( theta );
1496
1497 prc[0][0] = czeta * ctheta * cz - szeta * sz;
1498 prc[1][0] = czeta * ctheta * sz + szeta * cz;
1499 prc[2][0] = czeta * stheta;
1500 prc[0][1] = -szeta * ctheta * cz - czeta * sz;
1501 prc[1][1] = -szeta * ctheta * sz + czeta * cz;
1502 prc[2][1] = -szeta * stheta;
1503 prc[0][2] = -stheta * cz;
1504 prc[1][2] = -stheta * sz;
1505 prc[2][2] = ctheta;
1506
1507 nut[0][0] = 1.0;
1508 nut[0][1] = -dpsi * ceps;
1509 nut[0][2] = -dpsi * seps;
1510 nut[1][0] = -nut[0][1];
1511 nut[1][1] = 1.0;
1512 nut[1][2] = -deps;
1513 nut[2][0] = -nut[0][2];
1514 nut[2][1] = -nut[1][2];
1515 nut[2][2] = 1.0;
1516
1517 for ( i = 0; i < 3; i++ )
1518 for ( j = 0; j < 3; j++ ) {
1519 prn[j][i] = nut[i][0] * prc[0][j] + nut[i][1] * prc[1][j] + nut[i][2] * prc[2][j];
1520 }
1521}
1522
1523/**
1524 * Function to get the observatory site location with respect to the
1525 * centre of the Earth, taking into account precession and nutation.
1526 * This is based on the routines in the TEMPO2 get_ObsCoord.C code
1527 */
1528void observatoryEarth( REAL8 obsEarth[3], /**< [out] The x, y, z coordinates of the observatory from the centre of the Earth */
1529 const LALDetector det, /**< [in] The LAL detector site */
1530 const LIGOTimeGPS *tgps, /**< [in] The GPS time at the detector */
1531 REAL8 gmst, /**< [in] The Greenwich Mean Sidereal Time */
1532 REAL8 dpsi, /**< [in] dpsi for Earth nutation */
1533 REAL8 deps /**< [in] deps for Earth nutation */
1534 )
1535{
1536 static REAL8 erad; /* observatory distance from Earth centre */
1537 static REAL8 hlt; /* observatory latitude */
1538 static REAL8 alng; /* observatory longitude */
1539 REAL8 tmjd = 44244. + ( XLALGPSGetREAL8( tgps ) + 51.184 ) / 86400.;
1540
1541 INT4 j = 0;
1542
1543 /* note that det.location is in light-seconds */
1544 erad = sqrt( det.location[0] * det.location[0]
1545 + det.location[1] * det.location[1]
1546 + det.location[2] * det.location[2] );
1547 if ( erad == 0.0 ) {
1548 hlt = LAL_PI_2;
1549 } else {
1550 hlt = asin( det.location[2] / erad );
1551 }
1552
1553 alng = atan2( -det.location[1], det.location[0] );
1554
1555 static REAL8 siteCoord[3];
1556 REAL8 eeq[3], prn[3][3];
1557
1558 siteCoord[0] = erad * cos( hlt );
1559 siteCoord[1] = siteCoord[0] * tan( hlt );
1560 siteCoord[2] = alng;
1561
1562 /* PC,PS equatorial and meridional components of nutations of longitude */
1563 REAL8 toblq = ( tmjd - 5.15445e4 ) / 36525.0;
1564 REAL8 oblq = ( ( ( 1.813e-3 * toblq - 5.9e-4 ) * toblq - 4.6815e1 ) * toblq + 84381.448 ) * LAL_PI_180 / 3600.0;
1565
1566 REAL8 pc = cos( oblq + deps ) * dpsi;
1567
1568 /* Compute the local, true sidereal time */
1569 REAL8 ph = gmst + pc - siteCoord[2];
1570
1571 /* Get X-Y-Z coordinates taking out earth rotation */
1572 eeq[0] = siteCoord[0] * cos( ph );
1573 eeq[1] = siteCoord[0] * sin( ph );
1574 eeq[2] = siteCoord[1];
1575
1576 /* Now obtain PRN -- the precession matrix */
1577 precessionMatrix( prn, tmjd, dpsi, deps );
1578 /* Calculate the position after precession/nutation*/
1579 for ( j = 0; j < 3 ; j++ ) {
1580 obsEarth[j] = prn[j][0] * eeq[0] + prn[j][1] * eeq[1] + prn[j][2] * eeq[2];
1581 }
1582}
1583
1584/// @}
#define __func__
log an I/O error, i.e.
REAL8 zeta
#define OBLQ
Definition: LALBarycenter.c:24
int j
static double double delta
OMEGA
ParConversion pc[NUM_PARS]
Initialise conversion structure with most allowed TEMPO2 parameter names and conversion functions (co...
double e
double theta
const double sz
const double r2
#define IFTE_MJD0
Epoch of TCB, TCG and TT in Modified Julian Days.
int XLALBarycenterOpt(EmissionTime *emit, const BarycenterInput *baryinput, const EarthState *earth, BarycenterBuffer **buffer)
Speed optimized version of XLALBarycenter(), should be fully equivalent except for the additional buf...
static void observatoryEarth(REAL8 obsearth[3], const LALDetector det, const LIGOTimeGPS *tgps, REAL8 gmst, REAL8 dpsi, REAL8 deps)
Function to get the observatory site location with respect to the centre of the Earth,...
int XLALBarycenterEarth(EarthState *earth, const LIGOTimeGPS *tGPS, const EphemerisData *edat)
Computes the position and orientation of the Earth, at some arrival time , specified LIGOTimeGPS inp...
Definition: LALBarycenter.c:78
int XLALBarycenter(EmissionTime *emit, const BarycenterInput *baryinput, const EarthState *earth)
Transforms from detector arrival time in GPS (as specified in the LIGOTimeGPS structure) to pulse em...
#define IFTE_LC
Equation 20 of Irwin and Fukushima.
int XLALBarycenterEarthNew(EarthState *earth, const LIGOTimeGPS *tGPS, const EphemerisData *edat, const TimeCorrectionData *tdat, TimeCorrectionType ttype)
Computes the position and orientation of the Earth, at some arrival time, but unlike XLALBarycenterEa...
TimeCorrectionType
Enumerated type denoting the time system type to be produced in the solar system barycentring routine...
Definition: LALBarycenter.h:72
static void precessionMatrix(REAL8 prn[3][3], REAL8 mjd, REAL8 dpsi, REAL8 deps)
Function to calculate the precession matrix give Earth nutation values depsilon and dpsi for a given ...
@ TIMECORRECTION_TEMPO2
Definition: LALBarycenter.h:77
@ TIMECORRECTION_ORIGINAL
Definition: LALBarycenter.h:78
@ TIMECORRECTION_TCB
Definition: LALBarycenter.h:75
@ TIMECORRECTION_TDB
Definition: LALBarycenter.h:74
@ TIMECORRECTION_TEMPO
Definition: LALBarycenter.h:76
#define LAL_PI_2
#define LAL_PI_180
#define LAL_PI
#define LAL_TWOPI
unsigned char BOOLEAN
double REAL8
int16_t INT2
uint32_t UINT4
int32_t INT4
void * XLALCalloc(size_t m, size_t n)
void XLALFree(void *p)
int XLALGPSLeapSeconds(INT4 gpssec)
#define xlalErrno
#define XLAL_ERROR(...)
#define XLAL_CHECK(assertion,...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_ENOMEM
XLAL_SUCCESS
XLAL_EDOM
XLAL_EINVAL
REAL8 XLALGPSGetREAL8(const LIGOTimeGPS *epoch)
pos
n
double alpha
Basic input structure to LALBarycenter.c.
REAL8 alpha
Source right ascension in ICRS J2000 coords (radians).
REAL8 dInv
1/(distance to source), in 1/sec.
LIGOTimeGPS tgps
input GPS arrival time.
REAL8 delta
Source declination in ICRS J2000 coords (radians)
LALDetector site
detector site info.
Basic output structure of LALBarycenterEarth.c.
REAL8 velNow[3]
dimensionless velocity of Earth's center at tgps, extrapolated from JPL DE405 ephemeris
TimeCorrectionType ttype
Time correction type.
REAL8 drse
d(rse)/d(tgps); dimensionless
REAL8 rse
length of vector se[3]; units = sec
REAL8 delpsi
variable describing effect of Earth nutation, at tgps
REAL8 einstein
the einstein delay equiv TDB - TDT or TCB - TDT
REAL8 gmstRad
Greenwich Mean Sidereal Time (GMST) in radians, at tgps.
REAL8 zA
variable describing effect of lunisolar precession, at tgps
REAL8 se[3]
vector that points from Sun to Earth at instant tgps, in DE405 coords; units = sec
REAL8 posNow[3]
Cartesian coords of Earth's center at tgps, extrapolated from JPL DE405 ephemeris; units= sec.
REAL8 tzeA
variable describing effect of lunisolar precession, at tgps
REAL8 gastRad
Greenwich Apparent Sidereal Time, in radians, at tgps; Is basically the angle thru which Earth has sp...
REAL8 dse[3]
d(se[3])/d(tgps); Dimensionless
REAL8 deinstein
d(einstein)/d(tgps)
REAL8 thetaA
variable describing effect of lunisolar precession, at tgps
REAL8 deleps
variable describing effect of Earth nutation, at tgps
Basic output structure produced by LALBarycenter.c.
REAL8 derot
d(erot)/d(tgps)
REAL8 deltaT
(TDB) - (GPS)
REAL8 roemer
the Roemer delay
REAL8 dshapiro
d(Shapiro)/d(tgps)
REAL8 rDetector[3]
Cartesian coords (0=x,1=y,2=z) of detector position at $t_a$ (GPS), in ICRS J2000 coords.
REAL8 shapiro
the Shapiro delay
REAL8 erot
Earth rotation delay.
LIGOTimeGPS te
pulse emission time (TDB); also sometimes called `‘arrival time (TDB) of same wavefront at SSB’'
REAL8 tDot
d(emission time in TDB)/d(arrival time in GPS)
REAL8 vDetector[3]
REAL8 droemer
d(Roemer)/d(tgps)
This structure contains all information about the center-of-mass positions of the Earth and Sun,...
REAL8 location[3]
INT4 gpsNanoSeconds
This structure will contain a vector of time corrections used during conversion from TT to TDB/TCB/Te...
REAL8 latitude
geocentric (not geodetic!!) longitude of detector vertex
Definition: LALBarycenter.c:38
REAL8 sinLat
geocentric latitude of detector vertex
Definition: LALBarycenter.c:39
REAL8 rd_cosLat
rd * sin(latitude)
Definition: LALBarycenter.c:42
REAL8 rd_sinLat
cos(latitude);
Definition: LALBarycenter.c:41
REAL8 cosLat
sin(latitude)
Definition: LALBarycenter.c:40
REAL8 longitude
distance 'rd' from center of Earth, in light seconds
Definition: LALBarycenter.c:37
-------— internal buffer type for optimized Barycentering function -------—
Definition: LALBarycenter.c:27
REAL8 sinAlpha
Definition: LALBarycenter.c:28
REAL8 cosDelta
sin(delta)
Definition: LALBarycenter.c:31
REAL8 cosAlpha
sin(alpha)
Definition: LALBarycenter.c:29
REAL8 sinDelta
cos(alpha)
Definition: LALBarycenter.c:30
internal (opaque) buffer type for optimized Barycentering function
Definition: LALBarycenter.c:45
fixed_site_t fixed_site
buffered detector site
Definition: LALBarycenter.c:51
REAL8 delta
buffered sky-location: right-ascension in rad
Definition: LALBarycenter.c:47
fixed_sky_t fixed_sky
buffered sky-location: declination in rad
Definition: LALBarycenter.c:48
BOOLEAN active
fixed-site buffered quantities
Definition: LALBarycenter.c:53
LALDetector site
fixed-sky buffered quantities
Definition: LALBarycenter.c:50
double deltaT