mirror of
https://github.com/cosinekitty/astronomy.git
synced 2026-01-03 13:10:43 -05:00
I'm taking gcc 12.2 for a test drive today. It reports a few warnings that slipped through earlier versions. None of the warnings concern me for actual code safety, but I went ahead and resolved them to keep the build clean. Also provide a hook for a CPP environment variable to override the C++ compiler to use, instead of forcing g++.
10199 lines
258 KiB
C
10199 lines
258 KiB
C
/*
|
|
Naval Observatory Vector Astrometry Software (NOVAS)
|
|
C Edition, Version 3.1
|
|
|
|
novas.c: Main library
|
|
|
|
U. S. Naval Observatory
|
|
Astronomical Applications Dept.
|
|
Washington, DC
|
|
http://www.usno.navy.mil/USNO/astronomical-applications
|
|
*/
|
|
|
|
#ifndef _NOVAS_
|
|
#include "novas.h"
|
|
#endif
|
|
|
|
#include <math.h>
|
|
|
|
/*
|
|
Global variables.
|
|
|
|
'PSI_COR' and 'EPS_COR' are celestial pole offsets for high-
|
|
precision applications. See function 'cel_pole' for more details.
|
|
*/
|
|
|
|
static double PSI_COR = 0.0;
|
|
static double EPS_COR = 0.0;
|
|
|
|
|
|
|
|
/********app_star */
|
|
|
|
short int app_star (double jd_tt, cat_entry *star, short int accuracy,
|
|
|
|
double *ra, double *dec)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Computes the apparent place of a star at date 'jd_tt', given its
|
|
catalog mean place, proper motion, parallax, and radial velocity.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
Explanatory Supplement to the Astronomical Almanac (1992),
|
|
Chapter 3.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date for apparent place.
|
|
*star (struct cat_entry)
|
|
Pointer to catalog entry structure containing catalog data for
|
|
the object in the ICRS (defined in novas.h).
|
|
accuracy (short int)
|
|
Code specifying the relative accuracy of the output position.
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*ra (double)
|
|
Apparent right ascension in hours, referred to true equator
|
|
and equinox of date 'jd_tt'.
|
|
*dec (double)
|
|
Apparent declination in degrees, referred to true equator
|
|
and equinox of date 'jd_tt'.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... Everything OK.
|
|
> 10 ... Error code from function 'make_object'.
|
|
> 20 ... Error code from function 'place'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
SIZE_OF_OBJ_NAME novas.h
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
make_object novas.c
|
|
place novas.c
|
|
strcpy string.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/12-05/JAB (USNO/AA)
|
|
V1.1/10-06/JAB (USNO/AA): Incorporate 'output' structure.
|
|
V1.2/10-08/JAB (USNO/AA): Add 'accuracy' option to input.
|
|
V1.3/05-10/JAB (USNO/AA): Fix bug in set-up of 'obj_name'.
|
|
|
|
NOTES:
|
|
1. This function is the "C" version of Fortran NOVAS routine
|
|
'apstar'.
|
|
2. SIZE_OF_OBJ_NAME is defined in novas.h
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
char obj_name[SIZE_OF_OBJ_NAME];
|
|
|
|
short int error = 0;
|
|
short int type, number, coord_sys;
|
|
|
|
double delta_t = 0.0;
|
|
|
|
object cel_obj;
|
|
|
|
observer location;
|
|
|
|
sky_pos output;
|
|
|
|
*ra = *dec = 0.0; /* [Don Cross]: fix warnings */
|
|
|
|
/*
|
|
Set 'obj_name' equal to 'starname' in the 'star' structure. Length
|
|
will be checked in 'make_object'.
|
|
*/
|
|
|
|
strcpy (obj_name, star->starname);
|
|
|
|
/*
|
|
Set up a structure of type 'object' containing the star data.
|
|
*/
|
|
|
|
type = 2; /* Object located outside the solar system */
|
|
number = 0; /* Set to zero */
|
|
|
|
if ((error = make_object (type,number,obj_name,star, &cel_obj)) != 0)
|
|
{
|
|
error += 10;
|
|
return (error);
|
|
}
|
|
|
|
/*
|
|
Compute the apparent place with a call to function 'place'.
|
|
*/
|
|
|
|
location.where = 0; /* Geocenter */
|
|
coord_sys = 1; /* True equator and equinox of date */
|
|
|
|
if ((error = place (jd_tt,&cel_obj,&location,delta_t,coord_sys,
|
|
accuracy, &output)) != 0)
|
|
{
|
|
*ra = 0.0;
|
|
*dec = 0.0;
|
|
error += 20;
|
|
}
|
|
else
|
|
{
|
|
*ra = output.ra;
|
|
*dec = output.dec;
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********virtual_star */
|
|
|
|
short int virtual_star (double jd_tt, cat_entry *star,
|
|
short int accuracy,
|
|
|
|
double *ra, double *dec)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Computes the virtual place of a star at date 'jd_tt', given its
|
|
catalog mean place, proper motion, parallax, and radial velocity.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
Explanatory Supplement to the Astronomical Almanac (1992),
|
|
Chapter 3.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date for virtual place.
|
|
*star (struct cat_entry)
|
|
Pointer to catalog entry structure containing catalog data for
|
|
the object in the ICRS (defined in novas.h).
|
|
accuracy (short int)
|
|
Code specifying the relative accuracy of the output position.
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*ra (double)
|
|
Virtual right ascension in hours, referred to the GCRS.
|
|
*dec (double)
|
|
Virtual declination in degrees, referred to the GCRS.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... Everything OK.
|
|
> 10 ... Error code from function 'make_object'.
|
|
> 20 ... Error code from function 'place'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
SIZE_OF_OBJ_NAME novas.h
|
|
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
make_object novas.c
|
|
place novas.c
|
|
strcpy string.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/12-05/JAB (USNO/AA)
|
|
V1.1/10-06/JAB (USNO/AA): Incorporate 'output' structure.
|
|
V1.2/10-08/JAB (USNO/AA): Add 'accuracy' option to input.
|
|
V1.3/05-10/JAB (USNO/AA): Fix bug in set-up of 'obj_name'.
|
|
|
|
NOTES:
|
|
1. This function is the "C" version of Fortran NOVAS routine
|
|
'vpstar'.
|
|
2. SIZE_OF_OBJ_NAME is defined in novas.h
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
char obj_name[SIZE_OF_OBJ_NAME];
|
|
|
|
short int error = 0;
|
|
short int type, number, coord_sys;
|
|
|
|
double delta_t = 0.0;
|
|
|
|
object cel_obj;
|
|
|
|
observer location;
|
|
|
|
sky_pos output;
|
|
|
|
/*
|
|
Set 'obj_name' equal to 'starname' in the 'star' structure. Length
|
|
will be checked in 'make_object'.
|
|
*/
|
|
|
|
strcpy (obj_name, star->starname);
|
|
|
|
/*
|
|
Set up a structure of type 'object' containing the star data.
|
|
*/
|
|
|
|
type = 2; /* Object located outside the solar system */
|
|
number = 0; /* Set to zero */
|
|
|
|
if ((error = make_object (type,number,obj_name,star, &cel_obj)) != 0)
|
|
{
|
|
error += 10;
|
|
return (error);
|
|
}
|
|
|
|
/*
|
|
Compute the virtual place with a call to function 'place'.
|
|
*/
|
|
|
|
location.where = 0; /* Geocenter */
|
|
coord_sys = 0; /* GCRS */
|
|
|
|
if ((error = place (jd_tt,&cel_obj,&location,delta_t,coord_sys,
|
|
accuracy, &output)) != 0)
|
|
{
|
|
*ra = 0.0;
|
|
*dec = 0.0;
|
|
error += 20;
|
|
}
|
|
else
|
|
{
|
|
*ra = output.ra;
|
|
*dec = output.dec;
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********astro_star */
|
|
|
|
short int astro_star (double jd_tt, cat_entry *star, short int accuracy,
|
|
|
|
double *ra, double *dec)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Computes the astrometric place of a star at date 'jd_tt', given
|
|
its catalog mean place, proper motion, parallax, and radial
|
|
velocity.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
Explanatory Supplement to the Astronomical Almanac (1992),
|
|
Chapter 3.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date for astrometric place.
|
|
*star (struct cat_entry)
|
|
Pointer to catalog entry structure containing catalog data for
|
|
the object in the ICRS (defined in novas.h).
|
|
accuracy (short int)
|
|
Code specifying the relative accuracy of the output position.
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*ra (double)
|
|
Astrometric right ascension in hours (referred to the ICRS,
|
|
without light deflection or aberration).
|
|
*dec (double)
|
|
Astrometric declination in degrees (referred to the ICRS,
|
|
without light deflection or aberration).
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... Everything OK.
|
|
> 10 ... Error code from function 'make_object'.
|
|
> 20 ... Error code from function 'place'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
SIZE_OF_OBJ_NAME novas.h
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
make_object novas.c
|
|
place novas.c
|
|
strcpy string.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/12-05/JAB (USNO/AA)
|
|
V1.1/10-06/JAB (USNO/AA): Incorporate 'output' structure.
|
|
V1.2/10-08/JAB (USNO/AA): Add 'accuracy' option to input.
|
|
V1.3/05-10/JAB (USNO/AA): Fix bug in set-up of 'obj_name'.
|
|
|
|
NOTES:
|
|
1. This function is the "C" version of Fortran NOVAS routine
|
|
'asstar'.
|
|
2. SIZE_OF_OBJ_NAME is defined in novas.h
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
char obj_name[SIZE_OF_OBJ_NAME];
|
|
|
|
short int error = 0;
|
|
short int type, number, coord_sys;
|
|
|
|
double delta_t = 0.0;
|
|
|
|
object cel_obj;
|
|
|
|
observer location;
|
|
|
|
sky_pos output;
|
|
|
|
/*
|
|
Set 'obj_name' equal to 'starname' in the 'star' structure. Length
|
|
will be checked in 'make_object'.
|
|
*/
|
|
|
|
strcpy (obj_name, star->starname);
|
|
|
|
/*
|
|
Set up a structure of type 'object' containing the star data.
|
|
*/
|
|
|
|
type = 2; /* Object located outside the solar system */
|
|
number = 0; /* Set to zero */
|
|
|
|
if ((error = make_object (type,number,obj_name,star, &cel_obj)) != 0)
|
|
{
|
|
error += 10;
|
|
return (error);
|
|
}
|
|
|
|
/*
|
|
Compute the astrometric place with a call to function 'place'.
|
|
*/
|
|
|
|
location.where = 0; /* Geocenter */
|
|
coord_sys = 3; /* ICRS astrometric coordinates */
|
|
|
|
if ((error = place (jd_tt,&cel_obj,&location,delta_t,coord_sys,
|
|
accuracy, &output)) != 0)
|
|
{
|
|
*ra = 0.0;
|
|
*dec = 0.0;
|
|
error += 20;
|
|
}
|
|
else
|
|
{
|
|
*ra = output.ra;
|
|
*dec = output.dec;
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********app_planet */
|
|
|
|
short int app_planet (double jd_tt, object *ss_body, short int accuracy,
|
|
|
|
double *ra, double *dec, double *dis)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Compute the apparent place of a solar system body.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
Explanatory Supplement to the Astronomical Almanac (1992),
|
|
Chapter 3.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date for apparent place.
|
|
*ss_body (struct object)
|
|
Pointer to structure containing the body designation for the
|
|
solar system body (defined in novas.h).
|
|
accuracy (short int)
|
|
Code specifying the relative accuracy of the output position.
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*ra (double)
|
|
Apparent right ascension in hours, referred to true equator
|
|
and equinox of date.
|
|
*dec (double)
|
|
Apparent declination in degrees, referred to true equator
|
|
and equinox of date.
|
|
*dis (double)
|
|
True distance from Earth to the body at 'jd_tt' in AU.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... Everything OK.
|
|
= 1 ... Invalid value of 'type' in structure 'ss_body'.
|
|
> 10 ... Error code from function 'place'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
place novas.c
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/12-05/JAB (USNO/AA)
|
|
V1.1/10-06/JAB (USNO/AA): Incorporate 'output' structure.
|
|
V1.2/10-08/JAB (USNO/AA): Add 'accuracy' option to input.
|
|
|
|
NOTES:
|
|
1. This function is the "C" version of Fortran NOVAS routine
|
|
'applan'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
short int coord_sys;
|
|
|
|
double delta_t = 0.0;
|
|
|
|
observer location;
|
|
|
|
sky_pos output;
|
|
|
|
/*
|
|
Check for a valid value of 'type' in structure 'ss_body'.
|
|
*/
|
|
|
|
if ((ss_body->type < 0) || (ss_body->type > 1))
|
|
{
|
|
error = 1;
|
|
return (error);
|
|
}
|
|
|
|
/*
|
|
Compute the apparent place with a call to function 'place'.
|
|
*/
|
|
|
|
location.where = 0; /* Geocenter */
|
|
coord_sys = 1; /* True equator and equinox of date */
|
|
|
|
if ((error = place (jd_tt,ss_body,&location,delta_t,coord_sys,
|
|
accuracy, &output)) != 0)
|
|
{
|
|
*ra = 0.0;
|
|
*dec = 0.0;
|
|
*dis = 0.0;
|
|
error += 10;
|
|
}
|
|
else
|
|
{
|
|
*ra = output.ra;
|
|
*dec = output.dec;
|
|
*dis = output.dis;
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********virtual_planet */
|
|
|
|
short int virtual_planet (double jd_tt, object *ss_body,
|
|
short int accuracy,
|
|
|
|
double *ra, double *dec, double *dis)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Compute the virtual place of a solar system body.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
Explanatory Supplement to the Astronomical Almanac (1992),
|
|
Chapter 3.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date for virtual place.
|
|
*ss_body (struct object)
|
|
Pointer to structure containing the body designation for the
|
|
solar system body (defined in novas.h).
|
|
accuracy (short int)
|
|
Code specifying the relative accuracy of the output position.
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*ra (double)
|
|
Virtual right ascension in hours, referred to the GCRS.
|
|
*dec (double)
|
|
Virtual declination in degrees, referred to the GCRS.
|
|
*dis (double)
|
|
True distance from Earth to the body in AU.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... Everything OK.
|
|
= 1 ... Invalid value of 'type' in structure 'ss_body'.
|
|
> 10 ... Error code from function 'place'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
place novas.c
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/12-05/JAB (USNO/AA)
|
|
V1.1/10-06/JAB (USNO/AA): Incorporate 'output' structure.
|
|
V1.2/10-08/JAB (USNO/AA): Add 'accuracy' option to input.
|
|
|
|
NOTES:
|
|
1. This function is the "C" version of Fortran NOVAS routine
|
|
'vpplan'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
short int coord_sys;
|
|
|
|
double delta_t = 0.0;
|
|
|
|
observer location;
|
|
|
|
sky_pos output;
|
|
|
|
/*
|
|
Check for a valid value of 'type' in structure 'ss_body'.
|
|
*/
|
|
|
|
if ((ss_body->type < 0) || (ss_body->type > 1))
|
|
{
|
|
error = 1;
|
|
return (error);
|
|
}
|
|
|
|
/*
|
|
Compute the virtual place with a call to function 'place'.
|
|
*/
|
|
|
|
location.where = 0; /* Geocenter */
|
|
coord_sys = 0; /* GCRS */
|
|
|
|
if ((error = place (jd_tt,ss_body,&location,delta_t,coord_sys,
|
|
accuracy, &output)) != 0)
|
|
{
|
|
*ra = 0.0;
|
|
*dec = 0.0;
|
|
*dis = 0.0;
|
|
error += 10;
|
|
}
|
|
else
|
|
{
|
|
*ra = output.ra;
|
|
*dec = output.dec;
|
|
*dis = output.dis;
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********astro_planet */
|
|
|
|
short int astro_planet (double jd_tt, object *ss_body,
|
|
short int accuracy,
|
|
|
|
double *ra, double *dec, double *dis)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Compute the astrometric place of a solar system body.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
Explanatory Supplement to the Astronomical Almanac (1992),
|
|
Chapter 3.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date for astrometric place.
|
|
*ss_body (struct object)
|
|
Pointer to structure containing the body designation for the
|
|
solar system body (defined in novas.h).
|
|
accuracy (short int)
|
|
Code specifying the relative accuracy of the output position.
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*ra (double)
|
|
Astrometric right ascension in hours (referred to the ICRS,
|
|
without light deflection or aberration).
|
|
*dec (double)
|
|
Astrometric declination in degrees (referred to the ICRS,
|
|
without light deflection or aberration).
|
|
*dis (double)
|
|
True distance from Earth to the body in AU.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... Everything OK.
|
|
= 1 ... Invalid value of 'type' in structure 'ss_body'.
|
|
> 10 ... Error code from function 'place'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
place novas.c
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/12-05/JAB (USNO/AA)
|
|
V1.1/10-06/JAB (USNO/AA): Incorporate 'output' structure.
|
|
V1.2/10-08/JAB (USNO/AA): Add 'accuracy' option to input.
|
|
|
|
NOTES:
|
|
1. This function is the "C" version of Fortran NOVAS routine
|
|
'asplan'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
short int coord_sys;
|
|
|
|
double delta_t = 0.0;
|
|
|
|
observer location;
|
|
|
|
sky_pos output;
|
|
|
|
/*
|
|
Check for a valid value of 'type' in structure 'ss_body'.
|
|
*/
|
|
|
|
if ((ss_body->type < 0) || (ss_body->type > 1))
|
|
{
|
|
error = 1;
|
|
return (error);
|
|
}
|
|
|
|
/*
|
|
Compute the astrometric place with a call to function 'place'.
|
|
*/
|
|
|
|
location.where = 0; /* Geocenter */
|
|
coord_sys = 3; /* ICRS astrometric coordinates */
|
|
|
|
if ((error = place (jd_tt,ss_body,&location,delta_t,coord_sys,
|
|
accuracy, &output)) != 0)
|
|
{
|
|
*ra = 0.0;
|
|
*dec = 0.0;
|
|
*dis = 0.0;
|
|
error += 10;
|
|
}
|
|
else
|
|
{
|
|
*ra = output.ra;
|
|
*dec = output.dec;
|
|
*dis = output.dis;
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********topo_star */
|
|
|
|
short int topo_star (double jd_tt, double delta_t, cat_entry *star,
|
|
on_surface *position, short int accuracy,
|
|
|
|
double *ra, double *dec)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Computes the topocentric place of a star at date 'jd_tt', given its
|
|
catalog mean place, proper motion, parallax, and radial velocity.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
Explanatory Supplement to the Astronomical Almanac (1992),
|
|
Chapter 3.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date for topocentric place.
|
|
delta_t (double)
|
|
Difference TT-UT1 at 'jd_tt', in seconds of time.
|
|
*star (struct cat_entry)
|
|
Pointer to catalog entry structure containing catalog data for
|
|
the object in the ICRS (defined in novas.h).
|
|
*position (struct on_surface)
|
|
Specifies the position of the observer (structure defined in
|
|
novas.h).
|
|
accuracy (short int)
|
|
Code specifying the relative accuracy of the output position.
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*ra (double)
|
|
Topocentric right ascension in hours, referred to true equator
|
|
and equinox of date 'jd_tt'.
|
|
*dec (double)
|
|
Topocentric declination in degrees, referred to true equator
|
|
and equinox of date 'jd_tt'.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... Everything OK.
|
|
= 1 ... Invalid value of 'where' in structure 'location'.
|
|
> 10 ... Error code from function 'make_object'.
|
|
> 20 ... Error code from function 'place'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
SIZE_OF_OBJ_NAME novas.h
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
make_observer novas.c
|
|
make_object novas.c
|
|
place novas.c
|
|
strcpy string.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/01-06/JAB (USNO/AA)
|
|
V1.1/01-06/WKP (USNO/AA): Fixed minor syntax problem.
|
|
V1.2/10-06/JAB (USNO/AA): Incorporate 'output' structure.
|
|
V1.3/10-08/JAB (USNO/AA): Add 'accuracy' option to input.
|
|
V1.4/05-10/JAB (USNO/AA): Fix bug in set-up of 'obj_name'.
|
|
|
|
NOTES:
|
|
1. This function is the "C" version of Fortran NOVAS routine
|
|
'tpstar'.
|
|
2. SIZE_OF_OBJ_NAME is defined in novas.h
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
char obj_name[SIZE_OF_OBJ_NAME];
|
|
|
|
short int error = 0;
|
|
short int type, number, coord_sys;
|
|
|
|
in_space dummy;
|
|
|
|
observer location;
|
|
|
|
object cel_obj;
|
|
|
|
sky_pos output;
|
|
|
|
/*
|
|
Initialize the 'dummy' structure.
|
|
*/
|
|
|
|
dummy.sc_pos[0] = dummy.sc_pos[1] = dummy.sc_pos[2] = 0.0;
|
|
dummy.sc_vel[0] = dummy.sc_vel[1] = dummy.sc_vel[2] = 0.0;
|
|
|
|
/*
|
|
Set up a structure of type 'observer' containing the position
|
|
of the observer.
|
|
*/
|
|
|
|
if ((error = make_observer (1,position,&dummy, &location)) != 0)
|
|
{
|
|
error = 1;
|
|
return (error);
|
|
}
|
|
|
|
/*
|
|
Set 'obj_name' equal to 'starname' in the 'star' structure. Length
|
|
will be checked in 'make_object'.
|
|
*/
|
|
|
|
strcpy (obj_name, star->starname);
|
|
|
|
/*
|
|
Set up a structure of type 'object' containing the star data.
|
|
*/
|
|
|
|
type = 2; /* Object located outside the solar system */
|
|
number = 0; /* Set to zero */
|
|
|
|
if ((error = make_object (type,number,obj_name,star, &cel_obj)) != 0)
|
|
{
|
|
error += 10;
|
|
return (error);
|
|
}
|
|
|
|
/*
|
|
Compute the topocentric place with a call to function 'place'.
|
|
*/
|
|
|
|
coord_sys = 1; /* True equator and equinox of date */
|
|
|
|
if ((error = place (jd_tt,&cel_obj,&location,delta_t,coord_sys,
|
|
accuracy, &output)) != 0)
|
|
{
|
|
*ra = 0.0;
|
|
*dec = 0.0;
|
|
error += 20;
|
|
}
|
|
else
|
|
{
|
|
*ra = output.ra;
|
|
*dec = output.dec;
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********local_star */
|
|
|
|
short int local_star (double jd_tt, double delta_t, cat_entry *star,
|
|
on_surface *position, short int accuracy,
|
|
|
|
double *ra, double *dec)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Computes the local place of a star at date 'jd_tt', given its
|
|
catalog mean place, proper motion, parallax, and radial velocity.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
Explanatory Supplement to the Astronomical Almanac (1992),
|
|
Chapter 3.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date for local place.
|
|
delta_t (double)
|
|
Difference TT-UT1 at 'jd_tt', in seconds of time.
|
|
*star (struct cat_entry)
|
|
Pointer to catalog entry structure containing catalog data for
|
|
the object in the ICRS (defined in novas.h).
|
|
*position (struct on_surface)
|
|
Specifies the position of the observer (structure defined in
|
|
novas.h).
|
|
accuracy (short int)
|
|
Code specifying the relative accuracy of the output position.
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*ra (double)
|
|
Local right ascension in hours, referred to the 'local GCRS'.
|
|
*dec (double)
|
|
Local declination in degrees, referred to the 'local GCRS'.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... Everything OK.
|
|
= 1 ... Invalid value of 'where' in structure 'location'.
|
|
> 10 ... Error code from function 'make_object'.
|
|
> 20 ... Error code from function 'place'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
SIZE_OF_OBJ_NAME novas.h
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
make_observer novas.c
|
|
make_object novas.c
|
|
place novas.c
|
|
strcpy string.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/01-06/JAB (USNO/AA)
|
|
V1.1/10-06/JAB (USNO/AA): Incorporate 'output' structure.
|
|
V1.2/10-08/JAB (USNO/AA): Add 'accuracy' option to input.
|
|
V1.3/05-10/JAB (USNO/AA): Fix bug in set-up of 'obj_name'.
|
|
|
|
NOTES:
|
|
1. This function is the "C" version of Fortran NOVAS routine
|
|
'lpstar'.
|
|
2. SIZE_OF_OBJ_NAME is defined in novas.h
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
char obj_name[SIZE_OF_OBJ_NAME];
|
|
|
|
short int error = 0;
|
|
short int type, number, coord_sys;
|
|
|
|
in_space dummy;
|
|
|
|
observer location;
|
|
|
|
object cel_obj;
|
|
|
|
sky_pos output;
|
|
|
|
/*
|
|
Initialize the 'dummy' structure.
|
|
*/
|
|
|
|
dummy.sc_pos[0] = dummy.sc_pos[1] = dummy.sc_pos[2] = 0.0;
|
|
dummy.sc_vel[0] = dummy.sc_vel[1] = dummy.sc_vel[2] = 0.0;
|
|
|
|
/*
|
|
Set up a structure of type 'observer' containing the position
|
|
of the observer.
|
|
*/
|
|
|
|
if ((error = make_observer (1,position,&dummy, &location)) != 0)
|
|
{
|
|
error = 1;
|
|
return (error);
|
|
}
|
|
|
|
/*
|
|
Set 'obj_name' equal to 'starname' in the 'star' structure. Length
|
|
will be checked in 'make_object'.
|
|
*/
|
|
|
|
strcpy (obj_name, star->starname);
|
|
|
|
/*
|
|
Set up a structure of type 'object' containing the star data.
|
|
*/
|
|
|
|
type = 2; /* Object located outside the solar system */
|
|
number = 0; /* Set to zero */
|
|
|
|
if ((error = make_object (type,number,obj_name,star, &cel_obj)) != 0)
|
|
{
|
|
error += 10;
|
|
return (error);
|
|
}
|
|
|
|
/*
|
|
Compute the local place with a call to function 'place'.
|
|
*/
|
|
|
|
coord_sys = 0; /* "Local GCRS" */
|
|
|
|
if ((error = place (jd_tt,&cel_obj,&location,delta_t,coord_sys,
|
|
accuracy, &output)) != 0)
|
|
{
|
|
*ra = 0.0;
|
|
*dec = 0.0;
|
|
error += 20;
|
|
}
|
|
else
|
|
{
|
|
*ra = output.ra;
|
|
*dec = output.dec;
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********topo_planet */
|
|
|
|
short int topo_planet (double jd_tt, object *ss_body, double delta_t,
|
|
on_surface *position, short int accuracy,
|
|
|
|
double *ra, double *dec, double *dis)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Computes the topocentric place of a solar system body.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
Explanatory Supplement to the Astronomical Almanac (1992),
|
|
Chapter 3.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date for topocentric place.
|
|
*ss_body (struct object)
|
|
Pointer to structure containing the body designation for the
|
|
solar system body (defined in novas.h).
|
|
delta_t (double)
|
|
Difference TT-UT1 at 'jd_tt', in seconds of time.
|
|
*position (struct on_surface)
|
|
Specifies the position of the observer (structure defined in
|
|
novas.h).
|
|
accuracy (short int)
|
|
Code specifying the relative accuracy of the output position.
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*ra (double)
|
|
Topocentric right ascension in hours, referred to true equator
|
|
and equinox of date.
|
|
*dec (double)
|
|
Topocentric declination in degrees, referred to true equator
|
|
and equinox of date.
|
|
*dis (double)
|
|
True distance from Earth to the body at 'jd_tt' in AU.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... Everything OK.
|
|
= 1 ... Invalid value of 'where' in structure 'location'.
|
|
> 10 ... Error code from function 'place'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
make_observer novas.c
|
|
place novas.c
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/01-06/JAB (USNO/AA)
|
|
V1.1/01-06/WKP (USNO/AA): Fixed minor syntax problem.
|
|
V1.2/10-06/JAB (USNO/AA): Incorporate 'output' structure.
|
|
V1.3/10-08/JAB (USNO/AA): Add 'accuracy' option to input.
|
|
V1.4/07-10/JLB (USNO/AA): Fixed minor documentation error in prolog
|
|
|
|
NOTES:
|
|
1. This function is the "C" version of Fortran NOVAS routine
|
|
'tpplan'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
short int coord_sys;
|
|
|
|
in_space dummy;
|
|
|
|
observer location;
|
|
|
|
sky_pos output;
|
|
|
|
/*
|
|
Initialize the 'dummy' structure.
|
|
*/
|
|
|
|
dummy.sc_pos[0] = dummy.sc_pos[1] = dummy.sc_pos[2] = 0.0;
|
|
dummy.sc_vel[0] = dummy.sc_vel[1] = dummy.sc_vel[2] = 0.0;
|
|
|
|
/*
|
|
Set up a structure of type 'observer' containing the position
|
|
of the observer.
|
|
*/
|
|
|
|
if ((error = make_observer (1,position,&dummy, &location)) != 0)
|
|
{
|
|
error = 1;
|
|
return (error);
|
|
}
|
|
|
|
/*
|
|
Compute the topocentric place with a call to function 'place'.
|
|
*/
|
|
|
|
coord_sys = 1; /* True equator and equinox of date */
|
|
|
|
if ((error = place (jd_tt,ss_body,&location,delta_t,coord_sys,
|
|
accuracy, &output)) != 0)
|
|
{
|
|
*ra = 0.0;
|
|
*dec = 0.0;
|
|
*dis = 0.0;
|
|
error += 10;
|
|
}
|
|
else
|
|
{
|
|
*ra = output.ra;
|
|
*dec = output.dec;
|
|
*dis = output.dis;
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********local_planet */
|
|
|
|
short int local_planet (double jd_tt, object *ss_body,
|
|
double delta_t, on_surface *position,
|
|
short int accuracy,
|
|
|
|
double *ra, double *dec, double *dis)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Computes the local place of a solar system body.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
Explanatory Supplement to the Astronomical Almanac (1992),
|
|
Chapter 3.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date for local place.
|
|
*ss_body (struct object)
|
|
Pointer to structure containing the body designation for the
|
|
solar system body (defined in novas.h).
|
|
delta_t (double)
|
|
Difference TT-UT1 at 'jd_tt', in seconds of time.
|
|
*position (struct on_surface)
|
|
Specifies the position of the observer (structure defined in
|
|
novas.h).
|
|
accuracy (short int)
|
|
Code specifying the relative accuracy of the output position.
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*ra (double)
|
|
Local right ascension in hours, referred to the 'local GCRS'.
|
|
*dec (double)
|
|
Local declination in degrees, referred to the 'local GCRS'.
|
|
*dis (double)
|
|
True distance from Earth to the body in AU.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... Everything OK.
|
|
= 1 ... Invalid value of 'where' in structure 'location'.
|
|
> 10 ... Error code from function 'place'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
make_observer novas.c
|
|
place novas.c
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/01-06/JAB (USNO/AA)
|
|
V1.1/01-06/WKP (USNO/AA): Fixed minor syntax problem.
|
|
V1.2/10-06/JAB (USNO/AA): Incorporate 'output' structure.
|
|
V1.3/10-08/JAB (USNO/AA): Add 'accuracy' option to input.
|
|
|
|
NOTES:
|
|
1. This function is the "C" version of Fortran NOVAS routine
|
|
'lpplan'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
short int coord_sys;
|
|
|
|
in_space dummy;
|
|
|
|
observer location;
|
|
|
|
sky_pos output;
|
|
|
|
/*
|
|
Initialize the 'dummy' structure.
|
|
*/
|
|
|
|
dummy.sc_pos[0] = dummy.sc_pos[1] = dummy.sc_pos[2] = 0.0;
|
|
dummy.sc_vel[0] = dummy.sc_vel[1] = dummy.sc_vel[2] = 0.0;
|
|
|
|
/*
|
|
Set up a structure of type 'observer' containing the position
|
|
of the observer.
|
|
*/
|
|
|
|
if ((error = make_observer (1,position,&dummy, &location)) != 0)
|
|
{
|
|
error = 1;
|
|
return (error);
|
|
}
|
|
|
|
/*
|
|
Compute the local place with a call to function 'place'.
|
|
*/
|
|
|
|
coord_sys = 0; /* "Local GCRS" */
|
|
|
|
if ((error = place (jd_tt,ss_body,&location,delta_t,coord_sys,
|
|
accuracy, &output)) != 0)
|
|
{
|
|
*ra = 0.0;
|
|
*dec = 0.0;
|
|
*dis = 0.0;
|
|
error += 10;
|
|
}
|
|
else
|
|
{
|
|
*ra = output.ra;
|
|
*dec = output.dec;
|
|
*dis = output.dis;
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********mean_star */
|
|
|
|
short int mean_star (double jd_tt, double ra, double dec,
|
|
short int accuracy,
|
|
|
|
double *ira, double *idec)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Computes the ICRS position of a star, given its apparent place
|
|
at date 'jd_tt'. Proper motion, parallax and radial velocity
|
|
are assumed to be zero.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
Explanatory Supplement to the Astronomical Almanac (1992),
|
|
Chapter 3.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date of apparent place.
|
|
ra (double)
|
|
Apparent right ascension in hours, referred to true equator
|
|
and equinox of date.
|
|
dec (double)
|
|
Apparent declination in degrees, referred to true equator
|
|
and equinox of date.
|
|
accuracy (short int)
|
|
Code specifying the relative accuracy of the output position.
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*ira (double)
|
|
ICRS right ascension in hours.
|
|
*idec (double)
|
|
ICRS declination in degrees.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... Everything OK.
|
|
= 1 ... Iterative process did not converge after 30 iterations.
|
|
= 2 ... length of dummy star name out of bounds.
|
|
= 3 ... length of dummy catalog name out of bounds.
|
|
> 10 ... Error from function 'vector2radec'.
|
|
> 20 ... Error from function 'app_star'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
T0 novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
make_cat_entry novas.c
|
|
starvectors novas.c
|
|
precession novas.c
|
|
app_star novas.c
|
|
vector2radec novas.c
|
|
fabs math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/12-05/JAB (USNO/AA)
|
|
V1.1/03-08/WKP (USNO/AA): Fixed subtle bug in exit condition of
|
|
iteration and updated variable names.
|
|
V1.2/10-08/JAB (USNO/AA): Add 'accuracy' option to input.
|
|
V1.3/05-10/JAB (USNO/AA): Use 'make_cat_entry' to set up
|
|
local structure 'tempstar'.
|
|
|
|
NOTES:
|
|
1. This function is the "C" version of Fortran NOVAS routine
|
|
'mpstar'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
short int iter = 0;
|
|
|
|
double pos[3], dum[3], pos2[3], newira, newidec, oldira, oldidec, ra2,
|
|
dec2, deltara, deltadec;
|
|
|
|
cat_entry tempstar;
|
|
|
|
/*
|
|
Set up the 'tempstar' structure, then use it to create a position
|
|
vector based on the apparent RA and declination of the star.
|
|
*/
|
|
|
|
if ((error = make_cat_entry ("dummy","CAT",0,ra,dec,0.0,0.0,0.0,0.0,
|
|
&tempstar)) != 0)
|
|
{
|
|
return (error + 1);
|
|
}
|
|
|
|
starvectors (&tempstar, pos,dum);
|
|
|
|
/*
|
|
Get initial approximation by precessing star position at 'jd_tt'
|
|
to its position at J2000.0.
|
|
*/
|
|
|
|
precession (jd_tt,pos,T0, pos2);
|
|
if ((error = vector2radec (pos2, &newira,&newidec)) != 0)
|
|
{
|
|
return (error + 10);
|
|
}
|
|
|
|
/*
|
|
Iteratively find ICRS coordinates that produce input apparent place
|
|
of star at date 'jd_tt'.
|
|
*/
|
|
|
|
do
|
|
{
|
|
oldira = newira;
|
|
oldidec = newidec;
|
|
tempstar.ra = oldira;
|
|
tempstar.dec = oldidec;
|
|
if ((error = app_star (jd_tt,&tempstar,accuracy, &ra2,&dec2)) != 0)
|
|
{
|
|
*ira = 0.0;
|
|
*idec = 0.0;
|
|
return (error + 20);
|
|
}
|
|
|
|
deltara = ra2 - oldira;
|
|
deltadec = dec2 - oldidec;
|
|
if (deltara < -12.0)
|
|
deltara += 24.0;
|
|
if (deltara > 12.0)
|
|
deltara -= 24.0;
|
|
newira = ra - deltara;
|
|
newidec = dec - deltadec;
|
|
|
|
if (iter >= 30)
|
|
{
|
|
*ira = 0.0;
|
|
*idec = 0.0;
|
|
return (error = 1);
|
|
}
|
|
else
|
|
{
|
|
iter++;
|
|
}
|
|
} while (!(fabs (newira - oldira) <= 1.0e-12) ||
|
|
!(fabs (newidec - oldidec) <= 1.0e-11));
|
|
|
|
*ira = newira;
|
|
*idec = newidec;
|
|
if (*ira < 0.0)
|
|
*ira += 24.0;
|
|
if (*ira >= 24.0)
|
|
*ira -= 24.0;
|
|
|
|
return (error);
|
|
}
|
|
|
|
|
|
/********place */
|
|
|
|
short int place (double jd_tt, object *cel_object,
|
|
observer *location, double delta_t,
|
|
short int coord_sys, short int accuracy,
|
|
|
|
sky_pos *output)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function computes the apparent direction of a star or solar
|
|
system body at a specified time and in a specified coordinate
|
|
system.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. et al. (1989), Astronomical Journal 97, 1197-1210.
|
|
Klioner, S. (2003), Astronomical Journal 125, 1580-1597.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date for place.
|
|
*cel_object (struct object)
|
|
Specifies the celestial object of interest (structure defined
|
|
in novas.h).
|
|
*location (struct observer)
|
|
Specifies the location of the observer (structure defined in
|
|
novas.h).
|
|
delta_t (double)
|
|
Difference TT-UT1 at 'jd_tt', in seconds of time.
|
|
coord_sys (short int)
|
|
Code specifying coordinate system of the output position.
|
|
= 0 ... GCRS or "local GCRS"
|
|
= 1 ... true equator and equinox of date
|
|
= 2 ... true equator and CIO of date
|
|
= 3 ... astrometric coordinates, i.e., without light
|
|
deflection or aberration.
|
|
accuracy (short int)
|
|
Code specifying the relative accuracy of the output position.
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*output (struct sky_pos)
|
|
Output data specifying object's place on the sky at time
|
|
'jd_tt', with respect to the specified output coordinate system
|
|
(struct defined in novas.h).
|
|
|
|
RETURNED
|
|
VALUE:
|
|
= 0 ... No problems.
|
|
= 1 ... invalid value of 'coord_sys'
|
|
= 2 ... invalid value of 'accuracy'
|
|
= 3 ... Earth is the observed object, and the observer is
|
|
either at the geocenter or on the Earth's surface
|
|
(not permitted)
|
|
> 10, < 40 ... 10 + error from function 'ephemeris'
|
|
> 40, < 50 ... 40 + error from function 'geo_posvel'
|
|
> 50, < 70 ... 50 + error from function 'light_time'
|
|
> 70, < 80 ... 70 + error from function 'grav_def'
|
|
> 80, < 90 ... 80 + error from function 'cio_location'
|
|
> 90, < 100 ... 90 + error from function 'cio_basis'
|
|
|
|
GLOBALS
|
|
USED:
|
|
T0, C_AUDAY novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
make_cat_entry novas.c
|
|
make_object novas.c
|
|
tdb2tt novas.c
|
|
ephemeris novas.c
|
|
geo_posvel novas.c
|
|
starvectors novas.c
|
|
d_light novas.c
|
|
proper_motion novas.c
|
|
bary2obs novas.c
|
|
light_time novas.c
|
|
limb_angle novas.c
|
|
grav_def novas.c
|
|
aberration novas.c
|
|
frame_tie novas.c
|
|
precession novas.c
|
|
nutation novas.c
|
|
cio_location novas.c
|
|
cio_basis novas.c
|
|
rad_vel novas.c
|
|
vector2radec novas.c
|
|
fabs math.h
|
|
sqrt math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/01-05/JAB (USNO/AA)
|
|
V1.1/09-05/WKP (USNO/AA) Removed 'star' from the input argument
|
|
list since it is nested in the 'object'
|
|
structure.
|
|
V1.2/01-06/WKP (USNO/AA) Updated error codes and replaced 'mode'
|
|
with 'accuracy' where appropriate.
|
|
V1.3/01-06/JAB (USNO/AA) Added more static variables.
|
|
V1.4/07-06/JAB (USNO/AA) Implement 'cio_location' construct.
|
|
V1.5/10-06/JAB (USNO/AA) Add radial velocity calculation and
|
|
implement 'sky_pos' structure.
|
|
V1.6/01-07/JAB (USNO/AA) Update to accommodate new radial velocity
|
|
algorithm.
|
|
V1.7/10-08/JAB (USNO/AA) Modify calls to 'ephemeris' to support
|
|
two-part input Julian date.
|
|
V1.8/07-10/JLB (USNO/AA) Corrected citation to Kaplan et al.
|
|
|
|
NOTES:
|
|
1. Values of 'location->where' and 'coord_sys' dictate the various
|
|
standard kinds of place:
|
|
location->where = 0 and coord_sys = 1: apparent place
|
|
location->where = 1 and coord_sys = 1: topocentric place
|
|
location->where = 0 and coord_sys = 0: virtual place
|
|
location->where = 1 and coord_sys = 0: local place
|
|
location->where = 0 and coord_sys = 3: astrometric place
|
|
location->where = 1 and coord_sys = 3: topocentric astrometric
|
|
place
|
|
2. Input value of 'delta_t' is used only when 'location->where'
|
|
equals 1 or 2 (observer is on surface of Earth or in a
|
|
near-Earth satellite).
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
static short int first_time = 1;
|
|
short int error = 0;
|
|
short int loc, rs, i;
|
|
|
|
static double tlast1 = 0.0;
|
|
static double tlast2 = 0.0;
|
|
static double jd_tdb, peb[3], veb[3], psb[3], vsb[3], px[3], py[3],
|
|
pz[3];
|
|
double x, secdif, jd[2], pog[3], vog[3], pob[3], vob[3], pos1[3],
|
|
vel1[3], dt, pos2[3], pos3[3], t_light, t_light0, pos4[3], frlimb,
|
|
pos5[3], pos6[3], pos7[3], pos8[3], r_cio, d_obs_geo, d_obs_sun,
|
|
d_obj_sun;
|
|
|
|
cat_entry null_star;
|
|
|
|
static object earth, sun;
|
|
|
|
/*
|
|
Check for invalid value of 'coord_sys' or 'accuracy'.
|
|
*/
|
|
|
|
if ((coord_sys < 0) || (coord_sys > 3))
|
|
return (error = 1);
|
|
|
|
if ((accuracy < 0) || (accuracy > 1))
|
|
return (error = 2);
|
|
|
|
/*
|
|
Create a null star 'cat_entry' and Earth and Sun 'object's.
|
|
*/
|
|
|
|
if (first_time)
|
|
{
|
|
make_cat_entry ("NULL_STAR"," ",0L,0.0,0.0,0.0,0.0,0.0,0.0,
|
|
&null_star);
|
|
|
|
make_object (0,3,"Earth",&null_star, &earth);
|
|
make_object (0,10,"Sun",&null_star, &sun);
|
|
|
|
first_time = 0;
|
|
}
|
|
|
|
/*
|
|
---------------------------------------------------------------------
|
|
Check on Earth as an observed object. Earth can only be an observed
|
|
object when 'location' is a near-Earth satellite.
|
|
---------------------------------------------------------------------
|
|
*/
|
|
|
|
if ((cel_object->type == 0) && (cel_object->number == 3) &&
|
|
(location->where != 2))
|
|
return (error = 3);
|
|
|
|
/*
|
|
---------------------------------------------------------------------
|
|
Get position and velocity of Earth (geocenter) and Sun.
|
|
---------------------------------------------------------------------
|
|
*/
|
|
|
|
if (fabs (jd_tt - tlast1) > 1.0e-8)
|
|
{
|
|
|
|
/*
|
|
Compute 'jd_tdb', the TDB Julian date corresponding to 'jd_tt'.
|
|
*/
|
|
|
|
jd_tdb = jd_tt;
|
|
tdb2tt (jd_tdb, &x,&secdif);
|
|
jd_tdb = jd_tt + secdif / 86400.0;
|
|
|
|
/*
|
|
Get position and velocity of Earth wrt barycenter of solar system,
|
|
in ICRS.
|
|
*/
|
|
|
|
jd[0] = jd_tdb;
|
|
jd[1] = 0.0;
|
|
|
|
if ((error = ephemeris (jd,&earth,0,accuracy, peb,veb)) != 0)
|
|
return (error += 10);
|
|
|
|
/*
|
|
Get position and velocity of Sun wrt barycenter of solar system,
|
|
in ICRS.
|
|
*/
|
|
|
|
if ((error = ephemeris (jd,&sun,0,accuracy, psb,vsb)) != 0)
|
|
return (error += 10);
|
|
|
|
tlast1 = jd_tt;
|
|
}
|
|
|
|
/*
|
|
---------------------------------------------------------------------
|
|
Get position and velocity of observer.
|
|
---------------------------------------------------------------------
|
|
*/
|
|
|
|
if ((location->where == 1) || (location->where == 2))
|
|
{
|
|
|
|
/*
|
|
For topocentric place, get geocentric position and velocity vectors
|
|
of observer (observer is on surface of Earth or in a near-Earth
|
|
satellite).
|
|
*/
|
|
|
|
if ((error = geo_posvel (jd_tt,delta_t,accuracy,location, pog,vog))
|
|
!= 0)
|
|
return (error += 40);
|
|
|
|
loc = 1;
|
|
}
|
|
else
|
|
{
|
|
|
|
/*
|
|
For geocentric place, there is nothing to do (observer is at
|
|
geocenter).
|
|
*/
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
pog[i] = 0.0;
|
|
vog[i] = 0.0;
|
|
}
|
|
|
|
loc = 0;
|
|
}
|
|
|
|
/*
|
|
Compute position and velocity of observer wrt barycenter of
|
|
solar system (Galilean transformation).
|
|
*/
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
pob[i] = peb[i] + pog[i];
|
|
vob[i] = veb[i] + vog[i];
|
|
}
|
|
|
|
/*
|
|
---------------------------------------------------------------------
|
|
Find geometric position of observed object.
|
|
---------------------------------------------------------------------
|
|
*/
|
|
|
|
if (cel_object->type == 2) /* Observed object is star. */
|
|
{
|
|
|
|
/*
|
|
Get position of star updated for its space motion.
|
|
*/
|
|
|
|
starvectors (&cel_object->star, pos1,vel1);
|
|
dt = d_light (pos1,pob);
|
|
proper_motion (T0,pos1,vel1,(jd_tdb + dt), pos2);
|
|
|
|
/*
|
|
Get position of star wrt observer (corrected for parallax).
|
|
*/
|
|
|
|
bary2obs (pos2,pob, pos3,&t_light);
|
|
output->dis = 0.0;
|
|
}
|
|
|
|
else /* Observed object is solar system body. */
|
|
{
|
|
|
|
/*
|
|
Get position of body wrt barycenter of solar system.
|
|
*/
|
|
|
|
jd[0] = jd_tdb;
|
|
jd[1] = 0.0;
|
|
|
|
if ((error = ephemeris (jd,cel_object,0,accuracy, pos1,vel1)) != 0)
|
|
return (error += 10);
|
|
|
|
/*
|
|
Get position of body wrt observer, and true (Euclidian) distance.
|
|
*/
|
|
|
|
bary2obs (pos1,pob, pos2,&t_light0);
|
|
output->dis = t_light0 * C_AUDAY;
|
|
|
|
/*
|
|
Get position of body wrt observer, antedated for light-time.
|
|
*/
|
|
|
|
if ((error = light_time (jd_tdb,cel_object,pob,t_light0,accuracy,
|
|
pos3,&t_light)) != 0)
|
|
return (error += 50);
|
|
}
|
|
|
|
/*
|
|
---------------------------------------------------------------------
|
|
Apply gravitational deflection of light and aberration.
|
|
---------------------------------------------------------------------
|
|
*/
|
|
|
|
if (coord_sys == 3)
|
|
{
|
|
|
|
/*
|
|
These calculations are skipped for astrometric place.
|
|
*/
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
pos5[i] = pos3[i];
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
|
|
/*
|
|
Variable 'loc' determines whether Earth deflection is included.
|
|
*/
|
|
|
|
if (loc == 1)
|
|
{
|
|
limb_angle (pos3,pog, &x,&frlimb);
|
|
if (frlimb < 0.8)
|
|
loc = 0;
|
|
}
|
|
|
|
/*
|
|
Compute gravitational deflection and aberration.
|
|
*/
|
|
|
|
if ((error = grav_def (jd_tdb,loc,accuracy,pos3,pob, pos4)) != 0)
|
|
return (error += 70);
|
|
|
|
aberration (pos4,vob,t_light, pos5);
|
|
}
|
|
|
|
/*
|
|
---------------------------------------------------------------------
|
|
Transform, if necessary, to output coordinate system.
|
|
---------------------------------------------------------------------
|
|
*/
|
|
|
|
switch (coord_sys)
|
|
{
|
|
case (1): /* Transform to equator and equinox of date. */
|
|
|
|
frame_tie (pos5,1, pos6);
|
|
precession (T0,pos6,jd_tdb, pos7);
|
|
nutation (jd_tdb,0,accuracy,pos7, pos8);
|
|
break;
|
|
|
|
case (2): /* Transform to equator and CIO of date. */
|
|
|
|
if (fabs (jd_tdb - tlast2) > 1.0e-8 )
|
|
{
|
|
|
|
/*
|
|
Obtain the basis vectors, in the GCRS, of the celestial intermediate
|
|
system.
|
|
*/
|
|
|
|
if ((error = cio_location (jd_tdb,accuracy, &r_cio,
|
|
&rs)) != 0)
|
|
return (error += 80);
|
|
if ((error = cio_basis (jd_tdb,r_cio,rs,accuracy,
|
|
px,py,pz)) != 0)
|
|
return (error += 90);
|
|
|
|
tlast2 = jd_tdb;
|
|
}
|
|
|
|
/*
|
|
Transform position vector to celestial intermediate system.
|
|
*/
|
|
|
|
pos8[0] = px[0] * pos5[0] + px[1] * pos5[1] + px[2] * pos5[2];
|
|
pos8[1] = py[0] * pos5[0] + py[1] * pos5[1] + py[2] * pos5[2];
|
|
pos8[2] = pz[0] * pos5[0] + pz[1] * pos5[1] + pz[2] * pos5[2];
|
|
break;
|
|
|
|
default: /* No transformation -- keep coordinates in GCRS, */
|
|
/* or ICRS for astrometric coordinates. */
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
pos8[i] = pos5[i];
|
|
}
|
|
}
|
|
/*
|
|
---------------------------------------------------------------------
|
|
Compute radial velocity.
|
|
---------------------------------------------------------------------
|
|
*/
|
|
|
|
/*
|
|
Compute distances: observer-geocenter, observer-Sun, object-Sun.
|
|
*/
|
|
|
|
d_obs_geo = sqrt ((pob[0] - peb[0]) * (pob[0] - peb[0]) +
|
|
( pob[1] - peb[1]) * (pob[1] - peb[1]) +
|
|
( pob[2] - peb[2]) * (pob[2] - peb[2]));
|
|
|
|
d_obs_sun = sqrt ((pob[0] - psb[0]) * (pob[0] - psb[0]) +
|
|
( pob[1] - psb[1]) * (pob[1] - psb[1]) +
|
|
( pob[2] - psb[2]) * (pob[2] - psb[2]));
|
|
|
|
d_obj_sun = sqrt ((pos1[0] - psb[0]) * (pos1[0] - psb[0]) +
|
|
( pos1[1] - psb[1]) * (pos1[1] - psb[1]) +
|
|
( pos1[2] - psb[2]) * (pos1[2] - psb[2]));
|
|
|
|
rad_vel (cel_object,pos3,vel1,vob,d_obs_geo,d_obs_sun,d_obj_sun,
|
|
&output->rv);
|
|
|
|
/*
|
|
---------------------------------------------------------------------
|
|
Finish up.
|
|
---------------------------------------------------------------------
|
|
*/
|
|
|
|
vector2radec (pos8, &output->ra,&output->dec);
|
|
|
|
x = sqrt (pos8[0] * pos8[0] + pos8[1] * pos8[1] + pos8[2] * pos8[2]);
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
output->r_hat[i] = pos8[i] / x;
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********equ2gal */
|
|
|
|
void equ2gal (double rai, double deci,
|
|
|
|
double *glon, double *glat)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
To convert ICRS right ascension and declination to galactic
|
|
longitude and latitude.
|
|
|
|
REFERENCES:
|
|
Hipparcos and Tycho Catalogues, Vol. 1, Section 1.5.3.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
rai (double)
|
|
ICRS right ascension in hours.
|
|
deci (double)
|
|
ICRS declination in degrees.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*glon (double)
|
|
Galactic longitude in degrees.
|
|
*glat (double)
|
|
Galactic latitude in degrees.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
DEG2RAD, RAD2DEG novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
sin math.h
|
|
cos math.h
|
|
sqrt math.h
|
|
atan2 math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/11-03/JAB (USNO/AA)
|
|
V1.1/03-06/JAB (USNO/AA): Fixed initialization of 'ag'.
|
|
V1.2/03-11/WKP (USNO/AA): Added braces to 2-D array initialization
|
|
to quiet gcc warnings.
|
|
|
|
NOTES:
|
|
1. This function uses the coordinate transformation specified
|
|
in the reference.
|
|
2. This function is the C version of NOVAS Fortran routine
|
|
'eqgal'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
double r, d, pos1[3], pos2[3], xyproj, g;
|
|
|
|
/*
|
|
Rotation matrix A_g from Hipparcos documentation eq. 1.5.11.
|
|
*/
|
|
|
|
double ag[3][3] = {
|
|
{-0.0548755604, +0.4941094279, -0.8676661490},
|
|
{-0.8734370902, -0.4448296300, -0.1980763734},
|
|
{-0.4838350155, +0.7469822445, +0.4559837762}};
|
|
|
|
/*
|
|
Form position vector in equatorial system from input coordinates.
|
|
*/
|
|
|
|
r = rai * 15.0 * DEG2RAD;
|
|
d = deci * DEG2RAD;
|
|
pos1[0] = cos (d) * cos (r);
|
|
pos1[1] = cos (d) * sin (r);
|
|
pos1[2] = sin (d);
|
|
|
|
/*
|
|
Rotate position vector to galactic system, using Hipparcos
|
|
documentation eq. 1.5.13.
|
|
*/
|
|
|
|
pos2[0] = ag[0][0] * pos1[0] + ag[1][0] * pos1[1] +
|
|
|
|
ag[2][0] * pos1[2];
|
|
|
|
pos2[1] = ag[0][1] * pos1[0] + ag[1][1] * pos1[1] +
|
|
|
|
ag[2][1] * pos1[2];
|
|
|
|
pos2[2] = ag[0][2] * pos1[0] + ag[1][2] * pos1[1] +
|
|
|
|
ag[2][2] * pos1[2];
|
|
|
|
/*
|
|
Decompose galactic vector into longitude and latitude.
|
|
*/
|
|
|
|
xyproj = sqrt (pos2[0] * pos2[0] + pos2[1] * pos2[1]);
|
|
|
|
if (xyproj > 0.0)
|
|
g = atan2 (pos2[1], pos2[0]);
|
|
else
|
|
g = 0.0;
|
|
|
|
*glon = g * RAD2DEG;
|
|
if (*glon < 0.0)
|
|
*glon += 360.0;
|
|
|
|
g = atan2 (pos2[2], xyproj);
|
|
*glat = g * RAD2DEG;
|
|
|
|
return;
|
|
}
|
|
|
|
/********equ2ecl */
|
|
|
|
short int equ2ecl (double jd_tt, short int coord_sys,
|
|
short int accuracy, double ra, double dec,
|
|
|
|
double *elon, double *elat)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
To convert right ascension and declination to ecliptic longitude
|
|
and latitude.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date of equator, equinox, and ecliptic used for
|
|
coordinates.
|
|
coord_sys (short int)
|
|
Coordinate system selection.
|
|
= 0 ... mean equator and equinox of date 'jd_tt'
|
|
= 1 ... true equator and equinox of date 'jd_tt'
|
|
= 2 ... ICRS
|
|
(ecliptic is always the mean plane)
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
ra (double)
|
|
Right ascension in hours, referred to specified equator and
|
|
equinox of date.
|
|
dec (double)
|
|
Declination in degrees, referred to specified equator and
|
|
equinox of date.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*elon (double)
|
|
Ecliptic longitude in degrees, referred to specified ecliptic
|
|
and equinox of date.
|
|
*elat (double)
|
|
Ecliptic latitude in degrees, referred to specified ecliptic
|
|
and equinox of date.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... everything OK
|
|
= 1 ... invalid value of 'coord_sys'
|
|
|
|
GLOBALS
|
|
USED:
|
|
DEG2RAD, RAD2DEG novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
equ2ecl_vec novas.c
|
|
sin math.h
|
|
cos math.h
|
|
sqrt math.h
|
|
atan2 math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/11-03/JAB (USNO/AA)
|
|
V1.1/01-06/WKP (USNO/AA) Changed 'mode' to 'accuracy'.
|
|
V1.2/05-06/JAB (USNO/AA) Use vector transformation function.
|
|
V1.3/05-08/WKP (USNO/AA) Changed values of coord_sys to be
|
|
more consistent with gcrs2equ.
|
|
|
|
NOTES:
|
|
1. To convert ICRS RA and dec to ecliptic coordinates (mean
|
|
ecliptic and equinox of J2000.0), set 'coord_sys' = 2; the value
|
|
of 'jd_tt' can be set to anything, since J2000.0 is assumed.
|
|
Except for the input to this case, all input coordinates
|
|
are dynamical.
|
|
2. This function is the C version of NOVAS Fortran routine
|
|
'eqecl'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
|
|
double r, d, pos1[3], pos2[3], xyproj, e;
|
|
|
|
/*
|
|
Form position vector in equatorial system from input coordinates.
|
|
*/
|
|
|
|
r = ra * 15.0 * DEG2RAD;
|
|
d = dec * DEG2RAD;
|
|
pos1[0] = cos (d) * cos (r);
|
|
pos1[1] = cos (d) * sin (r);
|
|
pos1[2] = sin (d);
|
|
|
|
/*
|
|
Convert the vector from equatorial to ecliptic system.
|
|
*/
|
|
|
|
if ((error = equ2ecl_vec (jd_tt,coord_sys,accuracy,pos1, pos2)) != 0)
|
|
return (error);
|
|
|
|
/*
|
|
Decompose ecliptic vector into ecliptic longitude and latitude.
|
|
*/
|
|
|
|
xyproj = sqrt (pos2[0] * pos2[0] + pos2[1] * pos2[1]);
|
|
|
|
if (xyproj > 0.0)
|
|
e = atan2 (pos2[1], pos2[0]);
|
|
else
|
|
e = 0.0;
|
|
|
|
*elon = e * RAD2DEG;
|
|
if (*elon < 0.0)
|
|
*elon += 360.0;
|
|
|
|
e = atan2 (pos2[2], xyproj);
|
|
*elat = e * RAD2DEG;
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********equ2ecl_vec */
|
|
|
|
short int equ2ecl_vec (double jd_tt, short int coord_sys,
|
|
short int accuracy, double *pos1,
|
|
|
|
double *pos2)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Converts an equatorial position vector to an ecliptic position
|
|
vector.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date of equator, equinox, and ecliptic used for
|
|
coordinates.
|
|
coord_sys (short int)
|
|
Coordinate system selection.
|
|
= 0 ... mean equator and equinox of date 'jd_tt'
|
|
= 1 ... true equator and equinox of date 'jd_tt'
|
|
= 2 ... ICRS
|
|
(ecliptic is always the mean plane)
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
pos1[3] (double)
|
|
Position vector, referred to specified equator and equinox of
|
|
date.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
pos2[3] (double)
|
|
Position vector, referred to specified ecliptic and equinox
|
|
of date.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... everything OK
|
|
= 1 ... invalid value of 'coord_sys'
|
|
|
|
GLOBALS
|
|
USED:
|
|
T0, DEG2RAD novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
tdb2tt novas.c
|
|
e_tilt novas.c
|
|
frame_tie novas.c
|
|
fabs math.h
|
|
sin math.h
|
|
cos math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/05-06/JAB (USNO/AA)
|
|
V1.1/05-08/WKP (USNO/AA) Changed values of coord_sys to be
|
|
more consistent with gcrs2equ.
|
|
|
|
NOTES:
|
|
1. To convert an ICRS vector to an ecliptic vector (mean ecliptic
|
|
and equinox of J2000.0 only), set 'coord_sys' = 2; the value
|
|
of 'jd_tt' can be set to anything, since J2000.0 is assumed.
|
|
Except for the input to this case, all vectors are assumed
|
|
to be with respect to a dynamical system.
|
|
2. This function is the C version of NOVAS Fortran routine
|
|
'eqec'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
|
|
static double t_last = 0.0;
|
|
static double ob2000 = 0.0;
|
|
static double oblm, oblt;
|
|
double t, secdiff, jd_tdb, pos0[3], w, x, y, z, obl;
|
|
|
|
/*
|
|
'jd_tdb' is the TDB Julian date corresponding to 'jd_tt'.
|
|
*/
|
|
|
|
tdb2tt (jd_tt, &t,&secdiff);
|
|
jd_tdb = jd_tt + secdiff / 86400.0;
|
|
|
|
/*
|
|
Get obliquity, depending upon the "system" of the input coordinates.
|
|
*/
|
|
|
|
switch (coord_sys)
|
|
{
|
|
case 0: /* Input: mean equator and equinox of date */
|
|
case 1: /* Input: true equator and equinox of date */
|
|
pos0[0] = pos1[0];
|
|
pos0[1] = pos1[1];
|
|
pos0[2] = pos1[2];
|
|
if (fabs (jd_tt - t_last) > 1.0e-8)
|
|
{
|
|
e_tilt (jd_tdb,accuracy, &oblm,&oblt,&x,&y,&z);
|
|
t_last = jd_tt;
|
|
}
|
|
|
|
obl = DEG2RAD * ((coord_sys==0) ? oblm : oblt);
|
|
break;
|
|
|
|
case 2: /* Input: ICRS */
|
|
frame_tie (pos1,1, pos0);
|
|
|
|
if (ob2000 == 0.0)
|
|
{
|
|
e_tilt (T0,accuracy, &oblm,&w,&x,&y,&z);
|
|
ob2000 = oblm;
|
|
}
|
|
obl = ob2000 * DEG2RAD;
|
|
break;
|
|
|
|
default:
|
|
return (error = 1);
|
|
}
|
|
|
|
/*
|
|
Rotate position vector to ecliptic system.
|
|
*/
|
|
|
|
pos2[0] = pos0[0];
|
|
pos2[1] = pos0[1] * cos (obl) + pos0[2] * sin (obl);
|
|
pos2[2] = -pos0[1] * sin (obl) + pos0[2] * cos (obl);
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********ecl2equ_vec */
|
|
|
|
short int ecl2equ_vec (double jd_tt, short int coord_sys,
|
|
short int accuracy, double *pos1,
|
|
|
|
double *pos2)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Converts an ecliptic position vector to an equatorial position
|
|
vector.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date of equator, equinox, and ecliptic used for
|
|
coordinates.
|
|
coord_sys (short int)
|
|
Coordinate system selection.
|
|
= 0 ... mean equator and equinox of date
|
|
= 1 ... true equator and equinox of date
|
|
= 2 ... ICRS
|
|
(ecliptic is always the mean plane)
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
pos1[3] (double)
|
|
Position vector, referred to specified ecliptic and equinox of
|
|
date. If 'coord_sys' = 2, 'pos1' must be on mean ecliptic and
|
|
equinox of J2000.0; see Note 1 below.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
POS2[3] (double)
|
|
Position vector, referred to specified equator and equinox
|
|
of date.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... everything OK
|
|
= 1 ... invalid value of 'coord_sys'
|
|
|
|
GLOBALS
|
|
USED:
|
|
T0, DEG2RAD novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
tdb2tt novas.c
|
|
e_tilt novas.c
|
|
frame_tie novas.c
|
|
fabs math.h
|
|
sin math.h
|
|
cos math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/05-06/JAB (USNO/AA)
|
|
V1.1/05-08/WKP (USNO/AA) Changed values of coord_sys to be
|
|
more consistent with gcrs2equ.
|
|
V1.2/09-10/WKP (USNO/AA) Initialized 'obl' variable to silence
|
|
compiler warning.
|
|
|
|
NOTES:
|
|
1. To convert an ecliptic vector (mean ecliptic and equinox of
|
|
J2000.0 only) to an ICRS vector, set 'coord_sys' = 2; the value
|
|
of 'jd_tt' can be set to anything, since J2000.0 is assumed.
|
|
Except for the output from this case, all vectors are assumed to
|
|
be with respect to a dynamical system.
|
|
2. This function is the C version of NOVAS Fortran routine
|
|
'eceq'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
|
|
static double t_last = 0.0;
|
|
static double ob2000 = 0.0;
|
|
static double oblm, oblt;
|
|
double t, secdiff, jd_tdb, pos0[3], w, x, y, z, obl = 0.0;
|
|
|
|
/*
|
|
'jd_tdb' is the TDB Julian date.
|
|
*/
|
|
|
|
tdb2tt (jd_tt, &t,&secdiff);
|
|
jd_tdb = jd_tt + secdiff / 86400.0;
|
|
|
|
/*
|
|
Get obliquity, depending upon the "system" of the input coordinates.
|
|
*/
|
|
|
|
switch (coord_sys)
|
|
{
|
|
case 0: /* Output: mean equator and equinox of date */
|
|
case 1: /* Output: true equator and equinox of date */
|
|
if (fabs (jd_tt - t_last) > 1.0e-8)
|
|
{
|
|
e_tilt (jd_tdb,accuracy, &oblm,&oblt,&x,&y,&z);
|
|
t_last = jd_tt;
|
|
}
|
|
|
|
switch (coord_sys)
|
|
{
|
|
case 0: /* Use mean obliquity of date */
|
|
obl = oblm * DEG2RAD;
|
|
break;
|
|
case 1: /* Use true obliquity of date */
|
|
obl = oblt * DEG2RAD;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case 2: /* Output: ICRS */
|
|
if (ob2000 == 0.0)
|
|
{
|
|
e_tilt (T0,accuracy, &oblm,&w,&x,&y,&z);
|
|
ob2000 = oblm;
|
|
}
|
|
obl = ob2000 * DEG2RAD;
|
|
break;
|
|
|
|
default:
|
|
return (error = 1);
|
|
}
|
|
|
|
/*
|
|
Rotate position vector to ecliptic system.
|
|
*/
|
|
|
|
pos2[0] = pos1[0];
|
|
pos2[1] = pos1[1] * cos (obl) - pos1[2] * sin (obl);
|
|
pos2[2] = pos1[1] * sin (obl) + pos1[2] * cos (obl);
|
|
|
|
/*
|
|
Case where output vector is to be in ICRS, rotate from dynamical
|
|
system to ICRS.
|
|
*/
|
|
|
|
if (coord_sys == 2)
|
|
{
|
|
pos0[0] = pos2[0];
|
|
pos0[1] = pos2[1];
|
|
pos0[2] = pos2[2];
|
|
frame_tie (pos0,-1, pos2);
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********equ2hor */
|
|
|
|
void equ2hor (double jd_ut1, double delta_t, short int accuracy,
|
|
double xp, double yp, on_surface *location, double ra,
|
|
double dec, short int ref_option,
|
|
|
|
double *zd, double *az, double *rar, double *decr)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function transforms topocentric right ascension and
|
|
declination to zenith distance and azimuth. It uses a method
|
|
that properly accounts for polar motion, which is significant at
|
|
the sub-arcsecond level. This function can also adjust
|
|
coordinates for atmospheric refraction.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. (2008). USNO/AA Technical Note of 28 Apr 2008,
|
|
"Refraction as a Vector."
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_ut1 (double)
|
|
UT1 Julian date.
|
|
delta_t (double)
|
|
Difference TT-UT1 at 'jd_ut1', in seconds.
|
|
accuracy (short int)
|
|
Selection for method and accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
xp (double)
|
|
Conventionally-defined x coordinate of celestial intermediate
|
|
pole with respect to ITRS reference pole, in arcseconds.
|
|
yp (double)
|
|
Conventionally-defined y coordinate of celestial intermediate
|
|
pole with respect to ITRS reference pole, in arcseconds.
|
|
*location (struct on_surface)
|
|
Pointer to structure containing observer's location (defined
|
|
in novas.h).
|
|
ra (double)
|
|
Topocentric right ascension of object of interest, in hours,
|
|
referred to true equator and equinox of date.
|
|
dec (double)
|
|
Topocentric declination of object of interest, in degrees,
|
|
referred to true equator and equinox of date.
|
|
ref_option (short int)
|
|
= 0 ... no refraction
|
|
= 1 ... include refraction, using 'standard' atmospheric
|
|
conditions.
|
|
= 2 ... include refraction, using atmospheric parameters
|
|
input in the 'location' structure.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*zd (double)
|
|
Topocentric zenith distance in degrees, affected by
|
|
refraction if 'ref_option' is non-zero.
|
|
*az (double)
|
|
Topocentric azimuth (measured east from north) in degrees.
|
|
*rar (double)
|
|
Topocentric right ascension of object of interest, in hours,
|
|
referred to true equator and equinox of date, affected by
|
|
refraction if 'ref_option' is non-zero.
|
|
*decr (double)
|
|
Topocentric declination of object of interest, in degrees,
|
|
referred to true equator and equinox of date, affected by
|
|
refraction if 'ref_option' is non-zero.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
DEG2RAD, RAD2DEG novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
ter2cel novas.c
|
|
refract novas.c
|
|
sin math.h
|
|
cos math.h
|
|
sqrt math.h
|
|
atan2 math.h
|
|
fabs math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/06-98/JAB (USNO/AA)
|
|
V2.0/01-06/JAB (USNO/AA)
|
|
V2.1/01-06/WKP (USNO/AA): Changed 'mode' to 'accuracy'.
|
|
V2.2/11-07/JAB (USNO/AA): Cosmetic changes.
|
|
V2.2/05-08/WKP (USNO/AA): Updated the refraction algorithm.
|
|
V2.3/06-08/WKP (USNO/AA): Tweaked convergence criteria.
|
|
V2.4/03-09/JAB (USNO/AA): Conformed input variables to IERS
|
|
conventions.
|
|
|
|
NOTES:
|
|
1. 'xp' and 'yp' can be set to zero if sub-arcsecond accuracy is
|
|
not needed. 'ra' and 'dec' can be obtained from functions
|
|
'tpstar' or 'tpplan'.
|
|
2. The directions 'zd'= 0 (zenith) and 'az'= 0 (north) are here
|
|
considered fixed in the terrestrial system. Specifically, the
|
|
zenith is along the geodetic normal, and north is toward
|
|
the ITRS pole.
|
|
3. If 'ref_option'= 0, then 'rar'='ra' and 'decr'='dec'.
|
|
4. This function is the C version of NOVAS Fortran routine
|
|
'zdaz'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int j;
|
|
|
|
double sinlat, coslat, sinlon, coslon, sindc, cosdc, sinra, cosra,
|
|
uze[3], une[3], uwe[3], uz[3], un[3], uw[3], p[3], pz, pn, pw,
|
|
proj, zd0, zd1, refr, sinzd, coszd, sinzd0, coszd0, pr[3];
|
|
|
|
/*
|
|
Preliminaries.
|
|
*/
|
|
|
|
*rar = ra;
|
|
*decr = dec;
|
|
|
|
sinlat = sin (location->latitude * DEG2RAD);
|
|
coslat = cos (location->latitude * DEG2RAD);
|
|
sinlon = sin (location->longitude * DEG2RAD);
|
|
coslon = cos (location->longitude * DEG2RAD);
|
|
sindc = sin (dec * DEG2RAD);
|
|
cosdc = cos (dec * DEG2RAD);
|
|
sinra = sin (ra * 15.0 * DEG2RAD);
|
|
cosra = cos (ra * 15.0 * DEG2RAD);
|
|
|
|
/*
|
|
Set up orthonormal basis vectors in local Earth-fixed system.
|
|
|
|
Define vector toward local zenith in Earth-fixed system (z axis).
|
|
*/
|
|
uze[0] = coslat * coslon;
|
|
uze[1] = coslat * sinlon;
|
|
uze[2] = sinlat;
|
|
|
|
/*
|
|
Define vector toward local north in Earth-fixed system (x axis).
|
|
*/
|
|
|
|
une[0] = -sinlat * coslon;
|
|
une[1] = -sinlat * sinlon;
|
|
une[2] = coslat;
|
|
|
|
/*
|
|
Define vector toward local west in Earth-fixed system (y axis).
|
|
*/
|
|
|
|
uwe[0] = sinlon;
|
|
uwe[1] = -coslon;
|
|
uwe[2] = 0.0;
|
|
|
|
/*
|
|
Obtain vectors in celestial system.
|
|
|
|
Rotate Earth-fixed orthonormal basis vectors to celestial system
|
|
(wrt equator and equinox of date).
|
|
*/
|
|
|
|
ter2cel (jd_ut1,0.0,delta_t,1,accuracy,1,xp,yp,uze, uz);
|
|
ter2cel (jd_ut1,0.0,delta_t,1,accuracy,1,xp,yp,une, un);
|
|
ter2cel (jd_ut1,0.0,delta_t,1,accuracy,1,xp,yp,uwe, uw);
|
|
|
|
/*
|
|
Define unit vector 'p' toward object in celestial system
|
|
(wrt equator and equinox of date).
|
|
*/
|
|
|
|
p[0] = cosdc * cosra;
|
|
p[1] = cosdc * sinra;
|
|
p[2] = sindc;
|
|
|
|
/*
|
|
Compute coordinates of object wrt orthonormal basis.
|
|
|
|
Compute components of 'p' - projections of 'p' onto rotated
|
|
Earth-fixed basis vectors.
|
|
*/
|
|
|
|
pz = p[0] * uz[0] + p[1] * uz[1] + p[2] * uz[2];
|
|
pn = p[0] * un[0] + p[1] * un[1] + p[2] * un[2];
|
|
pw = p[0] * uw[0] + p[1] * uw[1] + p[2] * uw[2];
|
|
|
|
/*
|
|
Compute azimuth and zenith distance.
|
|
*/
|
|
|
|
proj = sqrt (pn * pn + pw * pw);
|
|
|
|
if (proj > 0.0)
|
|
*az = -atan2 (pw, pn) * RAD2DEG;
|
|
|
|
if (*az < 0.0)
|
|
*az += 360.0;
|
|
|
|
if (*az >= 360.0)
|
|
*az -= 360.0;
|
|
|
|
*zd = atan2 (proj, pz) * RAD2DEG;
|
|
|
|
/*
|
|
Apply atmospheric refraction if requested.
|
|
*/
|
|
|
|
if (ref_option != 0)
|
|
{
|
|
|
|
/*
|
|
Get refraction in zenith distance.
|
|
|
|
Iterative process is required because refraction algorithms are
|
|
always a function of observed (not computed) zenith distance.
|
|
Require convergence to 0.1 arcsec (actual accuracy less).
|
|
*/
|
|
|
|
zd0 = *zd;
|
|
|
|
do
|
|
{
|
|
zd1 = *zd;
|
|
refr = refract (location,ref_option,*zd);
|
|
*zd = zd0 - refr;
|
|
} while (fabs (*zd - zd1) > 3.0e-5);
|
|
|
|
/*
|
|
Apply refraction to celestial coordinates of object.
|
|
*/
|
|
|
|
if ((refr > 0.0) && (*zd > 3.0e-4))
|
|
{
|
|
|
|
/*
|
|
Shift position vector of object in celestial system to account
|
|
for refraction (see USNO/AA Technical Note 1998-09).
|
|
*/
|
|
|
|
sinzd = sin (*zd * DEG2RAD);
|
|
coszd = cos (*zd * DEG2RAD);
|
|
sinzd0 = sin (zd0 * DEG2RAD);
|
|
coszd0 = cos (zd0 * DEG2RAD);
|
|
|
|
/*
|
|
Compute refracted position vector.
|
|
*/
|
|
|
|
for (j = 0; j < 3; j++)
|
|
pr[j] = ((p[j] - coszd0 * uz[j]) / sinzd0) * sinzd + uz[j] *
|
|
coszd;
|
|
|
|
/*
|
|
Compute refracted right ascension and declination.
|
|
*/
|
|
|
|
proj = sqrt (pr[0] * pr[0] + pr[1] * pr[1]);
|
|
|
|
if (proj > 0.0)
|
|
*rar = atan2 (pr[1],pr[0]) * RAD2DEG / 15.0;
|
|
|
|
if (*rar < 0.0)
|
|
*rar += 24.0;
|
|
|
|
if (*rar >= 24.0)
|
|
*rar -= 24.0;
|
|
|
|
*decr = atan2 (pr[2],proj) * RAD2DEG;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
/********gcrs2equ */
|
|
|
|
short int gcrs2equ (double jd_tt, short int coord_sys,
|
|
short int accuracy, double rag, double decg,
|
|
|
|
double *ra, double *dec)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function converts GCRS right ascension and declination
|
|
to coordinates with respect to the equator of date (mean or true).
|
|
For coordinates with respect to the true equator of date, the
|
|
origin of right ascension can be either the true equinox or the
|
|
celestial intermediate origin (CIO).
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date of equator to be used for output coordinates.
|
|
coord_sys (short int)
|
|
Coordinate system selection for output coordinates.
|
|
= 0 ... mean equator and equinox of date
|
|
= 1 ... true equator and equinox of date
|
|
= 2 ... true equator and CIO of date
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
rag (double)
|
|
GCRS right ascension in hours.
|
|
decg (double)
|
|
GCRS declination in degrees.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
ra (double)
|
|
Right ascension in hours, referred to specified equator and
|
|
right ascension origin of date.
|
|
dec (double)
|
|
Declination in degrees, referred to specified equator of date.
|
|
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... everything OK.
|
|
< 0 ... error from function 'vector2radec'
|
|
> 10 ... 10 + error from function 'cio_location'
|
|
> 20 ... 20 + error from function 'cio_basis'
|
|
|
|
GLOBALS
|
|
USED:
|
|
DEG2RAD, T0 novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
tdb2tt novas.c
|
|
frame_tie novas.c
|
|
precession novas.c
|
|
nutation novas.c
|
|
cio_location novas.c
|
|
cio_basis novas.c
|
|
vector2radec novas.c
|
|
sin math.h
|
|
cos math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/09-04/JAB (USNO/AA)
|
|
V1.1/01-06/WKP (USNO/AA) Changed 'mode' to 'accuracy'.
|
|
V1.2/07-06/JAB (USNO/AA) Implement 'cio_location' construct.
|
|
V1.3/04-08/WKP (USNO/AA) Updated variable names.
|
|
|
|
NOTES:
|
|
1. Set input value of 'accuracy' equal to any short int if
|
|
'coord_sys' equals 0 or 1. It is not used in these cases.
|
|
2. This function only supports the CIO-based method.
|
|
3. This function is the C version of NOVAS Fortran routine
|
|
'gcrseq'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
short int rs;
|
|
|
|
double t1, t, secdiff, r, d, pos1[3], pos2[3], pos3[3], pos4[3],
|
|
r_cio, x[3], y[3], z[3];
|
|
|
|
/*
|
|
't1' is the TDB Julian date.
|
|
*/
|
|
|
|
tdb2tt (jd_tt, &t,&secdiff);
|
|
t1 = jd_tt + secdiff / 86400.0;
|
|
|
|
/*
|
|
Form position vector in equatorial system from input coordinates.
|
|
*/
|
|
|
|
r = rag * 15.0 * DEG2RAD;
|
|
d = decg * DEG2RAD;
|
|
|
|
pos1[0] = cos (d) * cos (r);
|
|
pos1[1] = cos (d) * sin (r);
|
|
pos1[2] = sin (d);
|
|
|
|
/*
|
|
Transform the position vector based on the value of 'coord_sys'.
|
|
*/
|
|
|
|
if (coord_sys <= 1 )
|
|
{
|
|
|
|
/*
|
|
Transform the position vector from GCRS to mean equator and equinox
|
|
of date.
|
|
*/
|
|
|
|
frame_tie (pos1,1, pos2);
|
|
precession (T0,pos2,t1, pos3);
|
|
|
|
/*
|
|
If requested, transform further to true equator and equinox of date.
|
|
*/
|
|
|
|
if (coord_sys == 1)
|
|
{
|
|
nutation (t1,0,accuracy,pos3, pos4);
|
|
}
|
|
else
|
|
{
|
|
pos4[0] = pos3[0];
|
|
pos4[1] = pos3[1];
|
|
pos4[2] = pos3[2];
|
|
}
|
|
}
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
Obtain the basis vectors, in the GCRS, of the celestial intermediate
|
|
system.
|
|
*/
|
|
|
|
if ((error = cio_location (t1,accuracy, &r_cio,&rs)) != 0)
|
|
return (error += 10);
|
|
|
|
if ((error = cio_basis (t1,r_cio,rs,accuracy, x,y,z)) != 0)
|
|
return (error += 20);
|
|
|
|
/*
|
|
Transform position vector to the celestial intermediate system
|
|
(which has the CIO as its origin of right ascension).
|
|
*/
|
|
|
|
pos4[0] = x[0] * pos1[0] + x[1] * pos1[1] + x[2] * pos1[2];
|
|
pos4[1] = y[0] * pos1[0] + y[1] * pos1[1] + y[2] * pos1[2];
|
|
pos4[2] = z[0] * pos1[0] + z[1] * pos1[1] + z[2] * pos1[2];
|
|
}
|
|
|
|
/*
|
|
Convert the position vector to equatorial spherical coordinates.
|
|
*/
|
|
|
|
if ((error = vector2radec (pos4, ra,dec)) != 0)
|
|
{
|
|
*ra = 0.0;
|
|
*dec = 0.0;
|
|
return (-1 * error);
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********sidereal_time */
|
|
|
|
short int sidereal_time (double jd_high, double jd_low,
|
|
double delta_t,short int gst_type,
|
|
short int method, short int accuracy,
|
|
|
|
double *gst)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Computes the Greenwich sidereal time, either mean or apparent, at
|
|
Julian date 'jd_high' + 'jd_low'.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. (2005), US Naval Observatory Circular 179.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_high (double)
|
|
High-order part of UT1 Julian date.
|
|
jd_low (double)
|
|
Low-order part of UT1 Julian date.
|
|
delta_t (double)
|
|
Difference TT-UT1 at 'jd_high'+'jd_low', in seconds
|
|
of time.
|
|
gst_type (short int)
|
|
= 0 ... compute Greenwich mean sidereal time
|
|
= 1 ... compute Greenwich apparent sidereal time
|
|
method (short int)
|
|
Selection for method
|
|
= 0 ... CIO-based method
|
|
= 1 ... equinox-based method
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*gst (double)
|
|
Greenwich (mean or apparent) sidereal time, in hours.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... everything OK
|
|
= 1 ... invalid value of 'accuracy'
|
|
= 2 ... invalid value of 'method'
|
|
> 10, < 30 ... 10 + error from function 'cio_rai'
|
|
|
|
GLOBALS
|
|
USED:
|
|
T0, RAD2DEG novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
tdb2tt novas.c
|
|
era novas.c
|
|
e_tilt novas.c
|
|
cio_location novas.c
|
|
cio_basis novas.c
|
|
nutation novas.c
|
|
precession novas.c
|
|
frame_tie novas.c
|
|
fabs math.h
|
|
atan2 math.h
|
|
fmod math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/06-92/TKB (USNO/NRL Optical Interfer.) Translate Fortran.
|
|
V1.1/08-93/WTH (USNO/AA) Update to C programing standards.
|
|
V1.2/03-98/JAB (USNO/AA) Expand documentation.
|
|
V1.3/08-98/JAB (USNO/AA) Match flow of the Fortran counterpart.
|
|
V2.0/09-03/JAB (USNO/AA) Incorporate the 2nd-reference changes.
|
|
V2.1/08-04/JAB (USNO/AA) Incorporate the 1st-reference changes.
|
|
V2.2/12-05/WKP (USNO/AA) Updated error handling.
|
|
V2.3/01-06/WKP (USNO/AA) Changed 'mode' to 'method' and 'accuracy'.
|
|
V2.4/04-06/JAB (USNO/AA) Use precession-in-RA terms in mean
|
|
sidereal time from third reference.
|
|
V2.5/07-06/JAB (USNO/AA) Implement 'cio_location' construct.
|
|
V2.6/06-08/WKP (USNO/AA) Changed value of direction argument in
|
|
call to 'nutation' from 1 to -1 for
|
|
consistency.
|
|
V2.7/03-11/WKP (USNO/AA) Updated prolog description to clarify
|
|
this function computes either mean or
|
|
apparent sidereal time, and removed
|
|
Note 1 for consistency with Fortran.
|
|
|
|
NOTES:
|
|
1. The Julian date may be split at any point, but for highest
|
|
precision, set 'jd_high' to be the integral part of the Julian
|
|
date, and set 'jd_low' to be the fractional part.
|
|
2. This function is the C version of NOVAS Fortran routine
|
|
'sidtim'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
short int ref_sys;
|
|
|
|
static double ee;
|
|
static double jd_last = -99.0;
|
|
double unitx[3] = {1.0, 0.0, 0.0};
|
|
double jd_ut, jd_tt, jd_tdb, tt_temp, t, theta, a, b, c, d,
|
|
ra_cio, x[3], y[3], z[3], w1[3], w2[3], eq[3], ha_eq, st,
|
|
secdiff, eqeq;
|
|
|
|
/*
|
|
Invalid value of 'accuracy'.
|
|
*/
|
|
|
|
if ((accuracy < 0) || (accuracy > 1))
|
|
return (error = 1);
|
|
|
|
/*
|
|
Time argument for precession and nutation components of sidereal
|
|
time is TDB. First approximation is TDB = TT, then refine.
|
|
*/
|
|
|
|
jd_ut = jd_high + jd_low;
|
|
jd_tt = jd_ut + (delta_t / 86400.0);
|
|
jd_tdb = jd_tt;
|
|
tdb2tt (jd_tdb, &tt_temp,&secdiff);
|
|
jd_tdb = jd_tt + (secdiff / 86400.0);
|
|
|
|
t = (jd_tdb - T0) / 36525.0;
|
|
|
|
/*
|
|
Compute the Earth Rotation Angle. Time argument is UT1.
|
|
*/
|
|
|
|
theta = era (jd_high, jd_low);
|
|
|
|
/*
|
|
Compute the equation of the equinoxes if needed, depending upon the
|
|
input values of 'gst_type' and 'method'. If not needed, set to zero.
|
|
*/
|
|
|
|
if (((gst_type == 0) && (method == 0)) || /* GMST; CIO-TIO */
|
|
((gst_type == 1) && (method == 1))) /* GAST; equinox */
|
|
{
|
|
if (fabs (jd_tdb - jd_last) > 1.0e-8)
|
|
{
|
|
e_tilt (jd_tdb,accuracy, &a,&b,&ee,&c,&d);
|
|
jd_last = jd_tdb;
|
|
}
|
|
eqeq = ee * 15.0;
|
|
}
|
|
else
|
|
{
|
|
eqeq = 0.0;
|
|
}
|
|
|
|
/*
|
|
Compute Greenwich sidereal time depending upon input values of
|
|
'method' and 'gst_type'.
|
|
*/
|
|
|
|
switch (method)
|
|
{
|
|
case (0):
|
|
|
|
/*
|
|
Use 'CIO-TIO-theta' method. See Circular 179, Section 6.5.4.
|
|
*/
|
|
|
|
/*
|
|
Obtain the basis vectors, in the GCRS, of the celestial intermediate
|
|
system.
|
|
*/
|
|
|
|
if ((error = cio_location (jd_tdb,accuracy, &ra_cio,
|
|
&ref_sys)) != 0)
|
|
{
|
|
*gst = 99.0;
|
|
return (error += 10);
|
|
}
|
|
|
|
cio_basis (jd_tdb,ra_cio,ref_sys,accuracy, x,y,z);
|
|
|
|
/*
|
|
Compute the direction of the true equinox in the GCRS.
|
|
*/
|
|
|
|
nutation (jd_tdb,-1,accuracy,unitx, w1);
|
|
precession (jd_tdb,w1,T0, w2);
|
|
frame_tie (w2,-1, eq);
|
|
|
|
/*
|
|
Compute the hour angle of the equinox wrt the TIO meridian
|
|
(near Greenwich, but passes through the CIP and TIO).
|
|
*/
|
|
|
|
ha_eq = theta - atan2 ((eq[0] * y[0] + eq[1] * y[1] +
|
|
eq[2] * y[2]), (eq[0] * x[0] + eq[1] * x[1] +
|
|
eq[2] * x[2])) * RAD2DEG;
|
|
|
|
/*
|
|
For mean sidereal time, subtract the equation of the equinoxes.
|
|
*/
|
|
|
|
ha_eq -= (eqeq / 240.0);
|
|
|
|
ha_eq = fmod (ha_eq, 360.0) / 15.0;
|
|
if (ha_eq < 0.0)
|
|
ha_eq += 24.0;
|
|
*gst = ha_eq;
|
|
break;
|
|
|
|
case (1):
|
|
|
|
/*
|
|
Use equinox method. See Circular 179, Section 2.6.2.
|
|
*/
|
|
|
|
/*
|
|
Precession-in-RA terms in mean sidereal time taken from third
|
|
reference, eq. (42), with coefficients in arcseconds.
|
|
*/
|
|
|
|
st = eqeq + 0.014506 +
|
|
(((( - 0.0000000368 * t
|
|
- 0.000029956 ) * t
|
|
- 0.00000044 ) * t
|
|
+ 1.3915817 ) * t
|
|
+ 4612.156534 ) * t;
|
|
|
|
/*
|
|
Form the Greenwich sidereal time.
|
|
*/
|
|
|
|
*gst = fmod ((st / 3600.0 + theta), 360.0) / 15.0;
|
|
|
|
if (*gst < 0.0)
|
|
*gst += 24.0;
|
|
break;
|
|
|
|
/*
|
|
Invalid value of 'method'.
|
|
*/
|
|
|
|
default:
|
|
*gst = 99.0;
|
|
error = 2;
|
|
break;
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********era */
|
|
|
|
double era (double jd_high, double jd_low)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function returns the value of the Earth Rotation Angle
|
|
(theta) for a given UT1 Julian date. The expression used is
|
|
taken from the note to IAU Resolution B1.8 of 2000.
|
|
|
|
REFERENCES:
|
|
IAU Resolution B1.8, adopted at the 2000 IAU General Assembly,
|
|
Manchester, UK.
|
|
Kaplan, G. (2005), US Naval Observatory Circular 179.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_high (double)
|
|
High-order part of UT1 Julian date.
|
|
jd_low (double)
|
|
Low-order part of UT1 Julian date.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
None.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(double)
|
|
The Earth Rotation Angle (theta) in degrees.
|
|
|
|
GLOBALS
|
|
USED:
|
|
T0 novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
fmod math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/09-03/JAB (USNO/AA)
|
|
|
|
NOTES:
|
|
1. The algorithm used here is equivalent to the canonical
|
|
theta = 0.7790572732640 + 1.00273781191135448 * t,
|
|
where t is the time in days from J2000 (t = jd_high +
|
|
jd_low - T0), but it avoids many two-PI 'wraps' that decrease
|
|
precision (adopted from SOFA Fortran routine iau_era00; see
|
|
also expression at top of page 35 of IERS Conventions (1996)).
|
|
2. This function is the C version of NOVAS Fortran routine
|
|
'erot'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
|
|
{
|
|
double theta, thet1, thet2, thet3;
|
|
|
|
thet1 = 0.7790572732640 + 0.00273781191135448 * (jd_high - T0);
|
|
thet2 = 0.00273781191135448 * jd_low;
|
|
thet3 = fmod (jd_high, 1.0) + fmod (jd_low, 1.0);
|
|
|
|
theta = fmod (thet1 + thet2 + thet3, 1.0) * 360.0;
|
|
if (theta < 0.0)
|
|
theta += 360.0;
|
|
|
|
return theta;
|
|
}
|
|
|
|
/********ter2cel */
|
|
|
|
short int ter2cel (double jd_ut_high, double jd_ut_low, double delta_t,
|
|
short int method, short int accuracy, short int option,
|
|
double xp, double yp, double *vec1,
|
|
|
|
double *vec2)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function rotates a vector from the terrestrial to the
|
|
celestial system. Specifically, it transforms a vector in the
|
|
ITRS (rotating earth-fixed system) to the GCRS (a local space-
|
|
fixed system) by applying rotations for polar motion, Earth
|
|
rotation, nutation, precession, and the dynamical-to-GCRS
|
|
frame tie.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
Kaplan, G. H. (2003), 'Another Look at Non-Rotating Origins',
|
|
Proceedings of IAU XXV Joint Discussion 16.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_ut_high (double)
|
|
High-order part of UT1 Julian date.
|
|
jd_ut_low (double)
|
|
Low-order part of UT1 Julian date.
|
|
delta_t (double)
|
|
Value of Delta T (= TT - UT1) at the input UT1 Julian date.
|
|
method (short int)
|
|
Selection for method
|
|
= 0 ... CIO-based method
|
|
= 1 ... equinox-based method
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
option (short int)
|
|
= 0 ... The output vector is referred to GCRS axes.
|
|
= 1 ... The output vector is produced with respect to the
|
|
equator and equinox of date.
|
|
See Note 2 below.
|
|
xp (double)
|
|
Conventionally-defined X coordinate of celestial intermediate
|
|
pole with respect to ITRS pole, in arcseconds.
|
|
yp (double)
|
|
Conventionally-defined Y coordinate of celestial intermediate
|
|
pole with respect to ITRS pole, in arcseconds.
|
|
vec1[3] (double)
|
|
Position vector, geocentric equatorial rectangular coordinates,
|
|
referred to ITRS axes (terrestrial system) in the normal case
|
|
where 'option' = 0.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
vec2[3] (double)
|
|
Position vector, geocentric equatorial rectangular coordinates,
|
|
referred to GCRS axes (celestial system) or with respect to
|
|
the equator and equinox of date, depending on 'option'.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
= 0 ... everything is ok.
|
|
= 1 ... invalid value of 'accuracy'
|
|
= 2 ... invalid value of 'method'
|
|
> 10 ... 10 + error from function 'cio_location'
|
|
> 20 ... 20 + error from function 'cio_basis'
|
|
|
|
GLOBALS
|
|
USED:
|
|
T0 novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
tdb2tt novas.c
|
|
wobble novas.c
|
|
cio_location novas.c
|
|
cio_basis novas.c
|
|
era novas.c
|
|
spin novas.c
|
|
sidereal_time novas.c
|
|
nutation novas.c
|
|
precession novas.c
|
|
frame_tie novas.c
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/08-93/WTH (USNO/AA) Translate Fortran.
|
|
V2.0/10-03/JAB (USNO/AA) Formerly function 'pnsw.' Update
|
|
for IAU 2000 resolutions.
|
|
V2.1/01-05/JAB (USNO/AA) Update to include 'mode' flexibility.
|
|
V2.2/12-05/WKP (USNO/AA) Check error codes.
|
|
V2.3/01-06/WKP (USNO/AA) Changed 'mode' to 'method' and 'accuracy'.
|
|
V2.4/07-06/JAB (USNO/AA) Implement 'cio_location' construct.
|
|
V2.5/06-08/WKP (USNO/AA) Corrected sign of direction argument in
|
|
'frame_tie' call and changed value of
|
|
direction argument in call to 'nutation'
|
|
for consistency.
|
|
V2.6/10-08/WKP (USNO/AA) Renamed input JD variables to include
|
|
time system.
|
|
V2.7/03-09/JAB (USNO/AA) Conformed input variables to IERS
|
|
conventions.
|
|
V2.8/12-10/JAB (USNO/AA) Cosmetic changes for consistency with
|
|
Fortran.
|
|
|
|
NOTES:
|
|
1. 'xp' = 'yp' = 0 means no polar motion transformation.
|
|
2. The 'option' flag only works for the equinox-based method.
|
|
3. This function is the C version of NOVAS Fortran routine
|
|
'tercel'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
short int rs, j;
|
|
|
|
double jd_ut1, jd_tt, dummy, secdiff, jd_tdb, gast, r_cio, theta,
|
|
v1[3], v2[3], v3[3], v4[3], x[3], y[3], z[3];
|
|
|
|
vec2[0] = vec2[1] = vec2[2] = 0.0; /* [Don Cross]: fix build warning. */
|
|
|
|
/*
|
|
Invalid value of 'accuracy'.
|
|
*/
|
|
|
|
if ((accuracy < 0) || (accuracy > 1))
|
|
return (error = 1);
|
|
|
|
/*
|
|
Compute the TT Julian date corresponding to the input UT1 Julian
|
|
date.
|
|
*/
|
|
|
|
jd_ut1 = jd_ut_high + jd_ut_low;
|
|
jd_tt = jd_ut1 + (delta_t / 86400.0);
|
|
|
|
/*
|
|
Compute the TDB Julian date corresponding to the input UT1 Julian
|
|
date.
|
|
*/
|
|
|
|
jd_tdb = jd_tt;
|
|
tdb2tt (jd_tdb, &dummy,&secdiff);
|
|
jd_tdb = jd_tt + secdiff / 86400.0;
|
|
|
|
switch (method)
|
|
{
|
|
case (0):
|
|
|
|
/*
|
|
'CIO-TIO-THETA' method.
|
|
|
|
See second reference, eq. (3) and (4).
|
|
|
|
Apply polar motion, transforming the vector to the terrestrial
|
|
intermediate system.
|
|
*/
|
|
|
|
if ((xp == 0.0) && (yp == 0.0))
|
|
{
|
|
v1[0] = vec1[0];
|
|
v1[1] = vec1[1];
|
|
v1[2] = vec1[2];
|
|
}
|
|
else
|
|
wobble (jd_tdb,0,xp,yp,vec1, v1);
|
|
|
|
/*
|
|
Obtain the basis vectors, in the GCRS, of the celestial intermediate
|
|
system.
|
|
*/
|
|
|
|
if ((error = cio_location (jd_tdb,accuracy, &r_cio,&rs)) != 0)
|
|
return (error += 10);
|
|
|
|
if ((error = cio_basis (jd_tdb,r_cio,rs,accuracy, x,y,z)) != 0)
|
|
return (error += 20);
|
|
|
|
/*
|
|
Compute and apply the Earth rotation angle, 'theta', transforming the
|
|
vector to the celestial intermediate system.
|
|
*/
|
|
|
|
theta = era (jd_ut_high,jd_ut_low);
|
|
spin (-theta,v1, v2);
|
|
|
|
/*
|
|
Transform the vector from the celestial intermediate system to the
|
|
GCRS.
|
|
*/
|
|
|
|
vec2[0] = x[0] * v2[0] + y[0] * v2[1] + z[0] * v2[2];
|
|
vec2[1] = x[1] * v2[0] + y[1] * v2[1] + z[1] * v2[2];
|
|
vec2[2] = x[2] * v2[0] + y[2] * v2[1] + z[2] * v2[2];
|
|
break;
|
|
|
|
case (1):
|
|
|
|
/*
|
|
Equinox mode.
|
|
|
|
Apply polar motion.
|
|
*/
|
|
|
|
if ((xp == 0.0) && (yp == 0.0))
|
|
{
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
v1[j] = vec1[j];
|
|
}
|
|
}
|
|
else
|
|
wobble (jd_tdb,0,xp,yp,vec1, v1);
|
|
|
|
/*
|
|
Apply Earth rotation.
|
|
*/
|
|
|
|
sidereal_time (jd_ut_high,jd_ut_low,delta_t,1,1,accuracy, &gast);
|
|
spin (-gast * 15.0,v1, v2);
|
|
|
|
/*
|
|
'option' = 1 skips remaining transformations.
|
|
*/
|
|
|
|
if (option == 1)
|
|
{
|
|
vec2[0] = v2[0];
|
|
vec2[1] = v2[1];
|
|
vec2[2] = v2[2];
|
|
}
|
|
else
|
|
{
|
|
|
|
/*
|
|
Apply precession, nutation, and frame tie.
|
|
*/
|
|
|
|
nutation (jd_tdb,-1,accuracy,v2, v3);
|
|
precession (jd_tdb,v3,T0, v4);
|
|
frame_tie (v4,-1, vec2);
|
|
}
|
|
break;
|
|
|
|
/*
|
|
Invalid value of 'method'.
|
|
*/
|
|
|
|
default:
|
|
error = 2;
|
|
break;
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********cel2ter */
|
|
|
|
short int cel2ter (double jd_ut_high, double jd_ut_low, double delta_t,
|
|
short int method, short int accuracy, short int option,
|
|
double xp, double yp, double *vec1,
|
|
|
|
double *vec2)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function rotates a vector from the celestial to the
|
|
terrestrial system. Specifically, it transforms a vector in the
|
|
GCRS (a local space-fixed system) to the ITRS (a rotating earth-
|
|
fixed system) by applying rotations for the GCRS-to-dynamical
|
|
frame tie, precession, nutation, Earth rotation, and polar motion.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
Kaplan, G. H. (2003), 'Another Look at Non-Rotating Origins',
|
|
Proceedings of IAU XXV Joint Discussion 16.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_ut_high (double)
|
|
High-order part of UT1 Julian date.
|
|
jd_ut_low (double)
|
|
Low-order part of UT1 Julian date.
|
|
delta_t (double)
|
|
Value of Delta T (= TT - UT1) at the input UT1 Julian date.
|
|
method (short int)
|
|
Selection for method
|
|
= 0 ... CIO-based method
|
|
= 1 ... equinox-based method
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
option (short int)
|
|
= 0 ... The input vector is referred to GCRS axes.
|
|
= 1 ... The input vector is produced with respect to the
|
|
equator and equinox of date.
|
|
See Note 2 below.
|
|
xp (double)
|
|
Conventionally-defined X coordinate of celestial intermediate
|
|
pole with respect to ITRS pole, in arcseconds.
|
|
yp (double)
|
|
Conventionally-defined Y coordinate of celestial intermediate
|
|
pole with respect to ITRS pole, in arcseconds.
|
|
vec1[3] (double)
|
|
Position vector, geocentric equatorial rectangular coordinates,
|
|
referred to GCRS axes (celestial system) or with respect to
|
|
the equator and equinox of date, depending on 'option'.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
vec2[3] (double)
|
|
Position vector, geocentric equatorial rectangular coordinates,
|
|
referred to ITRS axes (terrestrial system).
|
|
|
|
RETURNED
|
|
VALUE:
|
|
= 0 ... everything is ok.
|
|
= 1 ... invalid value of 'accuracy'
|
|
= 2 ... invalid value of 'method'
|
|
> 10 ... 10 + error from function 'cio_location'
|
|
> 20 ... 20 + error from function 'cio_basis'
|
|
|
|
GLOBALS
|
|
USED:
|
|
T0 novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
tdb2tt novas.c
|
|
wobble novas.c
|
|
cio_location novas.c
|
|
cio_basis novas.c
|
|
era novas.c
|
|
spin novas.c
|
|
sidereal_time novas.c
|
|
nutation novas.c
|
|
precession novas.c
|
|
frame_tie novas.c
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/03-09/JAB (USNO/AA)
|
|
V1.1/12-10/JAB (USNO/AA) Fix confusion with input/output vectors;
|
|
cosmetic changes to better match Fortran.
|
|
|
|
NOTES:
|
|
1. 'xp' = 'yp' = 0 means no polar motion transformation.
|
|
2. 'option' = 1 only works for the equinox-based method
|
|
('method' = 1).
|
|
3. This function is the C version of NOVAS Fortran routine
|
|
'celter'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
short int rs, j;
|
|
|
|
double jd_ut1, jd_tt, dummy, secdiff, jd_tdb, gast, r_cio, theta,
|
|
v1[3], v2[3], v3[3], v4[3], x[3], y[3], z[3];
|
|
|
|
/*
|
|
Invalid value of 'accuracy'.
|
|
*/
|
|
|
|
if ((accuracy < 0) || (accuracy > 1))
|
|
return (error = 1);
|
|
|
|
/*
|
|
Compute the TT Julian date corresponding to the input UT1 Julian
|
|
date.
|
|
*/
|
|
|
|
jd_ut1 = jd_ut_high + jd_ut_low;
|
|
jd_tt = jd_ut1 + (delta_t / 86400.0);
|
|
|
|
/*
|
|
Compute the TDB Julian date corresponding to the input UT1 Julian
|
|
date.
|
|
*/
|
|
|
|
jd_tdb = jd_tt;
|
|
tdb2tt (jd_tdb, &dummy,&secdiff);
|
|
jd_tdb = jd_tt + secdiff / 86400.0;
|
|
|
|
switch (method)
|
|
{
|
|
case (0):
|
|
|
|
/*
|
|
'CIO-TIO-THETA' method.
|
|
|
|
See second reference, eq. (3) and (4).
|
|
|
|
Obtain the basis vectors, in the GCRS, of the celestial intermediate
|
|
system.
|
|
*/
|
|
|
|
if ((error = cio_location (jd_tdb,accuracy, &r_cio,&rs)) != 0)
|
|
return (error += 10);
|
|
|
|
if ((error = cio_basis (jd_tdb,r_cio,rs,accuracy, x,y,z)) != 0)
|
|
return (error += 20);
|
|
|
|
/*
|
|
Transform the vector from the GCRS to the celestial intermediate
|
|
system.
|
|
*/
|
|
|
|
v1[0] = x[0] * vec1[0] + x[1] * vec1[1] + x[2] * vec1[2];
|
|
v1[1] = y[0] * vec1[0] + y[1] * vec1[1] + y[2] * vec1[2];
|
|
v1[2] = z[0] * vec1[0] + z[1] * vec1[1] + z[2] * vec1[2];
|
|
|
|
/*
|
|
Compute and apply the Earth rotation angle, 'theta', transforming the
|
|
vector to the terrestrial intermediate system.
|
|
*/
|
|
|
|
theta = era (jd_ut_high,jd_ut_low);
|
|
spin (theta,v1, v2);
|
|
|
|
/*
|
|
Apply polar motion, transforming the vector to the ITRS.
|
|
*/
|
|
|
|
if ((xp == 0.0) && (yp == 0.0))
|
|
{
|
|
vec2[0] = v2[0];
|
|
vec2[1] = v2[1];
|
|
vec2[2] = v2[2];
|
|
}
|
|
else
|
|
wobble (jd_tdb,1,xp,yp,v2, vec2);
|
|
|
|
break;
|
|
|
|
case (1):
|
|
|
|
/*
|
|
Equinox mode.
|
|
|
|
'option' = 1 skips initial transformations.
|
|
*/
|
|
|
|
if (option == 1)
|
|
{
|
|
v3[0] = vec1[0];
|
|
v3[1] = vec1[1];
|
|
v3[2] = vec1[2];
|
|
}
|
|
else
|
|
{
|
|
|
|
/*
|
|
Apply frame tie, nutation, and precession.
|
|
*/
|
|
|
|
frame_tie (vec1,1, v1);
|
|
precession (T0,v1,jd_tdb, v2);
|
|
nutation (jd_tdb,0,accuracy,v2, v3);
|
|
}
|
|
|
|
/*
|
|
Apply Earth rotation.
|
|
*/
|
|
|
|
sidereal_time (jd_ut_high,jd_ut_low,delta_t,1,1,accuracy, &gast);
|
|
spin (gast * 15.0,v3, v4);
|
|
|
|
/*
|
|
Apply polar motion.
|
|
*/
|
|
|
|
if ((xp == 0.0) && (yp == 0.0))
|
|
{
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
vec2[j] = v4[j];
|
|
}
|
|
}
|
|
else
|
|
wobble (jd_tdb,1,xp,yp,v4, vec2);
|
|
|
|
break;
|
|
|
|
/*
|
|
Invalid value of 'method'.
|
|
*/
|
|
|
|
default:
|
|
error = 2;
|
|
break;
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********spin */
|
|
|
|
void spin (double angle, double *pos1,
|
|
|
|
double *pos2)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function transforms a vector from one coordinate system
|
|
to another with same origin and axes rotated about the z-axis.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
angle (double)
|
|
Angle of coordinate system rotation, positive counterclockwise
|
|
when viewed from +z, in degrees.
|
|
pos1[3] (double)
|
|
Position vector.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
pos2[3] (double)
|
|
Position vector expressed in new coordinate system rotated
|
|
about z by 'angle'.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
DEG2RAD novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
sin math.h
|
|
cos math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/08-93/WTH (USNO/AA) Translate Fortran.
|
|
V2.0/10-03/JAB (USNO/AA) Update for IAU 2000 resolutions.
|
|
V2.1/01-05/JAB (USNO/AA) Generalize the function.
|
|
|
|
NOTES:
|
|
1. This function is the C version of NOVAS Fortran routine 'spin'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
static double ang_last = -999.0;
|
|
static double xx, yx, zx, xy, yy, zy, xz, yz, zz;
|
|
double angr, cosang, sinang;
|
|
|
|
if (fabs (angle - ang_last) >= 1.0e-12)
|
|
{
|
|
angr = angle * DEG2RAD;
|
|
cosang = cos (angr);
|
|
sinang = sin (angr);
|
|
|
|
/*
|
|
Rotation matrix follows.
|
|
*/
|
|
|
|
xx = cosang;
|
|
yx = sinang;
|
|
zx = 0.0;
|
|
xy = -sinang;
|
|
yy = cosang;
|
|
zy = 0.0;
|
|
xz = 0.0;
|
|
yz = 0.0;
|
|
zz = 1.0;
|
|
|
|
ang_last = angle;
|
|
}
|
|
|
|
/*
|
|
Perform rotation.
|
|
*/
|
|
|
|
pos2[0] = xx * pos1[0] + yx * pos1[1] + zx * pos1[2];
|
|
pos2[1] = xy * pos1[0] + yy * pos1[1] + zy * pos1[2];
|
|
pos2[2] = xz * pos1[0] + yz * pos1[1] + zz * pos1[2];
|
|
|
|
return;
|
|
}
|
|
|
|
/********wobble */
|
|
|
|
void wobble (double tjd, short int direction, double xp, double yp,
|
|
double *pos1,
|
|
|
|
double *pos2)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Corrects a vector in the ITRS (rotating Earth-fixed system)
|
|
for polar motion, and also corrects the longitude origin
|
|
(by a tiny amount) to the Terrestrial Intermediate Origin
|
|
(TIO). The ITRS vector is thereby transformed to the terrestrial
|
|
intermediate system, based on the true (rotational) equator and
|
|
TIO. Because the true equator is the plane orthogonal to the
|
|
direction of the Celestial Intermediate Pole (CIP), the components
|
|
of the output vector are referred to z and x axes toward the CIP
|
|
and TIO, respectively.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
Lambert & Bizouard (2002), Astronomy and Astrophysics 394,
|
|
317-321.
|
|
INPUT
|
|
ARGUMENTS:
|
|
tjd (double)
|
|
TT or UT1 Julian date.
|
|
direction (short int)
|
|
Flag determining 'direction' of transformation;
|
|
direction = 0 transformation applied, ITRS to terrestrial
|
|
intermediate system
|
|
direction != 0 inverse transformation applied, terrestrial
|
|
intermediate system to ITRS
|
|
xp (double)
|
|
Conventionally-defined X coordinate of Celestial Intermediate
|
|
Pole with respect to ITRS pole, in arcseconds.
|
|
yp (double)
|
|
Conventionally-defined Y coordinate of Celestial Intermediate
|
|
Pole with respect to ITRS pole, in arcseconds.
|
|
pos1[3] (double)
|
|
Position vector, geocentric equatorial rectangular coordinates,
|
|
referred to ITRS axes.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
pos2[3] (double)
|
|
Position vector, geocentric equatorial rectangular coordinates,
|
|
referred to true equator and TIO.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
T0, ASEC2RAD novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
sin math.h
|
|
cos math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/08-93/WTH (USNO/AA) Translate Fortran.
|
|
V2.0/10-03/JAB (USNO/AA) Update for IAU 2000 resolutions.
|
|
V2.1/01-05/JAB (USNO/AA) Include higher-order terms in the
|
|
rotation.
|
|
V2.2/06-05/JAB (USNO/AA) Corrected sign of first term in
|
|
expression for 'yy' (should be -).
|
|
V2.3/03-09/JAB (USNO/AA) Add 'direction' flag and inverse
|
|
transformation; conformed input
|
|
variables to IERS conventions.
|
|
|
|
NOTES:
|
|
1. This function is the C version of NOVAS Fortran routine
|
|
'wobble'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
double xpole, ypole, t, sprime, tiolon, sinx, cosx, siny, cosy, sinl,
|
|
cosl, xx, yx, zx, xy, yy, zy, xz, yz, zz;
|
|
|
|
xpole = xp * ASEC2RAD;
|
|
ypole = yp * ASEC2RAD;
|
|
|
|
/*
|
|
Compute approximate longitude of TIO, using eq. (10) of the second
|
|
reference.
|
|
|
|
Note that 'tiolon,' the longitude correction, is negligible for
|
|
most astronomical purposes.
|
|
*/
|
|
|
|
t = (tjd - T0) / 36525.0;
|
|
|
|
sprime = -47.0e-6 * t;
|
|
tiolon = -sprime * ASEC2RAD;
|
|
|
|
/*
|
|
Compute elements of rotation matrix.
|
|
Equivalent to R3(-s')R2(x)R1(y) as per IERS Conventions (2003).
|
|
*/
|
|
|
|
sinx = sin (xpole);
|
|
cosx = cos (xpole);
|
|
siny = sin (ypole);
|
|
cosy = cos (ypole);
|
|
sinl = sin (tiolon);
|
|
cosl = cos (tiolon);
|
|
|
|
xx = cosx * cosl;
|
|
yx = sinx * siny * cosl + cosy * sinl;
|
|
zx = -sinx * cosy * cosl + siny * sinl;
|
|
xy = -cosx * sinl;
|
|
yy = -sinx * siny * sinl + cosy * cosl;
|
|
zy = sinx * cosy * sinl + siny * cosl;
|
|
xz = sinx;
|
|
yz = -cosx * siny;
|
|
zz = cosx * cosy;
|
|
|
|
/*
|
|
Perform rotation from ITRS to terrestrial intermediate system.
|
|
*/
|
|
|
|
if (direction == 0)
|
|
{
|
|
pos2[0] = xx * pos1[0] + yx * pos1[1] + zx * pos1[2];
|
|
pos2[1] = xy * pos1[0] + yy * pos1[1] + zy * pos1[2];
|
|
pos2[2] = xz * pos1[0] + yz * pos1[1] + zz * pos1[2];
|
|
}
|
|
else
|
|
|
|
/*
|
|
Perform rotation from terrestrial intermediate system to ITRS.
|
|
*/
|
|
|
|
{
|
|
pos2[0] = xx * pos1[0] + xy * pos1[1] + xz * pos1[2];
|
|
pos2[1] = yx * pos1[0] + yy * pos1[1] + yz * pos1[2];
|
|
pos2[2] = zx * pos1[0] + zy * pos1[1] + zz * pos1[2];
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/********terra */
|
|
|
|
void terra (on_surface *location, double st,
|
|
|
|
double *pos, double *vel)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Computes the position and velocity vectors of a terrestrial
|
|
observer with respect to the center of the Earth.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
*location (struct on_surface)
|
|
Pointer to structure containing observer's location (defined
|
|
in novas.h).
|
|
st (double)
|
|
Local apparent sidereal time at reference meridian in hours.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
pos[3] (double)
|
|
Position vector of observer with respect to center of Earth,
|
|
equatorial rectangular coordinates, referred to true equator
|
|
and equinox of date, components in AU.
|
|
vel[3] (double)
|
|
Velocity vector of observer with respect to center of Earth,
|
|
equatorial rectangular coordinates, referred to true equator
|
|
and equinox of date, components in AU/day.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
AU_KM, ERAD, F novascon.c
|
|
ANGVEL, DEG2RAD novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
sin math.h
|
|
cos math.h
|
|
sqrt math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/04-93/WTH (USNO/AA): Translate Fortran.
|
|
V1.1/06-98/JAB (USNO/AA): Move constants 'f' and 'omega' to
|
|
file 'novascon.c'.
|
|
V1.2/10-03/JAB (USNO/AA): Updates Notes; removed call to 'pow'.
|
|
V1.3/12-04/JAB (USNO/AA): Update to use 'on_surface" structure.
|
|
V1.4/09-09/WKP (USNO/AA): Moved ht_km calculation from first_entry
|
|
block.
|
|
|
|
NOTES:
|
|
1. If reference meridian is Greenwich and st=0, 'pos' is
|
|
effectively referred to equator and Greenwich.
|
|
2. This function ignores polar motion, unless the
|
|
observer's longitude and latitude have been corrected for it,
|
|
and variation in the length of day (angular velocity of earth).
|
|
3. The true equator and equinox of date do not form an
|
|
inertial system. Therefore, with respect to an inertial system,
|
|
the very small velocity component (several meters/day) due to
|
|
the precession and nutation of the Earth's axis is not accounted
|
|
for here.
|
|
4. This function is the C version of NOVAS Fortran routine
|
|
'terra'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
static short int first_entry = 1;
|
|
short int j;
|
|
|
|
static double erad_km, ht_km;
|
|
double df, df2, phi, sinphi, cosphi, c, s, ach, ash, stlocl, sinst,
|
|
cosst;
|
|
|
|
if (first_entry)
|
|
{
|
|
erad_km = ERAD / 1000.0;
|
|
first_entry = 0;
|
|
}
|
|
|
|
/*
|
|
Compute parameters relating to geodetic to geocentric conversion.
|
|
*/
|
|
|
|
df = 1.0 - F;
|
|
df2 = df * df;
|
|
|
|
phi = location->latitude * DEG2RAD;
|
|
sinphi = sin (phi);
|
|
cosphi = cos (phi);
|
|
c = 1.0 / sqrt (cosphi * cosphi + df2 * sinphi * sinphi);
|
|
s = df2 * c;
|
|
ht_km = location->height / 1000.0;
|
|
ach = erad_km * c + ht_km;
|
|
ash = erad_km * s + ht_km;
|
|
|
|
/*
|
|
Compute local sidereal time factors at the observer's longitude.
|
|
*/
|
|
|
|
stlocl = (st * 15.0 + location->longitude) * DEG2RAD;
|
|
sinst = sin (stlocl);
|
|
cosst = cos (stlocl);
|
|
|
|
/*
|
|
Compute position vector components in kilometers.
|
|
*/
|
|
|
|
pos[0] = ach * cosphi * cosst;
|
|
pos[1] = ach * cosphi * sinst;
|
|
pos[2] = ash * sinphi;
|
|
|
|
/*
|
|
Compute velocity vector components in kilometers/sec.
|
|
*/
|
|
|
|
vel[0] = -ANGVEL * ach * cosphi * sinst;
|
|
vel[1] = ANGVEL * ach * cosphi * cosst;
|
|
vel[2] = 0.0;
|
|
|
|
/*
|
|
Convert position and velocity components to AU and AU/DAY.
|
|
*/
|
|
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
pos[j] /= AU_KM;
|
|
vel[j] /= AU_KM;
|
|
vel[j] *= 86400.0;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/********e_tilt */
|
|
|
|
void e_tilt (double jd_tdb, short int accuracy,
|
|
|
|
double *mobl, double *tobl, double *ee, double *dpsi,
|
|
double *deps)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Computes quantities related to the orientation of the Earth's
|
|
rotation axis at Julian date 'jd_tdb'.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tdb (double)
|
|
TDB Julian Date.
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*mobl (double)
|
|
Mean obliquity of the ecliptic in degrees at 'jd_tdb'.
|
|
*tobl (double)
|
|
True obliquity of the ecliptic in degrees at 'jd_tdb'.
|
|
*ee (double)
|
|
Equation of the equinoxes in seconds of time at 'jd_tdb'.
|
|
*dpsi (double)
|
|
Nutation in longitude in arcseconds at 'jd_tdb'.
|
|
*deps (double)
|
|
Nutation in obliquity in arcseconds at 'jd_tdb'.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
PSI_COR, EPS_COR novas.c
|
|
T0, ASEC2RAD novascon.c
|
|
DEG2RAD novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
nutation_angles novas.c
|
|
ee_ct novas.c
|
|
mean_obliq novas.c
|
|
fabs math.h
|
|
cos math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/08-93/WTH (USNO/AA) Translate Fortran.
|
|
V1.1/06-97/JAB (USNO/AA) Incorporate IAU (1994) and IERS (1996)
|
|
adjustment to the "equation of the
|
|
equinoxes".
|
|
V1.2/10-97/JAB (USNO/AA) Implement function that computes
|
|
arguments of the nutation series.
|
|
V1.3/07-98/JAB (USNO/AA) Use global variables 'PSI_COR' and
|
|
'EPS_COR' to apply celestial pole offsets
|
|
for high-precision applications.
|
|
V2.0/10-03/JAB (USNO/AA) Update function for IAU 2000 resolutions.
|
|
V2.1/12-04/JAB (USNO/AA) Add 'mode' argument.
|
|
V2.2/01-06/WKP (USNO/AA) Changed 'mode' to 'accuracy'.
|
|
|
|
NOTES:
|
|
1. Values of the celestial pole offsets 'PSI_COR' and 'EPS_COR'
|
|
are set using function 'cel_pole', if desired. See the prolog
|
|
of 'cel_pole' for details.
|
|
2. This function is the C version of NOVAS Fortran routine
|
|
'etilt'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
static short int accuracy_last = 0;
|
|
short int acc_diff;
|
|
|
|
static double jd_last = 0.0;
|
|
static double dp, de, c_terms;
|
|
double t, d_psi, d_eps, mean_ob, true_ob, eq_eq;
|
|
|
|
/*
|
|
Compute time in Julian centuries from epoch J2000.0.
|
|
*/
|
|
|
|
t = (jd_tdb - T0) / 36525.0;
|
|
|
|
/*
|
|
Check for difference in accuracy mode from last call.
|
|
*/
|
|
|
|
acc_diff = accuracy - accuracy_last;
|
|
|
|
/*
|
|
Compute the nutation angles (arcseconds) if the input Julian date
|
|
is significantly different from the last Julian date, or the
|
|
accuracy mode has changed from the last call.
|
|
*/
|
|
|
|
if (((fabs (jd_tdb - jd_last)) > 1.0e-8) || (acc_diff != 0))
|
|
{
|
|
nutation_angles (t,accuracy, &dp,&de);
|
|
|
|
/*
|
|
Obtain complementary terms for equation of the equinoxes in
|
|
arcseconds.
|
|
*/
|
|
|
|
c_terms = ee_ct (jd_tdb,0.0,accuracy) / ASEC2RAD;
|
|
|
|
/*
|
|
Reset the values of the last Julian date and last mode.
|
|
*/
|
|
|
|
jd_last = jd_tdb;
|
|
accuracy_last = accuracy;
|
|
}
|
|
|
|
/*
|
|
Apply observed celestial pole offsets.
|
|
*/
|
|
|
|
d_psi = dp + PSI_COR;
|
|
d_eps = de + EPS_COR;
|
|
|
|
/*
|
|
Compute mean obliquity of the ecliptic in arcseconds.
|
|
*/
|
|
|
|
mean_ob = mean_obliq (jd_tdb);
|
|
|
|
/*
|
|
Compute true obliquity of the ecliptic in arcseconds.
|
|
*/
|
|
|
|
true_ob = mean_ob + d_eps;
|
|
|
|
/*
|
|
Convert obliquity values to degrees.
|
|
*/
|
|
|
|
mean_ob /= 3600.0;
|
|
true_ob /= 3600.0;
|
|
|
|
/*
|
|
Compute equation of the equinoxes in seconds of time.
|
|
*/
|
|
|
|
eq_eq = d_psi * cos (mean_ob * DEG2RAD) + c_terms;
|
|
eq_eq /= 15.0;
|
|
|
|
/*
|
|
Set output values.
|
|
*/
|
|
|
|
*dpsi = d_psi;
|
|
*deps = d_eps;
|
|
*ee = eq_eq;
|
|
*mobl = mean_ob;
|
|
*tobl = true_ob;
|
|
|
|
return;
|
|
}
|
|
|
|
/********cel_pole */
|
|
|
|
short int cel_pole (double tjd, short int type, double dpole1,
|
|
double dpole2)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function allows for the specification of celestial pole
|
|
offsets for high-precision applications. Each set of offsets is
|
|
a correction to the modeled position of the pole for a specific
|
|
date, derived from observations and published by the IERS.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. (2005), US Naval Observatory Circular 179.
|
|
Kaplan, G. (2003), USNO/AA Technical Note 2003-03.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
tjd (double)
|
|
TDB or TT Julian date for pole offsets.
|
|
type (short int)
|
|
Type of pole offset
|
|
= 1 for corrections to angular coordinates of modeled pole
|
|
referred to mean ecliptic of date, that is,
|
|
delta-delta-psi and delta-delta-epsilon.
|
|
= 2 for corrections to components of modeled pole unit
|
|
vector referred to GCRS axes, that is, dx and dy.
|
|
dpole1 (double)
|
|
Value of celestial pole offset in first coordinate,
|
|
(delta-delta-psi or dx) in milliarcseconds.
|
|
dpole2 (double)
|
|
Value of celestial pole offset in second coordinate,
|
|
(delta-delta-epsilon or dy) in milliarcseconds.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
None.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... Everything OK.
|
|
= 1 ... Invalid value of 'type'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
PSI_COR, EPS_COR novas.c
|
|
T0, ASEC2RAD novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
frame_tie novas.c
|
|
precession novas.c
|
|
mean_obliq novas.c
|
|
sin math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/12-04/JAB (USNO/AA)
|
|
|
|
NOTES:
|
|
1. This function sets the values of global variables 'PSI_COR'
|
|
and 'EPS_COR' declared at the top of file 'novas.c'. These
|
|
global variables are used only in NOVAS function 'e_tilt'.
|
|
2. This function, if used, should be called before any other
|
|
NOVAS functions for a given date. Values of the pole offsets
|
|
specified via a call to this function will be used until
|
|
explicitly changed.
|
|
3. 'tjd' is used only for 'type' = 2, to transform dx and dy to
|
|
the equivalent delta-delta-psi and delta-delta-epsilon values.
|
|
4. For 'type' = 2, dx and dy are unit vector component
|
|
corrections, but are expressed in milliarcseconds simply by
|
|
multiplying by 206264806, the number of milliarcseconds in one
|
|
radian.
|
|
5. This function is the C version of NOVAS Fortran routine
|
|
'celpol'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
|
|
double dx, dy, t, mean_ob, sin_e, x, dz, dp1[3], dp2[3], dp3[3];
|
|
|
|
switch (type)
|
|
{
|
|
case (1):
|
|
|
|
/*
|
|
Angular coordinates of modeled pole referred to mean ecliptic of
|
|
date, that is,delta-delta-psi and delta-delta-epsilon.
|
|
*/
|
|
|
|
PSI_COR = dpole1 * 1.0e-3;
|
|
EPS_COR = dpole2 * 1.0e-3;
|
|
break;
|
|
|
|
case (2):
|
|
|
|
/*
|
|
Components of modeled pole unit vector referred to GCRS axes, that
|
|
is, dx and dy.
|
|
*/
|
|
|
|
dx = dpole1;
|
|
dy = dpole2;
|
|
|
|
t = (tjd - T0) / 36525.0;
|
|
|
|
/*
|
|
Compute sin_e of mean obliquity of date.
|
|
*/
|
|
|
|
mean_ob = mean_obliq (tjd);
|
|
sin_e = sin (mean_ob * ASEC2RAD);
|
|
|
|
/*
|
|
The following algorithm, to transform dx and dy to
|
|
delta-delta-psi and delta-delta-epsilon, is from eqs. (7)-(9) of the
|
|
second reference.
|
|
|
|
Trivial model of pole trajectory in GCRS allows computation of dz.
|
|
*/
|
|
|
|
x = (2004.190 * t) * ASEC2RAD;
|
|
dz = - (x + 0.5 * x * x * x) * dx;
|
|
|
|
/*
|
|
Form pole offset vector (observed - modeled) in GCRS.
|
|
*/
|
|
|
|
dp1[0] = dx * 1.0e-3 * ASEC2RAD;
|
|
dp1[1] = dy * 1.0e-3 * ASEC2RAD;
|
|
dp1[2] = dz * 1.0e-3 * ASEC2RAD;
|
|
|
|
/*
|
|
Precess pole offset vector to mean equator and equinox of date.
|
|
*/
|
|
|
|
frame_tie (dp1,1, dp2);
|
|
precession (T0,dp2,tjd, dp3);
|
|
|
|
/*
|
|
Compute delta-delta-psi and delta-delta-epsilon in arcseconds.
|
|
*/
|
|
|
|
PSI_COR = (dp3[0] / sin_e) / ASEC2RAD;
|
|
EPS_COR = dp3[1] / ASEC2RAD;
|
|
break;
|
|
|
|
default:
|
|
|
|
/*
|
|
Invalid value of 'type'.
|
|
*/
|
|
error = 1;
|
|
break;
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********ee_ct */
|
|
|
|
double ee_ct (double jd_high, double jd_low, short int accuracy)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
To compute the "complementary terms" of the equation of the
|
|
equinoxes.
|
|
|
|
REFERENCES:
|
|
Capitaine, N., Wallace, P.T., and McCarthy, D.D. (2003). Astron. &
|
|
Astrophys. 406, p. 1135-1149. Table 3.
|
|
IERS Conventions (2010), Chapter 5, p. 60, Table 5.2e.
|
|
(Table 5.2e presented in the printed publication is a truncated
|
|
series. The full series, which is used in NOVAS, is available
|
|
on the IERS Conventions Center website in file tab5.2e.txt.)
|
|
ftp://tai.bipm.org/iers/conv2010/chapter5/
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_high (double)
|
|
High-order part of TT Julian date.
|
|
jd_low (double)
|
|
Low-order part of TT Julian date.
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
None
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(double)
|
|
Complementary terms, in radians.
|
|
|
|
GLOBALS
|
|
USED:
|
|
T0, ASEC2RAD novascon.c
|
|
TWOPI novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
norm_ang novas.c
|
|
fund_args novas.c
|
|
fmod math.h
|
|
sin math.h
|
|
cos math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/09-03/JAB (USNO/AA)
|
|
V1.1/12-04/JAB (USNO/AA) Added low-accuracy formula.
|
|
V1.2/01-06/WKP (USNO/AA) Changed 'mode' to 'accuracy'.
|
|
V1.3/11-10/JAB (USNO/AA) Updated reference and notes.
|
|
V1.4/03-11/WKP (USNO/AA) Added braces to 2-D array initialization
|
|
to quiet gcc warnings.
|
|
|
|
NOTES:
|
|
1. The series used in this function was derived from the first
|
|
reference. This same series was also adopted for use in the IAU's
|
|
Standards of Fundamental Astronomy (SOFA) software (i.e.,
|
|
subroutine eect00.for and function eect00.c).
|
|
2. The low-accuracy series used in this function is a simple
|
|
implementation derived from the first reference, in which terms
|
|
smaller than 2 microarcseconds have been omitted.
|
|
3. This function is based on NOVAS Fortran routine 'eect2000',
|
|
with the low-accuracy formula taken from NOVAS Fortran routine
|
|
'etilt'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int i, j;
|
|
|
|
double t, fa[14], fa2[5], s0, s1, a, c_terms;
|
|
|
|
/*
|
|
Argument coefficients for t^0.
|
|
*/
|
|
|
|
const short int ke0_t[33][14] = {
|
|
{0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 0, 2, -2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 0, 2, -2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 0, 2, -2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 1, 2, -2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 1, 2, -2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 0, 4, -4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 0, 1, -1, 1, 0, -8, 12, 0, 0, 0, 0, 0, 0},
|
|
{0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{1, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 0, 2, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 1, -2, 2, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 1, -2, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 0, 0, 0, 0, 0, 8,-13, 0, 0, 0, 0, 0, -1},
|
|
{0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{2, 0, -2, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{1, 0, 0, -2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 1, 2, -2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{1, 0, 0, -2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 0, 4, -2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{0, 0, 2, -2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{1, 0, -2, 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
{1, 0, -2, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
|
|
|
|
/*
|
|
Argument coefficients for t^1.
|
|
*/
|
|
|
|
const short int ke1[14] =
|
|
{0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
|
/*
|
|
Sine and cosine coefficients for t^0.
|
|
*/
|
|
|
|
const double se0_t[33][2] = {
|
|
{+2640.96e-6, -0.39e-6},
|
|
{ +63.52e-6, -0.02e-6},
|
|
{ +11.75e-6, +0.01e-6},
|
|
{ +11.21e-6, +0.01e-6},
|
|
{ -4.55e-6, +0.00e-6},
|
|
{ +2.02e-6, +0.00e-6},
|
|
{ +1.98e-6, +0.00e-6},
|
|
{ -1.72e-6, +0.00e-6},
|
|
{ -1.41e-6, -0.01e-6},
|
|
{ -1.26e-6, -0.01e-6},
|
|
{ -0.63e-6, +0.00e-6},
|
|
{ -0.63e-6, +0.00e-6},
|
|
{ +0.46e-6, +0.00e-6},
|
|
{ +0.45e-6, +0.00e-6},
|
|
{ +0.36e-6, +0.00e-6},
|
|
{ -0.24e-6, -0.12e-6},
|
|
{ +0.32e-6, +0.00e-6},
|
|
{ +0.28e-6, +0.00e-6},
|
|
{ +0.27e-6, +0.00e-6},
|
|
{ +0.26e-6, +0.00e-6},
|
|
{ -0.21e-6, +0.00e-6},
|
|
{ +0.19e-6, +0.00e-6},
|
|
{ +0.18e-6, +0.00e-6},
|
|
{ -0.10e-6, +0.05e-6},
|
|
{ +0.15e-6, +0.00e-6},
|
|
{ -0.14e-6, +0.00e-6},
|
|
{ +0.14e-6, +0.00e-6},
|
|
{ -0.14e-6, +0.00e-6},
|
|
{ +0.14e-6, +0.00e-6},
|
|
{ +0.13e-6, +0.00e-6},
|
|
{ -0.11e-6, +0.00e-6},
|
|
{ +0.11e-6, +0.00e-6},
|
|
{ +0.11e-6, +0.00e-6}};
|
|
/*
|
|
Sine and cosine coefficients for t^1.
|
|
*/
|
|
|
|
const double se1[2] =
|
|
{ -0.87e-6, +0.00e-6};
|
|
|
|
/*
|
|
Interval between fundamental epoch J2000.0 and current date.
|
|
*/
|
|
|
|
t = ((jd_high - T0) + jd_low) / 36525.0;
|
|
|
|
/*
|
|
High accuracy mode.
|
|
*/
|
|
|
|
if (accuracy == 0)
|
|
{
|
|
|
|
/*
|
|
Fundamental Arguments.
|
|
|
|
Mean Anomaly of the Moon.
|
|
*/
|
|
|
|
fa[0] = norm_ang ((485868.249036 +
|
|
(715923.2178 +
|
|
( 31.8792 +
|
|
( 0.051635 +
|
|
( -0.00024470)
|
|
* t) * t) * t) * t) * ASEC2RAD
|
|
+ fmod (1325.0*t, 1.0) * TWOPI);
|
|
|
|
/*
|
|
Mean Anomaly of the Sun.
|
|
*/
|
|
|
|
fa[1] = norm_ang ((1287104.793048 +
|
|
(1292581.0481 +
|
|
( -0.5532 +
|
|
( +0.000136 +
|
|
( -0.00001149)
|
|
* t) * t) * t) * t) * ASEC2RAD
|
|
+ fmod (99.0*t, 1.0) * TWOPI);
|
|
|
|
/*
|
|
Mean Longitude of the Moon minus Mean Longitude of the Ascending
|
|
Node of the Moon.
|
|
*/
|
|
|
|
fa[2] = norm_ang (( 335779.526232 +
|
|
( 295262.8478 +
|
|
( -12.7512 +
|
|
( -0.001037 +
|
|
( 0.00000417)
|
|
* t) * t) * t) * t) * ASEC2RAD
|
|
+ fmod (1342.0*t, 1.0) * TWOPI);
|
|
|
|
/*
|
|
Mean Elongation of the Moon from the Sun.
|
|
*/
|
|
|
|
fa[3] = norm_ang ((1072260.703692 +
|
|
(1105601.2090 +
|
|
( -6.3706 +
|
|
( 0.006593 +
|
|
( -0.00003169)
|
|
* t) * t) * t) * t) * ASEC2RAD
|
|
+ fmod (1236.0*t, 1.0) * TWOPI);
|
|
|
|
/*
|
|
Mean Longitude of the Ascending Node of the Moon.
|
|
*/
|
|
|
|
fa[4] = norm_ang (( 450160.398036 +
|
|
(-482890.5431 +
|
|
( 7.4722 +
|
|
( 0.007702 +
|
|
( -0.00005939)
|
|
* t) * t) * t) * t) * ASEC2RAD
|
|
+ fmod (-5.0*t, 1.0) * TWOPI);
|
|
|
|
fa[ 5] = norm_ang (4.402608842 + 2608.7903141574 * t);
|
|
fa[ 6] = norm_ang (3.176146697 + 1021.3285546211 * t);
|
|
fa[ 7] = norm_ang (1.753470314 + 628.3075849991 * t);
|
|
fa[ 8] = norm_ang (6.203480913 + 334.0612426700 * t);
|
|
fa[ 9] = norm_ang (0.599546497 + 52.9690962641 * t);
|
|
fa[10] = norm_ang (0.874016757 + 21.3299104960 * t);
|
|
fa[11] = norm_ang (5.481293872 + 7.4781598567 * t);
|
|
fa[12] = norm_ang (5.311886287 + 3.8133035638 * t);
|
|
fa[13] = (0.024381750 + 0.00000538691 * t) * t;
|
|
|
|
/*
|
|
Evaluate the complementary terms.
|
|
*/
|
|
|
|
s0 = 0.0;
|
|
s1 = 0.0;
|
|
|
|
for (i = 32; i >= 0; i--)
|
|
{
|
|
a = 0.0;
|
|
|
|
for (j = 0; j < 14; j++)
|
|
{
|
|
a += (double) ke0_t[i][j] * fa[j];
|
|
}
|
|
|
|
s0 += (se0_t[i][0] * sin (a) + se0_t[i][1] * cos (a));
|
|
}
|
|
|
|
a = 0.0;
|
|
|
|
for (j = 0; j < 14; j++)
|
|
{
|
|
a += (double) (ke1[j]) * fa[j];
|
|
}
|
|
|
|
s1 += (se1[0] * sin (a) + se1[1] * cos (a));
|
|
|
|
c_terms = (s0 + s1 * t);
|
|
}
|
|
|
|
else
|
|
|
|
/*
|
|
Low accuracy mode: Terms smaller than 2 microarcseconds omitted.
|
|
*/
|
|
|
|
{
|
|
fund_args (t, fa2);
|
|
c_terms =
|
|
2640.96e-6 * sin (fa2[4])
|
|
+ 63.52e-6 * sin (2.0 * fa2[4])
|
|
+ 11.75e-6 * sin (2.0 * fa2[2] - 2.0 * fa2[3] + 3.0 * fa2[4])
|
|
+ 11.21e-6 * sin (2.0 * fa2[2] - 2.0 * fa2[3] + fa2[4])
|
|
- 4.55e-6 * sin (2.0 * fa2[2] - 2.0 * fa2[3] + 2.0 * fa2[4])
|
|
+ 2.02e-6 * sin (2.0 * fa2[2] + 3.0 * fa2[4])
|
|
+ 1.98e-6 * sin (2.0 * fa2[2] + fa2[4])
|
|
- 1.72e-6 * sin (3.0 * fa2[4])
|
|
- 0.87e-6 * t * sin (fa2[4]);
|
|
}
|
|
|
|
return (c_terms *= ASEC2RAD);
|
|
}
|
|
|
|
/********frame_tie */
|
|
|
|
void frame_tie (double *pos1, short int direction,
|
|
|
|
double *pos2)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
To transform a vector from the dynamical reference system to the
|
|
International Celestial Reference System (ICRS), or vice versa.
|
|
The dynamical reference system is based on the dynamical mean
|
|
equator and equinox of J2000.0. The ICRS is based on the space-
|
|
fixed ICRS axes defined by the radio catalog positions of several
|
|
hundred extragalactic objects.
|
|
|
|
REFERENCES:
|
|
Hilton, J. and Hohenkerk, C. (2004), Astronomy and Astrophysics
|
|
413, 765-770, eq. (6) and (8).
|
|
IERS (2003) Conventions, Chapter 5.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
pos1[3] (double)
|
|
Position vector, equatorial rectangular coordinates.
|
|
direction (short int)
|
|
Set 'direction' < 0 for dynamical to ICRS transformation.
|
|
Set 'direction' >= 0 for ICRS to dynamical transformation.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
pos2[3] (double)
|
|
Position vector, equatorial rectangular coordinates.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
ASEC2RAD novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
None.
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/09-03/JAB (USNO/AA)
|
|
V1.1/02-06/WKP (USNO/AA) Added second-order corrections to diagonal
|
|
elements.
|
|
|
|
NOTES:
|
|
1. For geocentric coordinates, the same transformation is used
|
|
between the dynamical reference system and the GCRS.
|
|
2. This function is the C version of NOVAS Fortran routine 'frame'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
static short int compute_matrix = 1;
|
|
|
|
/*
|
|
'xi0', 'eta0', and 'da0' are ICRS frame biases in arcseconds taken
|
|
from IERS (2003) Conventions, Chapter 5.
|
|
*/
|
|
|
|
const double xi0 = -0.0166170;
|
|
const double eta0 = -0.0068192;
|
|
const double da0 = -0.01460;
|
|
static double xx, yx, zx, xy, yy, zy, xz, yz, zz;
|
|
|
|
/*
|
|
Compute elements of rotation matrix to first order the first time
|
|
this function is called. Elements will be saved for future use and
|
|
not recomputed.
|
|
*/
|
|
|
|
if (compute_matrix == 1)
|
|
{
|
|
xx = 1.0;
|
|
yx = -da0 * ASEC2RAD;
|
|
zx = xi0 * ASEC2RAD;
|
|
xy = da0 * ASEC2RAD;
|
|
yy = 1.0;
|
|
zy = eta0 * ASEC2RAD;
|
|
xz = -xi0 * ASEC2RAD;
|
|
yz = -eta0 * ASEC2RAD;
|
|
zz = 1.0;
|
|
|
|
/*
|
|
Include second-order corrections to diagonal elements.
|
|
*/
|
|
|
|
xx = 1.0 - 0.5 * (yx * yx + zx * zx);
|
|
yy = 1.0 - 0.5 * (yx * yx + zy * zy);
|
|
zz = 1.0 - 0.5 * (zy * zy + zx * zx);
|
|
|
|
compute_matrix = 0;
|
|
}
|
|
|
|
/*
|
|
Perform the rotation in the sense specified by 'direction'.
|
|
*/
|
|
|
|
if (direction < 0)
|
|
{
|
|
|
|
/*
|
|
Perform rotation from dynamical system to ICRS.
|
|
*/
|
|
|
|
pos2[0] = xx * pos1[0] + yx * pos1[1] + zx * pos1[2];
|
|
pos2[1] = xy * pos1[0] + yy * pos1[1] + zy * pos1[2];
|
|
pos2[2] = xz * pos1[0] + yz * pos1[1] + zz * pos1[2];
|
|
}
|
|
else
|
|
{
|
|
|
|
/*
|
|
Perform rotation from ICRS to dynamical system.
|
|
*/
|
|
|
|
pos2[0] = xx * pos1[0] + xy * pos1[1] + xz * pos1[2];
|
|
pos2[1] = yx * pos1[0] + yy * pos1[1] + yz * pos1[2];
|
|
pos2[2] = zx * pos1[0] + zy * pos1[1] + zz * pos1[2];
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/********proper_motion */
|
|
|
|
void proper_motion (double jd_tdb1, double *pos, double *vel,
|
|
double jd_tdb2,
|
|
|
|
double *pos2)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Applies proper motion, including foreshortening effects, to a
|
|
star's position.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tdb1 (double)
|
|
TDB Julian date of first epoch.
|
|
pos[3] (double)
|
|
Position vector at first epoch.
|
|
vel[3] (double)
|
|
Velocity vector at first epoch.
|
|
jd_tdb2 (double)
|
|
TDB Julian date of second epoch.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
pos2[3] (double)
|
|
Position vector at second epoch.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
None.
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/01-93/TKB (USNO/NRL Optical Interfer.) Translate Fortran.
|
|
V1.1/08-93/WTH (USNO/AA) Updated to C programming standards.
|
|
|
|
NOTES:
|
|
1. This function is the C version of NOVAS Fortran routine
|
|
'propmo'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int j;
|
|
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
pos2[j] = pos[j] + (vel[j] * (jd_tdb2 - jd_tdb1));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/********bary2obs */
|
|
|
|
void bary2obs (double *pos, double *pos_obs,
|
|
|
|
double *pos2, double *lighttime)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function moves the origin of coordinates from the barycenter
|
|
of the solar system to the observer (or the geocenter); i.e.,
|
|
this function accounts for parallax (annual+geocentric or just
|
|
annual).
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
pos1[3] (double)
|
|
Position vector, referred to origin at solar system barycenter,
|
|
components in AU.
|
|
pos_obs[3] (double)
|
|
Position vector of observer (or the geocenter), with respect
|
|
to origin at solar system barycenter, components in AU.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
pos2[3] (double)
|
|
Position vector, referred to origin at center of mass of the
|
|
Earth, components in AU.
|
|
*lighttime (double)
|
|
Light time from object to Earth in days.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
C_AUDAY novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
sqrt math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/01-93/TKB (USNO/NRL Optical Interfer.) Translate Fortran.
|
|
V1.1/08-93/WTH (USNO/AA) Update to C Standards.
|
|
V1.2/10-03/JAB (USNO/AA) Remove calls to 'pow'.
|
|
V2.0/01-05/JAB (USNO/AA) Update documentation; change
|
|
'earthvector' to 'pos_obs'.
|
|
|
|
NOTES:
|
|
1. This function is the C version of NOVAS Fortran routine
|
|
'geocen'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int j;
|
|
|
|
/*
|
|
Translate vector to geocentric coordinates.
|
|
*/
|
|
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
pos2[j] = pos[j] - pos_obs[j];
|
|
}
|
|
|
|
/*
|
|
Calculate length of vector in terms of light time.
|
|
*/
|
|
|
|
*lighttime = sqrt (pos2[0] * pos2[0] + pos2[1] * pos2[1] +
|
|
pos2[2] * pos2[2]) / C_AUDAY;
|
|
|
|
return;
|
|
}
|
|
|
|
/********geo_posvel */
|
|
|
|
short int geo_posvel (double jd_tt, double delta_t, short int accuracy,
|
|
observer *obs,
|
|
|
|
double *pos, double *vel)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function computes the geocentric position and velocity
|
|
of an observer on the surface of the earth or on a near-earth
|
|
spacecraft. The final vectors are expressed in the GCRS.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date.
|
|
delta_t (double)
|
|
Value of Delta T (= TT - UT1) at 'jd_tt'.
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
*obs (struct observer)
|
|
Data specifying the location of the observer (struct defined
|
|
in novas.h).
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*pos (double)
|
|
Position vector of observer, with respect to origin at
|
|
geocenter, referred to GCRS axes, components in AU.
|
|
*vel (double)
|
|
Velocity vector of observer, with respect to origin at
|
|
geocenter, referred to GCRS axes, components in AU/day.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... everything OK.
|
|
= 1 ... invalid value of 'accuracy'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
AU_KM, T0 novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
tdb2tt novas.c
|
|
sidereal_time novas.c
|
|
e_tilt novas.c
|
|
terra novas.c
|
|
nutation novas.c
|
|
precession novas.c
|
|
frame_tie novas.c
|
|
fabs math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/12-04/JAB (USNO/AA)
|
|
V2.2/12-05/WKP (USNO/AA) Updated error handling.
|
|
V2.3/01-06/WKP (USNO/AA) Changed 'mode' to 'accuracy'.
|
|
V2.4/02-06/WKP (USNO/AA) Changed time argument in sidereal_time
|
|
call from 'jd_tt' to 'jd_ut1'.
|
|
V2.5/04-06/WKP (USNO/AA) Corrected calculation of 'fac' and
|
|
changed it to a static.
|
|
V2.6/10-06/JAB (USNO/AA) Remove 'jd_tdb' input argument; TDB
|
|
is approximated by TT.
|
|
V2.7/02-07/JAB (USNO/AA) Compute 'jd_tdb' corresponding to input
|
|
'jd_tt'.
|
|
|
|
|
|
NOTES:
|
|
1. This function is the C version of NOVAS Fortran routine
|
|
'geopos'. This C function differs from its Fortran counterpart
|
|
in that it does not use the input TT time as a substitute for
|
|
the TDB time.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
static double t_last = 0;
|
|
static double gast, fac;
|
|
static short int first_time = 1;
|
|
|
|
double x, secdif, gmst, x1, x2, x3, x4, eqeq, pos1[3], vel1[3],
|
|
pos2[3], vel2[3], pos3[3], vel3[3], jd_tdb, jd_ut1;
|
|
short int error = 0;
|
|
|
|
/*
|
|
Invalid value of 'accuracy'.
|
|
*/
|
|
|
|
if ((accuracy < 0) || (accuracy > 1))
|
|
return (error = 1);
|
|
|
|
/*
|
|
Compute 'jd_tdb', the TDB Julian date corresponding to 'jd_tt'.
|
|
*/
|
|
|
|
jd_tdb = jd_tt;
|
|
tdb2tt (jd_tdb, &x,&secdif);
|
|
jd_tdb = jd_tt + secdif / 86400.0;
|
|
|
|
switch (obs->where)
|
|
{
|
|
|
|
/*
|
|
Observer at geocenter. Trivial case.
|
|
*/
|
|
|
|
case (0):
|
|
pos[0] = 0.0;
|
|
pos[1] = 0.0;
|
|
pos[2] = 0.0;
|
|
vel[0] = 0.0;
|
|
vel[1] = 0.0;
|
|
vel[2] = 0.0;
|
|
return (error = 0);
|
|
break;
|
|
|
|
/*
|
|
Other two cases: Get geocentric position and velocity vectors of
|
|
observer wrt equator and equinox of date.
|
|
|
|
Observer on surface of Earth.
|
|
*/
|
|
|
|
case (1):
|
|
|
|
/*
|
|
Compute UT1 and sidereal time.
|
|
*/
|
|
|
|
jd_ut1 = jd_tt - (delta_t / 86400.0);
|
|
if (fabs (jd_ut1 - t_last) > 1.0e-8 )
|
|
{
|
|
sidereal_time (jd_ut1,0.0,delta_t,0,1,accuracy, &gmst);
|
|
e_tilt (jd_tdb,accuracy, &x1,&x2,&eqeq,&x3,&x4);
|
|
gast = gmst + eqeq / 3600.0;
|
|
t_last = jd_ut1;
|
|
}
|
|
|
|
/*
|
|
Function 'terra' does the hard work, given sidereal time.
|
|
*/
|
|
|
|
terra (&obs->on_surf,gast, pos1,vel1);
|
|
break;
|
|
|
|
/*
|
|
Observer on near-earth spacecraft.
|
|
*/
|
|
|
|
case (2):
|
|
|
|
/*
|
|
Convert units to AU and AU/day.
|
|
*/
|
|
|
|
if (first_time)
|
|
{
|
|
fac = AU_KM / 86400.0;
|
|
first_time = 0;
|
|
}
|
|
|
|
pos1[0] = obs->near_earth.sc_pos[0] / AU_KM;
|
|
pos1[1] = obs->near_earth.sc_pos[1] / AU_KM;
|
|
pos1[2] = obs->near_earth.sc_pos[2] / AU_KM;
|
|
|
|
vel1[0] = obs->near_earth.sc_vel[0] / fac;
|
|
vel1[1] = obs->near_earth.sc_vel[1] / fac;
|
|
vel1[2] = obs->near_earth.sc_vel[2] / fac;
|
|
break;
|
|
}
|
|
|
|
/*
|
|
Transform geocentric position vector of observer to GCRS.
|
|
*/
|
|
|
|
nutation (jd_tdb,-1,accuracy,pos1, pos2);
|
|
precession (jd_tdb,pos2,T0, pos3);
|
|
frame_tie (pos3,-1, pos);
|
|
|
|
/*
|
|
Transform geocentric velocity vector of observer to GCRS.
|
|
*/
|
|
|
|
nutation (jd_tdb,-1,accuracy,vel1, vel2);
|
|
precession (jd_tdb,vel2,T0, vel3);
|
|
frame_tie (vel3,-1, vel);
|
|
|
|
return (error = 0);
|
|
}
|
|
|
|
/********light_time */
|
|
|
|
short int light_time (double jd_tdb, object *ss_object, double pos_obs[3],
|
|
double tlight0, short int accuracy,
|
|
|
|
double pos[3], double *tlight)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function computes the geocentric position of a solar system
|
|
body, as antedated for light-time.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tdb (double)
|
|
TDB Julian date of observation.
|
|
*ss_object (struct object)
|
|
Pointer to structure containing the designation for the
|
|
solar system body (defined in novas.h).
|
|
pos_obs[3] (double)
|
|
Position vector of observer (or the geocenter), with respect to
|
|
origin at solar system barycenter, referred to ICRS axes,
|
|
components in AU.
|
|
tlight0 (double)
|
|
First approximation to light-time, in days (can be set to 0.0
|
|
if unknown).
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
pos[3] (double)
|
|
Position vector of body, with respect to origin at observer (or
|
|
the geocenter), referred to ICRS axes, components in AU.
|
|
tlight (double)
|
|
Final light-time, in days.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... everything OK.
|
|
= 1 ... algorithm failed to converge after 10 iterations.
|
|
> 10 ... error is 10 + error from function 'solarsystem'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
ephemeris novas.c
|
|
bary2obs novas.c
|
|
fabs math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/09-04/JAB (USNO/AA)
|
|
V1.1/06-05/JAB (USNO/AA): Changed the convergence tolerance from
|
|
1.0e-8 to 1.0e-10
|
|
V1.2/04-06/JAB (USNO/AA): Changed the convergence tolerance from
|
|
1.0e-10 to 1.0e-9
|
|
V2.0/12-06/JAB (USNO/AA): Support use of split Julian date to
|
|
improve accuracy when the full accuracy
|
|
option is selected.
|
|
V2.1/11-07/JAB (USNO/AA): Changed high-accuracy convergence
|
|
tolerance from 1.0e-11 to 1.0e-12.
|
|
V2.2/10-08/JAB (USNO/AA): Use function 'ephemeris' instead of
|
|
direct calls to the solar system
|
|
functions.
|
|
V2.3/09-10/WKP (USNO/AA): Initialized 't3' variable to silence
|
|
compiler warning.
|
|
|
|
NOTES:
|
|
1. This function is the C version of NOVAS Fortran routine
|
|
'littim'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
short int iter = 0;
|
|
|
|
double tol, jd[2], t1, t2, t3 = 0.0, pos1[3], vel1[3];
|
|
|
|
/*
|
|
Set light-time convergence tolerance. If full-accuracy option has
|
|
been selected, split the Julian date into whole days + fraction of
|
|
day.
|
|
*/
|
|
|
|
if (accuracy == 0)
|
|
{
|
|
tol = 1.0e-12;
|
|
|
|
jd[0] = (double) ((long int) jd_tdb);
|
|
t1 = jd_tdb - jd[0];
|
|
t2 = t1 - tlight0;
|
|
}
|
|
else
|
|
{
|
|
tol = 1.0e-9;
|
|
|
|
jd[0] = 0.0;
|
|
jd[1] = 0.0;
|
|
t1 = jd_tdb;
|
|
t2 = jd_tdb - tlight0;
|
|
}
|
|
|
|
/*
|
|
Iterate to obtain correct light-time (usually converges rapidly).
|
|
*/
|
|
|
|
do
|
|
{
|
|
if (iter > 10)
|
|
{
|
|
error = 1;
|
|
*tlight = 0.0;
|
|
break;
|
|
}
|
|
|
|
if (iter > 0)
|
|
{
|
|
t2 = t3;
|
|
}
|
|
|
|
jd[1] = t2;
|
|
error = ephemeris (jd,ss_object,0,accuracy, pos1, vel1);
|
|
|
|
if (error != 0)
|
|
{
|
|
error += 10;
|
|
*tlight = 0.0;
|
|
break;
|
|
}
|
|
|
|
bary2obs (pos1,pos_obs, pos,tlight);
|
|
|
|
t3 = t1 - *tlight;
|
|
iter++;
|
|
} while (fabs (t3 - t2) > tol);
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********d_light */
|
|
|
|
double d_light (double *pos1, double *pos_obs)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function returns the difference in light-time, for a star,
|
|
between the barycenter of the solar system and the observer (or
|
|
the geocenter).
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
pos1[3] (double)
|
|
Position vector of star, with respect to origin at solar
|
|
system barycenter.
|
|
pos_obs[3] (double)
|
|
Position vector of observer (or the geocenter), with respect
|
|
to origin at solar system barycenter, components in AU.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
None.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(double)
|
|
Difference in light time, in the sense star to barycenter minus
|
|
star to earth, in days.
|
|
|
|
GLOBALS
|
|
USED:
|
|
C_AUDAY novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
sqrt math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/12-04/JAB (USNO/AA)
|
|
|
|
NOTES:
|
|
1. Alternatively, this function returns the light-time from the
|
|
observer (or the geocenter) to a point on a light ray that is
|
|
closest to a specific solar system body. For this purpose, 'pos1'
|
|
is the position vector toward observed object, with respect to
|
|
origin at observer (or the geocenter); 'pos_obs' is the position
|
|
vector of solar system body, with respect to origin at observer
|
|
(or the geocenter), components in AU; and the returned value is
|
|
the light time to point on line defined by 'pos1' that is closest
|
|
to solar system body (positive if light passes body before hitting
|
|
observer, i.e., if 'pos1' is within 90 degrees of 'pos_obs').
|
|
2. This function is the C version of NOVAS Fortran routine
|
|
'dlight'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
double dis, u1[3], diflt;
|
|
|
|
/*
|
|
From 'pos1', form unit vector 'u1' in direction of star or light
|
|
source.
|
|
*/
|
|
|
|
dis = sqrt (pos1[0] * pos1[0] + pos1[1] * pos1[1] +
|
|
pos1[2] * pos1[2]);
|
|
|
|
u1[0] = pos1[0] / dis;
|
|
u1[1] = pos1[1] / dis;
|
|
u1[2] = pos1[2] / dis;
|
|
|
|
/*
|
|
Light-time returned is the projection of vector 'pos_obs' onto the
|
|
unit vector 'u1' (formed from 'pos1'), divided by the speed of light.
|
|
*/
|
|
|
|
diflt = (pos_obs[0] * u1[0] + pos_obs[1] * u1[1] +
|
|
pos_obs[2] * u1[2]) / C_AUDAY;
|
|
|
|
return (diflt);
|
|
}
|
|
|
|
/********grav_def */
|
|
|
|
short int grav_def (double jd_tdb, short int loc_code,
|
|
short int accuracy, double *pos1, double *pos_obs,
|
|
|
|
double *pos2)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function computes the total gravitational deflection of
|
|
light for the observed object due to the major gravitating bodies
|
|
in the solar system. This function valid for an observed body
|
|
within the solar system as well as for a star.
|
|
|
|
REFERENCES:
|
|
Klioner, S. (2003), Astronomical Journal 125, 1580-1597,
|
|
Section 6.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tdb (double)
|
|
TDB Julian date of observation.
|
|
loc_code (short int)
|
|
Code for location of observer, determining whether the
|
|
gravitational deflection due to the earth itself is applied.
|
|
= 0 ... No earth deflection (normally means observer
|
|
is at geocenter)
|
|
= 1 ... Add in earth deflection (normally means
|
|
observer is on or above surface of earth, including earth
|
|
orbit)
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
*pos1 (double)
|
|
Position vector of observed object, with respect to origin at
|
|
observer (or the geocenter), referred to ICRS axes, components
|
|
in AU.
|
|
*pos_obs (double)
|
|
Position vector of observer (or the geocenter), with respect to
|
|
origin at solar system barycenter, referred to ICRS axes,
|
|
components in AU.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*pos2 (double)
|
|
Position vector of observed object, with respect to origin at
|
|
observer (or the geocenter), referred to ICRS axes, corrected
|
|
for gravitational deflection, components in AU.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... Everything OK.
|
|
< 30 ... Error from function 'ephemeris'.
|
|
> 30 ... Error from function 'make_object'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
C_AUDAY novascon.c
|
|
RMASS[12] novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
make_cat_entry novas.c
|
|
make_object novas.c
|
|
ephemeris novas.c
|
|
bary2obs novas.c
|
|
d_light novas.c
|
|
grav_vec novas.c
|
|
sqrt math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/01-05/JAB (USNO/AA)
|
|
V1.1/04-06/WKP (USNO/AA): Added second note (superceded).
|
|
V1.2/10-08/JAB (USNO/AA): Substituted calls to 'ephemeris' for
|
|
calls to 'solarsystem'; added
|
|
actions based on 'accuracy' input.
|
|
|
|
NOTES:
|
|
1. This function is the C version of NOVAS Fortran routine
|
|
'grvdef'.
|
|
2. If 'accuracy' is set to zero (full accuracy), three bodies
|
|
(Sun, Jupiter, and Saturn) are used in the calculation. If
|
|
the reduced-accuracy option is set, only the Sun is used in the
|
|
calculation. In both cases, if the observer is not at the
|
|
geocenter, the deflection due to the Earth is included.
|
|
3. The number of bodies used at full and reduced accuracy can be
|
|
set by making a change to the code in this function as indicated
|
|
in the comments.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
/*
|
|
The following list of body numbers and corresponding names identifies
|
|
which gravitating bodies (aside from the Earth) are potentially
|
|
used -- list is taken from Klioner's table 1, the order based on area
|
|
of sky affected (col 2). Order is Sun, Jupiter, Saturn, Moon, Venus,
|
|
Uranus, Neptune.
|
|
*/
|
|
|
|
char body_name[7][8] = {"Sun", "Jupiter", "Saturn", "Moon",
|
|
"Venus", "Uranus", "Neptune"};
|
|
|
|
const short int body_num[7] = {10, 5, 6, 11, 2, 7, 8};
|
|
|
|
static short int first_time = 1;
|
|
static short int nbodies_last = 0;
|
|
|
|
short int error = 0;
|
|
short int nbodies, i;
|
|
|
|
double jd[2], tlt, pbody[3], vbody[3], pbodyo[3], x, dlt, tclose;
|
|
|
|
cat_entry dummy_star;
|
|
|
|
static object body[7], earth;
|
|
|
|
jd[1] = 0.0;
|
|
|
|
/*
|
|
Initialize output vector of observed object to equal input vector.
|
|
*/
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
pos2[i] = pos1[i];
|
|
}
|
|
|
|
/*
|
|
Set the number of bodies -- and hence the bodies used -- based on the
|
|
value of the 'accuracy' flag.
|
|
|
|
Change value of 'nbodies' to include or exclude gravitating bodies
|
|
('nbodies' <= 0 means no deflection calculated, 'nbodies' = 1 means
|
|
Sun only, 'nbodies' = 2 means Sun + Jupiter, etc.) Default is
|
|
'nbodies' = 3: Sun + Jupiter + Saturn.
|
|
*/
|
|
|
|
if (accuracy == 0)
|
|
{
|
|
nbodies = 3;
|
|
}
|
|
else
|
|
{
|
|
nbodies = 1;
|
|
}
|
|
|
|
/*
|
|
Set up the structures of type 'object' containing the body
|
|
information.
|
|
*/
|
|
|
|
if ((first_time == 1) || (nbodies != nbodies_last))
|
|
{
|
|
for (i = 0; i < nbodies; i++)
|
|
{
|
|
if (i == 0)
|
|
{
|
|
make_cat_entry ("dummy"," ",0,0.0,0.0,0.0,0.0,0.0,0.0,
|
|
&dummy_star);
|
|
|
|
make_object (0,3,"Earth",&dummy_star, &earth);
|
|
}
|
|
|
|
if ((error = make_object (0,body_num[i],body_name[i],
|
|
&dummy_star, &body[i])) != 0)
|
|
{
|
|
return (error += 30);
|
|
}
|
|
}
|
|
first_time = 0;
|
|
nbodies_last = nbodies;
|
|
}
|
|
|
|
/*
|
|
Compute light-time to observed object.
|
|
*/
|
|
|
|
tlt = sqrt (pos1[0] * pos1[0] + pos1[1] * pos1[1] +
|
|
pos1[2] *pos1[2]) / C_AUDAY;
|
|
|
|
/*
|
|
Cycle through gravitating bodies.
|
|
*/
|
|
|
|
for (i = 0; i < nbodies; i++)
|
|
{
|
|
|
|
|
|
/*
|
|
Get position of gravitating body wrt ss barycenter at time 'jd_tdb'.
|
|
*/
|
|
|
|
jd[0] = jd_tdb;
|
|
if ((error = ephemeris (jd,&body[i],0,accuracy, pbody,vbody))
|
|
!= 0)
|
|
{
|
|
return (error);
|
|
}
|
|
|
|
/*
|
|
Get position of gravitating body wrt observer at time 'jd_tdb'.
|
|
*/
|
|
|
|
bary2obs (pbody,pos_obs, pbodyo,&x);
|
|
|
|
/*
|
|
Compute light-time from point on incoming light ray that is closest
|
|
to gravitating body.
|
|
*/
|
|
|
|
dlt = d_light (pos2,pbodyo);
|
|
|
|
/*
|
|
Get position of gravitating body wrt ss barycenter at time when
|
|
incoming photons were closest to it.
|
|
*/
|
|
|
|
tclose = jd_tdb;
|
|
|
|
if (dlt > 0.0)
|
|
tclose = jd_tdb - dlt;
|
|
|
|
if (tlt < dlt)
|
|
tclose = jd_tdb - tlt;
|
|
|
|
jd[0] = tclose;
|
|
if ((error = ephemeris (jd,&body[i],0,accuracy, pbody,vbody))
|
|
!= 0)
|
|
{
|
|
return (error);
|
|
}
|
|
|
|
/*
|
|
Compute deflection due to gravitating body.
|
|
*/
|
|
|
|
grav_vec (pos2,pos_obs,pbody,RMASS[body_num[i]], pos2);
|
|
}
|
|
|
|
/*
|
|
If observer is not at geocenter, add in deflection due to Earth.
|
|
*/
|
|
|
|
if (loc_code != 0 )
|
|
{
|
|
|
|
/*
|
|
Get position of Earth wrt solar system barycenter at time 'jd_tdb'.
|
|
*/
|
|
|
|
jd[0] = jd_tdb;
|
|
if ((error = ephemeris (jd,&earth,0,accuracy, pbody,vbody))
|
|
!= 0)
|
|
{
|
|
return (error);
|
|
}
|
|
|
|
/*
|
|
Compute deflection due to Earth.
|
|
*/
|
|
|
|
grav_vec (pos2,pos_obs,pbody,RMASS[3], pos2);
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********grav_vec */
|
|
|
|
void grav_vec (double *pos1, double *pos_obs, double *pos_body,
|
|
double rmass,
|
|
|
|
double *pos2)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function corrects position vector for the deflection
|
|
of light in the gravitational field of an arbitrary body. This
|
|
function valid for an observed body within the solar system as
|
|
well as for a star.
|
|
|
|
REFERENCES:
|
|
Murray, C.A. (1981) Mon. Notices Royal Ast. Society 195, 639-648.
|
|
See also formulae in Section B of the Astronomical Almanac, or
|
|
Kaplan, G. et al. (1989) Astronomical Journal 97, 1197-1210,
|
|
section iii f.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
pos1[3] (double)
|
|
Position vector of observed object, with respect to origin at
|
|
observer (or the geocenter), components in AU.
|
|
pos_obs [3] (double)
|
|
Position vector of observer (or the geocenter), with respect
|
|
to origin at solar system barycenter, components in AU.
|
|
pos_body[3] (double)
|
|
Position vector of gravitating body, with respect to origin
|
|
at solar system barycenter, components in AU.
|
|
rmass (double)
|
|
Reciprocal mass of gravitating body in solar mass units,
|
|
that is, Sun mass / body mass.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
pos2[3] (double)
|
|
Position vector of observed object, with respect to origin at
|
|
observer (or the geocenter), corrected for gravitational
|
|
deflection, components in AU.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
C, AU, GS novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
sqrt math.h
|
|
fabs math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/12-04/JAB (USNO/AA)
|
|
|
|
NOTES:
|
|
1. This function is the C version of NOVAS Fortran routine
|
|
'grvd'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int i;
|
|
|
|
double pq[3], pe[3], pmag, emag, qmag, phat[3], ehat[3], qhat[3],
|
|
pdotq, edotp, qdote, fac1, fac2, p2i;
|
|
|
|
/*
|
|
Construct vector 'pq' from gravitating body to observed object and
|
|
construct vector 'pe' from gravitating body to observer.
|
|
*/
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
pq[i] = pos_obs[i] + pos1[i] - pos_body[i];
|
|
pe[i] = pos_obs[i] - pos_body[i];
|
|
}
|
|
|
|
/*
|
|
Compute vector magnitudes and unit vectors.
|
|
*/
|
|
|
|
pmag = sqrt (pos1[0] * pos1[0] + pos1[1] * pos1[1] +
|
|
pos1[2] * pos1[2]);
|
|
emag = sqrt (pe[0] * pe[0] + pe[1] * pe[1] + pe[2] * pe[2]);
|
|
qmag = sqrt (pq[0] * pq[0] + pq[1] * pq[1] + pq[2] * pq[2]);
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
phat[i] = pos1[i] / pmag;
|
|
ehat[i] = pe[i] / emag;
|
|
qhat[i] = pq[i] / qmag;
|
|
}
|
|
|
|
/*
|
|
Compute dot products of vectors.
|
|
*/
|
|
|
|
pdotq = phat[0] * qhat[0] + phat[1] * qhat[1] + phat[2] * qhat[2];
|
|
edotp = ehat[0] * phat[0] + ehat[1] * phat[1] + ehat[2] * phat[2];
|
|
qdote = qhat[0] * ehat[0] + qhat[1] * ehat[1] + qhat[2] * ehat[2];
|
|
|
|
/*
|
|
If gravitating body is observed object, or is on a straight line
|
|
toward or away from observed object to within 1 arcsec, deflection
|
|
is set to zero; set 'pos2' equal to 'pos1'.
|
|
*/
|
|
|
|
if (fabs (edotp) > 0.99999999999)
|
|
{
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
pos2[i] = pos1[i];
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
|
|
/*
|
|
Compute scalar factors.
|
|
*/
|
|
|
|
fac1 = 2.0 * GS / (C * C * emag * AU * rmass);
|
|
fac2 = 1.0 + qdote;
|
|
|
|
/*
|
|
Construct corrected position vector 'pos2'.
|
|
*/
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
p2i = phat[i] + fac1 * (pdotq * ehat[i] - edotp * qhat[i]) /
|
|
fac2;
|
|
pos2[i] = p2i * pmag;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/********aberration */
|
|
|
|
void aberration (double *pos, double *ve, double lighttime,
|
|
|
|
double *pos2)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Corrects position vector for aberration of light. Algorithm
|
|
includes relativistic terms.
|
|
|
|
REFERENCES:
|
|
Murray, C. A. (1981) Mon. Notices Royal Ast. Society 195, 639-648.
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
pos[3] (double)
|
|
Position vector, referred to origin at center of mass of the
|
|
Earth, components in AU.
|
|
ve[3] (double)
|
|
Velocity vector of center of mass of the Earth, referred to
|
|
origin at solar system barycenter, components in AU/day.
|
|
lighttime (double)
|
|
Light time from object to Earth in days.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
pos2[3] (double)
|
|
Position vector, referred to origin at center of mass of the
|
|
Earth, corrected for aberration, components in AU
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
C_AUDAY novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
sqrt math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/01-93/TKB (USNO/NRL Optical Interfer.) Translate Fortran.
|
|
V1.1/08-93/WTH (USNO/AA) Update to C Standards.
|
|
V1.2/12-02/JAB (USNO/AA) Improve efficiency by removing calls to
|
|
'pow' and replacing final 'for' loop
|
|
with direct assignment.
|
|
V1.3/11-03/JAB (USNO/AA) Remove returned value.
|
|
V1.4/02-06/WKP (USNO/AA) Changed C to C_AUDAY.
|
|
|
|
NOTES:
|
|
1. This function is the C version of NOVAS Fortran routine
|
|
'aberat'.
|
|
2. If 'lighttime' = 0 on input, this function will compute it.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
double p1mag, vemag, beta, dot, cosd, gammai, p, q, r;
|
|
|
|
if (lighttime == 0.0)
|
|
{
|
|
p1mag = sqrt (pos[0] * pos[0] + pos[1] * pos[1] + pos[2] *
|
|
pos[2]);
|
|
lighttime = p1mag / C_AUDAY;
|
|
}
|
|
else
|
|
p1mag = lighttime * C_AUDAY;
|
|
|
|
vemag = sqrt (ve[0] * ve[0] + ve[1] * ve[1] + ve[2] * ve[2]);
|
|
beta = vemag / C_AUDAY;
|
|
dot = pos[0] * ve[0] + pos[1] * ve[1] + pos[2] * ve[2];
|
|
|
|
cosd = dot / (p1mag * vemag);
|
|
gammai = sqrt (1.0 - beta * beta);
|
|
p = beta * cosd;
|
|
q = (1.0 + p / (1.0 + gammai)) * lighttime;
|
|
r = 1.0 + p;
|
|
|
|
pos2[0] = (gammai * pos[0] + q * ve[0]) / r;
|
|
pos2[1] = (gammai * pos[1] + q * ve[1]) / r;
|
|
pos2[2] = (gammai * pos[2] + q * ve[2]) / r;
|
|
|
|
return;
|
|
}
|
|
|
|
/********rad_vel */
|
|
|
|
void rad_vel (object *cel_object, double *pos, double *vel,
|
|
double *vel_obs, double d_obs_geo, double d_obs_sun,
|
|
double d_obj_sun,
|
|
|
|
double *rv)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Predicts the radial velocity of the observed object
|
|
as it would be measured by spectroscopic means. Radial
|
|
velocity is here defined as the radial velocity measure (z)
|
|
times the speed of light. For a solar system body, it applies
|
|
to a fictitious emitter at the center of the observed object,
|
|
assumed massless (no gravitational red shift), and does not
|
|
in general apply to reflected light. For stars, it includes
|
|
all effects, such as gravitational red shift, contained
|
|
in the catalog barycentric radial velocity measure, a scalar
|
|
derived from spectroscopy. Nearby stars with a known kinematic
|
|
velocity vector (obtained independently of spectroscopy) can be
|
|
treated like solar system objects.
|
|
|
|
REFERENCES:
|
|
Lindegren & Dravins (2003), Astronomy & Astrophysics 401,
|
|
1185-1201.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
*cel_object (struct object)
|
|
Specifies the celestial object of interest (structure defined
|
|
in novas.h).
|
|
*pos (double)
|
|
Geometric position vector of object with respect to observer,
|
|
corrected for light-time, in AU.
|
|
*vel (double)
|
|
Velocity vector of object with respect to solar system
|
|
barycenter, in AU/day.
|
|
*vel_obs (double)
|
|
Velocity vector of observer with respect to solar system
|
|
barycenter, in AU/day.
|
|
d_obs_geo (double)
|
|
Distance from observer to geocenter, in AU.
|
|
d_obs_sun (double)
|
|
Distance from observer to Sun, in AU.
|
|
d_obj_sun (double)
|
|
Distance from object to Sun, in AU.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*rv (double)
|
|
The observed radial velocity measure times the speed of light,
|
|
in kilometers/second.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
AU, C, GS, GE novascon.c
|
|
DEG2RAD novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
sqrt math.h
|
|
sin math.h
|
|
cos math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/09-06/JAB (USNO/AA)
|
|
V2.0/01-07/JAB (USNO/AA): Implement new algorithm
|
|
|
|
NOTES:
|
|
1. All the input arguments are BCRS quantities, expressed
|
|
with respect to the ICRS axes. 'vel' and 'vel_obs' are kinematic
|
|
velocities - derived from geometry or dynamics, not spectroscopy.
|
|
2. If the object is outside the solar system, the algorithm
|
|
used will be consistent with the IAU definition of stellar
|
|
radial velocity, specifically, the barycentric radial velocity
|
|
measure, which is derived from spectroscopy. In that case,
|
|
the vector 'vel' can be very approximate -- or, for distant stars
|
|
or galaxies, zero -- as it will be used only for a small geometric
|
|
correction that is proportional to proper motion.
|
|
3. Any of the distances (last three input arguments) can be set to
|
|
zero (0.0) if the corresponding general relativistic gravitational
|
|
potential term is not to be evaluated. These terms generally
|
|
are important only at the meter/second level. If 'd_obs_geo' and
|
|
'd_obs_sun' are both zero, an average value will be used for the
|
|
relativistic term for the observer, appropriate for an observer on
|
|
the surface of the Earth. 'd_obj_sun', if given, is used only for
|
|
solar system objects.
|
|
4. This function is the C version of NOVAS Fortran routine
|
|
'radvl'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
static short int first_call = 1;
|
|
short int i;
|
|
|
|
static double c2, toms, toms2;
|
|
double v[3], ra, dec, radvel, posmag, uk[3], v2, vo2, r, phigeo,
|
|
phisun, rel, rar, dcr, cosdec, du[3], zc, kv, zb1, kvobs, zobs1;
|
|
|
|
/*
|
|
Set up local constants the first time this function is called.
|
|
*/
|
|
|
|
if (first_call)
|
|
{
|
|
c2 = C * C;
|
|
toms = AU / 86400.0;
|
|
toms2 = toms * toms;
|
|
|
|
first_call = 0;
|
|
}
|
|
|
|
/*
|
|
Initialize variables needed for radial velocity calculation.
|
|
*/
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
v[i] = vel[i];
|
|
}
|
|
|
|
switch (cel_object->type)
|
|
{
|
|
case 2: /* Data for objects outside the solar system. */
|
|
ra = cel_object->star.ra;
|
|
dec = cel_object->star.dec;
|
|
radvel = cel_object->star.radialvelocity;
|
|
|
|
if (cel_object->star.parallax <= 0.0)
|
|
{
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
v[i] = 0.0;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default: /* Data not used for solar system objects. */
|
|
ra = 0.0;
|
|
dec = 0.0;
|
|
radvel = 0.0;
|
|
}
|
|
|
|
/*
|
|
Compute length of position vector = distance to object in AU.
|
|
*/
|
|
|
|
posmag = sqrt (pos[0] * pos[0] + pos[1] * pos[1] + pos[2] * pos[2]);
|
|
|
|
/*
|
|
Compute unit vector toward object.
|
|
*/
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
uk[i] = pos[i] / posmag;
|
|
}
|
|
|
|
/*
|
|
Compute velocity-squared factors.
|
|
*/
|
|
|
|
v2 = (v[0] * v[0] + v[1] * v[1] + v[2] * v[2]) * toms2;
|
|
vo2 = (vel_obs[0] * vel_obs[0] + vel_obs[1] * vel_obs[1] +
|
|
vel_obs[2] * vel_obs[2]) * toms2;
|
|
|
|
/*
|
|
Compute geopotential at observer, unless observer is geocentric.
|
|
*/
|
|
|
|
r = d_obs_geo * AU;
|
|
|
|
if (r > 1.0e6)
|
|
{
|
|
phigeo = GE / r;
|
|
}
|
|
else
|
|
{
|
|
phigeo = 0.0;
|
|
}
|
|
|
|
|
|
/*
|
|
Compute solar potential at observer.
|
|
*/
|
|
|
|
r = d_obs_sun * AU;
|
|
|
|
if (r > 1.0e8)
|
|
{
|
|
phisun = GS / r;
|
|
}
|
|
else
|
|
{
|
|
phisun = 0.0;
|
|
}
|
|
|
|
/*
|
|
Compute relativistic potential and velocity factor for observer.
|
|
*/
|
|
|
|
if ((d_obs_geo != 0.0) || (d_obs_sun != 0.0))
|
|
{
|
|
|
|
/*
|
|
Lindegren & Dravins eq. (41), second factor in parentheses.
|
|
*/
|
|
rel = 1.0 - (phigeo + phisun) / c2 - 0.5 * vo2 / c2;
|
|
}
|
|
else
|
|
{
|
|
|
|
/*
|
|
Lindegren & Dravins eq. (42), inverse.
|
|
*/
|
|
|
|
rel = 1.0 - 1.550e-8;
|
|
}
|
|
|
|
/*
|
|
Complete radial velocity calculation.
|
|
*/
|
|
|
|
switch (cel_object->type)
|
|
{
|
|
case 2: /* Objects outside the solar system. */
|
|
|
|
/*
|
|
For stars, update barycentric radial velocity measure for change
|
|
in view angle.
|
|
*/
|
|
|
|
rar = ra * 15.0 * DEG2RAD;
|
|
dcr = dec * DEG2RAD;
|
|
cosdec = cos (dcr);
|
|
du[0] = uk[0] - (cosdec * cos (rar));
|
|
du[1] = uk[1] - (cosdec * sin (rar));
|
|
du[2] = uk[2] - sin (dcr);
|
|
zc = radvel * 1.0e3 +
|
|
(v[0] * du[0] + v[1] * du[1] + v[2] * du[2]) * toms;
|
|
|
|
/*
|
|
Compute observed radial velocity measure of a star (inverse of
|
|
Lindegren & Dravins eq. (41)).
|
|
*/
|
|
|
|
zb1 = 1.0 + zc / C;
|
|
kvobs = (uk[0] * vel_obs[0] + uk[1] * vel_obs[1] +
|
|
uk[2] * vel_obs[2]) * toms;
|
|
zobs1 = zb1 * rel / (1.0 + kvobs / C);
|
|
break;
|
|
|
|
case 0: /* Objects in the solar system */
|
|
case 1:
|
|
default:
|
|
|
|
/*
|
|
Compute solar potential at object, if within solar system.
|
|
*/
|
|
|
|
r = d_obj_sun * AU;
|
|
|
|
if ((r > 1.0e8) && (r < 1.0e16))
|
|
{
|
|
phisun = GS / r;
|
|
}
|
|
else
|
|
{
|
|
phisun = 0.0;
|
|
}
|
|
|
|
/*
|
|
Compute observed radial velocity measure of a planet or other
|
|
object -- including a nearby star -- where kinematic barycentric
|
|
velocity vector is known and gravitational red shift is negligible
|
|
(Lindegren & Dravins eq. (40), applied as per S. Klioner private
|
|
communication (2006)).
|
|
*/
|
|
|
|
kv = (uk[0] * vel[0] + uk[1] * vel[1] + uk[2] * vel[2]) * toms;
|
|
zb1 = (1.0 + kv / C ) / (1.0 - phisun / c2 - 0.5 * v2 / c2);
|
|
kvobs = (uk[0] * vel_obs[0] + uk[1] * vel_obs[1] +
|
|
uk[2] * vel_obs[2] ) * toms;
|
|
zobs1 = zb1 * rel / (1.0 + kvobs / C);
|
|
}
|
|
|
|
/*
|
|
Convert observed radial velocity measure to kilometers/second.
|
|
*/
|
|
|
|
*rv = (zobs1 - 1.0) * C / 1000.0;
|
|
|
|
return;
|
|
}
|
|
|
|
/********precession */
|
|
|
|
short int precession (double jd_tdb1, double *pos1, double jd_tdb2,
|
|
|
|
double *pos2)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Precesses equatorial rectangular coordinates from one epoch to
|
|
another. One of the two epochs must be J2000.0. The coordinates
|
|
are referred to the mean dynamical equator and equinox of the two
|
|
respective epochs.
|
|
|
|
REFERENCES:
|
|
Explanatory Supplement To The Astronomical Almanac, pp. 103-104.
|
|
Capitaine, N. et al. (2003), Astronomy And Astrophysics 412,
|
|
pp. 567-586.
|
|
Hilton, J. L. et al. (2006), IAU WG report, Celest. Mech., 94,
|
|
pp. 351-367.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tdb1 (double)
|
|
TDB Julian date of first epoch. See Note 1 below.
|
|
pos1[3] (double)
|
|
Position vector, geocentric equatorial rectangular coordinates,
|
|
referred to mean dynamical equator and equinox of first epoch.
|
|
jd_tdb2 (double)
|
|
TDB Julian date of second epoch. See Note 1 below.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
pos2[3] (double)
|
|
Position vector, geocentric equatorial rectangular coordinates,
|
|
referred to mean dynamical equator and equinox of second epoch.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... everything OK.
|
|
= 1 ... Precession not to or from J2000.0; 'jd_tdb1' or 'jd_tdb2'
|
|
not 2451545.0.
|
|
|
|
GLOBALS
|
|
USED:
|
|
T0, ASEC2RAD novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
fabs math.h
|
|
sin math.h
|
|
cos math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/01-93/TKB (USNO/NRL Optical Interfer.) Translate Fortran.
|
|
V1.1/08-93/WTH (USNO/AA) Update to C Standards.
|
|
V1.2/03-98/JAB (USNO/AA) Change function type from 'short int' to
|
|
'void'.
|
|
V1.3/12-99/JAB (USNO/AA) Precompute trig terms for greater
|
|
efficiency.
|
|
V2.0/10-03/JAB (USNO/AA) Update function for consistency with
|
|
IERS (2000) Conventions.
|
|
V2.1/01-05/JAB (USNO/AA) Update expressions for the precession
|
|
angles (extra significant digits).
|
|
V2.2/04-06/JAB (USNO/AA) Update model to 2006 IAU convention.
|
|
This is model "P03" of second reference.
|
|
V2.3/03-10/JAB (USNO/AA) Implement 'first-time' to fix bug when
|
|
'jd_tdb2' is 'T0' on first call to
|
|
function.
|
|
|
|
NOTES:
|
|
1. Either 'jd_tdb1' or 'jd_tdb2' must be 2451545.0 (J2000.0) TDB.
|
|
2. This function is the C version of NOVAS Fortran routine
|
|
'preces'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
static short int first_time = 1;
|
|
short int error = 0;
|
|
|
|
static double t_last = 0.0;
|
|
static double xx, yx, zx, xy, yy, zy, xz, yz, zz;
|
|
double eps0 = 84381.406;
|
|
double t, psia, omegaa, chia, sa, ca, sb, cb, sc, cc, sd, cd;
|
|
|
|
/*
|
|
Check to be sure that either 'jd_tdb1' or 'jd_tdb2' is equal to T0.
|
|
*/
|
|
|
|
if ((jd_tdb1 != T0) && (jd_tdb2 != T0))
|
|
return (error = 1);
|
|
|
|
/*
|
|
't' is time in TDB centuries between the two epochs.
|
|
*/
|
|
|
|
t = (jd_tdb2 - jd_tdb1) / 36525.0;
|
|
|
|
if (jd_tdb2 == T0)
|
|
t = -t;
|
|
|
|
if ((fabs (t - t_last) >= 1.0e-15) || (first_time == 1))
|
|
{
|
|
|
|
/*
|
|
Numerical coefficients of psi_a, omega_a, and chi_a, along with
|
|
epsilon_0, the obliquity at J2000.0, are 4-angle formulation from
|
|
Capitaine et al. (2003), eqs. (4), (37), & (39).
|
|
*/
|
|
|
|
psia = ((((- 0.0000000951 * t
|
|
+ 0.000132851 ) * t
|
|
- 0.00114045 ) * t
|
|
- 1.0790069 ) * t
|
|
+ 5038.481507 ) * t;
|
|
|
|
omegaa = ((((+ 0.0000003337 * t
|
|
- 0.000000467 ) * t
|
|
- 0.00772503 ) * t
|
|
+ 0.0512623 ) * t
|
|
- 0.025754 ) * t + eps0;
|
|
|
|
chia = ((((- 0.0000000560 * t
|
|
+ 0.000170663 ) * t
|
|
- 0.00121197 ) * t
|
|
- 2.3814292 ) * t
|
|
+ 10.556403 ) * t;
|
|
|
|
eps0 = eps0 * ASEC2RAD;
|
|
psia = psia * ASEC2RAD;
|
|
omegaa = omegaa * ASEC2RAD;
|
|
chia = chia * ASEC2RAD;
|
|
|
|
sa = sin (eps0);
|
|
ca = cos (eps0);
|
|
sb = sin (-psia);
|
|
cb = cos (-psia);
|
|
sc = sin (-omegaa);
|
|
cc = cos (-omegaa);
|
|
sd = sin (chia);
|
|
cd = cos (chia);
|
|
/*
|
|
Compute elements of precession rotation matrix equivalent to
|
|
R3(chi_a) R1(-omega_a) R3(-psi_a) R1(epsilon_0).
|
|
*/
|
|
|
|
xx = cd * cb - sb * sd * cc;
|
|
yx = cd * sb * ca + sd * cc * cb * ca - sa * sd * sc;
|
|
zx = cd * sb * sa + sd * cc * cb * sa + ca * sd * sc;
|
|
xy = -sd * cb - sb * cd * cc;
|
|
yy = -sd * sb * ca + cd * cc * cb * ca - sa * cd * sc;
|
|
zy = -sd * sb * sa + cd * cc * cb * sa + ca * cd * sc;
|
|
xz = sb * sc;
|
|
yz = -sc * cb * ca - sa * cc;
|
|
zz = -sc * cb * sa + cc * ca;
|
|
|
|
t_last = t;
|
|
first_time = 0;
|
|
}
|
|
|
|
if (jd_tdb2 == T0)
|
|
{
|
|
|
|
/*
|
|
Perform rotation from epoch to J2000.0.
|
|
*/
|
|
pos2[0] = xx * pos1[0] + xy * pos1[1] + xz * pos1[2];
|
|
pos2[1] = yx * pos1[0] + yy * pos1[1] + yz * pos1[2];
|
|
pos2[2] = zx * pos1[0] + zy * pos1[1] + zz * pos1[2];
|
|
}
|
|
else
|
|
{
|
|
|
|
/*
|
|
Perform rotation from J2000.0 to epoch.
|
|
*/
|
|
|
|
pos2[0] = xx * pos1[0] + yx * pos1[1] + zx * pos1[2];
|
|
pos2[1] = xy * pos1[0] + yy * pos1[1] + zy * pos1[2];
|
|
pos2[2] = xz * pos1[0] + yz * pos1[1] + zz * pos1[2];
|
|
}
|
|
|
|
return (error = 0);
|
|
}
|
|
|
|
/********nutation */
|
|
|
|
void nutation (double jd_tdb, short int direction, short int accuracy,
|
|
double *pos,
|
|
|
|
double *pos2)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Nutates equatorial rectangular coordinates from mean equator and
|
|
equinox of epoch to true equator and equinox of epoch. Inverse
|
|
transformation may be applied by setting flag 'direction'.
|
|
|
|
REFERENCES:
|
|
Explanatory Supplement To The Astronomical Almanac, pp. 114-115.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tdb (double)
|
|
TDB Julian date of epoch.
|
|
direction (short int)
|
|
Flag determining 'direction' of transformation;
|
|
direction = 0 transformation applied, mean to true.
|
|
direction != 0 inverse transformation applied, true to mean.
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
pos[3] (double)
|
|
Position vector, geocentric equatorial rectangular coordinates,
|
|
referred to mean equator and equinox of epoch.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
pos2[3] (double)
|
|
Position vector, geocentric equatorial rectangular coordinates,
|
|
referred to true equator and equinox of epoch.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
DEG2RAD, ASEC2RAD novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
e_tilt novas.c
|
|
cos math.h
|
|
sin math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/01-93/TKB (USNO/NRL Optical Interfer.) Translate Fortran.
|
|
V1.1/08-93/WTH (USNO/AA) Update to C Standards.
|
|
V1.2/11-03/JAB (USNO/AA) Remove returned value.
|
|
V1.3/01-06/WKP (USNO/AA) Changed 'mode' to 'accuracy'.
|
|
|
|
NOTES:
|
|
1. This function is the C version of NOVAS Fortran routine
|
|
'nutate'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
double cobm, sobm, cobt, sobt, cpsi, spsi, xx, yx, zx, xy, yy, zy,
|
|
xz, yz, zz, oblm, oblt, eqeq, psi, eps;
|
|
|
|
/*
|
|
Call 'e_tilt' to get the obliquity and nutation angles.
|
|
*/
|
|
|
|
e_tilt (jd_tdb,accuracy, &oblm,&oblt,&eqeq,&psi,&eps);
|
|
|
|
cobm = cos (oblm * DEG2RAD);
|
|
sobm = sin (oblm * DEG2RAD);
|
|
cobt = cos (oblt * DEG2RAD);
|
|
sobt = sin (oblt * DEG2RAD);
|
|
cpsi = cos (psi * ASEC2RAD);
|
|
spsi = sin (psi * ASEC2RAD);
|
|
|
|
/*
|
|
Nutation rotation matrix follows.
|
|
*/
|
|
|
|
xx = cpsi;
|
|
yx = -spsi * cobm;
|
|
zx = -spsi * sobm;
|
|
xy = spsi * cobt;
|
|
yy = cpsi * cobm * cobt + sobm * sobt;
|
|
zy = cpsi * sobm * cobt - cobm * sobt;
|
|
xz = spsi * sobt;
|
|
yz = cpsi * cobm * sobt - sobm * cobt;
|
|
zz = cpsi * sobm * sobt + cobm * cobt;
|
|
|
|
if (!direction)
|
|
{
|
|
|
|
/*
|
|
Perform rotation.
|
|
*/
|
|
|
|
pos2[0] = xx * pos[0] + yx * pos[1] + zx * pos[2];
|
|
pos2[1] = xy * pos[0] + yy * pos[1] + zy * pos[2];
|
|
pos2[2] = xz * pos[0] + yz * pos[1] + zz * pos[2];
|
|
}
|
|
else
|
|
{
|
|
|
|
/*
|
|
Perform inverse rotation.
|
|
*/
|
|
|
|
pos2[0] = xx * pos[0] + xy * pos[1] + xz * pos[2];
|
|
pos2[1] = yx * pos[0] + yy * pos[1] + yz * pos[2];
|
|
pos2[2] = zx * pos[0] + zy * pos[1] + zz * pos[2];
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/********nutation_angles */
|
|
|
|
void nutation_angles (double t, short int accuracy,
|
|
|
|
double *dpsi, double *deps)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function returns the values for nutation in longitude and
|
|
nutation in obliquity for a given TDB Julian date. The nutation
|
|
model selected depends upon the input value of 'accuracy'. See
|
|
notes below for important details.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. (2005), US Naval Observatory Circular 179.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
t (double)
|
|
TDB time in Julian centuries since J2000.0
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
dpsi (double)
|
|
Nutation in longitude in arcseconds.
|
|
deps (double)
|
|
Nutation in obliquity in arcseconds.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
T0, ASEC2RAD novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
iau2000a nutation.c
|
|
iau2000b nutation.c
|
|
nu2000k nutation.c
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/12-04/JAB (USNO/AA)
|
|
V1.1/01-06/WKP (USNO/AA): Changed 'mode' to 'accuracy'.
|
|
V1.2/02-06/WKP (USNO/AA): Fixed units bug.
|
|
V1.3/01-07/JAB (USNO/AA): Implemented 'low_acc_choice' construct.
|
|
|
|
NOTES:
|
|
1. This function selects the nutation model depending first upon
|
|
the input value of 'accuracy'. If 'accuracy' = 0 (full accuracy),
|
|
the IAU 2000A nutation model is used. If 'accuracy' = 1 (reduced
|
|
accuracy, the model used depends upon the value of local
|
|
variable 'low_acc_choice', which is set below.
|
|
2. If local variable 'low_acc_choice' = 1 (the default), a
|
|
specially truncated version of IAU 2000A, called 'NU2000K' is
|
|
used. If 'low_acc_choice' = 2, the IAU 2000B nutation model is
|
|
used.
|
|
3. See the prologs of the nutation functions in file 'nutation.c'
|
|
for details concerning the models.
|
|
4. This function is the C version of NOVAS Fortran routine
|
|
'nod'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
|
|
/*
|
|
Set the value of 'low_acc_choice' according to the rules explained
|
|
under NOTES in the prolog.
|
|
*/
|
|
|
|
short int low_acc_choice = 1;
|
|
|
|
double t1;
|
|
|
|
t1 = t * 36525.0;
|
|
|
|
/*
|
|
High accuracy mode -- use IAU 2000A.
|
|
*/
|
|
|
|
if (accuracy == 0)
|
|
{
|
|
iau2000a (T0,t1, dpsi,deps);
|
|
}
|
|
|
|
/*
|
|
Low accuracy mode -- model depends upon value of 'low_acc_choice'.
|
|
*/
|
|
|
|
else
|
|
{
|
|
switch (low_acc_choice)
|
|
{
|
|
case 2: /* use IAU 2000B */
|
|
iau2000b (T0,t1, dpsi,deps);
|
|
break;
|
|
|
|
case 1: /* use NU2000K */
|
|
default:
|
|
nu2000k (T0,t1, dpsi,deps);
|
|
}
|
|
}
|
|
|
|
/*
|
|
Convert output to arcseconds.
|
|
*/
|
|
|
|
*dpsi /= ASEC2RAD;
|
|
*deps /= ASEC2RAD;
|
|
|
|
return;
|
|
}
|
|
|
|
/********fund_args */
|
|
|
|
void fund_args (double t,
|
|
|
|
double a[5])
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
To compute the fundamental arguments (mean elements) of the Sun
|
|
and Moon.
|
|
|
|
REFERENCES:
|
|
Simon et al. (1994) Astronomy and Astrophysics 282, 663-683,
|
|
esp. Sections 3.4-3.5.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
t (double)
|
|
TDB time in Julian centuries since J2000.0
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
a[5] (double)
|
|
Fundamental arguments, in radians:
|
|
a[0] = l (mean anomaly of the Moon)
|
|
a[1] = l' (mean anomaly of the Sun)
|
|
a[2] = F (mean argument of the latitude of the Moon)
|
|
a[3] = D (mean elongation of the Moon from the Sun)
|
|
a[4] = Omega (mean longitude of the Moon's ascending node);
|
|
from Simon section 3.4(b.3),
|
|
precession = 5028.8200 arcsec/cy)
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
ASEC2RAD, ASEC360 novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
fmod math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/10-97/JAB (USNO/AA)
|
|
V1.1/07-98/JAB (USNO/AA): Place arguments in the range 0-TWOPI
|
|
radians.
|
|
V1.2/09-03/JAB (USNO/AA): Incorporate function 'norm_ang'.
|
|
V1.3/11-03/JAB (USNO/AA): Update with Simon et al. expressions.
|
|
V1.4/01-06/JAB (USNO/AA): Remove function 'norm_ang'; rewrite for
|
|
consistency with Fortran.
|
|
V1.5/02-11/WKP (USNO/AA): Clarified a[4] description in prolog.
|
|
|
|
NOTES:
|
|
1. This function is the C version of NOVAS Fortran routine
|
|
'funarg'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
|
|
a[0] = fmod (485868.249036 +
|
|
t * (1717915923.2178 +
|
|
t * ( 31.8792 +
|
|
t * ( 0.051635 +
|
|
t * ( - 0.00024470)))), ASEC360) * ASEC2RAD;
|
|
|
|
a[1] = fmod (1287104.79305 +
|
|
t * ( 129596581.0481 +
|
|
t * ( - 0.5532 +
|
|
t * ( 0.000136 +
|
|
t * ( - 0.00001149)))), ASEC360) * ASEC2RAD;
|
|
|
|
a[2] = fmod (335779.526232 +
|
|
t * (1739527262.8478 +
|
|
t * ( - 12.7512 +
|
|
t * ( - 0.001037 +
|
|
t * ( 0.00000417)))), ASEC360) * ASEC2RAD;
|
|
|
|
a[3] = fmod (1072260.70369 +
|
|
t * (1602961601.2090 +
|
|
t * ( - 6.3706 +
|
|
t * ( 0.006593 +
|
|
t * ( - 0.00003169)))), ASEC360) * ASEC2RAD;
|
|
|
|
a[4] = fmod (450160.398036 +
|
|
t * ( - 6962890.5431 +
|
|
t * ( 7.4722 +
|
|
t * ( 0.007702 +
|
|
t * ( - 0.00005939)))), ASEC360) * ASEC2RAD;
|
|
|
|
return;
|
|
}
|
|
|
|
/********mean_obliq */
|
|
|
|
double mean_obliq (double jd_tdb)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
To compute the mean obliquity of the ecliptic.
|
|
|
|
REFERENCES:
|
|
Capitaine et al. (2003), Astronomy and Astrophysics 412, 567-586.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tdb (double)
|
|
TDB Julian Date.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
None.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(double)
|
|
Mean obliquity of the ecliptic in arcseconds.
|
|
|
|
GLOBALS
|
|
USED:
|
|
T0 novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
None.
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/12-04/JAB (USNO/AA)
|
|
V2.0/04-06/JAB (USNO/AA) Update the expression for mean obliquity
|
|
using data from the reference.
|
|
|
|
NOTES:
|
|
None.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
double t, epsilon;
|
|
|
|
/*
|
|
Compute time in Julian centuries from epoch J2000.0.
|
|
*/
|
|
|
|
t = (jd_tdb - T0) / 36525.0;
|
|
|
|
/*
|
|
Compute the mean obliquity in arcseconds. Use expression from the
|
|
reference's eq. (39) with obliquity at J2000.0 taken from eq. (37)
|
|
or Table 8.
|
|
*/
|
|
|
|
epsilon = (((( - 0.0000000434 * t
|
|
- 0.000000576 ) * t
|
|
+ 0.00200340 ) * t
|
|
- 0.0001831 ) * t
|
|
- 46.836769 ) * t + 84381.406;
|
|
|
|
return (epsilon);
|
|
}
|
|
|
|
/********vector2radec */
|
|
|
|
short int vector2radec (double *pos,
|
|
|
|
double *ra, double *dec)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Converts an vector in equatorial rectangular coordinates to
|
|
equatorial spherical coordinates.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
pos[3] (double)
|
|
Position vector, equatorial rectangular coordinates.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*rightascension (double)
|
|
Right ascension in hours.
|
|
*declination (double)
|
|
Declination in degrees.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... Everything OK.
|
|
= 1 ... All vector components are zero; 'ra' and 'dec' are
|
|
indeterminate.
|
|
= 2 ... Both pos[0] and pos[1] are zero, but pos[2] is nonzero;
|
|
'ra' is indeterminate.
|
|
GLOBALS
|
|
USED:
|
|
ASEC2RAD novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
sqrt math.h
|
|
atan2 math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/01-93/TKB (USNO/NRL Optical Interfer.) Translate Fortran.
|
|
V1.1/08-93/WTH (USNO/AA) Update to C Standards.
|
|
V1.2/01-04/JAB (USNO/AA) Remove calls to 'pow'.
|
|
|
|
NOTES:
|
|
1. This function is the C version of NOVAS Fortran routine
|
|
'angles'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
double xyproj;
|
|
|
|
xyproj = sqrt (pos[0] * pos[0] + pos[1] * pos[1]);
|
|
if ((xyproj == 0.0) && (pos[2] == 0))
|
|
{
|
|
*ra = 0.0;
|
|
*dec = 0.0;
|
|
return 1;
|
|
}
|
|
else if (xyproj == 0.0)
|
|
{
|
|
*ra = 0.0;
|
|
if (pos[2] < 0.0)
|
|
*dec = -90.0;
|
|
else
|
|
*dec = 90.0;
|
|
return 2;
|
|
}
|
|
else
|
|
{
|
|
*ra = atan2 (pos[1], pos[0]) / ASEC2RAD / 54000.0;
|
|
*dec = atan2 (pos[2], xyproj) / ASEC2RAD / 3600.0;
|
|
|
|
if (*ra < 0.0)
|
|
*ra += 24.0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/********radec2vector */
|
|
|
|
void radec2vector (double ra, double dec, double dist,
|
|
|
|
double *vector)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Converts equatorial spherical coordinates to a vector (equatorial
|
|
rectangular coordinates).
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
ra (double)
|
|
Right ascension (hours).
|
|
dec (double)
|
|
Declination (degrees).
|
|
dist (double)
|
|
Distance (AU)
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
vector[3] (double)
|
|
Position vector, equatorial rectangular coordinates (AU).
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... Everything OK.
|
|
|
|
GLOBALS
|
|
USED:
|
|
DEG2RAD novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
cos math.h
|
|
sin math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/05-92/TKB (USNO/NRL Optical Interfer.) Translate Fortran.
|
|
V1.1/08-93/WTH (USNO/AA) Update to C Standards.
|
|
V1.2/08-09/JLB (USNO/AA) Documented "dist" in prolog
|
|
|
|
NOTES:
|
|
None.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
|
|
vector[0] = dist * cos (DEG2RAD * dec) * cos (DEG2RAD * 15.0 * ra);
|
|
vector[1] = dist * cos (DEG2RAD * dec) * sin (DEG2RAD * 15.0 * ra);
|
|
vector[2] = dist * sin (DEG2RAD * dec);
|
|
|
|
return;
|
|
}
|
|
|
|
/********starvectors */
|
|
|
|
void starvectors (cat_entry *star,
|
|
|
|
double *pos, double *vel)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Converts angular quantities for stars to vectors.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. H. et. al. (1989). Astron. Journ. 97, 1197-1210.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
*star (struct cat_entry)
|
|
Pointer to catalog entry structure containing ICRS catalog
|
|
data (defined in novas.h).
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
pos[3] (double)
|
|
Position vector, equatorial rectangular coordinates,
|
|
components in AU.
|
|
vel[3] (double)
|
|
Velocity vector, equatorial rectangular coordinates,
|
|
components in AU/Day.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
ASEC2RAD, DEG2RAD novascon.c
|
|
AU_KM, C novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
sin math.h
|
|
cos math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/01-93/TKB (USNO/NRL Optical Interfer.) Translate Fortran.
|
|
V1.1/08-93/WTH (USNO/AA) Updated to C programming standards.
|
|
V1.2/11-03/JAB (USNO/AA) Update to account for parallax in units
|
|
of milliarcseconds and proper motion
|
|
in milliarcseconds/year.
|
|
V1.3/01-06/WKP (USNO/AA) Changed 'a[3]' to 'd' and added Doppler
|
|
factor.
|
|
V1.4/02-06/WKP (USNO/AA) Corrected units of C to km/sec.
|
|
|
|
NOTES:
|
|
1. This function is the C version of NOVAS Fortran routine
|
|
'vectrs'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
double paralx, dist, r, d, cra, sra, cdc, sdc, pmr, pmd, rvl, k;
|
|
|
|
/*
|
|
If parallax is unknown, undetermined, or zero, set it to 1e-6
|
|
milliarcsecond, corresponding to a distance of 1 gigaparsec.
|
|
*/
|
|
|
|
paralx = star->parallax;
|
|
|
|
if (star->parallax <= 0.0)
|
|
paralx = 1.0e-6;
|
|
|
|
/*
|
|
Convert right ascension, declination, and parallax to position vector
|
|
in equatorial system with units of AU.
|
|
*/
|
|
|
|
dist = 1.0 / sin (paralx * 1.0e-3 * ASEC2RAD);
|
|
r = (star->ra) * 15.0 * DEG2RAD;
|
|
d = (star->dec) * DEG2RAD;
|
|
cra = cos (r);
|
|
sra = sin (r);
|
|
cdc = cos (d);
|
|
sdc = sin (d);
|
|
|
|
pos[0] = dist * cdc * cra;
|
|
pos[1] = dist * cdc * sra;
|
|
pos[2] = dist * sdc;
|
|
|
|
/*
|
|
Compute Doppler factor, which accounts for change in
|
|
light travel time to star.
|
|
*/
|
|
|
|
k = 1.0 / (1.0 - star->radialvelocity / C * 1000.0);
|
|
|
|
/*
|
|
Convert proper motion and radial velocity to orthogonal components of
|
|
motion with units of AU/Day.
|
|
*/
|
|
|
|
pmr = star->promora / (paralx * 365.25) * k;
|
|
pmd = star->promodec / (paralx * 365.25) * k;
|
|
rvl = star->radialvelocity * 86400.0 / AU_KM * k;
|
|
|
|
/*
|
|
Transform motion vector to equatorial system.
|
|
*/
|
|
|
|
vel[0] = - pmr * sra - pmd * sdc * cra + rvl * cdc * cra;
|
|
vel[1] = pmr * cra - pmd * sdc * sra + rvl * cdc * sra;
|
|
vel[2] = pmd * cdc + rvl * sdc;
|
|
|
|
return;
|
|
}
|
|
|
|
/********tdb2tt */
|
|
|
|
void tdb2tt (double tdb_jd,
|
|
|
|
double *tt_jd, double *secdiff)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Computes the Terrestrial Time (TT) or Terrestrial Dynamical Time
|
|
(TDT) Julian date corresponding to a Barycentric Dynamical Time
|
|
(TDB) Julian date.
|
|
|
|
REFERENCES:
|
|
Fairhead, L. & Bretagnon, P. (1990) Astron. & Astrophys. 229, 240.
|
|
Kaplan, G. (2005), US Naval Observatory Circular 179.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
tdb_jd (double)
|
|
TDB Julian date.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*tt_jd (double)
|
|
TT Julian date.
|
|
*secdiff (double)
|
|
Difference 'tdb_jd'-'tt_jd', in seconds.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
T0 novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
sin math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/07-92/TKB (USNO/NRL Optical Interfer.) Translate Fortran.
|
|
V1.1/08-93/WTH (USNO/AA) Update to C Standards.
|
|
V1.2/06-98/JAB (USNO/AA) Adopt new model (Explanatory Supplement
|
|
to the Astronomical Almanac, pp. 42-44
|
|
and p. 316.)
|
|
V1.3/11-03/JAB (USNO/AA) Changed variable names of the input
|
|
Julian dates to make more descriptive.
|
|
V1.4/01-07/JAB (USNO/AA) Adopt Fairhead & Bretagnon expression.
|
|
|
|
NOTES:
|
|
1. Expression used in this function is a truncated form of a
|
|
longer and more precise series given in the first reference. The
|
|
result is good to about 10 microseconds.
|
|
2. This function is the C version of NOVAS Fortran routine
|
|
'times'.
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
double t;
|
|
|
|
t = (tdb_jd - T0) / 36525.0;
|
|
|
|
/*
|
|
Expression given in USNO Circular 179, eq. 2.6.
|
|
*/
|
|
|
|
*secdiff = 0.001657 * sin ( 628.3076 * t + 6.2401)
|
|
+ 0.000022 * sin ( 575.3385 * t + 4.2970)
|
|
+ 0.000014 * sin (1256.6152 * t + 6.1969)
|
|
+ 0.000005 * sin ( 606.9777 * t + 4.0212)
|
|
+ 0.000005 * sin ( 52.9691 * t + 0.4444)
|
|
+ 0.000002 * sin ( 21.3299 * t + 5.5431)
|
|
+ 0.000010 * t * sin ( 628.3076 * t + 4.2490);
|
|
|
|
*tt_jd = tdb_jd - *secdiff / 86400.0;
|
|
|
|
return;
|
|
}
|
|
|
|
/********cio_ra */
|
|
|
|
short int cio_ra (double jd_tt, short int accuracy,
|
|
|
|
double *ra_cio)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function computes the true right ascension of the celestial
|
|
intermediate origin (CIO) at a given TT Julian date. This is
|
|
-(equation of the origins).
|
|
|
|
REFERENCES:
|
|
Kaplan, G. (2005), US Naval Observatory Circular 179.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tt (double)
|
|
TT Julian date.
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*ra_cio (double)
|
|
Right ascension of the CIO, with respect to the true equinox
|
|
of date, in hours (+ or -).
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... everything OK.
|
|
= 1 ... invalid value of 'accuracy'.
|
|
> 10 ... 10 + the error code from function 'cio_location'.
|
|
> 20 ... 20 + the error code from function 'cio_basis'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
RAD2DEG, T0 novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
tdb2tt novas.c
|
|
cio_location novas.c
|
|
cio_basis novas.c
|
|
nutation novas.c
|
|
precession novas.c
|
|
frame_tie novas.c
|
|
atan2 math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/01-05/JAB (USNO/AA)
|
|
V1.1/12-05/WKP (USNO/AA) Corrected minor syntax problems.
|
|
V1.2/01-06/WKP (USNO/AA) Changed 'mode' to 'accuracy'.
|
|
V1.3/07-06/JAB (USNO/AA) Implement 'cio_location' construct.
|
|
|
|
NOTES:
|
|
1. This function is the C version of NOVAS Fortran routine
|
|
'ciora'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
short int rs;
|
|
|
|
double unitx[3] = {1.0, 0.0, 0.0};
|
|
double jd_tdb, t, secdif, x[3], y[3], z[3], w1[3], w2[3],
|
|
eq[3], az, r_cio;
|
|
|
|
/*
|
|
Check for valid value of 'accuracy'.
|
|
*/
|
|
|
|
if ((accuracy < 0) || (accuracy > 1))
|
|
return (error = 1);
|
|
|
|
/*
|
|
'jd_tdb' is the TDB Julian date.
|
|
*/
|
|
|
|
jd_tdb = jd_tt;
|
|
tdb2tt (jd_tdb, &t,&secdif);
|
|
jd_tdb = jd_tt + secdif / 86400.0;
|
|
|
|
/*
|
|
Obtain the basis vectors, in the GCRS, for the celestial intermediate
|
|
system defined by the CIP (in the z direction) and the CIO (in the
|
|
x direction).
|
|
*/
|
|
|
|
if ((error = cio_location (jd_tdb,accuracy, &r_cio,&rs)) != 0)
|
|
{
|
|
*ra_cio = 0.0;
|
|
return (error += 10);
|
|
}
|
|
|
|
if ((error = cio_basis (jd_tdb,r_cio,rs,accuracy, x,y,z)) != 0)
|
|
{
|
|
return (error += 20);
|
|
}
|
|
|
|
/*
|
|
Compute the direction of the true equinox in the GCRS.
|
|
*/
|
|
|
|
nutation (jd_tdb,-1,accuracy,unitx, w1);
|
|
precession (jd_tdb,w1,T0, w2);
|
|
frame_tie (w2,-1, eq);
|
|
|
|
/*
|
|
Compute the RA-like coordinate of the true equinox in the celestial
|
|
intermediate system.
|
|
*/
|
|
|
|
az = atan2 (eq[0] * y[0] + eq[1] * y[1] + eq[2] * y[2],
|
|
eq[0] * x[0] + eq[1] * x[1] + eq[2] * x[2]) * RAD2DEG;
|
|
|
|
/*
|
|
The RA of the CIO is minus this coordinate.
|
|
*/
|
|
|
|
*ra_cio = -az / 15.0;
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********cio_location */
|
|
|
|
short int cio_location (double jd_tdb, short int accuracy,
|
|
|
|
double *ra_cio, short int *ref_sys)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function returns the location of the celestial
|
|
intermediate origin (CIO) for a given Julian date, as a
|
|
right ascension with respect to either the GCRS (geocentric ICRS)
|
|
origin or the true equinox of date. The CIO is always located on
|
|
the true equator (= intermediate equator) of date.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tdb (double)
|
|
TDB Julian date.
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*ra_cio (double)
|
|
Right ascension of the CIO, in hours.
|
|
*ref_sys (short int)
|
|
Reference system in which right ascension is given
|
|
= 1 ... GCRS
|
|
= 2 ... True equator and equinox of date.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... everything OK.
|
|
= 1 ... unable to allocate memory for the 'cio' array.
|
|
> 10 ... 10 + the error code from function 'cio_array'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
cio_array novas.c
|
|
ira_equinox novas.c
|
|
fopen stdio.h
|
|
fclose stdio.h
|
|
fabs math.h
|
|
calloc stdlib.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/07-06/JAB (USNO/AA)
|
|
|
|
NOTES:
|
|
1. If an external file of CIO right ascensions is available,
|
|
it will be used and 'ref_sys' will be set to 1. Otherwise an
|
|
internal computation will be used and 'ref_sys' will be set to 2.
|
|
2. The external binary file of CIO right ascensions is assumed
|
|
to be named 'cio_ra.bin'. Utility program 'cio_file.c', provided
|
|
with the NOVAS-C package, creates this file from a text file also
|
|
provided with NOVAS-C.
|
|
3. This function is the C version of NOVAS Fortran routine
|
|
'cioloc'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
static short int first_call = 1;
|
|
static short int ref_sys_last = 0;
|
|
static short int use_file = 0;
|
|
short int error = 0;
|
|
|
|
long int n_pts = 6;
|
|
long int i, j;
|
|
|
|
static double t_last = 0.0;
|
|
static double ra_last;
|
|
double p, eq_origins;
|
|
|
|
size_t cio_size;
|
|
|
|
static ra_of_cio *cio;
|
|
|
|
static FILE *cio_file;
|
|
|
|
/*
|
|
Check if the input external binary file exists and can be read.
|
|
*/
|
|
|
|
if (first_call)
|
|
{
|
|
if ((cio_file = fopen ("cio_ra.bin", "rb")) == NULL)
|
|
{
|
|
use_file = 0;
|
|
}
|
|
else
|
|
{
|
|
use_file = 1;
|
|
fclose (cio_file);
|
|
}
|
|
}
|
|
|
|
/*
|
|
Check if previously computed RA value can be used.
|
|
*/
|
|
|
|
if ((fabs (jd_tdb - t_last) <= 1.0e-8))
|
|
{
|
|
*ra_cio = ra_last;
|
|
*ref_sys = ref_sys_last;
|
|
return (error = 0);
|
|
}
|
|
|
|
/*
|
|
Compute the RA of the CIO.
|
|
*/
|
|
|
|
switch (use_file)
|
|
{
|
|
|
|
/*
|
|
-----------------------------
|
|
Interpolate values from file.
|
|
-----------------------------
|
|
*/
|
|
|
|
case 1:
|
|
|
|
/*
|
|
Allocate memory for the array 'cio'. This array contains the values
|
|
to be interpolated, extracted from the CIO file.
|
|
*/
|
|
|
|
if (first_call)
|
|
{
|
|
cio_size = sizeof (ra_of_cio);
|
|
cio = (ra_of_cio *) calloc ((size_t) n_pts, cio_size);
|
|
if (cio == NULL)
|
|
return (error = 1);
|
|
else
|
|
first_call = 0;
|
|
}
|
|
|
|
/*
|
|
Get array of values to interpolate.
|
|
*/
|
|
|
|
if ((error = cio_array (jd_tdb,n_pts, cio)) != 0)
|
|
{
|
|
*ra_cio = 0.0;
|
|
return (error += 10);
|
|
}
|
|
|
|
/*
|
|
Perform Lagrangian interpolation for the RA at 'tdb_jd'.
|
|
*/
|
|
|
|
*ra_cio = 0.0;
|
|
for (j = 0L; j < n_pts; j++)
|
|
{
|
|
p = 1.0;
|
|
for (i = 0L; i < n_pts; i++)
|
|
{
|
|
if (i != j)
|
|
p *= ((jd_tdb - cio[i].jd_tdb) /
|
|
(cio[j].jd_tdb - cio[i].jd_tdb));
|
|
}
|
|
*ra_cio += (p * cio[j].ra_cio);
|
|
}
|
|
|
|
*ra_cio /= 54000.0;
|
|
*ref_sys = 1;
|
|
|
|
break;
|
|
|
|
/*
|
|
-------------------------
|
|
Use internal computation.
|
|
-------------------------
|
|
*/
|
|
|
|
case 0:
|
|
|
|
/*
|
|
Compute equation of the origins.
|
|
*/
|
|
|
|
if (first_call)
|
|
first_call = 0;
|
|
|
|
eq_origins = ira_equinox (jd_tdb,1,accuracy);
|
|
|
|
*ra_cio = -eq_origins;
|
|
*ref_sys = 2;
|
|
|
|
break;
|
|
}
|
|
|
|
t_last = jd_tdb;
|
|
ra_last = *ra_cio;
|
|
ref_sys_last = *ref_sys;
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********cio_basis */
|
|
|
|
short int cio_basis (double jd_tdb, double ra_cio, short int ref_sys,
|
|
short int accuracy,
|
|
|
|
double *x, double *y, double *z)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
To compute the orthonormal basis vectors, with
|
|
respect to the GCRS (geocentric ICRS), of the celestial
|
|
intermediate system defined by the celestial intermediate pole
|
|
(CIP) (in the z direction) and the celestial intermediate origin
|
|
(CIO) (in the x direction). A TDB Julian date and the right
|
|
ascension of the CIO at that date is required as input. The
|
|
right ascension of the CIO can be with respect to either the
|
|
GCRS origin or the true equinox of date -- different algorithms
|
|
are used in the two cases.
|
|
|
|
REFERENCES:
|
|
Kaplan, G. (2005), US Naval Observatory Circular 179.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tdb (double)
|
|
TDB Julian date of epoch.
|
|
ra_cio (double)
|
|
Right ascension of the CIO at epoch (hours).
|
|
ref_sys (short int)
|
|
Reference system in which right ascension is given (output
|
|
from function 'cio_location')
|
|
= 1 ... GCRS
|
|
= 2 ... True equator and equinox of date.
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*x (double)
|
|
Unit vector toward the CIO, equatorial rectangular
|
|
coordinates, referred to the GCRS.
|
|
*y (double)
|
|
Unit vector toward the y-direction, equatorial rectangular
|
|
coordinates, referred to the GCRS.
|
|
*z (double)
|
|
Unit vector toward north celestial pole (CIP), equatorial
|
|
rectangular coordinates, referred to the GCRS.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... everything OK.
|
|
= 1 ... invalid value of input variable 'ref_sys'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
T0, DEG2RAD novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
nutation novas.c
|
|
precession novas.c
|
|
frame_tie novas.c
|
|
fabs math.h
|
|
sin math.h
|
|
cos math.h
|
|
sqrt math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/08-04/JAB (USNO/AA)
|
|
V1.1/01-06/WKP (USNO/AA) Changed 'mode' to 'accuracy'.
|
|
V1.2/07-06/JAB (USNA/AA) Incorporate code to use 'ref_sys' input.
|
|
V1.3/06-08/WKP (USNO/AA) Changed value of direction argument in
|
|
calls to 'nutation' from 1 to -1 for
|
|
consistency.
|
|
|
|
NOTES:
|
|
1. This function effectively constructs the matrix C in eq. (3)
|
|
of the reference.
|
|
2. This function is the C version of NOVAS Fortran routine
|
|
'ciobas'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
static short int ref_sys_last = 0;
|
|
short int error = 0;
|
|
short int i;
|
|
|
|
static double t_last = 0.0;
|
|
static double xx[3], yy[3], zz[3];
|
|
double z0[3] = {0.0, 0.0, 1.0};
|
|
double w0[3], w1[3], w2[3], sinra, cosra, xmag;
|
|
|
|
/*
|
|
Compute unit vector z toward celestial pole.
|
|
*/
|
|
|
|
if (((fabs (jd_tdb - t_last) > 1.0e-8)) || (ref_sys != ref_sys_last))
|
|
{
|
|
nutation (jd_tdb,-1,accuracy,z0, w1);
|
|
precession (jd_tdb,w1,T0, w2);
|
|
frame_tie (w2,-1, zz);
|
|
|
|
t_last = jd_tdb;
|
|
ref_sys_last = ref_sys;
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
x[i] = xx[i];
|
|
y[i] = yy[i];
|
|
z[i] = zz[i];
|
|
}
|
|
return (error);
|
|
}
|
|
|
|
/*
|
|
Now compute unit vectors x and y. Method used depends on the
|
|
reference system in which right ascension of the CIO is given.
|
|
*/
|
|
|
|
switch (ref_sys)
|
|
{
|
|
|
|
/*
|
|
----------------------------
|
|
RA of CIO expressed in GCRS.
|
|
----------------------------
|
|
*/
|
|
|
|
case 1:
|
|
|
|
/*
|
|
Compute vector x toward CIO in GCRS.
|
|
*/
|
|
|
|
sinra = sin (ra_cio * 15.0 * DEG2RAD);
|
|
cosra = cos (ra_cio * 15.0 * DEG2RAD);
|
|
xx[0] = zz[2] * cosra;
|
|
xx[1] = zz[2] * sinra;
|
|
xx[2] = -zz[0] * cosra - zz[1] * sinra;
|
|
|
|
/*
|
|
Normalize vector x.
|
|
*/
|
|
|
|
xmag = sqrt (xx[0] * xx[0] + xx[1] * xx[1] + xx[2] * xx[2]);
|
|
xx[0] /= xmag;
|
|
xx[1] /= xmag;
|
|
xx[2] /= xmag;
|
|
|
|
/*
|
|
Compute unit vector y orthogonal to x and z (y = z cross x).
|
|
*/
|
|
|
|
yy[0] = zz[1] * xx[2] - zz[2] * xx[1];
|
|
yy[1] = zz[2] * xx[0] - zz[0] * xx[2];
|
|
yy[2] = zz[0] * xx[1] - zz[1] * xx[0];
|
|
|
|
break;
|
|
|
|
/*
|
|
----------------------------------------------------------
|
|
RA of CIO expressed in equator-and-equinox of date system.
|
|
----------------------------------------------------------
|
|
*/
|
|
|
|
case 2:
|
|
|
|
/*
|
|
Construct unit vector toward CIO in equator-and-equinox-of-date
|
|
system.
|
|
*/
|
|
|
|
w0[0] = cos (ra_cio * 15.0 * DEG2RAD);
|
|
w0[1] = sin (ra_cio * 15.0 * DEG2RAD);
|
|
w0[2] = 0.0;
|
|
|
|
/*
|
|
Rotate the vector into the GCRS to form unit vector x.
|
|
*/
|
|
|
|
nutation (jd_tdb,-1,accuracy,w0, w1);
|
|
precession (jd_tdb,w1,T0, w2);
|
|
frame_tie (w2,-1, xx);
|
|
|
|
/*
|
|
Compute unit vector y orthogonal to x and z (y = z cross x).
|
|
*/
|
|
|
|
yy[0] = zz[1] * xx[2] - zz[2] * xx[1];
|
|
yy[1] = zz[2] * xx[0] - zz[0] * xx[2];
|
|
yy[2] = zz[0] * xx[1] - zz[1] * xx[0];
|
|
|
|
break;
|
|
|
|
/*
|
|
---------------------------
|
|
Invalid value of 'ref_sys'.
|
|
---------------------------
|
|
*/
|
|
|
|
default:
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
xx[i] = 0.0;
|
|
yy[i] = 0.0;
|
|
zz[i] = 0.0;
|
|
}
|
|
|
|
error = 1;
|
|
break;
|
|
}
|
|
|
|
/*
|
|
Load the x, y, and z arrays.
|
|
*/
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
x[i] = xx[i];
|
|
y[i] = yy[i];
|
|
z[i] = zz[i];
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********cio_array */
|
|
|
|
short int cio_array (double jd_tdb, long int n_pts,
|
|
|
|
ra_of_cio *cio)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Given an input TDB Julian date and the number of data points
|
|
desired, this function returns a set of Julian dates and
|
|
corresponding values of the GCRS right ascension of the celestial
|
|
intermediate origin (CIO). The range of dates is centered (at
|
|
least approximately) on the requested date. The function obtains
|
|
the data from an external data file.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tdb (double)
|
|
TDB Julian date.
|
|
n_pts (long int)
|
|
Number of Julian dates and right ascension values requested
|
|
(not less than 2 or more than 20).
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*cio (struct ra_of_cio)
|
|
An time series (array) of the right ascension of the Celestial
|
|
Intermediate Origin (CIO) with respect to the GCRS (structure
|
|
defined in novas.h).
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... everything OK
|
|
= 1 ... error opening or reading the 'cio_ra.bin' file.
|
|
= 2 ... 'jd_tdb' not in the range of the CIO file.
|
|
= 3 ... 'n_pts' out of range.
|
|
= 4 ... unable to allocate memory for the internal 't' array.
|
|
= 5 ... unable to allocate memory for the internal 'ra' array.
|
|
= 6 ... 'jd_tdb' is too close to either end of the CIO file;
|
|
unable to put 'n_pts' data points into the output
|
|
structure.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
fopen stdio.h
|
|
fread stdio.h
|
|
fclose stdio.h
|
|
abs math.h
|
|
free stdlib.h
|
|
calloc stdlib.h
|
|
fseek stdio.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/09-04/JAB (USNO/AA)
|
|
V1.1/12-05/WKP (USNO/AA) Changed struct type from 'cio_ra' to
|
|
'ra_of_cio' to avoid conflicts.
|
|
V1.2/02-08/JAB (USNO/AA) Fix file-read strategy "Case 2" and
|
|
improve documentation.
|
|
|
|
NOTES:
|
|
1. This function assumes that binary, random-access file
|
|
'cio_ra.bin' has been created and is in the same directory as
|
|
your executable. This file is created by program 'cio_file.c',
|
|
included in the NOVAS-C package. On the first call to this
|
|
function, file 'cio_ra.bin' is opened in read mode.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
static short int first_call = 1;
|
|
short int error = 0;
|
|
|
|
static long int last_index_rec = -50L;
|
|
static long int last_n_pts = 0L;
|
|
static long int header_size, record_size, n_recs;
|
|
long int min_pts = 2;
|
|
long int max_pts = 20;
|
|
long int del_n_pts, index_rec, half_int, lo_limit, hi_limit,
|
|
del_index, abs_del_index, bytes_to_lo, n_swap, n_read, i, j;
|
|
|
|
static double jd_beg, jd_end, t_int, *t, *ra;
|
|
double t_temp, ra_temp;
|
|
|
|
static size_t double_size, long_size;
|
|
|
|
static FILE *cio_file;
|
|
|
|
/*
|
|
Set the sizes of the file header and data records, open the CIO file,
|
|
and read the file header on the first call to this function.
|
|
*/
|
|
|
|
if (first_call)
|
|
{
|
|
double_size = sizeof (double);
|
|
long_size = sizeof (long int);
|
|
header_size = (long) ((size_t) 3 * double_size + long_size);
|
|
record_size = (long) ((size_t) 2 * double_size);
|
|
|
|
/*
|
|
Open the input (binary, random-access) file.
|
|
*/
|
|
|
|
if ((cio_file = fopen ("cio_ra.bin", "rb")) == NULL)
|
|
{
|
|
error = 1;
|
|
goto fail;
|
|
}
|
|
|
|
/*
|
|
Read the file header.
|
|
*/
|
|
|
|
if (1 != fread (&jd_beg, double_size, (size_t) 1, cio_file) ||
|
|
1 != fread (&jd_end, double_size, (size_t) 1, cio_file) ||
|
|
1 != fread (&t_int, double_size, (size_t) 1, cio_file) ||
|
|
1 != fread (&n_recs, long_size, (size_t) 1, cio_file))
|
|
{
|
|
error = 1;
|
|
goto fail;
|
|
}
|
|
}
|
|
|
|
/*
|
|
Check the input data against limits.
|
|
*/
|
|
|
|
if ((jd_tdb < jd_beg) || (jd_tdb > jd_end))
|
|
return (error = 2);
|
|
|
|
if ((n_pts < min_pts) || (n_pts > max_pts))
|
|
return (error = 3);
|
|
|
|
/*
|
|
Calculate the difference between the current value of 'n_pts' and
|
|
the last value of 'n_pts'.
|
|
*/
|
|
|
|
/* [Don Cross - 2021-12-29] Removed 'abs', because it was not necessary. */
|
|
del_n_pts = n_pts - last_n_pts;
|
|
|
|
/*
|
|
Allocate memory for the 't' and 'ra' arrays.
|
|
*/
|
|
|
|
if (del_n_pts != 0L)
|
|
{
|
|
if (!first_call)
|
|
{
|
|
free (t);
|
|
t = NULL;
|
|
free (ra);
|
|
ra = NULL;
|
|
}
|
|
|
|
t = (double *) calloc ((size_t) n_pts, double_size);
|
|
if (t == NULL)
|
|
{
|
|
error = 4;
|
|
goto fail;
|
|
}
|
|
|
|
ra = (double *) calloc ((size_t) n_pts, double_size);
|
|
if (ra == NULL)
|
|
{
|
|
error = 5;
|
|
goto fail;
|
|
}
|
|
|
|
first_call = 0;
|
|
}
|
|
|
|
/*
|
|
Calculate the record number of the record immediately preceding
|
|
the date of interest: the "index record".
|
|
*/
|
|
|
|
index_rec = (long int) ((jd_tdb - jd_beg) / t_int) + 1L;
|
|
|
|
/*
|
|
Test the range of 'n_pts' values centered on 'index_rec' to be sure
|
|
the range of values requested falls within the file limits.
|
|
*/
|
|
|
|
half_int = (n_pts / 2L) - 1L;
|
|
lo_limit = index_rec - half_int;
|
|
hi_limit = index_rec + (n_pts - half_int - 1L);
|
|
|
|
if ((lo_limit < 1L) || (hi_limit > n_recs))
|
|
return (error = 6);
|
|
|
|
/*
|
|
Compute the number of bytes from the beginning of the file to
|
|
the 'lo_limit'.
|
|
*/
|
|
|
|
bytes_to_lo = header_size + (lo_limit - 1L) * record_size;
|
|
|
|
/*
|
|
Compare the current index record with the previous index record.
|
|
*/
|
|
|
|
del_index = index_rec - last_index_rec;
|
|
|
|
/* [Don Cross - 2021-12-29] Reworked abs() with inline logic to eliminate warnings about long int. */
|
|
abs_del_index = (del_index < 0) ? -del_index : del_index;
|
|
|
|
/*
|
|
Determine the file read strategy.
|
|
*/
|
|
|
|
/*
|
|
Case 1: The input value of 'n_pts' changed since the last entry,
|
|
or there are no data in the current arrays that can be re-used in the
|
|
new arrays. In this case, read all new data points into the arrays.
|
|
*/
|
|
|
|
if ((abs_del_index > n_pts) || (del_n_pts != 0))
|
|
{
|
|
if (fseek (cio_file, bytes_to_lo, SEEK_SET))
|
|
{
|
|
error = 1;
|
|
goto fail;
|
|
}
|
|
|
|
for (i = 0L; i < n_pts; i++)
|
|
{
|
|
if (1 != fread (&t[i], double_size, (size_t) 1, cio_file) ||
|
|
1 != fread (&ra[i], double_size, (size_t) 1, cio_file))
|
|
{
|
|
error = 1;
|
|
goto fail;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
Case 2: The new index is close enough to the previous index that
|
|
there are some data in the current arrays that can be re-used
|
|
in the new arrays. The remaining data will be read from the CIO
|
|
file.
|
|
|
|
Note that if the new index is the same as the previous index (i.e.,
|
|
'del_index' == 0), neither Case 2a nor 2b is satisfied, and the
|
|
program flow goes directly to load the output arrays with the same
|
|
values as in the current arrays.
|
|
*/
|
|
|
|
else if ((abs_del_index <= n_pts) && (del_n_pts == 0))
|
|
{
|
|
/* [Don Cross - 2021-12-30] Reworked abs() with inline logic to eliminate warnings about long int. */
|
|
n_swap = n_pts - abs_del_index;
|
|
if (n_swap < 0)
|
|
n_swap = -n_swap;
|
|
n_read = abs_del_index;
|
|
|
|
/*
|
|
Case 2a: The new index is less than the previous one. Put the "old"
|
|
data at the end of the new arrays, and read "new" data into the
|
|
beginning of the new arrays.
|
|
*/
|
|
|
|
if (del_index < 0L)
|
|
{
|
|
for (i = 0L; i < n_swap; i++)
|
|
{
|
|
t_temp = t[i];
|
|
ra_temp = ra[i];
|
|
|
|
j = i + abs_del_index;
|
|
t[j] = t_temp;
|
|
ra[j] = ra_temp;
|
|
}
|
|
|
|
fseek (cio_file, bytes_to_lo, SEEK_SET);
|
|
|
|
for (i = 0L; i < n_read; i++)
|
|
{
|
|
if (1 != fread (&t[i], double_size, (size_t) 1, cio_file) ||
|
|
1 != fread (&ra[i], double_size, (size_t) 1, cio_file))
|
|
{
|
|
error = 1;
|
|
goto fail;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
Case 2b: The new index is greater than the previous one. Put the
|
|
"old" data at the beginning of the new arrays, and read "new" data
|
|
into the end of the new arrays.
|
|
*/
|
|
|
|
else if (del_index > 0L)
|
|
{
|
|
for (i = 0L; i < n_swap; i++)
|
|
{
|
|
j = i + abs_del_index;
|
|
t_temp = t[j];
|
|
ra_temp = ra[j];
|
|
|
|
t[i] = t_temp;
|
|
ra[i] = ra_temp;
|
|
}
|
|
|
|
if (fseek (cio_file, bytes_to_lo + (n_swap * record_size), SEEK_SET))
|
|
{
|
|
error = 1;
|
|
goto fail;
|
|
}
|
|
|
|
j = i++;
|
|
for (i = j; i < n_pts; i++)
|
|
{
|
|
if (1 != fread (&t[i], double_size, (size_t) 1, cio_file) ||
|
|
1 != fread (&ra[i], double_size, (size_t) 1, cio_file))
|
|
{
|
|
error = 1;
|
|
goto fail;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
Load the output 'cio' array with the values in the 't' and 'ra'
|
|
arrays.
|
|
|
|
Note that if the input value of 'n_pts' has not changed since the
|
|
last entry, all data in the current arrays can be re-used in
|
|
the new arrays. The if statements above are bypassed and the new
|
|
arrays are the same as the current arrays.
|
|
*/
|
|
|
|
for (i = 0L; i < n_pts; i++)
|
|
{
|
|
cio[i].jd_tdb = t[i];
|
|
cio[i].ra_cio = ra[i];
|
|
}
|
|
|
|
/*
|
|
Set values of 'last_index_rec' and 'last_n_pts'.
|
|
*/
|
|
|
|
last_index_rec = index_rec;
|
|
last_n_pts = n_pts;
|
|
|
|
fail:
|
|
if (error)
|
|
{
|
|
if (t != NULL)
|
|
{
|
|
free(t);
|
|
t = NULL;
|
|
}
|
|
if (ra != NULL)
|
|
{
|
|
free(ra);
|
|
ra = NULL;
|
|
}
|
|
if (cio_file != NULL)
|
|
{
|
|
fclose (cio_file);
|
|
cio_file = NULL;
|
|
}
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********ira_equinox */
|
|
|
|
double ira_equinox (double jd_tdb, short int equinox,
|
|
short int accuracy)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
To compute the intermediate right ascension of the equinox at
|
|
the input Julian date, using an analytical expression for the
|
|
accumulated precession in right ascension. For the true equinox,
|
|
the result is the equation of the origins.
|
|
|
|
REFERENCES:
|
|
Capitaine, N. et al. (2003), Astronomy and Astrophysics 412,
|
|
567-586, eq. (42).
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd_tdb (double)
|
|
TDB Julian date.
|
|
equinox (short int)
|
|
Equinox selection flag:
|
|
= 0 ... mean equinox
|
|
= 1 ... true equinox.
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
None.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(double)
|
|
Intermediate right ascension of the equinox, in hours (+ or -).
|
|
If 'equinox' = 1 (i.e true equinox), then the returned value is
|
|
the equation of the origins.
|
|
|
|
GLOBALS
|
|
USED:
|
|
T0 novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
e_tilt novas.c
|
|
fabs math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/07-06/JAB (USNO/AA)
|
|
|
|
NOTES:
|
|
1. This function is the C version of NOVAS Fortran routine
|
|
'eqxra'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
static short int acc_last = 99;
|
|
|
|
static double t_last = 0.0;
|
|
static double eq_eq = 0.0;
|
|
double t, u, v, w, x, prec_ra, ra_eq;
|
|
|
|
/*
|
|
Compute time in Julian centuries.
|
|
*/
|
|
|
|
t = (jd_tdb - T0 ) / 36525.0;
|
|
|
|
/*
|
|
For the true equinox, obtain the equation of the equinoxes in time
|
|
seconds, which includes the 'complementary terms'.
|
|
*/
|
|
|
|
if (equinox == 1)
|
|
{
|
|
if (((fabs (jd_tdb - t_last)) > 1.0e-8) || (accuracy != acc_last))
|
|
{
|
|
e_tilt (jd_tdb,accuracy, &u, &v, &eq_eq, &w, &x);
|
|
t_last = jd_tdb;
|
|
acc_last = accuracy;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
eq_eq = 0.0;
|
|
}
|
|
|
|
/*
|
|
Precession in RA in arcseconds taken from the reference.
|
|
*/
|
|
|
|
prec_ra = 0.014506 +
|
|
(((( - 0.0000000368 * t
|
|
- 0.000029956 ) * t
|
|
- 0.00000044 ) * t
|
|
+ 1.3915817 ) * t
|
|
+ 4612.156534 ) * t;
|
|
|
|
ra_eq = - (prec_ra / 15.0 + eq_eq) / 3600.0;
|
|
|
|
return (ra_eq);
|
|
}
|
|
|
|
/********ephemeris */
|
|
|
|
short int ephemeris (double jd[2], object *cel_obj, short int origin,
|
|
short int accuracy,
|
|
|
|
double *pos, double *vel)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Retrieves the position and velocity of a solar system body from
|
|
a fundamental ephemeris.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
jd[2] (double)
|
|
TDB Julian date split into two parts, where the sum
|
|
jd[0] + jd[1] is the TDB Julian date.
|
|
*cel_obj (struct object)
|
|
Pointer to structure containing the designation of the body
|
|
of interest (defined in novas.h).
|
|
origin (short int)
|
|
Origin code
|
|
= 0 ... solar system barycenter
|
|
= 1 ... center of mass of the Sun
|
|
accuracy (short int)
|
|
Selection for accuracy
|
|
= 0 ... full accuracy
|
|
= 1 ... reduced accuracy
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
pos[3] (double)
|
|
Position vector of the body at 'jd_tdb'; equatorial rectangular
|
|
coordinates in AU referred to the ICRS.
|
|
vel[3] (double)
|
|
Velocity vector of the body at 'jd_tdb'; equatorial rectangular
|
|
coordinates in AU/day referred to the ICRS.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
0 ... Everything OK.
|
|
1 ... Invalid value of 'origin'.
|
|
2 ... Invalid value of 'type' in 'cel_obj'.
|
|
3 ... Unable to allocate memory.
|
|
10+n ... where n is the error code from 'solarsystem'.
|
|
20+n ... where n is the error code from 'readeph'.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
solarsystem novas.c
|
|
solarsystem_hp novas.c
|
|
readeph readeph.c
|
|
strlen string.h
|
|
strcpy string.h
|
|
malloc stdlib.h
|
|
free stdlib.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/06-97/JAB (USNO/AA)
|
|
V1.1/10-97/JAB (USNO/AA): Support error code from 'readeph'.
|
|
V1.2/08-98/JAB (USNO/AA): Add computation of barycentric
|
|
coordinates of a minor planet; support
|
|
new 'readeph' argument list.
|
|
V1.3/12-99/JAB (USNO/AA): Add error handling to call to
|
|
'solarsystem' (case 1).
|
|
V1.4/12-02/JAB (USNO/AA): Fix memory leaks with 'posvel' (case 1).
|
|
V1.5/10-08/JAB (USNO/AA): Incorporate higher-precision call to
|
|
the solar system ephemeris, primarily
|
|
to support light-time calculations.
|
|
V1.6/02-11/JLB (USNO/AA): Reformatted description of origin for
|
|
consistency with other documentation.
|
|
|
|
NOTES:
|
|
1. It is recommended that the input structure 'cel_obj' be
|
|
created using function 'make_object' in file novas.c.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
char *mp_name;
|
|
|
|
int err = 0;
|
|
int mp_number;
|
|
|
|
short int error = 0;
|
|
short int ss_number, i;
|
|
|
|
double jd_tdb, *posvel, *sun_pos, *sun_vel;
|
|
|
|
size_t name_len;
|
|
|
|
/*
|
|
Check the value of 'origin'.
|
|
*/
|
|
|
|
if ((origin < 0) || (origin > 1))
|
|
return (error = 1);
|
|
|
|
/*
|
|
Invoke the appropriate ephemeris access software depending upon the
|
|
type of object.
|
|
*/
|
|
|
|
switch (cel_obj->type)
|
|
{
|
|
|
|
/*
|
|
Get the position and velocity of a major planet, Pluto, Sun, or Moon.
|
|
When high accuracy is specified, use function 'solarsystem_hp' rather
|
|
than 'solarsystem'.
|
|
*/
|
|
|
|
case 0:
|
|
ss_number = cel_obj->number;
|
|
|
|
if (accuracy == 0)
|
|
{
|
|
if ((error = solarsystem_hp (jd,ss_number,origin, pos,vel))
|
|
!= 0)
|
|
error += 10;
|
|
}
|
|
else
|
|
{
|
|
jd_tdb = jd[0] + jd[1];
|
|
if ((error = solarsystem (jd_tdb,ss_number,origin, pos,vel))
|
|
!= 0)
|
|
error += 10;
|
|
}
|
|
break;
|
|
|
|
/*
|
|
Get the position and velocity of a minor planet.
|
|
|
|
*/
|
|
|
|
case 1:
|
|
mp_number = (int) cel_obj->number;
|
|
|
|
name_len = (strlen (cel_obj->name) + 1L) * sizeof (char);
|
|
mp_name = (char *) malloc (name_len);
|
|
if (mp_name == NULL)
|
|
return (error = 3);
|
|
strcpy (mp_name, cel_obj->name);
|
|
|
|
/* The USNO minor planet software returns heliocentric positions and
|
|
velocities.
|
|
*/
|
|
|
|
jd_tdb = jd[0] + jd[1];
|
|
posvel = readeph (mp_number,mp_name,jd_tdb, &err);
|
|
if (posvel == NULL)
|
|
{
|
|
free (mp_name);
|
|
return (error = 3);
|
|
}
|
|
|
|
if (err != 0)
|
|
{
|
|
free (mp_name);
|
|
free (posvel);
|
|
return ((short int) (20 + err));
|
|
}
|
|
|
|
/* Barycentric coordinates of the minor planet, if desired, are
|
|
computed via the barycentric coordinates of the Sun, obtained
|
|
from the solar system ephemeris.
|
|
*/
|
|
|
|
if (origin == 0)
|
|
{
|
|
sun_pos = (double *) malloc (3L * sizeof (double));
|
|
if (sun_pos == NULL)
|
|
{
|
|
free (mp_name);
|
|
free (posvel);
|
|
return (error = 3);
|
|
}
|
|
|
|
sun_vel = (double *) malloc (3L * sizeof (double));
|
|
if (sun_vel == NULL)
|
|
{
|
|
free (mp_name);
|
|
free (posvel);
|
|
free (sun_pos);
|
|
return (error = 3);
|
|
}
|
|
|
|
if ((error = solarsystem (jd_tdb,10,0, sun_pos,sun_vel)) != 0)
|
|
{
|
|
free (mp_name);
|
|
free (posvel);
|
|
free (sun_pos);
|
|
free (sun_vel);
|
|
return (error += 10);
|
|
}
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
posvel[i] += sun_pos[i];
|
|
posvel[i+3] += sun_vel[i];
|
|
}
|
|
|
|
free (sun_pos);
|
|
free (sun_vel);
|
|
}
|
|
|
|
/*
|
|
Break up 'posvel' into separate position and velocity vectors.
|
|
*/
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
pos[i] = posvel[i];
|
|
vel[i] = posvel[i+3];
|
|
}
|
|
|
|
free (mp_name);
|
|
free (posvel);
|
|
break;
|
|
|
|
/*
|
|
Invalid type of object.
|
|
*/
|
|
|
|
default:
|
|
error = 2;
|
|
break;
|
|
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********transform_hip */
|
|
|
|
void transform_hip (cat_entry *hipparcos,
|
|
|
|
cat_entry *hip_2000)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
To convert Hipparcos catalog data at epoch J1991.25 to epoch
|
|
J2000.0, for use within NOVAS. To be used only for Hipparcos or
|
|
Tycho stars with linear space motion. Both input and output data
|
|
is in the ICRS.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
*hipparcos (struct cat_entry)
|
|
An entry from the Hipparcos catalog, at epoch J1991.25, with
|
|
all members having Hipparcos catalog units. See Note 1
|
|
below (struct defined in novas.h).
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*hip_2000 (struct cat_entry)
|
|
The transformed input entry, at epoch J2000.0. See Note 2
|
|
below (struct defined in novas.h).
|
|
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
T0 novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
transform_cat novas.c
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/03-98/JAB (USNO/AA)
|
|
V1.1/11-03/JAB (USNO/AA) Update for ICRS
|
|
|
|
NOTES:
|
|
1. Input (Hipparcos catalog) epoch and units:
|
|
Epoch: J1991.25
|
|
Right ascension (RA): degrees
|
|
Declination (Dec): degrees
|
|
Proper motion in RA: milliarcseconds per year
|
|
Proper motion in Dec: milliarcseconds per year
|
|
Parallax: milliarcseconds
|
|
Radial velocity: kilometers per second (not in catalog)
|
|
2. Output (modified Hipparcos) epoch and units:
|
|
Epoch: J2000.0
|
|
Right ascension: hours
|
|
Declination: degrees
|
|
Proper motion in RA: milliarcseconds per year
|
|
Proper motion in Dec: milliarcseconds per year
|
|
Parallax: milliarcseconds
|
|
Radial velocity: kilometers per second
|
|
3. This function is the C version of NOVAS Fortran routine
|
|
'gethip'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
const double epoch_hip = 2448349.0625;
|
|
|
|
cat_entry scratch;
|
|
|
|
/*
|
|
Set up a "scratch" catalog entry containing Hipparcos data in
|
|
"NOVAS units."
|
|
*/
|
|
|
|
strcpy (scratch.starname, hipparcos->starname);
|
|
scratch.starnumber = hipparcos->starnumber;
|
|
scratch.dec = hipparcos->dec;
|
|
scratch.promora = hipparcos->promora;
|
|
scratch.promodec = hipparcos->promodec;
|
|
scratch.parallax = hipparcos->parallax;
|
|
scratch.radialvelocity = hipparcos->radialvelocity;
|
|
|
|
strcpy (scratch.catalog, "SCR");
|
|
|
|
/*
|
|
Convert right ascension from degrees to hours.
|
|
*/
|
|
|
|
scratch.ra = hipparcos->ra / 15.0;
|
|
|
|
/*
|
|
Change the epoch of the Hipparcos data from J1991.25 to J2000.0.
|
|
*/
|
|
|
|
transform_cat (1,epoch_hip,&scratch,T0,"HP2", hip_2000);
|
|
|
|
return;
|
|
}
|
|
|
|
/********transform_cat */
|
|
|
|
short int transform_cat (short int option, double date_incat,
|
|
cat_entry *incat, double date_newcat,
|
|
char newcat_id[SIZE_OF_CAT_NAME],
|
|
|
|
cat_entry *newcat)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
To transform a star's catalog quantities for a change of epoch
|
|
and/or equator and equinox. Also used to rotate catalog
|
|
quantities on the dynamical equator and equinox of J2000.0 to the
|
|
ICRS or vice versa.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
option (short int)
|
|
Transformation option
|
|
= 1 ... change epoch; same equator and equinox
|
|
= 2 ... change equator and equinox; same epoch
|
|
= 3 ... change equator and equinox and epoch
|
|
= 4 ... change equator and equinox J2000.0 to ICRS
|
|
= 5 ... change ICRS to equator and equinox of J2000.0
|
|
date_incat (double)
|
|
TT Julian date, or year, of input catalog data.
|
|
*incat (struct cat_entry)
|
|
An entry from the input catalog, with units as given in
|
|
the struct definition (struct defined in novas.h).
|
|
date_newcat (double)
|
|
TT Julian date, or year, of transformed catalog data.
|
|
newcat_id[SIZE_OF_CAT_NAME] (char)
|
|
Catalog identifier ((SIZE_OF_CAT_NAME - 1) characters maximum)
|
|
e.g. HIP = Hipparcos, TY2 = Tycho-2.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*newcat (struct cat_entry)
|
|
The transformed catalog entry, with units as given in
|
|
the struct definition (struct defined in novas.h).
|
|
|
|
RETURNED
|
|
VALUE:
|
|
= 0 ... Everything OK.
|
|
= 1 ... Invalid value of an input date for option 2 or 3 (see
|
|
Note 1 below).
|
|
= 2 ... length of 'newcat_id' out of bounds.
|
|
|
|
GLOBALS
|
|
USED:
|
|
SIZE_OF_CAT_NAME novas.h
|
|
T0, ASEC2RAD novascon.c
|
|
AU_KM, C novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
precession novas.c
|
|
frame_tie novas.c
|
|
sin math.h
|
|
cos math.h
|
|
sqrt math.h
|
|
atan2 math.h
|
|
asin math.h
|
|
strcpy string.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/03-98/JAB (USNO/AA)
|
|
V1.1/11-03/JAB (USNO/AA) Update for ICRS; add options 4 and 5.
|
|
V1.2/06-08/WKP (USNO/AA) Changed 'a[3]' to 'd', added Doppler factor,
|
|
and corrected 'frame_tie' direction.
|
|
V1.3/06-08/JAB (USNO/AA) Error check on dates for options 2 and 3.
|
|
V1.4/02-11/WKP (USNO/AA) Implement SIZE_OF_CAT_NAME.
|
|
|
|
NOTES:
|
|
1. 'date_incat' and 'date_newcat' may be specified either as a
|
|
Julian date (e.g., 2433282.5) or a Julian year and fraction
|
|
(e.g., 1950.0). Values less than 10000 are assumed to be years.
|
|
For 'option' = 2 or 'option' = 3, either 'date_incat' or
|
|
'date_newcat' must be 2451545.0 or 2000.0 (J2000.0). For
|
|
'option' = 4 and 'option' = 5, 'date_incat' and 'date_newcat'
|
|
are ignored.
|
|
2. 'option' = 1 updates the star's data to account for the
|
|
star's space motion between the first and second dates, within a
|
|
fixed reference frame.
|
|
'option' = 2 applies a rotation of the reference frame
|
|
corresponding to precession between the first and second dates,
|
|
but leaves the star fixed in space.
|
|
'option' = 3 provides both transformations.
|
|
'option' = 4 and 'option' = 5 provide a a fixed rotation
|
|
about very small angles (<0.1 arcsecond) to take data from the
|
|
dynamical system of J2000.0 to the ICRS ('option' = 4) or vice
|
|
versa ('option' = 5).
|
|
3. For 'option' = 1, input data can be in any fixed reference
|
|
system. for 'option' = 2 or 'option' = 3, this function assumes
|
|
the input data is in the dynamical system and produces output in
|
|
the dynamical system. for 'option' = 4, the input data must be
|
|
on the dynamical equator and equinox of J2000.0. for
|
|
'option' = 5, the input data must be in the ICRS.
|
|
4. This function cannot be properly used to bring data from
|
|
old star catalogs into the modern system, because old catalogs
|
|
were compiled using a set of constants that are
|
|
incompatible with modern values. In particular, it should not
|
|
be used for catalogs whose positions and proper motions were
|
|
derived by assuming a precession constant significantly different
|
|
from the value implicit in function 'precession'.
|
|
5. This function is the C version of NOVAS Fortran routine
|
|
'catran'.
|
|
6. SIZE_OF_CAT_NAME is defined in novas.h.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
short int j;
|
|
|
|
double jd_incat, jd_newcat, paralx, dist, r, d, cra, sra, cdc,
|
|
sdc, k, pos1[3], term1, pmr, pmd, rvl, vel1[3], pos2[3],
|
|
vel2[3], xyproj;
|
|
|
|
/*
|
|
If necessary, compute Julian dates.
|
|
|
|
This function uses TDB Julian dates internally, but no
|
|
distinction between TDB and TT is necessary.
|
|
*/
|
|
|
|
if (date_incat < 10000.0)
|
|
jd_incat = T0 + (date_incat - 2000.0) * 365.25;
|
|
else
|
|
jd_incat = date_incat;
|
|
|
|
if (date_newcat < 10000.0)
|
|
jd_newcat = T0 + (date_newcat - 2000.0) * 365.25;
|
|
else
|
|
jd_newcat = date_newcat;
|
|
|
|
/*
|
|
Convert input angular components to vectors
|
|
|
|
If parallax is unknown, undetermined, or zero, set it to 1.0e-6
|
|
milliarcsecond, corresponding to a distance of 1 gigaparsec.
|
|
*/
|
|
|
|
paralx = incat->parallax;
|
|
if (paralx <= 0.0)
|
|
paralx = 1.0e-6;
|
|
|
|
/*
|
|
Convert right ascension, declination, and parallax to position
|
|
vector in equatorial system with units of AU.
|
|
*/
|
|
|
|
dist = 1.0 / sin (paralx * 1.0e-3 * ASEC2RAD);
|
|
r = incat->ra * 54000.0 * ASEC2RAD;
|
|
d = incat->dec * 3600.0 * ASEC2RAD;
|
|
cra = cos (r);
|
|
sra = sin (r);
|
|
cdc = cos (d);
|
|
sdc = sin (d);
|
|
pos1[0] = dist * cdc * cra;
|
|
pos1[1] = dist * cdc * sra;
|
|
pos1[2] = dist * sdc;
|
|
|
|
/*
|
|
Compute Doppler factor, which accounts for change in light
|
|
travel time to star.
|
|
*/
|
|
|
|
k = 1.0 / (1.0 - incat->radialvelocity / C * 1000.0);
|
|
|
|
/*
|
|
Convert proper motion and radial velocity to orthogonal components
|
|
of motion, in spherical polar system at star's original position,
|
|
with units of AU/day.
|
|
*/
|
|
|
|
term1 = paralx * 365.25;
|
|
pmr = incat->promora / term1 * k;
|
|
pmd = incat->promodec / term1 * k;
|
|
rvl = incat->radialvelocity * 86400.0 / AU_KM * k;
|
|
|
|
/*
|
|
Transform motion vector to equatorial system.
|
|
*/
|
|
|
|
vel1[0] = - pmr * sra - pmd * sdc * cra + rvl * cdc * cra;
|
|
vel1[1] = pmr * cra - pmd * sdc * sra + rvl * cdc * sra;
|
|
vel1[2] = pmd * cdc + rvl * sdc;
|
|
|
|
/*
|
|
Update star's position vector for space motion (only if 'option' = 1
|
|
or 'option' = 3).
|
|
*/
|
|
|
|
if ((option == 1) || (option == 3))
|
|
{
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
pos2[j] = pos1[j] + vel1[j] * (jd_newcat - jd_incat);
|
|
vel2[j] = vel1[j];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
pos2[j] = pos1[j];
|
|
vel2[j] = vel1[j];
|
|
}
|
|
}
|
|
|
|
/*
|
|
Precess position and velocity vectors (only if 'option' = 2 or
|
|
'option' = 3).
|
|
*/
|
|
|
|
if ((option == 2) || (option == 3))
|
|
{
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
pos1[j] = pos2[j];
|
|
vel1[j] = vel2[j];
|
|
}
|
|
if ((error = precession (jd_incat,pos1,jd_newcat, pos2)) != 0)
|
|
return (error);
|
|
precession (jd_incat,vel1,jd_newcat, vel2);
|
|
}
|
|
|
|
/*
|
|
Rotate dynamical J2000.0 position and velocity vectors to ICRS
|
|
(only if 'option' = 4).
|
|
*/
|
|
|
|
if (option == 4)
|
|
{
|
|
frame_tie (pos1,-1, pos2);
|
|
frame_tie (vel1,-1, vel2);
|
|
}
|
|
|
|
/*
|
|
Rotate ICRS position and velocity vectors to dynamical J2000.0
|
|
(only if 'option' = 5).
|
|
*/
|
|
if (option == 5)
|
|
{
|
|
frame_tie (pos1,1, pos2);
|
|
frame_tie (vel1,1, vel2);
|
|
}
|
|
|
|
/*
|
|
Convert vectors back to angular components for output.
|
|
|
|
From updated position vector, obtain star's new position expressed
|
|
as angular quantities.
|
|
*/
|
|
|
|
xyproj = sqrt (pos2[0] * pos2[0] + pos2[1] * pos2[1]);
|
|
|
|
if (xyproj > 0.0)
|
|
r = atan2 (pos2[1], pos2[0]);
|
|
else
|
|
r = 0.0;
|
|
newcat->ra = r / ASEC2RAD / 54000.0;
|
|
if (newcat->ra < 0.0)
|
|
newcat->ra += 24.0;
|
|
if (newcat->ra >= 24.0)
|
|
newcat->ra -= 24.0;
|
|
|
|
d = atan2 (pos2[2], xyproj);
|
|
newcat->dec = d / ASEC2RAD / 3600.0;
|
|
|
|
dist = sqrt (pos2[0] * pos2[0] + pos2[1] * pos2[1] +
|
|
pos2[2] * pos2[2]);
|
|
|
|
paralx = asin (1.0 / dist) / ASEC2RAD * 1000.0;
|
|
newcat->parallax = paralx;
|
|
|
|
/*
|
|
Transform motion vector back to spherical polar system at star's
|
|
new position.
|
|
*/
|
|
|
|
cra = cos (r);
|
|
sra = sin (r);
|
|
cdc = cos (d);
|
|
sdc = sin (d);
|
|
pmr = - vel2[0] * sra + vel2[1] * cra;
|
|
pmd = - vel2[0] * cra * sdc - vel2[1] * sra * sdc + vel2[2] * cdc;
|
|
rvl = vel2[0] * cra * cdc + vel2[1] * sra * cdc + vel2[2] * sdc;
|
|
|
|
/*
|
|
Convert components of motion to from AU/day to normal catalog units.
|
|
*/
|
|
|
|
newcat->promora = pmr * paralx * 365.25 / k;
|
|
newcat->promodec = pmd * paralx * 365.25 / k;
|
|
newcat->radialvelocity = rvl * (AU_KM / 86400.0) / k;
|
|
|
|
/*
|
|
Take care of zero-parallax case.
|
|
*/
|
|
|
|
if (newcat->parallax <= 1.01e-6)
|
|
{
|
|
newcat->parallax = 0.0;
|
|
newcat->radialvelocity = incat->radialvelocity;
|
|
}
|
|
|
|
/*
|
|
Set the catalog identification code for the transformed catalog
|
|
entry.
|
|
*/
|
|
|
|
if ((short int) strlen (newcat_id) > SIZE_OF_CAT_NAME - 1)
|
|
return (2);
|
|
else
|
|
strcpy (newcat->catalog, newcat_id);
|
|
|
|
/*
|
|
Copy unchanged quantities from the input catalog entry to the
|
|
transformed catalog entry.
|
|
*/
|
|
|
|
strcpy (newcat->starname, incat->starname);
|
|
newcat->starnumber = incat->starnumber;
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********limb_angle */
|
|
|
|
void limb_angle (double pos_obj[3], double pos_obs[3],
|
|
|
|
double *limb_ang, double *nadir_ang)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function determines the angle of an object above or below
|
|
the Earth's limb (horizon). The geometric limb is computed,
|
|
assuming the Earth to be an airless sphere (no refraction or
|
|
oblateness is included). The observer can be on or above the
|
|
Earth. For an observer on the surface of the Earth, this
|
|
function returns the approximate unrefracted altitude.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
pos_obj[3] (double)
|
|
Position vector of observed object, with respect to origin at
|
|
geocenter, components in AU.
|
|
pos_obs[3] (double)
|
|
Position vector of observer, with respect to origin at
|
|
geocenter, components in AU.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*limb_ang (double)
|
|
Angle of observed object above (+) or below (-) limb
|
|
in degrees.
|
|
*nadir_ang (double)
|
|
Nadir angle of observed object as a fraction of apparent
|
|
radius of limb:
|
|
< 1.0 ... below the limb
|
|
= 1.0 ... on the limb
|
|
> 1.0 ... above the limb
|
|
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
TWOPI, ERAD novascon.c
|
|
AU, RAD2DEG novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
sqrt math.h
|
|
asin math.h
|
|
acos math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/09-04/JAB (USNO/AA)
|
|
|
|
NOTES:
|
|
1.This function is the C version of NOVAS Fortran routine
|
|
'limang'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
static short int first_entry = 1;
|
|
|
|
static double pi, halfpi, rade;
|
|
double disobj, disobs, aprad, zdlim, coszd, zdobj;
|
|
|
|
if (first_entry)
|
|
{
|
|
pi = TWOPI / 2.0;
|
|
halfpi = pi / 2.0;
|
|
rade = ERAD / AU;
|
|
first_entry = 0;
|
|
}
|
|
|
|
/*
|
|
Compute the distance to the object and the distance to the observer.
|
|
*/
|
|
|
|
disobj = sqrt (pos_obj[0] * pos_obj[0] +
|
|
pos_obj[1] * pos_obj[1] +
|
|
pos_obj[2] * pos_obj[2]);
|
|
|
|
disobs = sqrt (pos_obs[0] * pos_obs[0] +
|
|
pos_obs[1] * pos_obs[1] +
|
|
pos_obs[2] * pos_obs[2]);
|
|
|
|
/*
|
|
Compute apparent angular radius of Earth's limb.
|
|
*/
|
|
|
|
if (disobs >= rade)
|
|
{
|
|
aprad = asin (rade / disobs);
|
|
}
|
|
else
|
|
{
|
|
aprad = halfpi;
|
|
}
|
|
|
|
/*
|
|
Compute zenith distance of Earth's limb.
|
|
*/
|
|
|
|
zdlim = pi - aprad;
|
|
|
|
/*
|
|
Compute zenith distance of observed object.
|
|
*/
|
|
|
|
coszd = (pos_obj[0] * pos_obs[0] + pos_obj[1] * pos_obs[1] +
|
|
pos_obj[2] * pos_obs[2]) / (disobj * disobs);
|
|
|
|
if (coszd <= -1.0)
|
|
{
|
|
zdobj = pi;
|
|
}
|
|
else if (coszd >= 1.0)
|
|
{
|
|
zdobj = 0.0;
|
|
}
|
|
else
|
|
{
|
|
zdobj = acos (coszd);
|
|
}
|
|
|
|
/*
|
|
Angle of object wrt limb is difference in zenith distances.
|
|
*/
|
|
|
|
*limb_ang = (zdlim - zdobj) * RAD2DEG;
|
|
|
|
/*
|
|
Nadir angle of object as a fraction of angular radius of limb.
|
|
*/
|
|
|
|
*nadir_ang = (pi - zdobj) / aprad;
|
|
|
|
return;
|
|
}
|
|
|
|
/********refract */
|
|
|
|
double refract (on_surface *location, short int ref_option,
|
|
double zd_obs)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function computes atmospheric refraction in zenith
|
|
distance. This version computes approximate refraction for
|
|
optical wavelengths.
|
|
|
|
REFERENCES:
|
|
Explanatory Supplement to the Astronomical Almanac, p. 144.
|
|
Bennett, G. (1982), Journal of Navigation (Royal Institute) 35,
|
|
pp. 255-259.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
*location (struct on_surface)
|
|
Pointer to structure containing observer's location. This
|
|
structure also contains weather data (optional) for the
|
|
observer's location (defined in novas.h).
|
|
ref_option (short int)
|
|
= 1 ... Use 'standard' atmospheric conditions.
|
|
= 2 ... Use atmospheric parameters input in the 'location'
|
|
structure.
|
|
zd_obs (double)
|
|
Observed zenith distance, in degrees.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
None.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(double)
|
|
Atmospheric refraction, in degrees.
|
|
|
|
GLOBALS
|
|
USED:
|
|
DEG2RAD novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
exp math.h
|
|
tan math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/06-98/JAB (USNO/AA)
|
|
|
|
NOTES:
|
|
1. This function can be used for planning observations or
|
|
telescope pointing, but should not be used for the reduction
|
|
of precise observations.
|
|
2. This function is the C version of NOVAS Fortran routine
|
|
'refrac'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
|
|
/*
|
|
's' is the approximate scale height of atmosphere in meters.
|
|
*/
|
|
|
|
const double s = 9.1e3;
|
|
double refr, p, t, h, r;
|
|
|
|
/*
|
|
Compute refraction only for zenith distances between 0.1 and
|
|
91 degrees.
|
|
*/
|
|
|
|
if ((zd_obs < 0.1) || (zd_obs > 91.0))
|
|
refr = 0.0;
|
|
else
|
|
{
|
|
|
|
/*
|
|
If observed weather data are available, use them. Otherwise, use
|
|
crude estimates of average conditions.
|
|
*/
|
|
|
|
if (ref_option == 2)
|
|
{
|
|
p = location->pressure;
|
|
t = location->temperature;
|
|
}
|
|
else
|
|
{
|
|
p = 1010.0 * exp (-location->height / s);
|
|
t = 10.0;
|
|
}
|
|
|
|
h = 90.0 - zd_obs;
|
|
r = 0.016667 / tan ((h + 7.31 / (h + 4.4)) * DEG2RAD);
|
|
refr = r * (0.28 * p / (t + 273.0));
|
|
}
|
|
|
|
return (refr);
|
|
}
|
|
|
|
/********julian_date */
|
|
|
|
double julian_date (short int year, short int month, short int day,
|
|
double hour)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function will compute the Julian date for a given calendar
|
|
date (year, month, day, hour).
|
|
|
|
REFERENCES:
|
|
Fliegel, H. & Van Flandern, T. Comm. of the ACM, Vol. 11, No. 10,
|
|
October 1968, p. 657.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
year (short int)
|
|
Year.
|
|
month (short int)
|
|
Month number.
|
|
day (short int)
|
|
Day-of-month.
|
|
hour (double)
|
|
Hour-of-day.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
None.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(double)
|
|
Julian date.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
None.
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/06-98/JAB (USNO/AA)
|
|
V1.1/03-08/WKP (USNO/AA) Updated prolog.
|
|
|
|
NOTES:
|
|
1. This function is the C version of NOVAS Fortran routine
|
|
'juldat'.
|
|
2. This function makes no checks for a valid input calendar
|
|
date.
|
|
3. Input calendar date must be Gregorian.
|
|
4. Input time value can be based on any UT-like time scale
|
|
(UTC, UT1, TT, etc.) - output Julian date will have the same basis.
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
long int jd12h;
|
|
|
|
double tjd;
|
|
|
|
jd12h = (long) day - 32075L + 1461L * ((long) year + 4800L
|
|
+ ((long) month - 14L) / 12L) / 4L
|
|
+ 367L * ((long) month - 2L - ((long) month - 14L) / 12L * 12L)
|
|
/ 12L - 3L * (((long) year + 4900L + ((long) month - 14L) / 12L)
|
|
/ 100L) / 4L;
|
|
tjd = (double) jd12h - 0.5 + hour / 24.0;
|
|
|
|
return (tjd);
|
|
}
|
|
|
|
/********cal_date */
|
|
|
|
void cal_date (double tjd,
|
|
|
|
short int *year, short int *month, short int *day,
|
|
double *hour)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
This function will compute a date on the Gregorian calendar given
|
|
the Julian date.
|
|
|
|
REFERENCES:
|
|
Fliegel, H. & Van Flandern, T. Comm. of the ACM, Vol. 11, No. 10,
|
|
October 1968, p. 657.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
tjd (double)
|
|
Julian date.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*year (short int)
|
|
Year.
|
|
*month (short int)
|
|
Month number.
|
|
*day (short int)
|
|
Day-of-month.
|
|
*hour (double)
|
|
Hour-of-day.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
fmod math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/06-98/JAB (USNO/AA)
|
|
|
|
NOTES:
|
|
1. This routine valid for any 'jd' greater than zero.
|
|
2. Input Julian date can be based on any UT-like time scale
|
|
(UTC, UT1, TT, etc.) - output time value will have same basis.
|
|
3. This function is the C version of NOVAS Fortran routine
|
|
'caldat'.
|
|
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
long int jd, k, m, n;
|
|
|
|
double djd;
|
|
|
|
djd = tjd + 0.5;
|
|
jd = (long int) djd;
|
|
|
|
*hour = fmod (djd,1.0) * 24.0;
|
|
|
|
k = jd + 68569L;
|
|
n = 4L * k / 146097L;
|
|
|
|
k = k - (146097L * n + 3L) / 4L;
|
|
m = 4000L * (k + 1L) / 1461001L;
|
|
k = k - 1461L * m / 4L + 31L;
|
|
|
|
*month = (short int) (80L * k / 2447L);
|
|
*day = (short int) (k - 2447L * (long int) *month / 80L);
|
|
k = (long int) *month / 11L;
|
|
|
|
*month = (short int) ((long int) *month + 2L - 12L * k);
|
|
*year = (short int) (100L * (n - 49L) + m + k);
|
|
|
|
return;
|
|
}
|
|
|
|
/********norm_ang */
|
|
|
|
double norm_ang (double angle)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Normalize angle into the range 0 <= angle < (2 * pi).
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
angle (double)
|
|
Input angle (radians).
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
None.
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(double)
|
|
The input angle, normalized as described above (radians).
|
|
|
|
GLOBALS
|
|
USED:
|
|
TWOPI novascon.c
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
fmod math.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/09-03/JAB (USNO/AA)
|
|
|
|
NOTES:
|
|
None.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
double a;
|
|
|
|
a = fmod (angle,TWOPI);
|
|
if (a < 0.0)
|
|
a += TWOPI;
|
|
|
|
return (a);
|
|
}
|
|
|
|
/********make_cat_entry */
|
|
|
|
short int make_cat_entry (const char *star_name,
|
|
const char *catalog,
|
|
long int star_num, double ra, double dec,
|
|
double pm_ra, double pm_dec, double parallax,
|
|
double rad_vel,
|
|
|
|
cat_entry *star)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
To create a structure of type 'cat_entry' containing catalog
|
|
data for a star or "star-like" object.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
star_name[SIZE_OF_OBJ_NAME] (char)
|
|
Object name ((SIZE_OF_OBJ_NAME - 1) characters maximum).
|
|
catalog[SIZE_OF_CAT_NAME] (char)
|
|
Catalog identifier ((SIZE_OF_CAT_NAME - 1) characters maximum)
|
|
e.g. HIP = Hipparcos, TY2 = Tycho-2.
|
|
star_num (long int)
|
|
Object number in the catalog.
|
|
ra (double)
|
|
Right ascension of the object (hours).
|
|
dec (double)
|
|
Declination of the object (degrees).
|
|
pm_ra (double)
|
|
Proper motion in right ascension (milliarcseconds/year).
|
|
pm_dec (double)
|
|
Proper motion in declination (milliarcseconds/year).
|
|
parallax (double)
|
|
Parallax (milliarcseconds).
|
|
rad_vel (double)
|
|
Radial velocity (kilometers/second).
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
*star (struct cat_entry)
|
|
Structure containing the input data (structure defined in
|
|
novas.h).
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... no problems.
|
|
= 1 ... length of 'star_name' out of bounds.
|
|
= 2 ... length of 'catalog' out of bounds.
|
|
|
|
GLOBALS
|
|
USED:
|
|
SIZE_OF_OBJ_NAME novas.h
|
|
SIZE_OF_CAT_NAME novas.h
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
strlen string.h
|
|
strcpy string.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/03-98/JAB (USNO/AA)
|
|
V1.1/08-04/JAB (USNO/AA)
|
|
V1.3/05-10/JAB (USNO/AA): Fix bugs in set-up of 'star->starname'
|
|
and 'star->catalog'.
|
|
|
|
NOTES:
|
|
1. This utility function creates a single data structure
|
|
encapsulating the input data.
|
|
2. SIZE_OF_OBJ_NAME and SIZE_OF_CAT_NAME are defined in novas.h.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
|
|
/*
|
|
Set up the 'star' structure.
|
|
*/
|
|
|
|
if ((short int) strlen (star_name) > SIZE_OF_OBJ_NAME - 1)
|
|
return (1);
|
|
else
|
|
strcpy (star->starname, star_name);
|
|
|
|
if ((short int) strlen (catalog) > SIZE_OF_CAT_NAME - 1)
|
|
return (2);
|
|
else
|
|
strcpy (star->catalog, catalog);
|
|
|
|
star->starnumber = star_num;
|
|
star->ra = ra;
|
|
star->dec = dec;
|
|
star->promora = pm_ra;
|
|
star->promodec = pm_dec;
|
|
star->parallax = parallax;
|
|
star->radialvelocity = rad_vel;
|
|
|
|
return (0);
|
|
}
|
|
|
|
/********make_object */
|
|
|
|
short int make_object (short int type, short int number,
|
|
char name[/*SIZE_OF_OBJ_NAME*/],
|
|
cat_entry *star_data,
|
|
object *cel_obj)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Makes a structure of type 'object' - specifying a celestial
|
|
object - based on the input parameters.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
type (short int)
|
|
Type of object
|
|
= 0 ... major planet, Pluto, Sun, or Moon
|
|
= 1 ... minor planet
|
|
= 2 ... object located outside the solar system
|
|
(e.g. star, galaxy, nebula, etc.)
|
|
number (short int)
|
|
Body number
|
|
For 'type' = 0: Mercury = 1,...,Pluto = 9, Sun = 10,
|
|
Moon = 11
|
|
For 'type' = 1: minor planet number
|
|
For 'type' = 2: set to 0 (zero)
|
|
name[SIZE_OF_OBJ_NAME] (char)
|
|
Name of the object ((SIZE_OF_OBJ_NAME - 1) characters maximum).
|
|
*star_data (struct cat_entry)
|
|
Structure containing basic astrometric data for any celestial
|
|
object located outside the solar system; the catalog
|
|
data for a star (defined in novas.h).
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
struct object *cel_obj
|
|
Structure containing the object definition (defined in novas.h).
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... everything OK
|
|
= 1 ... invalid value of 'type'
|
|
= 2 ... 'number' out of range
|
|
= 3 ... Initialization of 'cel_obj' failed (object name).
|
|
= 4 ... Initialization of 'cel_obj' failed (catalog name).
|
|
= 5 ... 'name' is out of string bounds.
|
|
|
|
GLOBALS
|
|
USED:
|
|
SIZE_OF_OBJ_NAME novas.h
|
|
SIZE_OF_CAT_NAME novas.h
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
strlen string.h
|
|
strcpy string.h
|
|
toupper ctype.h
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/06-97/JAB (USNO/AA)
|
|
V1.1/10-98/JAB (USNO/AA): Change object name to mixed case.
|
|
V1.2/12-02/JAB (USNO/AA): Fix bug by adding brackets in the "Set
|
|
the object number" 'if' block.
|
|
V1.3/07-04/JAB (USNO/AA): Change name from 'set_body'; expand to
|
|
include objects outside solar system.
|
|
V1.4/05-10/JAB (USNO/AA): Implement SIZE_OF_OBJ_NAME and
|
|
SIZE_OF_CAT_NAME; check length of
|
|
'name'.
|
|
V1.5/09-10/WKP (USNO/AA): Explicitly cast 'toupper' return value
|
|
to type 'char' to silence compiler.
|
|
|
|
NOTES:
|
|
1. SIZE_OF_OBJ_NAME and SIZE_OF_CAT_NAME are defined in novas.h.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
short int i;
|
|
|
|
/*
|
|
Initialize the structure.
|
|
*/
|
|
|
|
cel_obj->type = 0;
|
|
cel_obj->number = 0;
|
|
strcpy (cel_obj->name, " ");
|
|
|
|
if ((short int) strlen (" ") > SIZE_OF_OBJ_NAME - 1)
|
|
return (error = 3);
|
|
else
|
|
{
|
|
strcpy (cel_obj->name, " ");
|
|
strcpy (cel_obj->star.starname, " ");
|
|
}
|
|
|
|
if ((short int) strlen (" ") > SIZE_OF_CAT_NAME - 1)
|
|
return (error = 4);
|
|
else
|
|
strcpy (cel_obj->star.catalog, " ");
|
|
|
|
cel_obj->star.starnumber = 0L;
|
|
cel_obj->star.ra = 0.0;
|
|
cel_obj->star.dec = 0.0;
|
|
cel_obj->star.promora = 0.0;
|
|
cel_obj->star.promodec = 0.0;
|
|
cel_obj->star.parallax = 0.0;
|
|
cel_obj->star.radialvelocity = 0.0;
|
|
|
|
/*
|
|
Set the object type.
|
|
*/
|
|
|
|
if ((type < 0) || (type > 2))
|
|
return (error = 1);
|
|
else
|
|
cel_obj->type = type;
|
|
|
|
/*
|
|
Set the object number.
|
|
*/
|
|
|
|
if (type == 0)
|
|
{
|
|
if ((number <= 0) || (number > 11))
|
|
return (error = 2);
|
|
}
|
|
else if (type == 1)
|
|
{
|
|
if (number <= 0)
|
|
return (error = 2);
|
|
}
|
|
else
|
|
{
|
|
number = 0;
|
|
}
|
|
|
|
cel_obj->number = number;
|
|
|
|
/*
|
|
Check length of 'name'. Set the object name in upper case.
|
|
*/
|
|
|
|
if ((short int) strlen (name) > SIZE_OF_OBJ_NAME - 1)
|
|
return (error = 5);
|
|
|
|
for (i = 0; i < SIZE_OF_OBJ_NAME - 1; i++)
|
|
{
|
|
cel_obj->name[i] = (char) toupper (name[i]);
|
|
if (name[i] == '\0')
|
|
break;
|
|
}
|
|
cel_obj->name[i] = '\0';
|
|
|
|
/*
|
|
Populate the astrometric-data structure if the object is 'type' = 2.
|
|
*/
|
|
|
|
if (type == 2)
|
|
{
|
|
strcpy (cel_obj->star.starname, star_data->starname);
|
|
strcpy (cel_obj->star.catalog, star_data->catalog);
|
|
cel_obj->star.starnumber = star_data->starnumber;
|
|
cel_obj->star.ra = star_data->ra;
|
|
cel_obj->star.dec = star_data->dec;
|
|
cel_obj->star.promora = star_data->promora;
|
|
cel_obj->star.promodec = star_data->promodec;
|
|
cel_obj->star.parallax = star_data->parallax;
|
|
cel_obj->star.radialvelocity = star_data->radialvelocity;
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********make_observer */
|
|
|
|
short int make_observer (short int where, on_surface *obs_surface,
|
|
in_space *obs_space,
|
|
|
|
observer *obs)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Makes a structure of type 'observer' - specifying the location of
|
|
the observer.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
where (short int)
|
|
Integer code specifying location of observer.
|
|
= 0: observer at geocenter
|
|
= 1: observer on surface of earth
|
|
= 2: observer on near-earth spacecraft
|
|
*obs_surface (struct on_surface)
|
|
Structure containing data for an observer's location on the
|
|
surface of the Earth; used when 'where' = 1 (defined in
|
|
novas.h).
|
|
*obs_space (struct in_space)
|
|
Data for an observer's location on a near-Earth spacecraft;
|
|
used when 'where' = 2 (defined in novas.h).
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
struct observer *obs
|
|
Structure specifying the location of the observer (defined in
|
|
novas.h).
|
|
|
|
RETURNED
|
|
VALUE:
|
|
(short int)
|
|
= 0 ... everything OK.
|
|
= 1 ... input value of 'where' is out-of-range.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
None.
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/08-04/JAB (USNO/AA)
|
|
|
|
NOTES:
|
|
None.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
short int error = 0;
|
|
|
|
/*
|
|
Initialize the output structure.
|
|
*/
|
|
|
|
obs->where = where;
|
|
obs->on_surf.latitude = 0.0;
|
|
obs->on_surf.longitude = 0.0;
|
|
obs->on_surf.height = 0.0;
|
|
obs->on_surf.temperature = 0.0;
|
|
obs->on_surf.pressure = 0.0;
|
|
obs->near_earth.sc_pos[0] = 0.0;
|
|
obs->near_earth.sc_pos[1] = 0.0;
|
|
obs->near_earth.sc_pos[2] = 0.0;
|
|
obs->near_earth.sc_vel[0] = 0.0;
|
|
obs->near_earth.sc_vel[1] = 0.0;
|
|
obs->near_earth.sc_vel[2] = 0.0;
|
|
|
|
/*
|
|
Populate the output structure based on the value of 'where'.
|
|
*/
|
|
|
|
switch (where)
|
|
{
|
|
case (0): /* Geocentric */
|
|
break;
|
|
|
|
case (1): /* On surface of Earth */
|
|
obs->on_surf.latitude = obs_surface->latitude;
|
|
obs->on_surf.longitude = obs_surface->longitude;
|
|
obs->on_surf.height = obs_surface->height;
|
|
obs->on_surf.temperature = obs_surface->temperature;
|
|
obs->on_surf.pressure = obs_surface->pressure;
|
|
break;
|
|
|
|
case (2): /* In near-Earth spacecraft */
|
|
obs->near_earth.sc_pos[0] = obs_space->sc_pos[0];
|
|
obs->near_earth.sc_pos[1] = obs_space->sc_pos[1];
|
|
obs->near_earth.sc_pos[2] = obs_space->sc_pos[2];
|
|
obs->near_earth.sc_vel[0] = obs_space->sc_vel[0];
|
|
obs->near_earth.sc_vel[1] = obs_space->sc_vel[1];
|
|
obs->near_earth.sc_vel[2] = obs_space->sc_vel[2];
|
|
break;
|
|
|
|
default:
|
|
error = 1;
|
|
break;
|
|
}
|
|
|
|
return (error);
|
|
}
|
|
|
|
/********make_observer_at_geocenter */
|
|
|
|
void make_observer_at_geocenter (
|
|
|
|
observer *obs_at_geocenter)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Makes a structure of type 'observer' specifying an observer at the
|
|
geocenter.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
None.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
struct observer *obs_at_geocenter
|
|
Structure specifying the location of the observer at the geocenter
|
|
(defined in novas.h).
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
make_in_space novas.c
|
|
make_on_surface novas.c
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/03-07/JAB (USNO/AA)
|
|
|
|
NOTES:
|
|
1. The output data structure is one of the inputs to NOVAS-C
|
|
function 'place'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
double latitude = 0.0;
|
|
double longitude = 0.0;
|
|
double height = 0.0;
|
|
double temperature = 0.0;
|
|
double pressure = 0.0;
|
|
double sat_pos[3] = {0.0, 0.0, 0.0};
|
|
double sat_vel[3] = {0.0, 0.0, 0.0};
|
|
|
|
in_space sat_state;
|
|
|
|
on_surface surface_loc;
|
|
|
|
make_in_space (sat_pos,sat_vel, &sat_state);
|
|
make_on_surface (latitude,longitude,height,temperature,pressure,
|
|
&surface_loc);
|
|
|
|
obs_at_geocenter->where = 0;
|
|
obs_at_geocenter->on_surf = surface_loc;
|
|
obs_at_geocenter->near_earth = sat_state;
|
|
}
|
|
|
|
/********make_observer_on_surface */
|
|
|
|
void make_observer_on_surface (double latitude, double longitude,
|
|
double height, double temperature,
|
|
double pressure,
|
|
|
|
observer *obs_on_surface)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Makes a structure of type 'observer' specifying the location
|
|
of and weather for an observer on the surface of the Earth.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
latitude (double)
|
|
Geodetic (ITRS) latitude in degrees; north positive.
|
|
longitude (double)
|
|
Geodetic (ITRS) longitude in degrees; east positive.
|
|
height (double)
|
|
Height of the observer (meters).
|
|
temperature (double)
|
|
Temperature (degrees Celsius).
|
|
pressure (double)
|
|
Atmospheric pressure (millibars).
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
struct observer *obs_on_surface
|
|
Structure containing the location of and weather for an
|
|
observer on the surface of the Earth (defined in novas.h).
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
make_in_space novas.c
|
|
make_on_surface novas.c
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/03-07/JAB (USNO/AA)
|
|
|
|
NOTES:
|
|
1. The output data structure is one of the inputs to NOVAS-C
|
|
function 'place'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
double sat_pos[3] = {0.0, 0.0, 0.0};
|
|
double sat_vel[3] = {0.0, 0.0, 0.0};
|
|
|
|
in_space sat_state;
|
|
|
|
on_surface surface_loc;
|
|
|
|
make_in_space (sat_pos,sat_vel, &sat_state);
|
|
make_on_surface (latitude,longitude,height,temperature,pressure,
|
|
&surface_loc);
|
|
|
|
obs_on_surface->where = 1;
|
|
obs_on_surface->on_surf = surface_loc;
|
|
obs_on_surface->near_earth = sat_state;
|
|
}
|
|
|
|
/********make_observer_in_space */
|
|
|
|
void make_observer_in_space (double sc_pos[3], double sc_vel[3],
|
|
|
|
observer *obs_in_space)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Makes a structure of type 'observer' specifying the position and
|
|
velocity of an observer situated on a near-Earth spacecraft.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
sc_pos[3] (double)
|
|
Geocentric position vector (x, y, z) in km.
|
|
sc_vel[3] (double)
|
|
Geocentric velocity vector (x_dot, y_dot, z_dot) in km/s.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
struct observer *obs_in_space
|
|
Structure containing the position and velocity of an observer
|
|
situated on a near-Earth spacecraft (defined in novas.h).
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
make_in_space novas.c
|
|
make_on_surface novas.c
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/03-07/JAB (USNO/AA)
|
|
|
|
NOTES:
|
|
1. Both input vectors are with respect to true equator and equinox
|
|
of date.
|
|
2. The output data structure is one of the inputs to NOVAS-C
|
|
function 'place'.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
const double latitude = 0.0;
|
|
const double longitude = 0.0;
|
|
const double height = 0.0;
|
|
const double temperature = 0.0;
|
|
const double pressure = 0.0;
|
|
|
|
in_space sat_state;
|
|
|
|
on_surface surface_loc;
|
|
|
|
make_in_space (sc_pos,sc_vel, &sat_state);
|
|
make_on_surface (latitude,longitude,height,temperature,pressure,
|
|
&surface_loc);
|
|
|
|
obs_in_space->where = 2;
|
|
obs_in_space->on_surf = surface_loc;
|
|
obs_in_space->near_earth = sat_state;
|
|
}
|
|
|
|
/********make_on_surface */
|
|
|
|
void make_on_surface (double latitude, double longitude, double height,
|
|
double temperature, double pressure,
|
|
|
|
on_surface *obs_surface)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Makes a structure of type 'on_surface' - specifying the location
|
|
of and weather for an observer on the surface of the Earth.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
latitude (double)
|
|
Geodetic (ITRS) latitude in degrees; north positive.
|
|
longitude (double)
|
|
Geodetic (ITRS) longitude in degrees; east positive.
|
|
height (double)
|
|
Height of the observer (meters).
|
|
temperature (double)
|
|
Temperature (degrees Celsius).
|
|
pressure (double)
|
|
Atmospheric pressure (millibars).
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
struct on_surface *obs_surface
|
|
Structure containing the location of and weather for an
|
|
observer on the surface of the Earth (defined in novas.h).
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
None.
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/08-04/JAB (USNO/AA)
|
|
|
|
NOTES:
|
|
None.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
obs_surface->latitude = latitude;
|
|
obs_surface->longitude = longitude;
|
|
obs_surface->height = height;
|
|
obs_surface->temperature = temperature;
|
|
obs_surface->pressure = pressure;
|
|
}
|
|
|
|
/********make_in_space */
|
|
|
|
void make_in_space (double sc_pos[3], double sc_vel[3],
|
|
|
|
in_space *obs_space)
|
|
/*
|
|
------------------------------------------------------------------------
|
|
|
|
PURPOSE:
|
|
Makes a structure of type 'in_space' - specifying the position and
|
|
velocity of an observer situated on a near-Earth spacecraft.
|
|
|
|
REFERENCES:
|
|
None.
|
|
|
|
INPUT
|
|
ARGUMENTS:
|
|
sc_pos[3] (double)
|
|
Geocentric position vector (x, y, z) in km.
|
|
sc_vel[3] (double)
|
|
Geocentric velocity vector (x_dot, y_dot, z_dot) in km/s.
|
|
|
|
OUTPUT
|
|
ARGUMENTS:
|
|
struct in_space *obs_space
|
|
Structure containing the position and velocity of an observer
|
|
situated on a near-Earth spacecraft (defined in novas.h).
|
|
|
|
RETURNED
|
|
VALUE:
|
|
None.
|
|
|
|
GLOBALS
|
|
USED:
|
|
None.
|
|
|
|
FUNCTIONS
|
|
CALLED:
|
|
None.
|
|
|
|
VER./DATE/
|
|
PROGRAMMER:
|
|
V1.0/08-04/JAB (USNO/AA)
|
|
|
|
NOTES:
|
|
1. Both vectors with respect to true equator and equinox of date.
|
|
|
|
------------------------------------------------------------------------
|
|
*/
|
|
{
|
|
obs_space->sc_pos[0] = sc_pos[0];
|
|
obs_space->sc_pos[1] = sc_pos[1];
|
|
obs_space->sc_pos[2] = sc_pos[2];
|
|
|
|
obs_space->sc_vel[0] = sc_vel[0];
|
|
obs_space->sc_vel[1] = sc_vel[1];
|
|
obs_space->sc_vel[2] = sc_vel[2];
|
|
}
|