++ed by:
TYLDUM BKB HAMMER

3 PAUSE users

Tom Wyant
and 1 contributors

NAME

Astro::Coord::ECI::Utils - Utility routines for astronomical calculations

SYNOPSIS

 use Astro::Coord::ECI::Utils qw{:all};
 my $now = time ();
 print "The current Julian day is ", julianday ($now);

DESCRIPTION

This module was written to provide a home for all the constants and utility subroutines used by Astro::Coord::ECI and its descendents. What ended up here was anything that was essentially a subroutine, not a method.

This package exports nothing by default. But all the constants, variables, and subroutines documented below are exportable, and the :all tag gets you all of them.

The following constants are exportable:

 AU = number of kilometers in an astronomical unit
 JD_OF_EPOCH = the Julian Day of Perl epoch 0
 LIGHTYEAR = number of kilometers in a light year
 PARSEC = number of kilometers in a parsec
 PERL2000 = January 1 2000, 12 noon universal, in Perl time
 PI = the circle ratio, computed as atan2 (0, -1)
 PIOVER2 = half the circle ratio
 SECSPERDAY = the number of seconds in a day
 TWOPI = twice the circle ratio

The following global variable is exportable:

$DATETIMEFORMAT

This variable represents the POSIX::strftime format used to convert times to strings. The default value is '%a %b %d %Y %H:%M:%S' to be consistent with the behavior of gmtime (or, to be precise, the behavior of ctime as documented on my system).

$JD_GREGORIAN

This variable represents the Julian Day of the switch from Julian to Gregorian calendars. This is used by date2jd(), jd2date(), and the routines which depend on them, for deciding whether the date is to be interpreted as in the Julian or Gregorian calendar. Its initial setting is 2299160.5, which represents midnight October 15 1582 in the Gregorian calendar, which is the date that calendar was first adopted. This is slightly different than the value of 2299161 (noon of the same day) used by Jean Meeus.

If you are interested in historical calculations, you may wish to reset this appropriately. If you use date2jd to calculate the new value, be aware of the effect the current setting of $JD_GREGORIAN has on the interpretation of the date you give.

In addition, the following subroutines are exportable:

$angle = acos ($value)

This subroutine calculates the arc in radians whose cosine is the given value.

$angle = asin ($value)

This subroutine calculates the arc in radians whose sine is the given value.

$magnitude = atmospheric_extinction ($elevation, $height);

This subroutine calculates the typical atmospheric extinction in magnitudes at the given elevation above the horizon in radians and the given height above sea level in kilometers.

The algorithm comes from Daniel W. E. Green's article "Magnitude Corrections for Atmospheric Extinction", which was published in the July 1992 issue of "International Comet Quarterly", and is available online at http://www.cfa.harvard.edu/icq/ICQExtinct.html. The text of this article makes it clear that the actual value of the atmospheric extinction can vary greatly from the typical values given even in the absence of cloud cover.

$jd = date2jd ($sec, $min, $hr, $day, $mon, $yr)

This subroutine converts the given date to the corresponding Julian day. The inputs are as for Time::Local::timegm; $mon is in the range 0 - 11, and $yr is from 1900, with earlier years being negative. The year 1 BC is represented as -1900.

If less than 6 arguments are provided, zeroes will be prepended to the argument list as needed.

The date is presumed to be in the Gregorian calendar. If the resultant Julian Day is before $JD_GREGORIAN, the date is reinterpreted as being from the Julian calendar.

The only validation is that the month be between 0 and 11 inclusive, and that the year be not less than -6612 (4713 BC). Fractional days are accepted.

The algorithm is from Jean Meeus' "Astronomical Algorithms", second edition, chapter 7 ("Julian Day"), pages 60ff, but the month is zero-based, not 1-based, and years are 1900-based.

$epoch = date2epoch ($sec, $min, $hr, $day, $mon, $yr)

This is a convenience routine that converts the given date to seconds since the epoch, going through date2jd() to do so. The arguments are the same as those of date2jd().

If less than 6 arguments are provided, zeroes will be prepended to the argument list as needed.

The functionality is the same as Time::Local::timegm, but this function lacks timegm's limited date range. These days, though, Time::y2038::timegm is probably preferred over this subroutine.

$rad = deg2rad ($degr)

This subroutine converts degrees to radians.

$value = distsq (\@coord1, \@coord2)

This subroutine calculates the square of the distance between the two sets of Cartesian coordinates. We do not take the square root here because of cases (e.g. the law of cosines) where we would just have to square the result again.

