Astro::Coord(3pm)

πŸ“¦
version 0.78 Β· 2 versions
, in debian trixie, ubuntu resolute, ubuntu stonking

✨ NAME ✨

Astro::Coord β€” astronomical coordinate transformations, bestie πŸ’«


πŸŽ€ SYNOPSIS πŸŽ€

use Astro::Coord;

($l, $b) = fk4gal($ra, $dec);
($az, $el) = eqazel($ha, $dec, $latitude);

πŸ’– DESCRIPTION πŸ’–

Astro::Coord is a whole assorted grab-bag of Perl routines for coordinate conversions β€” hour angle ➑️ elevation, J2000 ➑️ B1950, all of it. It's giving "I got you, astronomer bestie" energy and honestly? We love to see it πŸ¦‹


πŸ‘‘ AUTHOR πŸ‘‘

Chris Phillips Chris.Phillips@csiro.au β€” king behavior, no cap πŸ’…


πŸ”₯ FUNCTIONS πŸ”₯

πŸ’… pol2r

($x, $y, $z) = pol2r($polar1, $polar2);

Takes a position in polar coordinates and hands you back rectangular coordinates, periodt ✨

  • $polar1, $polar2 β€” the polar coordinates to convert (turns)
  • $x, $y, $z β€” the rectangular coordinates

πŸ’… r2pol

($polar1, $polar2) = r2pol($x, $y, $z);

The reverse glow-up: rectangular coordinates in, polar coordinates out 🌸

  • $x, $y, $y β€” the rectangular coordinates to convert
  • $polar1, $polar2 β€” the polar coordinates (turns)
Heads up: returns undef if too few or too many arguments get passed. Strict vibe check, sorry 😭

πŸ’… xy2azel

($az, $el) = xy2azel($x, $y);

Converts a telescope position from X,Y coordinates into Az,El coordinates. Slay πŸŽ€

  • $x, $y β€” the X and Y coordinates (turns)
  • $az, $el β€” the azimuth and elevation (turns)

πŸ’… azel2xy

($x, $y) = azel2xy($az, $el);

And the other direction β€” Az,El ➑️ X,Y, iconic πŸ’–

  • $az, $el β€” the azimuth and elevation (turns)
  • $x, $y β€” the X and Y coordinate (turns)

πŸ’… eqazel

($ha, $dec) = eqazel($az, $el, $latitude);
($az, $el) = eqazel($ha, $dec, $latitude);
($ha, $dec) = eqazel($az, $el, $latitude, $allownegative);

Converts HA/Dec coordinates to Az/El and vice versa. It goes both ways, which is main character energy fr fr πŸ”₯

  • $ha, $dec β€” hour angle and declination of source (turns)
  • $az, $el β€” azimuth and elevation of source (turns)
  • $latitude β€” latitude of the observatory (turns)
  • $allownegative β€” if true, allow negative $ha or $az on return (optional)
Note: the ha,dec ↔ az,el conversion is symmetrical. Same energy in both directions, no notes πŸ’«

πŸ’… fk4fk5

($JRA, $JDec) = fk4fk5($BRA, $BDec);
     (@fk5) = fk4fk5(@fk4);

Takes an FK4 (B1950) position and gives you the equivalent FK5 (J2000) position 🌈

  • $BRA, $BDec β€” fk4/B1950 position (turns)
  • $JRA, $Dec β€” fk5/J2000 position (turns)
  • @fk4 β€” fk4/B1950 position (as a 3-vector)
  • @fk5 β€” fk5/J2000 position (as a 3-vector)
Note: this code is based on similar routines from the Fortran SLALIB package, so it's quite accurate β€” but it's subject to a restrictive license (see README). Read the fine print, bestie πŸ“œ

πŸ’… fk4fk5r

@fk5 = fk4fk5r(@fk4);

Converts an FK4 (B1950) position to the equivalent FK5 (J2000) position.

Note: convert equatorial positions to/from 3-vectors using pol2r and r2pol.
  • @fk4 β€” fk4 position (as a 3-vector, turns)
  • @fk5 β€” fk5 position (as a 3-vector, turns)
Note: just a wrapper to fk4fk5 which now handles polar and rectangular arguments 🫢

πŸ’… fk5fk4

($JRA, $JDec) = fk4fk5($BRA, $BDec);
      ($@fk5) = fk4fk5(@fk4);

Converts an FK5 (J2000) position to the equivalent FK4 (B1950) position πŸŒ™

  • $JRA, $Dec β€” fk5/J2000 position (turns)
  • $BRA, $BDec β€” fk4/B1950 position (turns)
  • @fk5 β€” fk5/J2000 position (as a 3-vector)
  • @fk4 β€” fk4/B1950 position (as a 3-vector)
