CelestialCoordinates.c

Go to the documentation of this file.
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 }

Generated on Fri Sep 5 03:06:34 2008 for LAL by  doxygen 1.5.2