00001 /* 00002 * Copyright (C) 2007 Jolien Creighton, Reinhard Prix, Teviet Creighton, John Whelan 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with with program; see the file COPYING. If not, write to the 00016 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 00017 * MA 02111-1307 USA 00018 */ 00019 00020 /** \file 00021 * \ingroup SkyCoordinates 00022 * \author Creighton, T. D. 00023 * \date $Date: 2007/06/08 14:41:47 $ 00024 * \brief Converts among Galactic, ecliptic, and equatorial coordinates. 00025 * 00026 * $Id: CelestialCoordinates.c,v 1.9 2007/06/08 14:41:47 bema Exp $ 00027 * 00028 These functions perform the specified coordinate transformation on the 00029 contents of \a input and store the result in \a *output. The 00030 two pointers may point to the same object, in which case the 00031 conversion is done in place. The functions will also check 00032 <tt>input->system</tt> and set <tt>output->system</tt> as appropriate. 00033 00034 These routines are collected together because they involve fixed, 00035 absolute coordinate systems, so the transformations require no 00036 additional parameters such as the time or site of observation. We 00037 also note that there are no direct conversions between Galactic and 00038 ecliptic coordinates. At the risk of additional computational 00039 overhead, it is simple to use the equatorial coordinate system as an 00040 intermediate step. 00041 00042 \par Description 00043 00044 These functions perform the specified coordinate transformation on the 00045 contents of \a input and store the result in \a output. The 00046 two pointers may point to the same object, in which case the 00047 conversion is done in place. The functions will also check 00048 <tt>input->system</tt> and set <tt>output->system</tt> as appropriate. 00049 00050 These routines are collected together because they involve fixed, 00051 absolute coordinate systems, so the transformations require no 00052 additional parameters such as the time or site of observation. We 00053 also note that there are no direct conversions between Galactic and 00054 ecliptic coordinates. At the risk of additional computational 00055 overhead, it is simple to use the equatorial coordinate system as an 00056 intermediate step. 00057 00058 \par Algorithm 00059 00060 These routines follow the spherical angle relations on p. 13 00061 of \ref Lang_K1999. Note that the actual formulae for Galactic 00062 longitude and right ascension in this reference are wrong; we give 00063 corrected formulae below derived from the sine and cosine equations. 00064 (The Galactic to equatorial transformations can also be found in 00065 Sec. 12.3 of \ref GRASP2000. All positions are assumed to 00066 be in the J2000 epoch. 00067 00068 00069 <b>Galactic coordinates:</b> The following formulae relate 00070 Galactic latitude \f$b\f$ and longitude \f$l\f$ to declination \f$\delta\f$ and 00071 right ascension \f$\alpha\f$: 00072 \f{eqnarray} 00073 \label{eq:b-galactic} 00074 b & = & \arcsin[\cos\delta\cos\delta_\mathrm{NGP} 00075 \cos(\alpha-\alpha_\mathrm{NGP}) + 00076 \sin\delta\sin\delta_\mathrm{NGP}] \;,\\ 00077 l & = & \arctan\!2[\sin\delta\cos\delta_\mathrm{NGP} - 00078 \cos\delta\cos(\alpha-\alpha_\mathrm{NGP}) 00079 \sin\delta_\mathrm{NGP}, 00080 \cos\delta\sin(\alpha-\alpha_\mathrm{NGP})] \nonumber\\ 00081 \label{eq:l-galactic} 00082 & & \quad + \; l_\mathrm{ascend} \;, 00083 \f} 00084 where \f$\arctan\!2(y,x)\f$ can be thought of as the argument of the 00085 complex number \f$x+iy\f$; unlike \f$\arctan(y/x)\f$, it ranges over the full 00086 range \f$[0,2\pi)\f$ instead of just half of it. The inverse 00087 transformations are: 00088 \f{eqnarray} 00089 \label{eq:delta-galactic} 00090 \delta & = & \arcsin[\cos b\cos\delta_\mathrm{NGP}\sin(l-l_\mathrm{ascend}) + 00091 \sin b\sin\delta_\mathrm{NGP}] \;,\\ 00092 \alpha & = & \arctan\!2[\cos b\cos(l-l_\mathrm{ascend}), 00093 \sin b\cos\delta_\mathrm{NGP} - 00094 \cos b\sin(l-l_\mathrm{ascend})\sin\delta_\mathrm{NGP}] 00095 \nonumber\\ 00096 \label{eq:alpha-galactic} 00097 & & \quad + \; \alpha_\mathrm{NGP} \;. 00098 \f} 00099 In these equations we have defined the orientation of the Galaxy with 00100 the following parameters (which should eventually be placed in <tt>LALConstants.h</tt>: 00101 \f[ 00102 \begin{array}{r@{\quad=\quad}l@{\quad=\quad}l} 00103 \alpha_\mathrm{NGP} & 192.8594813^\circ & 00104 \mbox{the right ascension (epoch J2000) of the north Galactic pole} \\ 00105 \delta_\mathrm{NGP} & 27.1282511^\circ & 00106 \mbox{the declination (epoch J2000) of the north Galactic pole} \\ 00107 l_\mathrm{ascend} & 33^\circ & 00108 \mbox{the longitude of the ascending node of the Galactic plane} 00109 \end{array} 00110 \f] 00111 The ascending node of the Galactic plane is defined as the direction 00112 along the intersection of the Galactic and equatorial planes where 00113 rotation in the positive sense about the Galactic \f$z\f$ axis carries a 00114 point from the southern to northern equatorial hemisphere. That is, 00115 if \f$\mathbf{u}\f$ points in the direction \f$\delta=90^\circ\f$ 00116 (celestial north), and \f$\mathbf{v}\f$ points in the direction 00117 \f$b=90^\circ\f$ (Galactic north), then 00118 \f$\mathbf{u} \times \mathbf{v}\f$ points along the ascending node. 00119 00120 <b>Ecliptic coordinates:</b> The following formulae relate 00121 Ecliptic latitude \f$\beta\f$ and longitude \f$\lambda\f$ to declination 00122 \f$\delta\f$ and right ascension \f$\alpha\f$: 00123 \f{eqnarray} 00124 \label{eq:beta-ecliptic} 00125 \beta & = & \arcsin(\sin\delta\cos\epsilon - 00126 \cos\delta\sin\alpha\sin\epsilon) \;, \\ 00127 \label{eq:l-ecliptic} 00128 \lambda & = & \arctan\!2(\cos\delta\sin\alpha\cos\epsilon + 00129 \sin\delta\sin\epsilon, \cos\delta\cos\alpha) \;. 00130 \f} 00131 The inverse transformations are: 00132 \f{eqnarray} 00133 \label{eq:delta-ecliptic} 00134 \delta & = & \arcsin(\cos\beta\sin\lambda\sin\epsilon + 00135 \sin\beta\cos\epsilon) \;, \\ 00136 \label{eq:alpha-ecliptic} 00137 \alpha & = & \arctan\!2(\cos\beta\sin\lambda\cos\epsilon - 00138 \sin\beta\sin\epsilon, \cos\beta\cos\lambda) \;. 00139 \f} 00140 Here \f$\epsilon\f$ is the obliquity (inclination) of the ecliptic plane, 00141 which varies over time; at epoch J200 it has a mean value of: 00142 \f[ 00143 \epsilon = 23.4392911^\circ \; . 00144 \f] 00145 00146 */ 00147 00148 #include <math.h> 00149 #include <lal/LALStdlib.h> 00150 #include <lal/LALConstants.h> 00151 #include <lal/SkyCoordinates.h> 00152 00153 #define LAL_ALPHAGAL (3.366032942) 00154 #define LAL_DELTAGAL (0.473477302) 00155 #define LAL_LGAL (0.576) 00156 00157 NRCSID( CELESTIALCOORDINATESC, "$Id: CelestialCoordinates.c,v 1.9 2007/06/08 14:41:47 bema Exp $" ); 00158 00159 void 00160 LALGalacticToEquatorial( LALStatus *stat, 00161 SkyPosition *output, 00162 SkyPosition *input ) 00163 { 00164 REAL8 sinDGal = sin( LAL_DELTAGAL ); /* sin(delta_NGP) */ 00165 REAL8 cosDGal = cos( LAL_DELTAGAL ); /* cos(delta_NGP) */ 00166 REAL8 l = -LAL_LGAL; /* will be l-l(ascend) */ 00167 REAL8 sinB, cosB, sinL, cosL; /* sin and cos of b and l */ 00168 REAL8 sinD, sinA, cosA; /* sin and cos of delta and alpha */ 00169 00170 INITSTATUS( stat, "LALGalacticToEquatorial", CELESTIALCOORDINATESC ); 00171 00172 /* Make sure parameter structures exist. */ 00173 ASSERT( input, stat, SKYCOORDINATESH_ENUL, SKYCOORDINATESH_MSGENUL ); 00174 ASSERT( output, stat, SKYCOORDINATESH_ENUL, SKYCOORDINATESH_MSGENUL ); 00175 00176 /* Make sure we're given the right coordinate system. */ 00177 if ( input->system != COORDINATESYSTEM_GALACTIC ) { 00178 ABORT( stat, SKYCOORDINATESH_ESYS, SKYCOORDINATESH_MSGESYS ); 00179 } 00180 00181 /* Compute intermediates. */ 00182 l += input->longitude; 00183 sinB = sin( input->latitude ); 00184 cosB = cos( input->latitude ); 00185 sinL = sin( l ); 00186 cosL = cos( l ); 00187 00188 /* Compute components. */ 00189 sinD = cosB*cosDGal*sinL + sinB*sinDGal; 00190 sinA = cosB*cosL; 00191 cosA = sinB*cosDGal - cosB*sinL*sinDGal; 00192 00193 /* Compute final results. */ 00194 output->system = COORDINATESYSTEM_EQUATORIAL; 00195 output->latitude = asin( sinD ); 00196 l = atan2( sinA, cosA ) + LAL_ALPHAGAL; 00197 00198 /* Optional phase correction. */ 00199 if ( l < 0.0 ) 00200 l += LAL_TWOPI; 00201 output->longitude = l; 00202 00203 RETURN( stat ); 00204 } 00205 00206 00207 void 00208 LALEquatorialToGalactic( LALStatus *stat, 00209 SkyPosition *output, 00210 SkyPosition *input ) 00211 { 00212 REAL8 sinDGal = sin( LAL_DELTAGAL ); /* sin(delta_NGP) */ 00213 REAL8 cosDGal = cos( LAL_DELTAGAL ); /* cos(delta_NGP) */ 00214 REAL8 a = -LAL_ALPHAGAL; /* will be alpha-alpha_NGP */ 00215 REAL8 sinD, cosD, sinA, cosA; /* sin and cos of delta and alpha */ 00216 REAL8 sinB, sinL, cosL; /* sin and cos of b and l */ 00217 00218 INITSTATUS( stat, "LALGalacticToEquatorial", CELESTIALCOORDINATESC ); 00219 00220 /* Make sure parameter structures exist. */ 00221 ASSERT( input, stat, SKYCOORDINATESH_ENUL, SKYCOORDINATESH_MSGENUL ); 00222 ASSERT( output, stat, SKYCOORDINATESH_ENUL, SKYCOORDINATESH_MSGENUL ); 00223 00224 /* Make sure we're given the right coordinate system. */ 00225 if ( input->system != COORDINATESYSTEM_EQUATORIAL ) { 00226 ABORT( stat, SKYCOORDINATESH_ESYS, SKYCOORDINATESH_MSGESYS ); 00227 } 00228 00229 /* Compute intermediates. */ 00230 a += input->longitude; 00231 sinD = sin( input->latitude ); 00232 cosD = cos( input->latitude ); 00233 sinA = sin( a ); 00234 cosA = cos( a ); 00235 00236 /* Compute components. */ 00237 sinB = cosD*cosDGal*cosA + sinD*sinDGal; 00238 sinL = sinD*cosDGal - cosD*cosA*sinDGal; 00239 cosL = cosD*sinA; 00240 00241 /* Compute final results. */ 00242 output->system = COORDINATESYSTEM_GALACTIC; 00243 output->latitude = asin( sinB ); 00244 a = atan2( sinL, cosL ) + LAL_LGAL; 00245 00246 /* Optional phase correction. */ 00247 if ( a < 0.0 ) 00248 a += LAL_TWOPI; 00249 output->longitude = a; 00250 00251 RETURN( stat ); 00252 } 00253 00254 00255 void 00256 LALEclipticToEquatorial( LALStatus *stat, 00257 SkyPosition *output, 00258 SkyPosition *input ) 00259 { 00260 REAL8 sinE = sin( LAL_IEARTH ); /* sin(epsilon) */ 00261 REAL8 cosE = cos( LAL_IEARTH ); /* cos(epsilon) */ 00262 REAL8 sinB, cosB, sinL, cosL; /* sin and cos of b and l */ 00263 REAL8 sinD, sinA, cosA; /* sin and cos of delta and alpha */ 00264 00265 INITSTATUS( stat, "LALGalacticToEquatorial", CELESTIALCOORDINATESC ); 00266 00267 /* Make sure parameter structures exist. */ 00268 ASSERT( input, stat, SKYCOORDINATESH_ENUL, SKYCOORDINATESH_MSGENUL ); 00269 ASSERT( output, stat, SKYCOORDINATESH_ENUL, SKYCOORDINATESH_MSGENUL ); 00270 00271 /* Make sure we're given the right coordinate system. */ 00272 if ( input->system != COORDINATESYSTEM_ECLIPTIC ) { 00273 ABORT( stat, SKYCOORDINATESH_ESYS, SKYCOORDINATESH_MSGESYS ); 00274 } 00275 00276 /* Compute intermediates. */ 00277 sinB = sin( input->latitude ); 00278 cosB = cos( input->latitude ); 00279 sinL = sin( input->longitude ); 00280 cosL = cos( input->longitude ); 00281 00282 /* Compute components. */ 00283 sinD = cosB*sinL*sinE + sinB*cosE; 00284 sinA = cosB*sinL*cosE - sinB*sinE; 00285 cosA = cosB*cosL; 00286 00287 /* Compute final results. */ 00288 output->system = COORDINATESYSTEM_EQUATORIAL; 00289 output->latitude = asin( sinD ); 00290 output->longitude = atan2( sinA, cosA ); 00291 00292 /* Optional phase correction. */ 00293 if ( output->longitude < 0.0 ) 00294 output->longitude += LAL_TWOPI; 00295 00296 RETURN( stat ); 00297 } 00298 00299 00300 void 00301 LALEquatorialToEcliptic( LALStatus *stat, 00302 SkyPosition *output, 00303 SkyPosition *input ) 00304 { 00305 REAL8 sinE = sin( LAL_IEARTH ); /* sin(epsilon) */ 00306 REAL8 cosE = cos( LAL_IEARTH ); /* cos(epsilon) */ 00307 REAL8 sinD, cosD, sinA, cosA; /* sin and cos of delta and alpha */ 00308 REAL8 sinB, sinL, cosL; /* sin and cos of b and l */ 00309 00310 INITSTATUS( stat, "LALGalacticToEquatorial", CELESTIALCOORDINATESC ); 00311 00312 /* Make sure parameter structures exist. */ 00313 ASSERT( input, stat, SKYCOORDINATESH_ENUL, SKYCOORDINATESH_MSGENUL ); 00314 ASSERT( output, stat, SKYCOORDINATESH_ENUL, SKYCOORDINATESH_MSGENUL ); 00315 00316 /* Make sure we're given the right coordinate system. */ 00317 if ( input->system != COORDINATESYSTEM_EQUATORIAL ) { 00318 ABORT( stat, SKYCOORDINATESH_ESYS, SKYCOORDINATESH_MSGESYS ); 00319 } 00320 00321 /* Compute intermediates. */ 00322 sinD = sin( input->latitude ); 00323 cosD = cos( input->latitude ); 00324 sinA = sin( input->longitude ); 00325 cosA = cos( input->longitude ); 00326 00327 /* Compute components. */ 00328 sinB = sinD*cosE - cosD*sinA*sinE; 00329 sinL = cosD*sinA*cosE + sinD*sinE; 00330 cosL = cosD*cosA; 00331 00332 /* Compute final results. */ 00333 output->system = COORDINATESYSTEM_ECLIPTIC; 00334 output->latitude = asin( sinB ); 00335 output->longitude = atan2( sinL, cosL ); 00336 00337 /* Optional phase correction. */ 00338 if ( output->longitude < 0.0 ) 00339 output->longitude += LAL_TWOPI; 00340 00341 RETURN( stat ); 00342 }
1.5.2