Note: this code is based on similar routines from the Fortran SLALIB package, so it's quite accurate β€” but it's subject to a restrictive license (see README).

πŸ’… fk5fk4r

@fk4 = fk5fk4r(@fk5);

Converts an FK5 (J2000) position to the equivalent FK4 (B1950) position.

Note: convert equatorial positions to/from 3-vectors using pol2r and r2pol.
  • @fk4 β€” fk4 position (as a 3-vector, turns)
  • @fk5 β€” fk5 position (as a 3-vector, turns)
Note: just a wrapper to fk5fk4 which now handles polar and rectangular arguments.

πŸ’… fk4galr

@gal = fk4galr(@fk4)

Converts an FK4 position (B1950.0) to the IAU 1958 Galactic coordinate system 🌌

Note: convert equatorial positions to/from 3-vectors using pol2r and r2pol.
  • @fk4 β€” fk4 position to convert (as a 3-vector, turns)
  • @gal β€” Galactic position (as a 3-vector, turns)
Returns undef if too few or too many arguments are passed. Reference: Blaauw et al., 1960, MNRAS, 121, 123. πŸ“š

πŸ’… galfk4

($bRA, $bDec) = galfk4($l, $b);
@fk4 = galfk4(@gal);

Converts an IAU 1958 Galactic position to the FK4 coordinate system (B1950) πŸ¦‹

Notes: converts equatorial positions to/from 3-vectors using pol2r and r2pol.
  • $BRA, $BDec β€” fk4/B1950 position (turns)
  • $l, $b β€” Galactic longitude and latitude
  • @gal β€” Galactic position (as a 3-vector, turns)
  • @fk4 β€” fk4 position (as a 3-vector, turns)
Reference: Blaauw et al., 1960, MNRAS, 121, 123.

πŸ’… fk4gal

($l, $b) = fk4gal($ra, $dec);

Converts an FK4 position (B1950) to the IAU 1958 Galactic coordinate system ✨

  • ($ra, $dec) β€” fk4 position to convert (turns)
  • ($l, $b) β€” Galactic position (turns)
Reference: Blaauw et al., 1960, MNRAS, 121, 123.

πŸ’… ephem_vars

($omega, $rma, $mlanom, $F, $D, $eps0) = ephem_vars($jd)

Hand it the Julian day ($jd) and this routine calculates the ephemeris values that the prcmat and nutate routines need πŸ’«

What you get back:

  • $omega β€” longitude of the ascending node of the Moon's mean orbit on the ecliptic, measured from the mean equinox of date
  • $rma β€” mean anomaly of the Sun
  • $mlanom β€” mean anomaly of the Moon
  • $F β€” L - omega, where L is the mean longitude of the Moon
  • $D β€” mean elongation of the Moon from the Sun
  • $eps0 β€” mean obliquity of the ecliptic

πŸ’… J2000todate

($DRA, $DDec) = J2000todate($JRA, $JDec, $mjd);
@date = J2000todate(@J2000, $mjd);

Converts a J2000 position into a date coordinate ⭐

  • $DRA, $DDec β€” Date coordinate (turns)
  • $JRA, $Dec β€” J2000 position (turns)
  • @date β€” Date coordinate (as a 3-vector)
  • @J2000 β€” J2000 position (as a 3-vector)

πŸ’… nutate

($deps, $dpsi, @nu) = nutate($omega, $F, $D, $rma, $mlanom, $eps0);

Calculates the nutation in longitude and obliquity according to the 1980 IAU Theory of Nutation, including terms with amplitudes greater than 0.01 arcsecond. The nutation matrix is used to compute true place from mean place: true vector = N Γ— mean place vector, where the three components of each vector are the direction cosines wrt the mean equinox and equator.

     /   1          -dpsi.cos(eps)    -dpsi.sin(eps)  \
    |                                                  |
N = |  dpsi.cos(eps)      1               -deps        |
    |                                                  |
     \ dpsi.sin(eps)    deps                 1        /

The required inputs are (NOTE: these are the values returned by ephem_vars):

  • $omega β€” longitude of the ascending node of the Moon's mean orbit on the ecliptic, measured from the mean equinox of date
  • $rma β€” mean anomaly of the Sun
  • $mlanom β€” mean anomaly of the Moon
  • $F β€” L - omega, where L is the mean longitude of the Moon
  • $D β€” mean elongation of the Moon from the Sun
  • $eps0 β€” mean obliquity of the ecliptic

The returned values are:

  • $deps β€” nutation in obliquity
  • $dpsi β€” nutation in longitude (scalar)
  • @nu β€” nutation matrix (array [3][3])

