Loading [MathJax]/extensions/TeX/AMSsymbols.js
LAL 7.7.0.1-3a66518
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
XLALSiderealTime.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2007 Jolien Creighton, and Kipp Cannon
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
12 * Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19#include <math.h>
20#include <lal/Date.h>
21#include <lal/XLALError.h>
22
23/**
24 * \defgroup XLALSideralTime_c SideralTime
25 * \ingroup Date_h
26 * \author Creighton, J., and Cannon, K.
27 * \brief XLAL routines for computing the sidereal time.
28 *
29 * ### Synopsis ###
30 *
31 * \code
32 * #include <lal/Date.h>
33 * \endcode
34 */
35
36/** @{ */
37
38/**
39 * Returns the Greenwich Sidereal Time IN RADIANS corresponding to a
40 * specified GPS time. Aparent sidereal time is computed by providing the
41 * equation of equinoxes in units of seconds. For mean sidereal time, set
42 * this parameter to 0.
43 *
44 * This function returns the sidereal time in radians measured from the
45 * Julian epoch (current J2000). The result is NOT modulo 2 pi.
46 *
47 * Inspired by the function sidereal_time() in the NOVAS-C library, version
48 * 2.0.1, which is dated December 10th, 1999, and carries the following
49 * references:
50 *
51 * Aoki, et al. (1982) Astronomy and Astrophysics 105, 359-361.
52 * Kaplan, G. H. "NOVAS: Naval Observatory Vector Astrometry
53 * Subroutines"; USNO internal document dated 20 Oct 1988;
54 * revised 15 Mar 1990.
55 *
56 * See http://aa.usno.navy.mil/software/novas for more information.
57 *
58 * Note: rather than maintaining this code separately, it would be a good
59 * idea for LAL to simply link to the NOVAS-C library directly. Something
60 * to do when we have some spare time.
61 */
63 const LIGOTimeGPS *gpstime,
64 REAL8 equation_of_equinoxes
65)
66{
67 struct tm utc;
68 double julian_day;
69 double t_hi, t_lo;
70 double t;
71 double sidereal_time;
72
73 /*
74 * Convert GPS seconds to UTC. This is where we pick up knowledge
75 * of leap seconds which are required for the mapping of atomic
76 * time scales to celestial time scales. We deal only with integer
77 * seconds.
78 */
79
80 if(!XLALGPSToUTC(&utc, gpstime->gpsSeconds))
82
83 /*
84 * And now to Julian day number. Again, only accurate to integer
85 * seconds.
86 */
87
88 julian_day = XLALConvertCivilTimeToJD(&utc);
89 if(XLAL_IS_REAL8_FAIL_NAN(julian_day))
91
92 /*
93 * Convert Julian day number to the number of centuries since the
94 * Julian epoch (1 century = 36525.0 days). Here, we incorporate
95 * the fractional part of the seconds. For precision, we keep
96 * track of the most significant and least significant parts of the
97 * time separately. The original code in NOVAS-C determined t_hi
98 * and t_lo from Julian days, with t_hi receiving the integer part
99 * and t_lo the fractional part. Because LAL's Julian day routine
100 * is accurate to the second, here the hi/lo split is most
101 * naturally done at the integer seconds boundary. Note that the
102 * "hi" and "lo" components have the same units and so the split
103 * can be done anywhere.
104 */
105
106 t_hi = (julian_day - XLAL_EPOCH_J2000_0_JD) / 36525.0;
107 t_lo = gpstime->gpsNanoSeconds / (1e9 * 36525.0 * 86400.0);
108
109 /*
110 * Compute sidereal time in sidereal seconds. (magic)
111 */
112
113 t = t_hi + t_lo;
114
115 sidereal_time = equation_of_equinoxes + (-6.2e-6 * t + 0.093104) * t * t + 67310.54841;
116 sidereal_time += 8640184.812866 * t_lo;
117 sidereal_time += 3155760000.0 * t_lo;
118 sidereal_time += 8640184.812866 * t_hi;
119 sidereal_time += 3155760000.0 * t_hi;
120
121 /*
122 * Return radians (2 pi radians in 1 sidereal day = 86400 sidereal
123 * seconds).
124 */
125
126 return sidereal_time * LAL_PI / 43200.0;
127}
128
129
130/**
131 * Convenience wrapper, calling XLALGreenwichSiderealTime() with the
132 * equation of equinoxes set to 0.
133 */
135 const LIGOTimeGPS *gpstime
136)
137{
138 return XLALGreenwichSiderealTime(gpstime, 0.0);
139}
140
141
142/**
143 * Inverse of XLALGreenwichMeanSiderealTime(). The input is sidereal time
144 * in radians since the Julian epoch (currently J2000 for LAL), and the
145 * output is the corresponding GPS time. The algorithm uses a naive
146 * iterative root-finder, so it's slow.
147 */
149 REAL8 gmst,
150 LIGOTimeGPS *gps
151)
152{
153 const double gps_seconds_per_sidereal_radian = 13713.44; /* approx */
154 const double precision = 1e-14;
155 int iterations = 10;
156 double error;
157
158 XLALGPSSet(gps, 0, 0);
159
160 do {
162 if(fabs(error / gmst) <= precision)
163 return gps;
164 XLALGPSAdd(gps, error * gps_seconds_per_sidereal_radian);
165 } while(--iterations);
167}
168
169
170/**
171 * Convenience wrapper of XLALGreenwichMeanSiderealTimeToGPS(), adjusting
172 * the input by the equation of equinoxes.
173 */
175 REAL8 gmst,
176 REAL8 equation_of_equinoxes,
177 LIGOTimeGPS *gps
178)
179{
180 return XLALGreenwichMeanSiderealTimeToGPS(gmst - equation_of_equinoxes, gps);
181}
182
183/** @} */
static REAL8TimeSeries * error(const REAL8TimeSeries *s1, const REAL8TimeSeries *s0)
#define XLAL_EPOCH_J2000_0_JD
Julian Day (UTC) of the J2000.0 epoch (2000 JAN 1 12h UTC).
Definition: Date.h:84
#define LAL_PI
Archimedes's constant, pi.
Definition: LALConstants.h:179
double REAL8
Double precision real floating-point number (8 bytes).
REAL8 XLALConvertCivilTimeToJD(const struct tm *civil)
Returns the Julian Day (JD) corresponding to the civil date and time given in a broken down time stru...
struct tm * XLALGPSToUTC(struct tm *utc, INT4 gpssec)
Returns a pointer to a tm structure representing the time specified in seconds since the GPS epoch.
#define XLAL_ERROR_REAL8(...)
Macro to invoke a failure from a XLAL routine returning a REAL8.
Definition: XLALError.h:752
#define XLAL_ERROR_NULL(...)
Macro to invoke a failure from a XLAL routine returning a pointer.
Definition: XLALError.h:713
#define XLAL_IS_REAL8_FAIL_NAN(val)
Tests if val is a XLAL REAL8 failure NaN.
Definition: XLALError.h:393
@ XLAL_EFUNC
Internal function call failed bit: "or" this with existing error number.
Definition: XLALError.h:462
@ XLAL_EMAXITER
Exceeded maximum number of iterations.
Definition: XLALError.h:455
REAL8 XLALGreenwichSiderealTime(const LIGOTimeGPS *gpstime, REAL8 equation_of_equinoxes)
Returns the Greenwich Sidereal Time IN RADIANS corresponding to a specified GPS time.
LIGOTimeGPS * XLALGreenwichSiderealTimeToGPS(REAL8 gmst, REAL8 equation_of_equinoxes, LIGOTimeGPS *gps)
Convenience wrapper of XLALGreenwichMeanSiderealTimeToGPS(), adjusting the input by the equation of e...
REAL8 XLALGreenwichMeanSiderealTime(const LIGOTimeGPS *gpstime)
Convenience wrapper, calling XLALGreenwichSiderealTime() with the equation of equinoxes set to 0.
LIGOTimeGPS * XLALGreenwichMeanSiderealTimeToGPS(REAL8 gmst, LIGOTimeGPS *gps)
Inverse of XLALGreenwichMeanSiderealTime().
LIGOTimeGPS * XLALGPSSet(LIGOTimeGPS *epoch, INT4 gpssec, INT8 gpsnan)
Sets GPS time given GPS integer seconds and residual nanoseconds.
Definition: XLALTime.c:63
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
Adds a double to a GPS time.
Definition: XLALTime.c:131
Epoch relative to GPS epoch, see LIGOTimeGPS type for more details.
Definition: LALDatatypes.h:458
INT4 gpsSeconds
Seconds since 0h UTC 6 Jan 1980.
Definition: LALDatatypes.h:459
INT4 gpsNanoSeconds
Residual nanoseconds.
Definition: LALDatatypes.h:460