Notice that the subroutine does not assume three-dimensional coordinates. If @coord1 and @coord2 have six entries, you will get a six-dimensional distance.

$seconds = dynamical_delta ($time);

This method returns the difference between dynamical and universal time at the given universal time. That is,

 $dynamical = $time + dynamical_delta ($time)

if $time is universal time.

The algorithm is from Jean Meeus' "Astronomical Algorithms", 2nd Edition, Chapter 10, page 78.

$boolean = embodies ($thingy, $class)

This subroutine represents a safe way to call the 'represents' method on $thingy. You get back true if and only if $thingy->can('represents') does not throw an exception and returns true, and $thingy->represents($class) returns true. Otherwise it returns false. Any exception is trapped and dismissed.

This subroutine is called 'embodies' because it was too confusing to call it 'represents', both for the author and for the Perl interpreter.

($sec, $min, $hr, $day, $mon, $yr, $wday, $yday, 0) = epoch2datetime ($epoch)

This convenience subroutine converts the given time in seconds from the system epoch to the corresponding date and time. It is implemented in terms of jd2date (), with the year and month returned from that subroutine. The day is a whole number, with the fractional part converted to hours, minutes, and seconds. The $wday is the day of the week, with Sunday being 0. The $yday is the day of the year, with January 1 being 0. The trailing 0 is the summer time (or daylight saving time) indicator which is always 0 to be consistent with gmtime.

If called in scalar context, it returns the date formatted by POSIX::strftime, using the format string in $DATETIMEFORMAT.

The functionality is similar to gmtime, but lacks gmtime's limited date range.

The input must convert to a non-negative Julian date. The exact lower limit depends on the system, but is computed by -(JD_OF_EPOCH * 86400). For Unix systems with an epoch of January 1 1970, this is -210866760000.

Additional algorithms for day of week and day of year come from Jean Meeus' "Astronomical Algorithms", 2nd Edition, Chapter 7 (Julian Day), page 65.

$seconds = equation_of_time ($time);

This method returns the equation of time at the given dynamical time.

The algorithm is from W. S. Smart's "Text-Book on Spherical Astronomy", as reported in Jean Meeus' "Astronomical Algorithms", 2nd Edition, Chapter 28, page 185.

$time = find_first_true ($start, $end, \&test, $limit);

This function finds the first time between $start and $end for which test ($time) is true. The resolution is $limit, which defaults to 1 if not specified. If the times are reversed (i.e. the start time is after the end time) the time returned is the last time test ($time) is true.

The test () function is assumed to be false for the first part of the interval, and true for the rest. If this assumption is violated, the result of this subroutine should be considered meaningless.

The calculation is done by, essentially, a binary search; the interval is repeatedly split, the function is evaluated at the midpoint, and a new interval selected based on whether the result is true or false.

Actually, nothing in this function says the independent variable has to be time.

$difference = intensity_to_magnitude ($ratio)

This method converts a ratio of light intensities to a difference in stellar magnitudes. The algorithm comes from Jean Meeus' "Astronomical Algorithms", Second Edition, Chapter 56, Page 395.

Note that, because of the way magnitudes work (a more negative number represents a brighter star) you get back a positive result for an intensity ratio less than 1, and a negative result for an intensity ratio greater than 1.

($day, $mon, $yr, $greg, $leap) = jd2date ($jd)

This subroutine converts the given Julian day to the corresponding date. The returns are year - 1900, month (0 to 11), day (which may have a fractional part), a Gregorian calendar indicator which is true if the date is in the Gregorian calendar and false if it is in the Julian calendar, and a leap (or bissextile) year indicator which is true if the year is a leap year and false otherwise. The year 1 BC is returned as -1900 (i.e. as year 0), and so on. The date will probably have a fractional part (e.g. 2006 1 1.5 for noon January first 2006).

If the $jd is before $JD_GREGORIAN, the date will be in the Julian calendar; otherwise it will be in the Gregorian calendar.

The input may not be less than 0.

The algorithm is from Jean Meeus' "Astronomical Algorithms", second edition, chapter 7 ("Julian Day"), pages 63ff, but the month is zero-based, not 1-based, and the year is 1900-based.

($sec, $min, $hr, $day, $mon, $yr, $wday, $yday, 0) = jd2datetime ($jd)

This convenience subroutine converts the given Julian day to the corresponding date and time. All this really does is converts its argument to seconds since the system epoch, and pass off to epoch2datetime().

The input may not be less than 0.

$century = jcent2000 ($time);