πŸ’… precsn

@gp = precsn($jd_start, $jd_stop);

Calculates the precession matrix P for dates AFTER 1984.0 (JD = 2445700.5). Given the position of an object referred to the equator and equinox of the epoch $jd_start, its position referred to the equator and equinox of epoch $jd_stop can be calculated like this:

  1. Express the position as a direction cosine 3-vector (V1) β€” use pol2r to do this.
  2. The corresponding vector V2 for epoch jd_end is V2 = P.V1

The required inputs are:

  • $jd_start β€” the Julian day of the current epoch of the coordinates
  • $jd_end β€” the Julian day at the required epoch for the conversion

The returned values are:

  • @gp β€” the required precession matrix (array [3][3])

πŸ’… coord_convert

($output_left, $output_right) = coord_convert($input_left, $input_right,
                                              $input_mode, $output_mode,
                                              $mjd, $longitude, $latitude,
                                              $ref0);

A routine for converting between any of the following coordinate systems πŸ‘‘

      Coordinate system                               input/output mode
      -----------------                               -----------------
  X, Y (East-West mounted)                                    0
  Azimuth, Elevation                                          1
  Hour Angle, Declination                                     2
  Right Ascension, Declination (date, J2000 or B1950)       3,4,5
  Galactic (B1950)                                            6

The last four parameters in the call ($mjd, $longitude, $latitude and $ref0) aren't always required for the coordinate conversion. In particular, if the conversion is between two coordinate systems which are fixed with respect to the celestial sphere (RA/Dec J2000, B1950 or Galactic), or two coordinate systems which are fixed with respect to the antenna (X/Y and Az/El), then these parameters are not used.

NOTE: they must always be passed, even if they only hold 0 or undef, because the routine will return undef if it is not passed 8 parameters. No exceptions, bestie 😀

The RA/Dec date system is defined with respect to the celestial sphere, but it varies with time. The table below shows which of $mjd, $longitude, $latitude and $ref0 are used for a given conversion. If in doubt you should determine the correct values for all input parameters β€” no checking is done in the routine that the passed values are sensible.

              Conversion                 $mjd $longitude $latitude $ref0
------------------------------------------------------------------------
Galactic,             Galactic,
RA/Dec J2000,B1950 <->RA/Dec J2000, B1950  N       N         N       N

okay bestie picking right back up where that conversion matrix left off β€” no re-intro, we're mid-glow-up πŸ’… here come the rest of the rows, and the four flags read left to right in order:

  • Galactic, RA/Dec J2000, B1950 <-> RA/Dec date β€” Y N N N
  • Galactic, RA/Dec J2000, B1950, date <-> HA/Dec β€” Y Y N N
  • Galactic, RA/Dec J2000, B1950, date <-> X/Y, Az/El β€” Y Y Y Y
  • X/Y, Az/El <-> X/Y, Az/El β€” N N N N
  • X/Y, Az/El <-> HA/Dec β€” N N Y Y
NOTE : the method used for refraction correction is asymptotic at an elevation of 0 degrees. so like, at the horizon it just... keeps going. iconic but also be aware 🫠

