/**
* copyright
* @file
* @author Team RSIS
* @date 04-07-2004
* @brief This file interfaces to the NOVAS libraries to calculate the position of the Sun for Suncheck tests.
*
* Change Log:
*
* Programmer Name--------------------Description-----------------Date
*
*/
#include "rsts_sun_pos.h"
/* Local Function Declarations */
static void rsts_get_tdt_julian_date( double *current_tdt_julian_date);
static void rsts_get_tdt_julian_date_at_time( double *tdt_julian_date, time_t desired_time );
#ifdef _RSTS_SUN_POS_UNIT_TEST
/**
* This function is used for stand alone debugging of the code in this file. Must
* Define _RSTS_SUN_POS_UNIT_TEST when the file is compiled, to make a stand alone
* program from this file.
*
* --------------------------------------------------------
*
* @return (int) Always 0.
*
* --------------------------------------------------------
*/
int main()
{
/**
The following is a detailed description of the steps for main():
*/
/** Radar location. */
site_info here = {35.0 + 13.0/60.0 /*lat*/,
-97.0 - 27.0/60.0 /*long*/,
300/*height*/,
0/*temp Celsius*/,
1010/*pressure millibars*/};
double DELTAT=-0.45;
double SunAz,SunEl;
double distanceAU;
time_t Tnow;
rsts_SunNovasComputePos(here,DELTAT,&SunAz,&SunEl, &distanceAU );
Tnow = time(NULL);
fprintf(stdout,"Sun position on %s is Az: %g El : %g\n",ctime(&Tnow),
SunAz,SunEl);
}
#else
/* #include "rsts.h" */
#endif
/**
* This function uses the NOVAS software library to compute
* the current position of the Sun on the local horizon.
*
* --------------------------------------------------------
*
* @param here (site_info) The point on the surface of the earth we are at.
* @param deltat (double) The difference between terrestrial dynamical time system 1 time, and universal time.
* @param *SunAz (double *) The returned sun azimuth, in degrees from true north.
* @param *SunEl (double *) The returned sun elevation, in degrees above the local horizon.
* @param *distanceAU (double *) The returned distance to the sun, in astronomical units.
*
* --------------------------------------------------------
*/
void rsts_SunNovasComputePos( site_info here, double deltat, double *SunAz, double *SunEl, double *distanceAU)
{
/** Local Variables */
/** */
/** - body earth,sun - The earth and sun body structures. See NOVAS
* documentation for more information.
*/
body earth,sun;
/** - double ra,declination - The right ascension, and declination of the sun
*/
double ra,declination;
/** - double current_tdt_julian_date - the current terrestrial dynamical time (TDT) julian date
*/
double current_tdt_julian_date;
/** - double zenith_distance - The Sun's zenith distance, measured from the local vertical.
*/
double zenith_distance;
/** - double azimuth - The Sun's azimuth is measured from the north
*/
double azimuth;
/** - double rar,decr - rar -right ascension. decr -declination. In the equatorial coordinate system
*/
double rar,decr;
/**
*/
/**------------------------------------------------------*/
/** The following is a detailed description of the steps for rsts_SunNovasComputePos():
*/
/** Call NOVAS subroutine set_body to setup Sun and Earth body structures. */
set_body(0,10,"Sun",&sun);
set_body(0,3,"Earth",&earth);
/** Get the current TDT date. */
rsts_get_tdt_julian_date( ¤t_tdt_julian_date);
/** Call NOVAS routine topo_planet to get the right ascension and declination
* of the Sun in topographic/equatorial coordinate system. */
topo_planet( current_tdt_julian_date,
&sun, &earth, deltat,
&here ,
&ra , &declination , distanceAU);
/** Call NOVAS subroutine equ2hor to convert the Sun's position to local horizon coordinates. */
equ2hor( current_tdt_julian_date, deltat,
0.0 /*x_ephemeris*/, 0.0 /*y_ephemeris*/,
&here,ra,declination,1/*normal refraction*/,
&zenith_distance,
&azimuth,
&rar,&decr);
/** Convert zenith_distance reference point so that the Sun's elevation is referenced to the local horizon. */
*SunEl = 90.0 - zenith_distance;
/** Azimuth needs no conversion, its local horizon reference is already true north. */
*SunAz = azimuth;
/** If this is a stand alone unit test, the results of the subroutine are printed for
* comparison with the naval observatory's web pages. */
#ifdef _RSTS_SUN_POS_UNIT_TEST
printf(" El : %f Az : %f \n", *SunEl, *SunAz);
#endif
}
/*---------------------------------------------------------*/
/**
* This function uses the NOVAS software library to compute the position
* of the Sun on the local horizon, but for an input time, instead of the current time.
*
* --------------------------------------------------------
*
* @param here (site_info) The point on the surface of the earth we are at.
* @param deltat (double) The difference between terrestrial dynamical time system 1 time, and universal time.
* @param *SunAz (double *) The returned sun azimuth, in degrees from true north.
* @param *SunEl (double *) The returned sun elevation, in degrees above the local horizon.
* @param time_in (time_t) The utc time in seconds that we need to compute the Sun's position.
*
* --------------------------------------------------------
*/
void rsts_SunNovasComputePosAtTime( site_info here, double deltat, double *SunAz, double *SunEl, time_t time_in )
{
/** Local Variables */
/** */
/** - body earth,sun - The earth and sun body structures. See NOVAS documentation for more information.
*/
body earth,sun;
/** - double ra,declination - The right ascension, and declination of the sun
*/
double ra,declination;
/** - double tdt_julian_date - the current terrestrial dynamical time (TDT) julian date
*/
double tdt_julian_date;
/** - double zenith_distance - Zenith distance, measured from the local vertical.
*/
double zenith_distance;
/** - double azimuth - The Sun's azimuth is measured from the north
*/
double azimuth;
/** - double rar,decr - rar -right ascension. decr -declination. In equatorial coordinate system
*/
double rar,decr;
/** - double distanceAU - The distance to the Sun, units of AU, not returned by this function.
*/
double distanceAU;
/**
*/
/**------------------------------------------------------*/
/** The following is a detailed description of the steps for rsts_SunNovasComputePosAtTime():
*/
/** Call NOVAS subroutine set_body to setup Sun and Earth body structures. */
set_body(0,10,"Sun",&sun);
set_body(0,3,"Earth",&earth);
/** Get the TDT date for the input time. */
rsts_get_tdt_julian_date_at_time( &tdt_julian_date, time_in);
/** Call NOVOS routine topo_planet to get the right ascension and declination
* of the Sun in topographic/equatorial coordinate system. */
topo_planet( tdt_julian_date,
&sun, &earth, deltat,
&here ,
&ra , &declination , &distanceAU);
/** Call NOVAS subroutine equ2hor to convert the Sun's position to local horizon coordinates. */
equ2hor( tdt_julian_date, deltat,
0.0 /*x_ephemeris*/, 0.0 /*y_ephemeris*/,
&here,ra,declination,1/*normal refraction*/,
&zenith_distance,
&azimuth,
&rar,&decr);
/** Convert zenith_distance reference point so that the Sun's elevation is referenced to the local horizon. */
*SunEl = 90.0 - zenith_distance;
/** Azimuth needs no conversion, its local horizon reference is already true north. */
*SunAz = azimuth;
/** Log a message to the test log with the input time, and position of the sun given. */
/** RSTS_LOG_MSG(LOG_RDA_OTEST,"Sun Pos at TDT JD %f - Az %f El %f",tdt_julian_date,*SunAz,*SunEl); */
/** If this is a stand alone unit test, the results of the subroutine are printed
* for comparison with the naval observatory's web pages. */
#ifdef _RSTS_SUN_POS_UNIT_TEST
printf(" El : %f Az : %f \n", *SunEl, *SunAz);
#endif
}
/*---------------------------------------------------------*/
/**
* This function calculates the current tdt (Terrestrial Dynamic Time) Julian Date.
*
* --------------------------------------------------------
*
* @param current_tdt_julian_date (double) The current tdt date is returned here.
*
* --------------------------------------------------------
*/
void rsts_get_tdt_julian_date( double *current_tdt_julian_date)
{
/** Local Variables */
/** */
/** - time_t tnow - the current time in UNIX Epoch (UTC on rcp8.)
*/
time_t tnow;
/**
*/
/**------------------------------------------------------*/
/** The following is a detailed description of the steps for rsts_get_tdt_julian_date():
*/
/** Get the current time. */
tnow = time (NULL);
/** Calculate the tdt_julian_date for the current time, using rsts_get_tdt_julian_date_at_time(). */
rsts_get_tdt_julian_date_at_time( current_tdt_julian_date, tnow);
}
/*---------------------------------------------------------*/
/**
* This function gets the tdt (Terrestrial Dynamic Time) Julian Date at the time desired.
*
* --------------------------------------------------------
*
* @param tdt_julian_date (double) The tdt date is returned here, corresponding to the desired time.
* @param desired_time (time_t) The time in seconds since the epoch that the Sun position is desired for.
*
* --------------------------------------------------------
*/
void rsts_get_tdt_julian_date_at_time( double *tdt_julian_date, time_t desired_time )
{
/** Local Variables */
/** */
/** - double epic2k=2451545.0 - The year 2000 corresponds to a
* modified julian tdt of 2451545.0 (days)
*/
double epic2k=2451545.0;
/** - double secs_per_geoid = 86400.0 - basically the number of seconds in a tdt day.
*/
double secs_per_geoid = 86400.0;
/** - double seconds_since_epic2k - The number of seconds since the year 2000
*/
double seconds_since_epic2k;
/** - time_t tnow - The time sinch the (unix) epoch
*/
time_t tnow;
/** - time_t ty2k = 946684800 - Seconds from the epoch to y2k-GMT
*/
time_t ty2k = 946684800;
/**
*/
/**------------------------------------------------------*/
/** The following is a detailed description of the steps for rsts_get_tdt_julian_date_at_time():
*/
/** Use the input time as the current time. */
tnow = desired_time ;
/** Get seconds since y2k TT. */
seconds_since_epic2k = tnow - ty2k;
/** Calculate tdt julian date. Subtract half a day ( the -0.5 term ) to get back from
* modified julian date.(Noon referenced). */
*tdt_julian_date = epic2k + (seconds_since_epic2k/secs_per_geoid) - 0.5;
/** If called during a stand alone unit test, print the results of the
* intermediate calculation for desk checking. */
#ifdef _RSTS_SUN_POS_UNIT_TEST
printf("The current seconds since epoch %d\n",tnow);
printf("The seconds y2k was from epoch %d\n",ty2k);
printf("TDT Julian Date for given time %f\n",*tdt_julian_date);
#else
/** Not compiled for unit test, then log the tdt date to the OTLOG. */
/* RSTS_DEBUG_MSG(VERBOSE, "TDT Julian Date for given time %f\n",*tdt_julian_date); */
#endif
}