Several of the algorithms in Jean Meeus' "Astronomical Algorithms" are expressed in terms of the number of Julian centuries from epoch J2000.0 (e.g equations 12.1, 22.1). This subroutine encapsulates that calculation.

$jd = jday2000 ($time);

This subroutine converts a Perl date to the number of Julian days (and fractions thereof) since Julian 2000.0. This quantity is used in a number of the algorithms in Jean Meeus' "Astronomical Algorithms".

The computation makes use of information from Jean Meeus' "Astronomical Algorithms", 2nd Edition, Chapter 7, page 62.

$jd = julianday ($time);

This subroutine converts a Perl date to a Julian day number.

The computation makes use of information from Jean Meeus' "Astronomical Algorithms", 2nd Edition, Chapter 7, page 62.

$rslt = load_module ($module_name)

This convenience method loads the named module (using 'require'), throwing an exception if the load fails. If the load succeeds, it returns the result of the 'require' built-in, which is required to be true for a successful load. Results are cached, and subsequent attempts to load the same module simply give the cached results.

$boolean = looks_like_number ($string);

This subroutine returns true if the input looks like a number. It uses Scalar::Util::looks_like_number if that is available, otherwise it uses its own code, which is lifted verbatim from Scalar::Util 1.19, which in turn leans heavily on perlfaq4.

$maximum = max (...);

This subroutine returns the maximum of its arguments. If List::Util can be loaded and 'max' imported, that's what you get. Otherwise you get a pure Perl implementation.

$minimum = min (...);

This subroutine returns the minimum of its arguments. If List::Util can be loaded and 'min' imported, that's what you get. Otherwise you get a pure Perl implementation.

$theta = mod2pi ($theta)

This subroutine reduces the given angle in radians to the range 0 <= $theta < TWOPI.

$delta_psi = nutation_in_longitude ($time)

This subroutine calculates the nutation in longitude (delta psi) for the given dynamical time.

The algorithm comes from Jean Meeus' "Astronomical Algorithms", 2nd Edition, Chapter 22, pages 143ff. Meeus states that it is good to 0.5 seconds of arc.

$delta_epsilon = nutation_in_obliquity ($time)

This subroutine calculates the nutation in obliquity (delta epsilon) for the given dynamical time.

The algorithm comes from Jean Meeus' "Astronomical Algorithms", 2nd Edition, Chapter 22, pages 143ff. Meeus states that it is good to 0.1 seconds of arc.

$epsilon = obliquity ($time)

This subroutine calculates the obliquity of the ecliptic in radians at the given dynamical time.

The algorithm comes from Jean Meeus' "Astronomical Algorithms", 2nd Edition, Chapter 22, pages 143ff. The conversion from universal to dynamical time comes from chapter 10, equation 10.2 on page 78.

$radians = omega ($time);

This subroutine calculates the ecliptic longitude of the ascending node of the Moon's mean orbit at the given dynamical time.

The algorithm comes from Jean Meeus' "Astronomical Algorithms", 2nd Edition, Chapter 22, pages 143ff.

$degrees = rad2deg ($radians)

This subroutine converts the given angle in radians to its equivalent in degrees.

$value = tan ($angle)

This subroutine computes the tangent of the given angle in radians.

$value = theta0 ($time);

This subroutine returns the Greenwich hour angle of the mean equinox at 0 hours universal on the day whose time is given (i.e. the argument is a standard Perl time).

$value = thetag ($time);

This subroutine returns the Greenwich hour angle of the mean equinox at the given time.

The algorithm comes from Jean Meeus' "Astronomical Algorithms", 2nd Edition, equation 12.4, page 88.

ACKNOWLEDGMENTS

The author wishes to acknowledge Jean Meeus, whose book "Astronomical Algorithms" (second edition) published by Willmann-Bell Inc (http://www.willbell.com/) provided several of the algorithms implemented herein.

BUGS

Bugs can be reported to the author by mail, or through http://rt.cpan.org/.

AUTHOR

Thomas R. Wyant, III (wyant at cpan dot org)

COPYRIGHT

Copyright 2005, 2006, 2007, 2008, 2009 by Thomas R. Wyant, III (wyant at cpan dot org). All rights reserved.

LICENSE

This module is free software; you can use it, redistribute it and/or modify it under the same terms as Perl itself. Please see http://perldoc.perl.org/index-licence.html for the current licenses.

This software is provided without any warranty of any kind, express or implied. The author will not be liable for any damages of any sort relating in any way to this software.