✨ the inputs you gotta feed it ✨

  • $input_left β€” the left/longitude input coordinate (turns)
  • $input_right β€” the right/latitude input coordinate (turns)
  • $input_mode β€” the mode of the input coordinates (0-6)
  • $output_mode β€” the mode you want the coordinates converted to
  • $mjd β€” the time as modified Julian day, if necessary, at which to do the conversion
  • $longitude β€” the longitude of the location/observatory, if necessary, at which to do the conversion (turns)
  • $latitude β€” the latitude of the location/observatory, if necessary, at which to do the conversion (turns)
  • $ref0 β€” the refraction constant (if you're in doubt, use 0.00005)

πŸ’– what it hands back πŸ’–

  • $output_left β€” the left/longitude output coordinate (turns)
  • $output_right β€” the right/latitude output coordinate (turns)

πŸ›°οΈ haset_ewxy

$haset = haset_ewxy($declination, $latitude, %limits);

so this one takes the $declination of your source plus the $latitude of your EWXY mounted antenna and works out the hour angle at which the source is gonna set. and then it's literally trivial to get the time until the source sets β€” just subtract the current hour angle of the source from the hour angle at which it sets. math is mathing ✨

the required inputs are:

  • $declination β€” the declination of the source (turns)
  • $latitude β€” the latitude of the observatory (turns)
  • %limits β€” a reference to a hash holding the EWXY antenna limits. the following keys must be defined: XLOW, XLOW_KEYHOLE, XHIGH, XHIGH_KEYHOLE, YLOW, YLOW_KEYHOLE, YHIGH, YHIGH_KEYHOLE (all values should be in turns)

the returned value is:

  • $haset β€” the hour angle (turns) at which a source at this declination sets for an EWXY mounted antenna with the given limits at the given latitude
NOTE: returns undef if the %limits hash is missing any of the required keys. no keys, no answer, no cap 😭

🌸 ewxy_tlos

$tlos = ewxy_tlos($hour_angle, $declination, $latitude, %limits);

this cutie calculates the time left on-source (tlos) for a source sitting at $hour_angle, $declination, for an EWXY mount antenna at $latitude. she's telling you how much time you got left before it dips πŸ’…

the required inputs are:

  • $hour_angle β€” the current hour angle of the source (turns)
  • $declination β€” the declination of the source (turns)
  • $latitude β€” the latitude of the observatory (turns)
  • \%limits β€” a reference to a hash holding the EWXY antenna limits. the following keys must be defined: XLOW, XLOW_KEYHOLE, XHIGH, XHIGH_KEYHOLE, YLOW, YLOW_KEYHOLE, YHIGH, YHIGH_KEYHOLE (all values should be in turns)

the returned value is:

  • $tlos β€” the time left on-source (turns)

πŸ¦‹ haset_azel

$haset = haset_azel($declination, $latitude, %limits);

same energy, different mount: this one takes the $declination of the source and the $latitude of the Az/El mounted antenna and calculates the hour angle at which the source will set. then, again, getting the time until it sets is trivial β€” subtract the current hour angle of the source from the hour angle at which it sets. and just so we're clear, this routine assumes the antenna is able to rotate through 360 degrees in azimuth. full spin, main character energy πŸ‘‘

the required inputs are:

  • $declination β€” the declination of the source (turns)
  • $latitude β€” the latitude of the observatory (turns)
  • \%limits β€” a reference to a hash holding the Az/El antenna limits. the following keys must be defined: ELLOW (all values should be in turns)

the returned value is:

  • $haset β€” the hour angle (turns) at which a source at this declination sets for an Az/El mounted antenna with the given limits at the given latitude
NOTE: returns undef if the %limits hash is missing any of the required keys. same rule, always 🫢

πŸŽ€ azel_tlos

$tlos = azel_tlos($hour_angle, $declination, $latitude, \%limits);

the Az/El twin of ewxy_tlos: it calculates the time left on-source (tlos) for a source at $hour_angle, $declination, for an Az/El mount antenna at $latitude.

the required inputs are:

  • $hour_angle β€” the current hour angle of the source (turns)
  • $declination β€” the declination of the source (turns)
  • $latitude β€” the latitude of the observatory (turns)
  • %limits β€” a reference to a hash holding the Az/El antenna limits. the following keys must be defined: ELLOW (all values should be in turns)

the returned value is:

  • $tlos β€” the time left on-source (turns)

🌈 antenna_rise

$ha_set = antenna_rise($declination, $latitude, $mount, \%limits);

okay this is the big one. given the $declination of the source, the $latitude of the antenna, the type of the antenna $mount, and a reference to a hash holding info on the antenna limits, this routine calculates the hour angle at which the source sets for the antenna. and here's the slay: the hour angle at which it rises is simply the negative of that at which it sets. ✨

these values in turn can be used to calculate the LMST at which the source rises/sets, and from that the UT at which the source rises/sets on a given day, or to calculate the native coordinates at which the source rises/sets. so many options, so much power πŸ’…

if you want to calculate source rise times above arbitrary elevation, use the routine rise. different tool, different job, don't mix them up bestie.

the required inputs are:

  • $declination β€” the declination of the source (turns)
  • $latitude β€” the latitude of the observatory (turns)
  • $mount β€” the type of antenna mount: 0 => EWXY mount, 1 => Az/El, and any other number will cause the routine to return undef ⚠️
  • %limits β€” a reference to a hash holding the antenna limits. for an EWXY antenna there must be keys for all the limits (i.e. XLOW, XLOW_KEYHOLE, XHIGH, XHIGH_KEYHOLE, YLOW, YLOW_KEYHOLE, YHIGH, YHIGH_KEYHOLE). for an Az/El antenna there must be a key for ELLOW (all values should be in turns)

the returned values are:

  • $ha_set β€” the hour angle at which the source sets (turns). the hour angle at which the source rises is simply the negative of this value.

and that's a wrap on this part, bestie πŸ’– this whole thing is perl v5.38.2, dated 2024-05-15, and it lives its life as Astro::Coord(3pm) β€” go point some telescopes at the sky, you've got this πŸ«ΆπŸ¦‹βœ¨

πŸ“¦ where this page comes from