\documentclass[11pt,twoside]{article} \setcounter{tocdepth}{2} \pagestyle{myheadings} % ----------------------------------------------------------------------------- % ? Document identification \newcommand{\stardoccategory} {Starlink User Note} \newcommand{\stardocinitials} {SUN} \newcommand{\stardocsource} {sun67.45} \newcommand{\stardocnumber} {67.45} \newcommand{\stardocauthors} {P.\,T.\,Wallace} \newcommand{\stardocdate} {12 October 1999} \newcommand{\stardoctitle} {SLALIB --- Positional Astronomy Library} \newcommand{\stardocversion} {2.4-0} \newcommand{\stardocmanual} {Programmer's Manual} % ? End of document identification %%% Also see \nroutines definition later %%% % ----------------------------------------------------------------------------- \newcommand{\stardocname}{\stardocinitials /\stardocnumber} \markright{\stardocname} %---------------------------------------------------- % Comment out unwanted definitions to suit stationery \setlength{\textwidth}{160mm} % \setlength{\textheight}{230mm} % European A4 \setlength{\topmargin}{-5mm} % %\setlength{\textwidth}{167mm} % %\setlength{\textheight}{220mm} % US Letter %\setlength{\topmargin}{-10mm} % % %---------------------------------------------------- \setlength{\textwidth}{160mm} \setlength{\textheight}{230mm} \setlength{\topmargin}{-2mm} \setlength{\oddsidemargin}{0mm} \setlength{\evensidemargin}{0mm} \setlength{\parindent}{0mm} \setlength{\parskip}{\medskipamount} \setlength{\unitlength}{1mm} % ----------------------------------------------------------------------------- % Hypertext definitions. % ====================== % These are used by the LaTeX2HTML translator in conjunction with star2html. % Comment.sty: version 2.0, 19 June 1992 % Selectively in/exclude pieces of text. % % Author % Victor Eijkhout % Department of Computer Science % University Tennessee at Knoxville % 104 Ayres Hall % Knoxville, TN 37996 % USA % Do not remove the %\begin{rawtex} and %\end{rawtex} lines (used by % star2html to signify raw TeX that latex2html cannot process). %\begin{rawtex} \makeatletter \def\makeinnocent#1{\catcode`#1=12 } \def\csarg#1#2{\expandafter#1\csname#2\endcsname} \def\ThrowAwayComment#1{\begingroup \def\CurrentComment{#1}% \let\do\makeinnocent \dospecials \makeinnocent\^^L% and whatever other special cases \endlinechar`\^^M \catcode`\^^M=12 \xComment} {\catcode`\^^M=12 \endlinechar=-1 % \gdef\xComment#1^^M{\def\test{#1} \csarg\ifx{PlainEnd\CurrentComment Test}\test \let\html@next\endgroup \else \csarg\ifx{LaLaEnd\CurrentComment Test}\test \edef\html@next{\endgroup\noexpand\end{\CurrentComment}} \else \let\html@next\xComment \fi \fi \html@next} } \makeatother \def\includecomment #1{\expandafter\def\csname#1\endcsname{}% \expandafter\def\csname end#1\endcsname{}} \def\excludecomment #1{\expandafter\def\csname#1\endcsname{\ThrowAwayComment{#1}}% {\escapechar=-1\relax \csarg\xdef{PlainEnd#1Test}{\string\\end#1}% \csarg\xdef{LaLaEnd#1Test}{\string\\end\string\{#1\string\}}% }} % Define environments that ignore their contents. \excludecomment{comment} \excludecomment{rawhtml} \excludecomment{htmlonly} %\end{rawtex} % Hypertext commands etc. This is a condensed version of the html.sty % file supplied with LaTeX2HTML by: Nikos Drakos & % Jelle van Zeijl . The LaTeX2HTML documentation % should be consulted about all commands (and the environments defined above) % except \xref and \xlabel which are Starlink specific. \newcommand{\htmladdnormallinkfoot}[2]{#1\footnote{#2}} \newcommand{\htmladdnormallink}[2]{#1} \newcommand{\htmladdimg}[1]{} \newenvironment{latexonly}{}{} \newcommand{\hyperref}[4]{#2\ref{#4}#3} \newcommand{\htmlref}[2]{#1} \newcommand{\htmlimage}[1]{} \newcommand{\htmladdtonavigation}[1]{} % Starlink cross-references and labels. \newcommand{\xref}[3]{#1} \newcommand{\xlabel}[1]{} % LaTeX2HTML symbol. \newcommand{\latextohtml}{{\bf LaTeX}{2}{\tt{HTML}}} % Define command to re-centre underscore for Latex and leave as normal % for HTML (severe problems with \_ in tabbing environments and \_\_ % generally otherwise). \newcommand{\latex}[1]{#1} \newcommand{\setunderscore}{\renewcommand{\_}{{\tt\symbol{95}}}} \latex{\setunderscore} % Redefine the \tableofcontents command. This procrastination is necessary % to stop the automatic creation of a second table of contents page % by latex2html. \newcommand{\latexonlytoc}[0]{\tableofcontents} % ----------------------------------------------------------------------------- % Debugging. % ========= % Remove % on the following to debug links in the HTML version using Latex. % \newcommand{\hotlink}[2]{\fbox{\begin{tabular}[t]{@{}c@{}}#1\\\hline{\footnotesize #2}\end{tabular}}} % \renewcommand{\htmladdnormallinkfoot}[2]{\hotlink{#1}{#2}} % \renewcommand{\htmladdnormallink}[2]{\hotlink{#1}{#2}} % \renewcommand{\hyperref}[4]{\hotlink{#1}{\S\ref{#4}}} % \renewcommand{\htmlref}[2]{\hotlink{#1}{\S\ref{#2}}} % \renewcommand{\xref}[3]{\hotlink{#1}{#2 -- #3}} % ----------------------------------------------------------------------------- % ? Document specific \newcommand or \newenvironment commands. %------------------------------------------------------------------------------ \newcommand{\nroutines} {183} \newcommand{\radec} {$[\,\alpha,\delta\,]$} \newcommand{\hadec} {$[\,h,\delta\,]$} \newcommand{\xieta} {$[\,\xi,\eta\,]$} \newcommand{\azel} {$[\,Az,El~]$} \newcommand{\ecl} {$[\,\lambda,\beta~]$} \newcommand{\gal} {$[\,l^{I\!I},b^{I\!I}\,]$} \newcommand{\xy} {$[\,x,y\,]$} \newcommand{\xyz} {$[\,x,y,z\,]$} \newcommand{\xyzd} {$[\,\dot{x},\dot{y},\dot{z}\,]$} \newcommand{\xyzxyzd} {$[\,x,y,z,\dot{x},\dot{y},\dot{z}\,]$} \newcommand{\degree}[2] {$#1^{\circ} \hspace{-0.37em}.\hspace{0.02em}#2$} \newcommand{\arcsec}[2] {\arcseci{#1}$\hspace{-0.4em}.#2$} \begin{htmlonly} \newcommand{\arcsec}[2] { {$#1\hspace{-0.05em}^{'\hspace{-0.1em}'}\hspace{-0.4em}.#2$} } \end{htmlonly} \newcommand{\arcseci}[1] {$#1\hspace{-0.05em}$\raisebox{-0.5ex} {$^{'\hspace{-0.1em}'}$}} \begin{htmlonly} \renewcommand{\arcseci}[1] {$#1\hspace{-0.05em}^{'\hspace{-0.1em}'}$} \end{htmlonly} \newcommand{\dms}[4] {$#1^{\circ}\,#2\raisebox{-0.5ex} {$^{'}$}\,$\arcsec{#3}{#4}} \begin{htmlonly} \renewcommand{\dms}[4]{$#1^{\circ}\,#2^{'}\,#3^{''}.#4$} \end{htmlonly} \newcommand{\tseci}[1] {$#1$\mbox{$^{\rm s}$}} \newcommand{\tsec}[2] {\tseci{#1}$\hspace{-0.3em}.#2$} \begin{htmlonly} \renewcommand{\tsec}[2] {$#1^{\rm s}\hspace{-0.3em}.#2$} \end{htmlonly} \newcommand{\hms}[4] {$#1^{\rm h}\,#2^{\rm m}\,$\tsec{#3}{#4}} \begin{htmlonly} \renewcommand{\hms}[4] {$#1^{h}\,#2^{m}\,#3^{s}.#4$} \end{htmlonly} \newcommand{\callhead}[1]{\goodbreak\vspace{\bigskipamount}{\large\bf{#1}}} \newenvironment{callset}{\begin{list}{}{\setlength{\leftmargin}{2cm} \setlength{\parsep}{\smallskipamount}}}{\end{list}} \newcommand{\subp}[1]{\item\hspace{-1cm}#1\\} \newcommand{\subq}[2]{\item\hspace{-1cm}#1\\\hspace*{-1cm}#2\\} \newcommand{\name}[1]{\mbox{#1}} \newcommand{\fortvar}[1]{\mbox{\em #1}} \newcommand{\routine}[3] {\hbadness=10000 \vbox { \rule{\textwidth}{0.3mm}\\ {\Large {\bf #1} \hfill #2 \hfill {\bf #1}}\\ \setlength{\oldspacing}{\topsep} \setlength{\topsep}{0.3ex} \begin{description} #3 \end{description} \setlength{\topsep}{\oldspacing} } } % Replacement for HTML version (each routine in own subsection). \begin{htmlonly} \renewcommand{\routine}[3] { \subsection{#1\xlabel{#1} - #2\label{#1}} \begin{description} #3 \end{description} } \end{htmlonly} \newcommand{\action}[1] {\item[ACTION]: #1} \begin{htmlonly} \newcommand{\action}[1] {\item[ACTION:] #1} \end{htmlonly} \newcommand{\call}[1] {\item[CALL]: \hspace{0.4em}{\tt #1}} \newlength{\oldspacing} \begin{htmlonly} \renewcommand{\call}[1] { \item[CALL:] {\tt #1} } \end{htmlonly} \newcommand{\args}[2] { \goodbreak \setlength{\oldspacing}{\topsep} \setlength{\topsep}{0.3ex} \begin{description} \item[#1]:\\[1.5ex] \begin{tabular}{p{7em}p{6em}p{22em}} #2 \end{tabular} \end{description} \setlength{\topsep}{\oldspacing} } \begin{htmlonly} \renewcommand{\args}[2] { \begin{description} \item[#1:]\\ \begin{tabular}{p{7em}p{6em}l} #2 \end{tabular} \end{description} } \end{htmlonly} \newcommand{\spec}[3] { {\em {#1}} & {\bf \mbox{#2}} & {#3} } \newcommand{\specel}[2] { \multicolumn{1}{c}{#1} & {} & {#2} } \newcommand{\anote}[1] { \goodbreak \setlength{\oldspacing}{\topsep} \setlength{\topsep}{0.3ex} \begin{description} \item[NOTE]: #1 \end{description} \setlength{\topsep}{\oldspacing} } \begin{htmlonly} \renewcommand{\anote}[1] { \begin{description} \item[NOTE:] #1 \end{description} } \end{htmlonly} \newcommand{\notes}[1] { \goodbreak \setlength{\oldspacing}{\topsep} \setlength{\topsep}{0.3ex} \begin{description} \item[NOTES]: #1 \end{description} \setlength{\topsep}{\oldspacing} } \begin{htmlonly} \renewcommand{\notes}[1] { \begin{description} \item[NOTES:] #1 \end{description} } \end{htmlonly} \newcommand{\aref}[1] { \goodbreak \setlength{\oldspacing}{\topsep} \setlength{\topsep}{0.3ex} \begin{description} \item[REFERENCE]: #1 \end{description} \setlength{\topsep}{\oldspacing} } \begin{htmlonly} \newcommand{\aref}[1] { \begin{description} \item[REFERENCE:] #1 \end{description} } \end{htmlonly} \newcommand{\refs}[1] { \goodbreak \setlength{\oldspacing}{\topsep} \setlength{\topsep}{0.3ex} \begin{description} \item[REFERENCES]: #1 \end{description} \setlength{\topsep}{\oldspacing} } \begin{htmlonly} \newcommand{\refs}[1] { \begin{description} \item[REFERENCES:] #1 \end{description} } \end{htmlonly} \newcommand{\exampleitem}{\item [EXAMPLE]:} \begin{htmlonly} \renewcommand{\exampleitem}{\item [EXAMPLE:]} \end{htmlonly} %------------------------------------------------------------------------------ % ? End of document specific commands % ----------------------------------------------------------------------------- % Title Page. % =========== \renewcommand{\thepage}{\roman{page}} \begin{document} \thispagestyle{empty} % Latex document header. % ====================== \begin{latexonly} CCLRC / {\sc Rutherford Appleton Laboratory} \hfill {\bf \stardocname}\\ {\large Particle Physics \& Astronomy Research Council}\\ {\large Starlink Project\\} {\large \stardoccategory\ \stardocnumber} \begin{flushright} \stardocauthors\\ \stardocdate \end{flushright} \vspace{-4mm} \rule{\textwidth}{0.5mm} \vspace{5mm} \begin{center} {\Huge\bf \stardoctitle \\ [2.5ex]} {\LARGE\bf \stardocversion \\ [4ex]} {\Huge\bf \stardocmanual} \end{center} \vspace{5mm} % ? Heading for abstract if used. \vspace{10mm} \begin{center} {\Large\bf Abstract} \end{center} % ? End of heading for abstract. \end{latexonly} % HTML documentation header. % ========================== \begin{htmlonly} \xlabel{} \begin{rawhtml}

\end{rawhtml} \stardoctitle\\ \stardocversion\\ \stardocmanual \begin{rawhtml}

\end{rawhtml} % ? Add picture here if required. % ? End of picture \begin{rawhtml}

\end{rawhtml} \stardoccategory \stardocnumber \\ \stardocauthors \\ \stardocdate \begin{rawhtml}

\end{rawhtml} \htmladdnormallink{CCLRC}{http://www.cclrc.ac.uk} / \htmladdnormallink{Rutherford Appleton Laboratory} {http://www.cclrc.ac.uk/ral} \\ \htmladdnormallink{Particle Physics \& Astronomy Research Council} {http://www.pparc.ac.uk} \\ \begin{rawhtml}

\end{rawhtml} \htmladdnormallink{Starlink Project}{http://star-www.rl.ac.uk/} \begin{rawhtml}

\end{rawhtml} \htmladdnormallink{\htmladdimg{source.gif} Retrieve hardcopy} {http://star-www.rl.ac.uk/cgi-bin/hcserver?\stardocsource}\\ % HTML document table of contents. % ================================ % Add table of contents header and a navigation button to return to this % point in the document (this should always go before the abstract \section). \label{stardoccontents} \begin{rawhtml}

Contents

\end{rawhtml} \renewcommand{\latexonlytoc}[0]{} \htmladdtonavigation{\htmlref{\htmladdimg{contents_motif.gif}} {stardoccontents}} % ? New section for abstract if used. \section{\xlabel{abstract}Abstract} % ? End of new section for abstract \end{htmlonly} % ----------------------------------------------------------------------------- % ? Document Abstract. (if used) % ================== SLALIB is a library used by writers of positional-astronomy applications. Most of the \nroutines\ routines are concerned with astronomical position and time, but a number have wider trigonometrical, numerical or general applications. % ? End of document abstract % ----------------------------------------------------------------------------- % ? Latex document Table of Contents (if used). % =========================================== \newpage \begin{latexonly} \setlength{\parskip}{0mm} \latexonlytoc \setlength{\parskip}{\medskipamount} \markright{\stardocname} \end{latexonly} % ? End of Latex document table of contents % ----------------------------------------------------------------------------- \newpage \renewcommand{\thepage}{\arabic{page}} \setcounter{page}{1} \section{INTRODUCTION} \subsection{Purpose} SLALIB\footnote{The name isn't an acronym; it just stands for ``Subprogram Library~A''.} is a library of routines intended to make accurate and reliable positional-astronomy applications easier to write. Most SLALIB routines are concerned with astronomical position and time, but a number have wider trigonometrical, numerical or general applications. The applications ASTROM, COCO, RV and TPOINT all make extensive use of the SLALIB routines, as do a number of telescope control systems around the world. The SLALIB versions currently in service are written in Fortran~77 and run on VAX/VMS, several Unix platforms and PC. A generic ANSI~C version is also available from the author; it is functionally similar to the Fortran version upon which the present document concentrates. \subsection{Example Application} Here is a simple example of an application program written using SLALIB calls: \begin{verbatim} PROGRAM FK4FK5 * * Read a B1950 position from I/O unit 5 and reply on I/O unit 6 * with the J2000 equivalent. Enter a period to quit. * IMPLICIT NONE CHARACTER C*80,S INTEGER I,J,IHMSF(4),IDMSF(4) DOUBLE PRECISION R4,D4,R5,D5 LOGICAL BAD * Loop until a period is entered C = ' ' DO WHILE (C(:1).NE.'.') * Read h m s d ' " READ (5,'(A)') C IF (C(:1).NE.'.') THEN BAD = .TRUE. * Decode the RA I = 1 CALL sla_DAFIN(C,I,R4,J) IF (J.EQ.0) THEN R4 = 15D0*R4 * Decode the Dec CALL sla_DAFIN(C,I,D4,J) IF (J.EQ.0) THEN * FK4 to FK5 CALL sla_FK45Z(R4,D4,1950D0,R5,D5) * Format and output the result CALL sla_DR2TF(2,R5,S,IHMSF) CALL sla_DR2AF(1,D5,S,IDMSF) WRITE (6, : '(1X,I2.2,2I3.2,''.'',I2.2,2X,A,I2.2,2I3.2,''.'',I1)') : IHMSF,S,IDMSF BAD = .FALSE. END IF END IF IF (BAD) WRITE (6,'(1X,''?'')') END IF END DO END \end{verbatim} In this example, SLALIB not only provides the complicated FK4 to FK5 transformation but also simplifies the tedious and error-prone tasks of decoding and formatting angles expressed as hours, minutes {\it etc}. The example incorporates range checking, and avoids the notorious ``minus zero'' problem (an often-perpetrated bug where declinations between $0^{\circ}$ and $-1^{\circ}$ lose their minus sign). With a little extra elaboration and a few more calls to SLALIB, defaulting can be provided (enabling unused fields to be replaced with commas to avoid retyping), proper motions can be handled, different epochs can be specified, and so on. See the program COCO (SUN/56) for further ideas. \subsection{Scope} SLALIB contains \nroutines\ routines covering the following topics: \begin{itemize} \item String Decoding, Sexagesimal Conversions \item Angles, Vectors \& Rotation Matrices \item Calendars, Timescales \item Precession \& Nutation \item Proper Motion \item FK4/FK5/Hipparcos, Elliptic Aberration \item Geocentric Coordinates \item Apparent \& Observed Place \item Azimuth \& Elevation \item Refraction \& Air Mass \item Ecliptic, Galactic, Supergalactic Coordinates \item Ephemerides \item Astrometry \item Numerical Methods \end{itemize} \subsection{Objectives} SLALIB was designed to give application programmers a basic set of positional-astronomy tools which were accurate and easy to use. To this end, the library is: \begin{itemize} \item Readily available, including source code and documentation. \item Supported and maintained. \item Portable -- coded in standard languages and available for multiple computers and operating systems. \item Thoroughly commented, both for maintainability and to assist those wishing to cannibalize the code. \item Stable. \item Trustworthy -- some care has gone into testing SLALIB, both by comparison with published data and by checks for internal consistency. \item Rigorous -- corners are not cut, even where the practical consequences would, as a rule, be negligible. \item Comprehensive, without including too many esoteric features required only by specialists. \item Practical -- almost all the routines have been written to satisfy real needs encountered during the development of real-life applications. \item Environment-independent -- the package is completely free of pauses, stops, I/O {\it etc}. \item Self-contained -- SLALIB calls no other libraries. \end{itemize} A few {\it caveats}: \begin{itemize} \item SLALIB does not pretend to be canonical. It is in essence an anthology, and the adopted algorithms are liable to change as more up-to-date ones become available. \item The functions aren't orthogonal -- there are several cases of different routines doing similar things, and many examples where sequences of SLALIB calls have simply been packaged, all to make applications less trouble to write. \item There are omissions -- for example there are no routines for calculating physical ephemerides of Solar-System bodies. \item SLALIB is not homogeneous, though important subsets (for example the FK4/FK5 routines) are. \item The library is not foolproof. You have to know what you are trying to do ({\it e.g.}\ by reading textbooks on positional astronomy), and it is the caller's responsibility to supply sensible arguments (although enough internal validation is done to avoid arithmetic errors). \item Without being written in a wasteful manner, SLALIB is nonetheless optimized for maintainability rather than speed. In addition, there are many places where considerable simplification would be possible if some specified amount of accuracy could be sacrificed; such compromises are left to the individual programmer and are not allowed to limit SLALIB's value as a source of comparison results. \end{itemize} \subsection{Fortran Version} The Fortran versions of SLALIB use ANSI Fortran~77 with a few commonplace extensions. Just three out of the \nroutines\ routines require platform-specific techniques and accordingly are supplied in different forms. SLALIB has been implemented on the following platforms: VAX/VMS, PC (Microsoft Fortran, Linux), DECstation (Ultrix), DEC Alpha (DEC Unix), Sun (SunOS, Solaris), Hewlett Packard (HP-UX), CONVEX, Perkin-Elmer and Fujitsu. \subsection{C Version} An ANSI C version of SLALIB is available from the author but is not part of the Starlink release. The functionality of this (proprietary) C version closely matches that of the Starlink Fortran SLALIB, partly for the convenience of existing users of the Fortran version, some of whom have in the past implemented C ``wrappers''. The function names cannot be the same as the Fortran versions because of potential linking problems when both forms of the library are present; the C routine which is the equivalent of (for example) {\tt SLA\_REFRO} is {\tt slaRefro}. The types of arguments follow the Fortran version, except that integers are {\tt int} rather than {\tt long}. Argument passing is by value (except for arrays and strings of course) for given arguments and by pointer for returned arguments. All the C functions are re-entrant. The Fortran routines {\tt sla\_GRESID}, {\tt sla\_RANDOM} and {\tt sla\_WAIT} have no C counterparts. Further details of the C version of SLALIB are available from the author. The definitive guide to the calling sequences is the file {\tt slalib.h}. \subsection{Future Versions} The homogeneity and ease of use of SLALIB could perhaps be improved in the future by turning to C++ and object-oriented techniques. For example ``celestial position'' could be a class and many of the transformations could happen automatically. This requires further study and would almost certainly result in a complete redesign. Similarly, the impact of Fortran~90 has yet to be assessed. Once compilers become widely available, some internal recoding may be worthwhile in order to simplify parts of the code. However, as with C++, a redesign of the application interfaces will be needed if the capabilities of the new language are to be exploited to the full. \subsection{New Functions} In a package like SLALIB it is difficult to know how far to go. Is it enough to provide the primitive operations, or should more complicated functions be packaged? Is it worth encroaching on specialist areas, where individual experts have all written their own software already? To what extent should CPU efficiency be an issue? How much support of different numerical precisions is required? And so on. In practice, almost all the routines in SLALIB are there because they were needed for some specific application, and this is likely to remain the pattern for any enhancements in the future. Suggestions for additional SLALIB routines should be addressed to the author. \subsection{Acknowledgements} SLALIB is descended from a package of routines written for the AAO 16-bit minicomputers in the mid-1970s. The coming of the VAX allowed a much more comprehensive and thorough package to be designed for Starlink, especially important at a time when the adoption of the IAU 1976 resolutions meant that astronomers would have to cope with a mixture of reference frames, timescales and nomenclature. Much of the preparatory work on SLALIB was done by Althea~Wilkinson of Manchester University. During its development, Andrew~Murray, Catherine~Hohenkerk, Andrew~Sinclair, Bernard~Yallop and Brian~Emerson of Her Majesty's Nautical Almanac Office were consulted on many occasions; their advice was indispensable. I am especially grateful to Catherine~Hohenkerk for supplying preprints of papers, and test data. A number of enhancements to SLALIB were at the suggestion of Russell~Owen, University of Washington, the late Phil~Hill, St~Andrews University, Bill~Vacca, JILA, Boulder and Ron~Maddalena, NRAO. Mark~Calabretta, CSIRO Radiophysics, Sydney supplied changes to suit Convex. I am indebted to Derek~Jones (RGO) for introducing me to the ``universal variables'' method of calculating orbits. The first C version of SLALIB was a hand-coded transcription of the Starlink Fortran version carried out by Steve~Eaton (University of Leeds) in the course of MSc work. This was later enhanced by John~Straede (AAO) and Martin~Shepherd (Caltech). The current C SLALIB is a complete rewrite by the present author and includes a comprehensive validation suite. Additional comments on the C version came from Bob~Payne (NRAO) and Jeremy~Bailey (AAO). \section{LINKING} On Unix systems (Sun, DEC Alpha {\it etc.}): \begin{verse} {\tt \%~~f77 progname.o -L/star/lib `sla\_link` -o progname} \end{verse} (The above assumes that all Starlink directories have been added to the {\tt LD\_LIBRARY\_PATH} and {\tt PATH} environment variables as described in SUN/202.) On VAX/VMS: \begin{verse} {\tt \$~~LINK progname,SLALIB\_DIR:SLALIB/LIB} \end{verse} \pagebreak \section{SUBPROGRAM SPECIFICATIONS} %----------------------------------------------------------------------- \routine{SLA\_ADDET}{Add E-terms of Aberration} { \action{Add the E-terms (elliptic component of annual aberration) to a pre IAU 1976 mean place to conform to the old catalogue convention.} \call{CALL sla\_ADDET (RM, DM, EQ, RC, DC)} } \args{GIVEN} { \spec{RM,DM}{D}{\radec\ without E-terms (radians)} \\ \spec{EQ}{D}{Besselian epoch of mean equator and equinox} } \args{RETURNED} { \spec{RC,DC}{D}{\radec\ with E-terms included (radians)} } \anote{Most star positions from pre-1984 optical catalogues (or obtained by astrometry with respect to such stars) have the E-terms built-in. If it is necessary to convert a formal mean place (for example a pulsar timing position) to one consistent with such a star catalogue, then the \radec\ should be adjusted using this routine.} \aref{{\it Explanatory Supplement to the Astronomical Ephemeris}, section 2D, page 48.} %----------------------------------------------------------------------- \routine{SLA\_AFIN}{Sexagesimal character string to angle} { \action{Decode a free-format sexagesimal string (degrees, arcminutes, arcseconds) into a single precision floating point number (radians).} \call{CALL sla\_AFIN (STRING, NSTRT, RESLT, JF)} } \args{GIVEN} { \spec{STRING}{C*(*)}{string containing deg, arcmin, arcsec fields} \\ \spec{NSTRT}{I}{pointer to start of decode (beginning of STRING = 1)} } \args{RETURNED} { \spec{NSTRT}{I}{advanced past the decoded angle} \\ \spec{RESLT}{R}{angle in radians} \\ \spec{JF}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 0 = OK} \\ \spec{}{}{\hspace{0.7em} $+1$ = default, RESLT unchanged (note 2)} \\ \spec{}{}{\hspace{0.7em} $-1$ = bad degrees (note 3)} \\ \spec{}{}{\hspace{0.7em} $-2$ = bad arcminutes (note 3)} \\ \spec{}{}{\hspace{0.7em} $-3$ = bad arcseconds (note 3)} \\ } \goodbreak \setlength{\oldspacing}{\topsep} \setlength{\topsep}{0.3ex} \begin{description} \exampleitem \\ [1.5ex] \begin{tabular}{p{7em}p{15em}p{12em}} {\it argument} & {\it before} & {\it after} \\ \\ STRING & $'$\verb*}-57 17 44.806 12 34 56.7}$'$ & unchanged \\ NSTRT & 1 & 16 ({\it i.e.}\ pointing to 12...) \\ RESLT & - & $-1.00000$ \\ JF & - & 0 \end{tabular} \item A further call to sla\_AFIN, without adjustment of NSTRT, will decode the second angle, \dms{12}{34}{56}{7}. \end{description} \setlength{\topsep}{\oldspacing} \notes { \begin{enumerate} \item The first three ``fields'' in STRING are degrees, arcminutes, arcseconds, separated by spaces or commas. The degrees field may be signed, but not the others. The decoding is carried out by the sla\_DFLTIN routine and is free-format. \item Successive fields may be absent, defaulting to zero. For zero status, the only combinations allowed are degrees alone, degrees and arcminutes, and all three fields present. If all three fields are omitted, a status of +1 is returned and RESLT is unchanged. In all other cases RESLT is changed. \item Range checking: \begin{itemize} \item The degrees field is not range checked. However, it is expected to be integral unless the other two fields are absent. \item The arcminutes field is expected to be 0-59, and integral if the arcseconds field is present. If the arcseconds field is absent, the arcminutes is expected to be 0-59.9999... \item The arcseconds field is expected to be 0-59.9999... \item Decoding continues even when a check has failed. Under these circumstances the field takes the supplied value, defaulting to zero, and the result RESLT is computed and returned. \end{itemize} \item Further fields after the three expected ones are not treated as an error. The pointer NSTRT is left in the correct state for further decoding with the present routine or with sla\_DFLTIN {\it etc}. See the example, above. \item If STRING contains hours, minutes, seconds instead of degrees {\it etc}, or if the required units are turns (or days) instead of radians, the result RESLT should be multiplied as follows: \\ [1.5ex] \begin{tabular}{p{6em}p{5em}p{15em}} {\it for STRING} & {\it to obtain} & {\it multiply RESLT by} \\ \\ ${\circ}$~~\raisebox{-0.7ex}{$'$}~~\raisebox{-0.7ex}{$''$} & radians & $1.0$ \\ ${\circ}$~~\raisebox{-0.7ex}{$'$}~~\raisebox{-0.7ex}{$''$} & turns & $1/{2 \pi} = 0.1591549430918953358$ \\ h m s & radians & $15.0$ \\ h m s & days & $15/{2\pi} = 2.3873241463784300365$ \\ \end{tabular} \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_AIRMAS}{Air Mass} { \action{Air mass at given zenith distance (double precision).} \call{D~=~sla\_AIRMAS (ZD)} } \args{GIVEN} { \spec{ZD}{D}{observed zenith distance (radians)} } \args{RETURNED} { \spec{sla\_AIRMAS}{D}{air mass (1 at zenith)} } \notes { \begin{enumerate} \item The {\it observed}\/ zenith distance referred to above means ``as affected by refraction''. \item The routine uses Hardie's (1962) polynomial fit to Bemporad's data for the relative air mass, $X$, in units of thickness at the zenith as tabulated by Schoenberg (1929). This is adequate for all normal needs as it is accurate to better than 0.1\% up to $X = 6.8$ and better than 1\% up to $X = 10$. Bemporad's tabulated values are unlikely to be trustworthy to such accuracy because of variations in density, pressure and other conditions in the atmosphere from those assumed in his work. \item The sign of the ZD is ignored. \item At zenith distances greater than about $\zeta = 87^{\circ}$ the air mass is held constant to avoid arithmetic overflows. \end{enumerate} } \refs { \begin{enumerate} \item Hardie, R.H., 1962, in {\it Astronomical Techniques}\, ed. W.A.\ Hiltner, University of Chicago Press, p180. \item Schoenberg, E., 1929, Hdb.\ d.\ Ap., Berlin, Julius Springer, 2, 268. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_ALTAZ}{Velocities {\it etc.}\ for Altazimuth Mount} { \action{Positions, velocities and accelerations for an altazimuth telescope mount tracking a star (double precision).} \call{CALL sla\_ALTAZ (\vtop{ \hbox{HA, DEC, PHI,} \hbox{AZ, AZD, AZDD, EL, ELD, ELDD, PA, PAD, PADD)}}} } \args{GIVEN} { \spec{HA}{D}{hour angle} \\ \spec{DEC}{D}{declination} \\ \spec{PHI}{D}{observatory latitude} } \args{RETURNED} { \spec{AZ}{D}{azimuth} \\ \spec{AZD}{D}{azimuth velocity} \\ \spec{AZDD}{D}{azimuth acceleration} \\ \spec{EL}{D}{elevation} \\ \spec{ELD}{D}{elevation velocity} \\ \spec{ELDD}{D}{elevation acceleration} \\ \spec{PA}{D}{parallactic angle} \\ \spec{PAD}{D}{parallactic angle velocity} \\ \spec{PADD}{D}{parallactic angle acceleration} } \notes { \begin{enumerate} \setlength{\parskip}{\medskipamount} \item Natural units are used throughout. HA, DEC, PHI, AZ, EL and ZD are in radians. The velocities and accelerations assume constant declination and constant rate of change of hour angle (as for tracking a star); the units of AZD, ELD and PAD are radians per radian of HA, while the units of AZDD, ELDD and PADD are radians per radian of HA squared. To convert into practical degree- and second-based units: \begin{center} \begin{tabular}{rlcl} angles & $\times 360/2\pi$ & $\rightarrow$ & degrees \\ velocities & $\times (2\pi/86400) \times (360/2\pi)$ & $\rightarrow$ & degree/sec \\ accelerations & $\times (2\pi/86400)^2 \times (360/2\pi)$ & $\rightarrow$ & degree/sec/sec \\ \end{tabular} \end{center} Note that the seconds here are sidereal rather than SI. One sidereal second is about 0.99727 SI seconds. The velocity and acceleration factors assume the sidereal tracking case. Their respective numerical values are (exactly) 1/240 and (approximately) 1/3300236.9. \item Azimuth is returned in the range $[\,0,2\pi\,]$; north is zero, and east is $+\pi/2$. Elevation and parallactic angle are returned in the range $\pm\pi/2$. Position angle is +ve for a star west of the meridian and is the angle NP--star--zenith. \item The latitude is geodetic as opposed to geocentric. The hour angle and declination are topocentric. Refraction and deficiencies in the telescope mounting are ignored. The purpose of the routine is to give the general form of the quantities. The details of a real telescope could profoundly change the results, especially close to the zenith. \item No range checking of arguments is carried out. \item In applications which involve many such calculations, rather than calling the present routine it will be more efficient to use inline code, having previously computed fixed terms such as sine and cosine of latitude, and (for tracking a star) sine and cosine of declination. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_AMP}{Apparent to Mean} { \action{Convert star \radec\ from geocentric apparent to mean place (post IAU 1976).} \call{CALL sla\_AMP (RA, DA, DATE, EQ, RM, DM)} } \args{GIVEN} { \spec{RA,DA}{D}{apparent \radec\ (radians)} \\ \spec{DATE}{D}{TDB for apparent place (JD$-$2400000.5)} \\ \spec{EQ}{D}{equinox: Julian epoch of mean place} } \args{RETURNED} { \spec{RM,DM}{D}{mean \radec\ (radians)} } \notes { \begin{enumerate} \item The distinction between the required TDB and TT is always negligible. Moreover, for all but the most critical applications UTC is adequate. \item The accuracy is limited by the routine sla\_EVP, called by sla\_MAPPA, which computes the Earth position and velocity using the methods of Stumpff. The maximum error is about 0.3~milliarcsecond. \item Iterative techniques are used for the aberration and light deflection corrections so that the routines sla\_AMP (or sla\_AMPQK) and sla\_MAP (or sla\_MAPQK) are accurate inverses; even at the edge of the Sun's disc the discrepancy is only about 1~nanoarcsecond. \item Where multiple apparent places are to be converted to mean places, for a fixed date and equinox, it is more efficient to use the sla\_MAPPA routine to compute the required parameters once, followed by one call to sla\_AMPQK per star. \end{enumerate} } \refs { \begin{enumerate} \item 1984 {\it Astronomical Almanac}, pp B39-B41. \item Lederle \& Schwan, 1984.\ {\it Astr.Astrophys.}\ {\bf 134}, 1-6. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_AMPQK}{Quick Apparent to Mean} { \action{Convert star \radec\ from geocentric apparent to mean place (post IAU 1976). Use of this routine is appropriate when efficiency is important and where many star positions are all to be transformed for one epoch and equinox. The star-independent parameters can be obtained by calling the sla\_MAPPA routine.} \call{CALL sla\_AMPQK (RA, DA, AMPRMS, RM, DM)} } \args{GIVEN} { \spec{RA,DA}{D}{apparent \radec\ (radians)} \\ \spec{AMPRMS}{D(21)}{star-independent mean-to-apparent parameters:} \\ \specel {(1)} {time interval for proper motion (Julian years)} \\ \specel {(2-4)} {barycentric position of the Earth (AU)} \\ \specel {(5-7)} {heliocentric direction of the Earth (unit vector)} \\ \specel {(8)} {(gravitational radius of Sun)$\times 2 / $(Sun-Earth distance)} \\ \specel {(9-11)} {{\bf v}: barycentric Earth velocity in units of c} \\ \specel {(12)} {$\sqrt{1-\left|\mbox{\bf v}\right|^2}$} \\ \specel {(13-21)} {precession/nutation $3\times3$ matrix} } \args{RETURNED} { \spec{RM,DM}{D}{mean \radec\ (radians)} } \notes { \begin{enumerate} \item The accuracy is limited by the routine sla\_EVP, called by sla\_MAPPA, which computes the Earth position and velocity using the methods of Stumpff. The maximum error is about 0.3~milliarcsecond. \item Iterative techniques are used for the aberration and light deflection corrections so that the routines sla\_AMP (or sla\_AMPQK) and sla\_MAP (or sla\_MAPQK) are accurate inverses; even at the edge of the Sun's disc the discrepancy is only about 1~nanoarcsecond. \end{enumerate} } \refs { \begin{enumerate} \item 1984 {\it Astronomical Almanac}, pp B39-B41. \item Lederle \& Schwan, 1984.\ {\it Astr.Astrophys.}\ {\bf 134}, 1-6. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_AOP}{Apparent to Observed} { \action{Apparent to observed place, for optical sources distant from the solar system.} \call{CALL sla\_AOP (\vtop{ \hbox{RAP, DAP, DATE, DUT, ELONGM, PHIM, HM, XP, YP,} \hbox{TDK, PMB, RH, WL, TLR, AOB, ZOB, HOB, DOB, ROB)}}} } \args{GIVEN} { \spec{RAP,DAP}{D}{geocentric apparent \radec\ (radians)} \\ \spec{DATE}{D}{UTC date/time (Modified Julian Date, JD$-$2400000.5)} \\ \spec{DUT}{D}{$\Delta$UT: UT1$-$UTC (UTC seconds)} \\ \spec{ELONGM}{D}{observer's mean longitude (radians, east +ve)} \\ \spec{PHIM}{D}{observer's mean geodetic latitude (radians)} \\ \spec{HM}{D}{observer's height above sea level (metres)} \\ \spec{XP,YP}{D}{polar motion \xy\ coordinates (radians)} \\ \spec{TDK}{D}{local ambient temperature (degrees K; std=273.155D0)} \\ \spec{PMB}{D}{local atmospheric pressure (mB; std=1013.25D0)} \\ \spec{RH}{D}{local relative humidity (in the range 0D0\,--\,1D0)} \\ \spec{WL}{D}{effective wavelength ($\mu{\rm m}$, {\it e.g.}\ 0.55D0)} \\ \spec{TLR}{D}{tropospheric lapse rate (degrees K per metre, {\it e.g.}\ 0.0065D0)} } \args{RETURNED} { \spec{AOB}{D}{observed azimuth (radians: N=0, E=$90^{\circ}$)} \\ \spec{ZOB}{D}{observed zenith distance (radians)} \\ \spec{HOB}{D}{observed Hour Angle (radians)} \\ \spec{DOB}{D}{observed $\delta$ (radians)} \\ \spec{ROB}{D}{observed $\alpha$ (radians)} } \notes { \begin{enumerate} \item This routine returns zenith distance rather than elevation in order to reflect the fact that no allowance is made for depression of the horizon. \item The accuracy of the result is limited by the corrections for refraction. Providing the meteorological parameters are known accurately and there are no gross local effects, the predicted azimuth and elevation should be within about \arcsec{0}{1} for $\zeta<70^{\circ}$. Even at a topocentric zenith distance of $90^{\circ}$, the accuracy in elevation should be better than 1~arcminute; useful results are available for a further $3^{\circ}$, beyond which the sla\_REFRO routine returns a fixed value of the refraction. The complementary routines sla\_AOP (or sla\_AOPQK) and sla\_OAP (or sla\_OAPQK) are self-consistent to better than 1~microarcsecond all over the celestial sphere. \item It is advisable to take great care with units, as even unlikely values of the input parameters are accepted and processed in accordance with the models used. \item {\it Apparent}\/ \radec\ means the geocentric apparent right ascension and declination, which is obtained from a catalogue mean place by allowing for space motion, parallax, precession, nutation, annual aberration, and the Sun's gravitational lens effect. For star positions in the FK5 system ({\it i.e.}\ J2000), these effects can be applied by means of the sla\_MAP {\it etc.}\ routines. Starting from other mean place systems, additional transformations will be needed; for example, FK4 ({\it i.e.}\ B1950) mean places would first have to be converted to FK5, which can be done with the sla\_FK425 {\it etc.}\ routines. \item {\it Observed}\/ \azel\ means the position that would be seen by a perfect theodolite located at the observer. This is obtained from the geocentric apparent \radec\ by allowing for Earth orientation and diurnal aberration, rotating from equator to horizon coordinates, and then adjusting for refraction. The \hadec\ is obtained by rotating back into equatorial coordinates, using the geodetic latitude corrected for polar motion, and is the position that would be seen by a perfect equatorial located at the observer and with its polar axis aligned to the Earth's axis of rotation ({\it n.b.}\ not to the refracted pole). Finally, the $\alpha$ is obtained by subtracting the {\it h}\/ from the local apparent ST. \item To predict the required setting of a real telescope, the observed place produced by this routine would have to be adjusted for the tilt of the azimuth or polar axis of the mounting (with appropriate corrections for mount flexures), for non-perpendicularity between the mounting axes, for the position of the rotator axis and the pointing axis relative to it, for tube flexure, for gear and encoder errors, and finally for encoder zero points. Some telescopes would, of course, exhibit other properties which would need to be accounted for at the appropriate point in the sequence. \item This routine takes time to execute, due mainly to the rigorous integration used to evaluate the refraction. For processing multiple stars for one location and time, call sla\_AOPPA once followed by one call per star to sla\_AOPQK. Where a range of times within a limited period of a few hours is involved, and the highest precision is not required, call sla\_AOPPA once, followed by a call to sla\_AOPPAT each time the time changes, followed by one call per star to sla\_AOPQK. \item The DATE argument is UTC expressed as an MJD. This is, strictly speaking, wrong, because of leap seconds. However, as long as the $\Delta$UT and the UTC are consistent there are no difficulties, except during a leap second. In this case, the start of the 61st second of the final minute should begin a new MJD day and the old pre-leap $\Delta$UT should continue to be used. As the 61st second completes, the MJD should revert to the start of the day as, simultaneously, the $\Delta$UT changes by one second to its post-leap new value. \item The $\Delta$UT (UT1$-$UTC) is tabulated in IERS circulars and elsewhere. It increases by exactly one second at the end of each UTC leap second, introduced in order to keep $\Delta$UT within $\pm$\tsec{0}{9}. \item IMPORTANT -- TAKE CARE WITH THE LONGITUDE SIGN CONVENTION. The longitude required by the present routine is {\bf east-positive}, in accordance with geographical convention (and right-handed). In particular, note that the longitudes returned by the sla\_OBS routine are west-positive (as in the {\it Astronomical Almanac}\/ before 1984) and must be reversed in sign before use in the present routine. \item The polar coordinates XP,YP can be obtained from IERS circulars and equivalent publications. The maximum amplitude is about \arcsec{0}{3}. If XP,YP values are unavailable, use XP=YP=0D0. See page B60 of the 1988 {\it Astronomical Almanac}\/ for a definition of the two angles. \item The height above sea level of the observing station, HM, can be obtained from the {\it Astronomical Almanac}\/ (Section J in the 1988 edition), or via the routine sla\_OBS. If P, the pressure in mB, is available, an adequate estimate of HM can be obtained from the following expression: \begin{quote} {\tt HM=-29.3D0*TSL*LOG(P/1013.25D0)} \end{quote} where TSL is the approximate sea-level air temperature in degrees K (see {\it Astrophysical Quantities}, C.W.Allen, 3rd~edition, \S 52). Similarly, if the pressure P is not known, it can be estimated from the height of the observing station, HM as follows: \begin{quote} {\tt P=1013.25D0*EXP(-HM/(29.3D0*TSL))} \end{quote} Note, however, that the refraction is proportional to the pressure and that an accurate P value is important for precise work. \item The azimuths {\it etc.}\ used by the present routine are with respect to the celestial pole. Corrections to the terrestrial pole can be computed using sla\_POLMO. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_AOPPA}{Appt-to-Obs Parameters} { \action{Pre-compute the set of apparent to observed place parameters required by the ``quick'' routines sla\_AOPQK and sla\_OAPQK.} \call{CALL sla\_AOPPA (\vtop{ \hbox{DATE, DUT, ELONGM, PHIM, HM, XP, YP,} \hbox{TDK, PMB, RH, WL, TLR, AOPRMS)}}} } \args{GIVEN} { \spec{DATE}{D}{UTC date/time (Modified Julian Date, JD$-$2400000.5)} \\ \spec{DUT}{D}{$\Delta$UT: UT1$-$UTC (UTC seconds)} \\ \spec{ELONGM}{D}{observer's mean longitude (radians, east +ve)} \\ \spec{PHIM}{D}{observer's mean geodetic latitude (radians)} \\ \spec{HM}{D}{observer's height above sea level (metres)} \\ \spec{XP,YP}{D}{polar motion \xy\ coordinates (radians)} \\ \spec{TDK}{D}{local ambient temperature (degrees K; std=273.155D0)} \\ \spec{PMB}{D}{local atmospheric pressure (mB; std=1013.25D0)} \\ \spec{RH}{D}{local relative humidity (in the range 0D0\,--\,1D0)} \\ \spec{WL}{D}{effective wavelength ($\mu{\rm m}$, {\it e.g.}\ 0.55D0)} \\ \spec{TLR}{D}{tropospheric lapse rate (degrees K per metre, {\it e.g.}\ 0.0065D0)} } \args{RETURNED} { \spec{AOPRMS}{D(14)}{star-independent apparent-to-observed parameters:} \\ \specel {(1)} {geodetic latitude (radians)} \\ \specel {(2,3)} {sine and cosine of geodetic latitude} \\ \specel {(4)} {magnitude of diurnal aberration vector} \\ \specel {(5)} {height (HM)} \\ \specel {(6)} {ambient temperature (TDK)} \\ \specel {(7)} {pressure (PMB)} \\ \specel {(8)} {relative humidity (RH)} \\ \specel {(9)} {wavelength (WL)} \\ \specel {(10)} {lapse rate (TLR)} \\ \specel {(11,12)} {refraction constants A and B (radians)} \\ \specel {(13)} {longitude + eqn of equinoxes + ``sidereal $\Delta$UT'' (radians)} \\ \specel {(14)} {local apparent sidereal time (radians)} } \notes { \begin{enumerate} \item It is advisable to take great care with units, as even unlikely values of the input parameters are accepted and processed in accordance with the models used. \item The DATE argument is UTC expressed as an MJD. This is, strictly speaking, wrong, because of leap seconds. However, as long as the $\Delta$UT and the UTC are consistent there are no difficulties, except during a leap second. In this case, the start of the 61st second of the final minute should begin a new MJD day and the old pre-leap $\Delta$UT should continue to be used. As the 61st second completes, the MJD should revert to the start of the day as, simultaneously, the $\Delta$UT changes by one second to its post-leap new value. \item The $\Delta$UT (UT1$-$UTC) is tabulated in IERS circulars and elsewhere. It increases by exactly one second at the end of each UTC leap second, introduced in order to keep $\Delta$UT within $\pm$\tsec{0}{9}. The ``sidereal $\Delta$UT'' which forms part of AOPRMS(13) is the same quantity, but converted from solar to sidereal seconds and expressed in radians. \item IMPORTANT -- TAKE CARE WITH THE LONGITUDE SIGN CONVENTION. The longitude required by the present routine is {\bf east-positive}, in accordance with geographical convention (and right-handed). In particular, note that the longitudes returned by the sla\_OBS routine are west-positive (as in the {\it Astronomical Almanac}\/ before 1984) and must be reversed in sign before use in the present routine. \item The polar coordinates XP,YP can be obtained from IERS circulars and equivalent publications. The maximum amplitude is about \arcsec{0}{3}. If XP,YP values are unavailable, use XP=YP=0D0. See page B60 of the 1988 {\it Astronomical Almanac}\/ for a definition of the two angles. \item The height above sea level of the observing station, HM, can be obtained from the {\it Astronomical Almanac}\/ (Section J in the 1988 edition), or via the routine sla\_OBS. If P, the pressure in mB, is available, an adequate estimate of HM can be obtained from the following expression: \begin{quote} {\tt HM=-29.3D0*TSL*LOG(P/1013.25D0)} \end{quote} where TSL is the approximate sea-level air temperature in degrees K (see {\it Astrophysical Quantities}, C.W.Allen, 3rd~edition, \S 52). Similarly, if the pressure P is not known, it can be estimated from the height of the observing station, HM as follows: \begin{quote} {\tt P=1013.25D0*EXP(-HM/(29.3D0*TSL))} \end{quote} Note, however, that the refraction is proportional to the pressure and that an accurate P value is important for precise work. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_AOPPAT}{Update Appt-to-Obs Parameters} { \action{Recompute the sidereal time in the apparent to observed place star-independent parameter block.} \call{CALL sla\_AOPPAT (DATE, AOPRMS)} } \args{GIVEN} { \spec{DATE}{D}{UTC date/time (Modified Julian Date, JD$-$2400000.5)} \\ \spec{AOPRMS}{D(14)}{star-independent apparent-to-observed parameters:} \\ \specel{(1-12)}{not required} \\ \specel{(13)}{longitude + eqn of equinoxes + ``sidereal $\Delta$UT'' (radians)} \\ \specel{(14)}{not required} } \args{RETURNED} { \spec{AOPRMS}{D(14)}{star-independent apparent-to-observed parameters:} \\ \specel{(1-13)}{not changed} \\ \specel{(14)}{local apparent sidereal time (radians)} } \anote{For more information, see sla\_AOPPA.} %----------------------------------------------------------------------- \routine{SLA\_AOPQK}{Quick Appt-to-Observed} { \action{Quick apparent to observed place (but see Note~8, below).} \call{CALL sla\_AOPQK (RAP, DAP, AOPRMS, AOB, ZOB, HOB, DOB, ROB)} } \args{GIVEN} { \spec{RAP,DAP}{D}{geocentric apparent \radec\ (radians)} \\ \spec{AOPRMS}{D(14)}{star-independent apparent-to-observed parameters:} \\ \specel{(1)}{geodetic latitude (radians)} \\ \specel{(2,3)}{sine and cosine of geodetic latitude} \\ \specel{(4)}{magnitude of diurnal aberration vector} \\ \specel{(5)}{height (metres)} \\ \specel{(6)}{ambient temperature (degrees K)} \\ \specel{(7)}{pressure (mB)} \\ \specel{(8)}{relative humidity (0\,--\,1)} \\ \specel{(9)}{wavelength ($\mu{\rm m}$)} \\ \specel{(10)}{lapse rate (degrees K per metre)} \\ \specel{(11,12)}{refraction constants A and B (radians)} \\ \specel{(13)}{longitude + eqn of equinoxes + ``sidereal $\Delta$UT'' (radians)} \\ \specel{(14)}{local apparent sidereal time (radians)} } \args{RETURNED} { \spec{AOB}{D}{observed azimuth (radians: N=0, E=$90^{\circ}$)} \\ \spec{ZOB}{D}{observed zenith distance (radians)} \\ \spec{HOB}{D}{observed Hour Angle (radians)} \\ \spec{DOB}{D}{observed Declination (radians)} \\ \spec{ROB}{D}{observed Right Ascension (radians)} } \notes { \begin{enumerate} \item This routine returns zenith distance rather than elevation in order to reflect the fact that no allowance is made for depression of the horizon. \item The accuracy of the result is limited by the corrections for refraction. Providing the meteorological parameters are known accurately and there are no gross local effects, the predicted azimuth and elevation should be within about \arcsec{0}{1} for $\zeta<70^{\circ}$. Even at a topocentric zenith distance of $90^{\circ}$, the accuracy in elevation should be better than 1~arcminute; useful results are available for a further $3^{\circ}$, beyond which the sla\_REFRO routine returns a fixed value of the refraction. The complementary routines sla\_AOP (or sla\_AOPQK) and sla\_OAP (or sla\_OAPQK) are self-consistent to better than 1~microarcsecond all over the celestial sphere. \item It is advisable to take great care with units, as even unlikely values of the input parameters are accepted and processed in accordance with the models used. \item {\it Apparent}\/ \radec\ means the geocentric apparent right ascension and declination, which is obtained from a catalogue mean place by allowing for space motion, parallax, precession, nutation, annual aberration, and the Sun's gravitational lens effect. For star positions in the FK5 system ({\it i.e.}\ J2000), these effects can be applied by means of the sla\_MAP {\it etc.}\ routines. Starting from other mean place systems, additional transformations will be needed; for example, FK4 ({\it i.e.}\ B1950) mean places would first have to be converted to FK5, which can be done with the sla\_FK425 {\it etc.}\ routines. \item {\it Observed}\/ \azel\ means the position that would be seen by a perfect theodolite located at the observer. This is obtained from the geocentric apparent \radec\ by allowing for Earth orientation and diurnal aberration, rotating from equator to horizon coordinates, and then adjusting for refraction. The \hadec\ is obtained by rotating back into equatorial coordinates, using the geodetic latitude corrected for polar motion, and is the position that would be seen by a perfect equatorial located at the observer and with its polar axis aligned to the Earth's axis of rotation ({\it n.b.}\ not to the refracted pole). Finally, the $\alpha$ is obtained by subtracting the {\it h}\/ from the local apparent ST. \item To predict the required setting of a real telescope, the observed place produced by this routine would have to be adjusted for the tilt of the azimuth or polar axis of the mounting (with appropriate corrections for mount flexures), for non-perpendicularity between the mounting axes, for the position of the rotator axis and the pointing axis relative to it, for tube flexure, for gear and encoder errors, and finally for encoder zero points. Some telescopes would, of course, exhibit other properties which would need to be accounted for at the appropriate point in the sequence. \item The star-independent apparent-to-observed-place parameters in AOPRMS may be computed by means of the sla\_AOPPA routine. If nothing has changed significantly except the time, the sla\_AOPPAT routine may be used to perform the requisite partial recomputation of AOPRMS. \item The ``sidereal $\Delta$UT'' which forms part of AOPRMS(13) is UT1$-$UTC converted from solar to sidereal seconds and expressed in radians. \item At zenith distances beyond about $76^\circ$, the need for special care with the corrections for refraction causes a marked increase in execution time. Moreover, the effect gets worse with increasing zenith distance. Adroit programming in the calling application may allow the problem to be reduced. Prepare an alternative AOPRMS array, computed for zero air-pressure; this will disable the refraction corrections and cause rapid execution. Using this AOPRMS array, a preliminary call to the present routine will, depending on the application, produce a rough position which may be enough to establish whether the full, slow calculation (using the real AOPRMS array) is worthwhile. For example, there would be no need for the full calculation if the preliminary call had already established that the source was well below the elevation limits for a particular telescope. \item The azimuths {\it etc.}\ used by the present routine are with respect to the celestial pole. Corrections to the terrestrial pole can be computed using sla\_POLMO. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_ATMDSP}{Atmospheric Dispersion} { \action{Apply atmospheric-dispersion adjustments to refraction coefficients.} \call{CALL sla\_ATMDSP (TDK, PMB, RH, WL1, A1, B1, WL2, A2, B2)} } \args{GIVEN} { \spec{TDK}{D}{ambient temperature at the observer (degrees K)} \\ \spec{PMB}{D}{pressure at the observer (mB)} \\ \spec{RH}{D}{relative humidity at the observer (range 0\,--\,1)} \\ \spec{WL1}{D}{base wavelength ($\mu{\rm m}$)} \\ \spec{A1}{D}{refraction coefficient A for wavelength WL1 (radians)} \\ \spec{B1}{D}{refraction coefficient B for wavelength WL1 (radians)} \\ \spec{WL2}{D}{wavelength for which adjusted A,B required ($\mu{\rm m}$)} } \args{RETURNED} { \spec{A2}{D}{refraction coefficient A for wavelength WL2 (radians)} \\ \spec{B2}{D}{refraction coefficient B for wavelength WL2 (radians)} } \notes { \begin{enumerate} \item To use this routine, first call sla\_REFCO specifying WL1 as the wavelength. This yields refraction coefficients A1, B1, correct for that wavelength. Subsequently, calls to sla\_ATMDSP specifying different wavelengths will produce new, slightly adjusted refraction coefficients A2, B2, which apply to the specified wavelength. \item Most of the atmospheric dispersion happens between $0.7\,\mu{\rm m}$ and the UV atmospheric cutoff, and the effect increases strongly towards the UV end. For this reason a blue reference wavelength is recommended, for example $0.4\,\mu{\rm m}$. \item The accuracy, for this set of conditions: \\[1pc] \hspace*{5ex} \begin{tabular}{rcl} height above sea level & ~ & 2000\,m \\ latitude & ~ & $29^\circ$ \\ pressure & ~ & 793\,mB \\ temperature & ~ & $290^\circ$\,K \\ humidity & ~ & 0.5 (50\%) \\ lapse rate & ~ & $0.0065^\circ m^{-1}$ \\ reference wavelength & ~ & $0.4\,\mu{\rm m}$ \\ star elevation & ~ & $15^\circ$ \\ \end{tabular}\\[1pc] is about 2.5\,mas RMS between 0.3 and $1.0\,\mu{\rm m}$, and stays within 4\,mas for the whole range longward of $0.3\,\mu{\rm m}$ (compared with a total dispersion from 0.3 to $20\,\mu{\rm m}$ of about \arcseci{11}). These errors are typical for ordinary conditions; in extreme conditions values a few times this size may occur. \item If either wavelength exceeds $100\,\mu{\rm m}$, the radio case is assumed and the returned refraction coefficients are the same as the given ones. \item The algorithm consists of calculation of the refractivity of the air at the observer for the two wavelengths, using the methods of the sla\_REFRO routine, and then scaling of the two refraction coefficients according to classical refraction theory. This amounts to scaling the A coefficient in proportion to $(\mu-1)$ and the B coefficient almost in the same ratio (see R.M.Green, {\it Spherical Astronomy,}\/ Cambridge University Press, 1985). \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_AV2M}{Rotation Matrix from Axial Vector} { \action{Form the rotation matrix corresponding to a given axial vector (single precision).} \call{CALL sla\_AV2M (AXVEC, RMAT)} } \args{GIVEN} { \spec{AXVEC}{R(3)}{axial vector (radians)} } \args{RETURNED} { \spec{RMAT}{R(3,3)}{rotation matrix} } \notes { \begin{enumerate} \item A rotation matrix describes a rotation about some arbitrary axis. The axis is called the {\it Euler axis}, and the angle through which the reference frame rotates is called the Euler angle. The axial vector supplied to this routine has the same direction as the Euler axis, and its magnitude is the Euler angle in radians. \item If AXVEC is null, the unit matrix is returned. \item The reference frame rotates clockwise as seen looking along the axial vector from the origin. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_BEAR}{Direction Between Points on a Sphere} { \action{Returns the bearing (position angle) of one point on a sphere seen from another (single precision).} \call{R~=~sla\_BEAR (A1, B1, A2, B2)} } \args{GIVEN} { \spec{A1,B1}{R}{spherical coordinates of one point} \\ \spec{A2,B2}{R}{spherical coordinates of the other point} } \args{RETURNED} { \spec{sla\_BEAR}{R}{bearing from first point to second} } \notes { \begin{enumerate} \item The spherical coordinates are \radec, $[\lambda,\phi]$ {\it etc.}, in radians. \item The result is the bearing (position angle), in radians, of point [A2,B2] as seen from point [A1,B1]. It is in the range $\pm \pi$. The sense is such that if [A2,B2] is a small distance due east of [A1,B1] the result is about $+\pi/2$. Zero is returned if the two points are coincident. \item If either B-coordinate is outside the range $\pm\pi/2$, the result may correspond to ``the long way round''. \item The routine sla\_PAV performs an equivalent function except that the points are specified in the form of Cartesian unit vectors. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_CAF2R}{Deg,Arcmin,Arcsec to Radians} { \action{Convert degrees, arcminutes, arcseconds to radians (single precision).} \call{CALL sla\_CAF2R (IDEG, IAMIN, ASEC, RAD, J)} } \args{GIVEN} { \spec{IDEG}{I}{degrees} \\ \spec{IAMIN}{I}{arcminutes} \\ \spec{ASEC}{R}{arcseconds} } \args{RETURNED} { \spec{RAD}{R}{angle in radians} \\ \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 1 = IDEG outside range 0$-$359} \\ \spec{}{}{\hspace{1.5em} 2 = IAMIN outside range 0$-$59} \\ \spec{}{}{\hspace{1.5em} 3 = ASEC outside range 0$-$59.999$\cdots$} } \notes { \begin{enumerate} \item The result is computed even if any of the range checks fail. \item The sign must be dealt with outside this routine. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_CALDJ}{Calendar Date to MJD} { \action{Gregorian Calendar to Modified Julian Date, with century default.} \call{CALL sla\_CALDJ (IY, IM, ID, DJM, J)} } \args{GIVEN} { \spec{IY,IM,ID}{I}{year, month, day in Gregorian calendar} } \args{RETURNED} { \spec{DJM}{D}{modified Julian Date (JD$-$2400000.5) for $0^{\rm h}$} \\ \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 0 = OK} \\ \spec{}{}{\hspace{1.5em} 1 = bad year (MJD not computed)} \\ \spec{}{}{\hspace{1.5em} 2 = bad month (MJD not computed)} \\ \spec{}{}{\hspace{1.5em} 3 = bad day (MJD computed)} \\ } \notes { \begin{enumerate} \item This routine supports the {\it century default}\/ feature. Acceptable years are: \begin{itemize} \item 00-49, interpreted as 2000\,--\,2049, \item 50-99, interpreted as 1950\,--\,1999, and \item 100 upwards, interpreted literally. \end{itemize} For 1-100AD use the routine sla\_CLDJ instead. \item For year $n$BC use IY = $-(n-1)$. \item When an invalid year or month is supplied (status J~=~1~or~2) the MJD is {\bf not} computed. When an invalid day is supplied (status J~=~3) the MJD {\bf is} computed. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_CALYD}{Calendar to Year, Day} { \action{Gregorian calendar date to year and day in year, in a Julian calendar aligned to the 20th/21st century Gregorian calendar, with century default.} \call{CALL sla\_CALYD (IY, IM, ID, NY, ND, J)} } \args{GIVEN} { \spec{IY,IM,ID}{I}{year, month, day in Gregorian calendar: year may optionally omit the century} } \args{RETURNED} { \spec{NY}{I}{year (re-aligned Julian calendar)} \\ \spec{ND}{I}{day in year (1 = January 1st)} \\ \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 0 = OK} \\ \spec{}{}{\hspace{1.5em} 1 = bad year (before $-4711$)} \\ \spec{}{}{\hspace{1.5em} 2 = bad month} \\ \spec{}{}{\hspace{1.5em} 3 = bad day} } \notes { \begin{enumerate} \item This routine supports the {\it century default}\/ feature. Acceptable years are: \begin{itemize} \item 00-49, interpreted as 2000\,--\,2049, \item 50-99, interpreted as 1950\,--\,1999, and \item other years after -4712 , interpreted literally. \end{itemize} Use sla\_CLYD for years before 100AD. \item The purpose of sla\_CALDJ is to support sla\_EARTH, sla\_MOON and sla\_ECOR. \item Between 1900~March~1 and 2100~February~28 it returns answers which are consistent with the ordinary Gregorian calendar. Outside this range there will be a discrepancy which increases by one day for every non-leap century year. \item When an invalid year or month is supplied (status J~=~1 or J~=~2) the results are {\bf not} computed. When a day is supplied which is outside the conventional range (status J~=~3) the results {\bf are} computed. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_CC2S}{Cartesian to Spherical} { \action{Cartesian coordinates to spherical coordinates (single precision).} \call{CALL sla\_CC2S (V, A, B)} } \args{GIVEN} { \spec{V}{R(3)}{\xyz\ vector} } \args{RETURNED} { \spec{A,B}{R}{spherical coordinates in radians} } \notes { \begin{enumerate} \item The spherical coordinates are longitude (+ve anticlockwise looking from the +ve latitude pole) and latitude. The Cartesian coordinates are right handed, with the {\it x}-axis at zero longitude and latitude, and the {\it z}-axis at the +ve latitude pole. \item If V is null, zero A and B are returned. \item At either pole, zero A is returned. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_CC62S}{Cartesian 6-Vector to Spherical} { \action{Conversion of position \& velocity in Cartesian coordinates to spherical coordinates (single precision).} \call{CALL sla\_CC62S (V, A, B, R, AD, BD, RD)} } \args{GIVEN} { \spec{V}{R(6)}{\xyzxyzd} } \args{RETURNED} { \spec{A}{R}{longitude (radians) -- for example $\alpha$} \\ \spec{B}{R}{latitude (radians) -- for example $\delta$} \\ \spec{R}{R}{radial coordinate} \\ \spec{AD}{R}{longitude derivative (radians per unit time)} \\ \spec{BD}{R}{latitude derivative (radians per unit time)} \\ \spec{RD}{R}{radial derivative} } %----------------------------------------------------------------------- \routine{SLA\_CD2TF}{Days to Hour,Min,Sec} { \action{Convert an interval in days to hours, minutes, seconds (single precision).} \call{CALL sla\_CD2TF (NDP, DAYS, SIGN, IHMSF)} } \args{GIVEN} { \spec{NDP}{I}{number of decimal places of seconds} \\ \spec{DAYS}{R}{interval in days} } \args{RETURNED} { \spec{SIGN}{C}{`+' or `$-$'} \\ \spec{IHMSF}{I(4)}{hours, minutes, seconds, fraction} } \notes { \begin{enumerate} \item NDP less than zero is interpreted as zero. \item The largest useful value for NDP is determined by the size of DAYS, the format of REAL floating-point numbers on the target machine, and the risk of overflowing IHMSF(4). For example, on a VAX computer, for DAYS up to 1.0, the available floating-point precision corresponds roughly to NDP=3. This is well below the ultimate limit of NDP=9 set by the capacity of the 32-bit integer IHMSF(4). \item The absolute value of DAYS may exceed 1.0. In cases where it does not, it is up to the caller to test for and handle the case where DAYS is very nearly 1.0 and rounds up to 24~hours, by testing for IHMSF(1)=24 and setting IHMSF(1-4) to zero. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_CLDJ}{Calendar to MJD} { \action{Gregorian Calendar to Modified Julian Date.} \call{CALL sla\_CLDJ (IY, IM, ID, DJM, J)} } \args{GIVEN} { \spec{IY,IM,ID}{I}{year, month, day in Gregorian calendar} } \args{RETURNED} { \spec{DJM}{D}{modified Julian Date (JD$-$2400000.5) for $0^{\rm h}$} \\ \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 0 = OK} \\ \spec{}{}{\hspace{1.5em} 1 = bad year} \\ \spec{}{}{\hspace{1.5em} 2 = bad month} \\ \spec{}{}{\hspace{1.5em} 3 = bad day} } \notes { \begin{enumerate} \item When an invalid year or month is supplied (status J~=~1~or~2) the MJD is {\bf not} computed. When an invalid day is supplied (status J~=~3) the MJD {\bf is} computed. \item The year must be $-$4699 ({\it i.e.}\ 4700BC) or later. For year $n$BC use IY = $-(n-1)$. \item An alternative to the present routine is sla\_CALDJ, which accepts a year with the century missing. \end{enumerate} } \aref{The algorithm is derived from that of Hatcher, {\it Q.\,Jl.\,R.\,astr.\,Soc.}\ (1984) {\bf 25}, 53-55.} %----------------------------------------------------------------------- \routine{SLA\_CLYD}{Calendar to Year, Day} { \action{Gregorian calendar date to year and day in year, in a Julian calendar aligned to the 20th/21st century Gregorian calendar.} \call{CALL sla\_CLYD (IY, IM, ID, NY, ND, J)} } \args{GIVEN} { \spec{IY,IM,ID}{I}{year, month, day in Gregorian calendar} } \args{RETURNED} { \spec{NY}{I}{year (re-aligned Julian calendar)} \\ \spec{ND}{I}{day in year (1 = January 1st)} \\ \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 0 = OK} \\ \spec{}{}{\hspace{1.5em} 1 = bad year (before $-4711$)} \\ \spec{}{}{\hspace{1.5em} 2 = bad month} \\ \spec{}{}{\hspace{1.5em} 3 = bad day} } \notes { \begin{enumerate} \item The purpose of sla\_CLYD is to support sla\_EARTH, sla\_MOON and sla\_ECOR. \item Between 1900~March~1 and 2100~February~28 it returns answers which are consistent with the ordinary Gregorian calendar. Outside this range there will be a discrepancy which increases by one day for every non-leap century year. \item When an invalid year or month is supplied (status J~=~1 or J~=~2) the results are {\bf not} computed. When a day is supplied which is outside the conventional range (status J~=~3) the results {\bf are} computed. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_COMBN}{Next Combination} { \action{Generate the next combination, a subset of a specified size chosen from a specified number of items.} \call{CALL sla\_COMBN (NSEL, NCAND, LIST, J)} } \args{GIVEN} { \spec{NSEL}{I}{number of items (subset size)} \\ \spec{NCAND}{I}{number of candidates (set size)} } \args{GIVEN and RETURNED} { \spec{LIST}{I(NSEL)}{latest combination, LIST(1)=0 to initialize} } \args{RETURNED} { \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} $-$1 = illegal NSEL or NCAND} \\ \spec{}{}{\hspace{2.3em} 0 = OK} \\ \spec{}{}{\hspace{1.5em} $+$1 = no more combinations available} } \notes { \begin{enumerate} \item NSEL and NCAND must both be at least 1, and NSEL must be less than or equal to NCAND. \item This routine returns, in the LIST array, a subset of NSEL integers chosen from the range 1 to NCAND inclusive, in ascending order. Before calling the routine for the first time, the caller must set the first element of the LIST array to zero (any value less than 1 will do) to cause initialization. \item The first combination to be generated is: \begin{verse} LIST(1)=1, LIST(2)=2, \ldots, LIST(NSEL)=NSEL \end{verse} This is also the combination returned for the ``finished'' (J=1) case. The final permutation to be generated is: \begin{verse} LIST(1)=NCAND, LIST(2)=NCAND$-$1, \ldots, \\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~LIST(NSEL)=NCAND$-$NSEL+1 \end{verse} \item If the ``finished'' (J=1) status is ignored, the routine continues to deliver combinations, the pattern repeating every NCAND!/(NSEL!(NCAND$-$NSEL)!) calls. \item The algorithm is by R.\,F.\,Warren-Smith (private communication). \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_CR2AF}{Radians to Deg,Arcmin,Arcsec} { \action{Convert an angle in radians to degrees, arcminutes, arcseconds (single precision).} \call{CALL sla\_CR2AF (NDP, ANGLE, SIGN, IDMSF)} } \args{GIVEN} { \spec{NDP}{I}{number of decimal places of arcseconds} \\ \spec{ANGLE}{R}{angle in radians} } \args{RETURNED} { \spec{SIGN}{C}{`+' or `$-$'} \\ \spec{IDMSF}{I(4)}{degrees, arcminutes, arcseconds, fraction} } \notes { \begin{enumerate} \item NDP less than zero is interpreted as zero. \item The largest useful value for NDP is determined by the size of ANGLE, the format of REAL floating-point numbers on the target machine, and the risk of overflowing IDMSF(4). For example, on a VAX computer, for ANGLE up to $2\pi$, the available floating-point precision corresponds roughly to NDP=3. This is well below the ultimate limit of NDP=9 set by the capacity of the 32-bit integer IHMSF(4). \item The absolute value of ANGLE may exceed $2\pi$. In cases where it does not, it is up to the caller to test for and handle the case where ANGLE is very nearly $2\pi$ and rounds up to $360^{\circ}$, by testing for IDMSF(1)=360 and setting IDMSF(1-4) to zero. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_CR2TF}{Radians to Hour,Min,Sec} { \action{Convert an angle in radians to hours, minutes, seconds (single precision).} \call{CALL sla\_CR2TF (NDP, ANGLE, SIGN, IHMSF)} } \args{GIVEN} { \spec{NDP}{I}{number of decimal places of seconds} \\ \spec{ANGLE}{R}{angle in radians} } \args{RETURNED} { \spec{SIGN}{C}{`+' or `$-$'} \\ \spec{IHMSF}{I(4)}{hours, minutes, seconds, fraction} } \notes { \begin{enumerate} \item NDP less than zero is interpreted as zero. \item The largest useful value for NDP is determined by the size of ANGLE, the format of REAL floating-point numbers on the target machine, and the risk of overflowing IHMSF(4). For example, on a VAX computer, for ANGLE up to $2\pi$, the available floating-point precision corresponds roughly to NDP=3. This is well below the ultimate limit of NDP=9 set by the capacity of the 32-bit integer IHMSF(4). \item The absolute value of ANGLE may exceed $2\pi$. In cases where it does not, it is up to the caller to test for and handle the case where ANGLE is very nearly $2\pi$ and rounds up to 24~hours, by testing for IHMSF(1)=24 and setting IHMSF(1-4) to zero. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_CS2C}{Spherical to Cartesian} { \action{Spherical coordinates to Cartesian coordinates (single precision).} \call{CALL sla\_CS2C (A, B, V)} } \args{GIVEN} { \spec{A,B}{R}{spherical coordinates in radians: \radec\ {\it etc.}} } \args{RETURNED} { \spec{V}{R(3)}{\xyz\ unit vector} } \anote{The spherical coordinates are longitude (+ve anticlockwise looking from the +ve latitude pole) and latitude. The Cartesian coordinates are right handed, with the {\it x}-axis at zero longitude and latitude, and the {\it z}-axis at the +ve latitude pole.} %----------------------------------------------------------------------- \routine{SLA\_CS2C6}{Spherical Pos/Vel to Cartesian} { \action{Conversion of position \& velocity in spherical coordinates to Cartesian coordinates (single precision).} \call{CALL sla\_CS2C6 (A, B, R, AD, BD, RD, V)} } \args{GIVEN} { \spec{A}{R}{longitude (radians) -- for example $\alpha$} \\ \spec{B}{R}{latitude (radians) -- for example $\delta$} \\ \spec{R}{R}{radial coordinate} \\ \spec{AD}{R}{longitude derivative (radians per unit time)} \\ \spec{BD}{R}{latitude derivative (radians per unit time)} \\ \spec{RD}{R}{radial derivative} } \args{RETURNED} { \spec{V}{R(6)}{\xyzxyzd} } %----------------------------------------------------------------------- \routine{SLA\_CTF2D}{Hour,Min,Sec to Days} { \action{Convert hours, minutes, seconds to days (single precision).} \call{CALL sla\_CTF2D (IHOUR, IMIN, SEC, DAYS, J)} } \args{GIVEN} { \spec{IHOUR}{I}{hours} \\ \spec{IMIN}{I}{minutes} \\ \spec{SEC}{R}{seconds} } \args{RETURNED} { \spec{DAYS}{R}{interval in days} \\ \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 0 = OK} \\ \spec{}{}{\hspace{1.5em} 1 = IHOUR outside range 0-23} \\ \spec{}{}{\hspace{1.5em} 2 = IMIN outside range 0-59} \\ \spec{}{}{\hspace{1.5em} 3 = SEC outside range 0-59.999$\cdots$} } \notes { \begin{enumerate} \item The result is computed even if any of the range checks fail. \item The sign must be dealt with outside this routine. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_CTF2R}{Hour,Min,Sec to Radians} { \action{Convert hours, minutes, seconds to radians (single precision).} \call{CALL sla\_CTF2R (IHOUR, IMIN, SEC, RAD, J)} } \args{GIVEN} { \spec{IHOUR}{I}{hours} \\ \spec{IMIN}{I}{minutes} \\ \spec{SEC}{R}{seconds} } \args{RETURNED} { \spec{RAD}{R}{angle in radians} \\ \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 0 = OK} \\ \spec{}{}{\hspace{1.5em} 1 = IHOUR outside range 0-23} \\ \spec{}{}{\hspace{1.5em} 2 = IMIN outside range 0-59} \\ \spec{}{}{\hspace{1.5em} 3 = SEC outside range 0-59.999$\cdots$} } \notes { \begin{enumerate} \item The result is computed even if any of the range checks fail. \item The sign must be dealt with outside this routine. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DAF2R}{Deg,Arcmin,Arcsec to Radians} { \action{Convert degrees, arcminutes, arcseconds to radians (double precision).} \call{CALL sla\_DAF2R (IDEG, IAMIN, ASEC, RAD, J)} } \args{GIVEN} { \spec{IDEG}{I}{degrees} \\ \spec{IAMIN}{I}{arcminutes} \\ \spec{ASEC}{D}{arcseconds} } \args{RETURNED} { \spec{RAD}{D}{angle in radians} \\ \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 1 = IDEG outside range 0$-$359} \\ \spec{}{}{\hspace{1.5em} 2 = IAMIN outside range 0$-$59} \\ \spec{}{}{\hspace{1.5em} 3 = ASEC outside range 0$-$59.999$\cdots$} } \notes { \begin{enumerate} \item The result is computed even if any of the range checks fail. \item The sign must be dealt with outside this routine. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DAFIN}{Sexagesimal character string to angle} { \action{Decode a free-format sexagesimal string (degrees, arcminutes, arcseconds) into a double precision floating point number (radians).} \call{CALL sla\_DAFIN (STRING, NSTRT, DRESLT, JF)} } \args{GIVEN} { \spec{STRING}{C*(*)}{string containing deg, arcmin, arcsec fields} \\ \spec{NSTRT}{I}{pointer to start of decode (beginning of STRING = 1)} } \args{RETURNED} { \spec{NSTRT}{I}{advanced past the decoded angle} \\ \spec{DRESLT}{D}{angle in radians} \\ \spec{JF}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 0 = OK} \\ \spec{}{}{\hspace{0.7em} $+1$ = default, DRESLT unchanged (note 2)} \\ \spec{}{}{\hspace{0.7em} $-1$ = bad degrees (note 3)} \\ \spec{}{}{\hspace{0.7em} $-2$ = bad arcminutes (note 3)} \\ \spec{}{}{\hspace{0.7em} $-3$ = bad arcseconds (note 3)} \\ } \goodbreak \setlength{\oldspacing}{\topsep} \setlength{\topsep}{0.3ex} \begin{description} \item [EXAMPLE]: \\ [1.5ex] \begin{tabular}{p{7em}p{15em}p{12em}} {\it argument} & {\it before} & {\it after} \\ \\ STRING & $'$\verb*}-57 17 44.806 12 34 56.7}$'$ & unchanged \\ NSTRT & 1 & 16 ({\it i.e.}\ pointing to 12...) \\ RESLT & - & $-1.00000${\tt D0} \\ JF & - & 0 \end{tabular} \item A further call to sla\_DAFIN, without adjustment of NSTRT, will decode the second angle, \dms{12}{34}{56}{7}. \end{description} \setlength{\topsep}{\oldspacing} \notes { \begin{enumerate} \item The first three ``fields'' in STRING are degrees, arcminutes, arcseconds, separated by spaces or commas. The degrees field may be signed, but not the others. The decoding is carried out by the sla\_DFLTIN routine and is free-format. \item Successive fields may be absent, defaulting to zero. For zero status, the only combinations allowed are degrees alone, degrees and arcminutes, and all three fields present. If all three fields are omitted, a status of +1 is returned and DRESLT is unchanged. In all other cases DRESLT is changed. \item Range checking: \begin{itemize} \item The degrees field is not range checked. However, it is expected to be integral unless the other two fields are absent. \item The arcminutes field is expected to be 0-59, and integral if the arcseconds field is present. If the arcseconds field is absent, the arcminutes is expected to be 0-59.9999... \item The arcseconds field is expected to be 0-59.9999... \item Decoding continues even when a check has failed. Under these circumstances the field takes the supplied value, defaulting to zero, and the result DRESLT is computed and returned. \end{itemize} \item Further fields after the three expected ones are not treated as an error. The pointer NSTRT is left in the correct state for further decoding with the present routine or with sla\_DFLTIN {\it etc}. See the example, above. \item If STRING contains hours, minutes, seconds instead of degrees {\it etc}, or if the required units are turns (or days) instead of radians, the result DRESLT should be multiplied as follows: \\ [1.5ex] \begin{tabular}{p{6em}p{5em}p{18em}} {\it for STRING} & {\it to obtain} & {\it multiply DRESLT by} \\ \\ ${\circ}$~~\raisebox{-0.7ex}{$'$}~~\raisebox{-0.7ex}{$''$} & radians & $1.0${\tt D0} \\ ${\circ}$~~\raisebox{-0.7ex}{$'$}~~\raisebox{-0.7ex}{$''$} & turns & $1/{2 \pi} = 0.1591549430918953358${\tt D0} \\ h m s & radians & $15.0${\tt D0} \\ h m s & days & $15/{2\pi} = 2.3873241463784300365${\tt D0} \end{tabular} \end{enumerate} } %------------------------------------------------------------------------------ \routine{SLA\_DAT}{TAI$-$UTC} { \action{Increment to be applied to Coordinated Universal Time UTC to give International Atomic Time TAI.} \call{D~=~sla\_DAT (UTC)} } \args{GIVEN} { \spec{UTC}{D}{UTC date as a modified JD (JD$-$2400000.5)} } \args{RETURNED} { \spec{sla\_DAT}{D}{TAI$-$UTC in seconds} } \notes { \begin{enumerate} \item The UTC is specified to be a date rather than a time to indicate that care needs to be taken not to specify an instant which lies within a leap second. Though in most cases UTC can include the fractional part, correct behaviour on the day of a leap second can be guaranteed only up to the end of the second $23^{\rm h}\,59^{\rm m}\,59^{\rm s}$. \item UTC began at 1960 January 1. To specify a UTC prior to this date would be meaningless; in such cases the parameters for the year 1960 are used by default. \item This routine has to be updated on each occasion that a leap second is announced, and programs using it relinked. Refer to the program source code for information on when the most recent leap second was added. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DAV2M}{Rotation Matrix from Axial Vector} { \action{Form the rotation matrix corresponding to a given axial vector (double precision).} \call{CALL sla\_DAV2M (AXVEC, RMAT)} } \args{GIVEN} { \spec{AXVEC}{D(3)}{axial vector (radians)} } \args{RETURNED} { \spec{RMAT}{D(3,3)}{rotation matrix} } \notes { \begin{enumerate} \item A rotation matrix describes a rotation about some arbitrary axis. The axis is called the {\it Euler axis}, and the angle through which the reference frame rotates is called the {\it Euler angle}. The axial vector supplied to this routine has the same direction as the Euler axis, and its magnitude is the Euler angle in radians. \item If AXVEC is null, the unit matrix is returned. \item The reference frame rotates clockwise as seen looking along the axial vector from the origin. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DBEAR}{Direction Between Points on a Sphere} { \action{Returns the bearing (position angle) of one point on a sphere relative to another (double precision).} \call{D~=~sla\_DBEAR (A1, B1, A2, B2)} } \args{GIVEN} { \spec{A1,B1}{D}{spherical coordinates of one point} \\ \spec{A2,B2}{D}{spherical coordinates of the other point} } \args{RETURNED} { \spec{sla\_DBEAR}{D}{bearing from first point to second} } \notes { \begin{enumerate} \item The spherical coordinates are \radec, $[\lambda,\phi]$ {\it etc.}, in radians. \item The result is the bearing (position angle), in radians, of point [A2,B2] as seen from point [A1,B1]. It is in the range $\pm \pi$. The sense is such that if [A2,B2] is a small distance due east of [A1,B1] the result is about $+\pi/2$. Zero is returned if the two points are coincident. \item If either B-coordinate is outside the range $\pm\pi/2$, the result may correspond to ``the long way round''. \item The routine sla\_DPAV performs an equivalent function except that the points are specified in the form of Cartesian unit vectors. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DBJIN}{Decode String to B/J Epoch (DP)} { \action{Decode a character string into a DOUBLE PRECISION number, with special provision for Besselian and Julian epochs. The string syntax is as for sla\_DFLTIN, prefixed by an optional `B' or `J'.} \call{CALL sla\_DBJIN (STRING, NSTRT, DRESLT, J1, J2)} } \args{GIVEN} { \spec{STRING}{C}{string containing field to be decoded} \\ \spec{NSTRT}{I}{pointer to first character of field in string} } \args{RETURNED} { \spec{NSTRT}{I}{incremented past the decoded field} \\ \spec{DRESLT}{D}{result} \\ \spec{J1}{I}{DFLTIN status:} \\ \spec{}{}{\hspace{0.7em} $-$1 = $-$OK} \\ \spec{}{}{\hspace{1.5em} 0 = +OK} \\ \spec{}{}{\hspace{1.5em} 1 = null field} \\ \spec{}{}{\hspace{1.5em} 2 = error} \\ \spec{J2}{I}{syntax flag:} \\ \spec{}{}{\hspace{1.5em} 0 = normal DFLTIN syntax} \\ \spec{}{}{\hspace{1.5em} 1 = `B' or `b'} \\ \spec{}{}{\hspace{1.5em} 2 = `J' or `j'} } \notes { \begin{enumerate} \item The purpose of the syntax extensions is to help cope with mixed FK4 and FK5 data, allowing fields such as `B1950' or `J2000' to be decoded. \item In addition to the syntax accepted by sla\_DFLTIN, the following two extensions are recognized by sla\_DBJIN: \begin{enumerate} \item A valid non-null field preceded by the character `B' (or `b') is accepted. \item A valid non-null field preceded by the character `J' (or `j') is accepted. \end{enumerate} \item The calling program is told of the `B' or `J' through an supplementary status argument. The rest of the arguments are as for sla\_DFLTIN. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DC62S}{Cartesian 6-Vector to Spherical} { \action{Conversion of position \& velocity in Cartesian coordinates to spherical coordinates (double precision).} \call{CALL sla\_DC62S (V, A, B, R, AD, BD, RD)} } \args{GIVEN} { \spec{V}{D(6)}{\xyzxyzd} } \args{RETURNED} { \spec{A}{D}{longitude (radians)} \\ \spec{B}{D}{latitude (radians)} \\ \spec{R}{D}{radial coordinate} \\ \spec{AD}{D}{longitude derivative (radians per unit time)} \\ \spec{BD}{D}{latitude derivative (radians per unit time)} \\ \spec{RD}{D}{radial derivative} } %----------------------------------------------------------------------- \routine{SLA\_DCC2S}{Cartesian to Spherical} { \action{Cartesian coordinates to spherical coordinates (double precision).} \call{CALL sla\_DCC2S (V, A, B)} } \args{GIVEN} { \spec{V}{D(3)}{\xyz\ vector} } \args{RETURNED} { \spec{A,B}{D}{spherical coordinates in radians} } \notes { \begin{enumerate} \item The spherical coordinates are longitude (+ve anticlockwise looking from the +ve latitude pole) and latitude. The Cartesian coordinates are right handed, with the {\it x}-axis at zero longitude and latitude, and the {\it z}-axis at the +ve latitude pole. \item If V is null, zero A and B are returned. \item At either pole, zero A is returned. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DCMPF}{Interpret Linear Fit} { \action{Decompose an \xy\ linear fit into its constituent parameters: zero points, scales, nonperpendicularity and orientation.} \call{CALL sla\_DCMPF (COEFFS,XZ,YZ,XS,YS,PERP,ORIENT)} } \args{GIVEN} { \spec{COEFFS}{D(6)}{transformation coefficients (see note)} } \args{RETURNED} { \spec{XZ}{D}{{\it x} zero point} \\ \spec{YZ}{D}{{\it y} zero point} \\ \spec{XS}{D}{{\it x} scale} \\ \spec{YS}{D}{{\it y} scale} \\ \spec{PERP}{D}{nonperpendicularity (radians)} \\ \spec{ORIENT}{D}{orientation (radians)} } \notes { \begin{enumerate} \item The model relates two sets of \xy\ coordinates as follows. Naming the six elements of COEFFS $a,b,c,d,e$ \& $f$, the model transforms coordinates $[x_{1},y_{1}\,]$ into coordinates $[x_{2},y_{2}\,]$ as follows: \begin{verse} $x_{2} = a + bx_{1} + cy_{1}$ \\ $y_{2} = d + ex_{1} + fy_{1}$ \end{verse} The sla\_DCMPF routine decomposes this transformation into four steps: \begin{enumerate} \item Zero points: \begin{verse} $x' = x_{1} + {\rm XZ}$ \\ $y' = y_{1} + {\rm YZ}$ \end{verse} \item Scales: \begin{verse} $x'' = x' {\rm XS}$ \\ $y'' = y' {\rm YS}$ \end{verse} \item Nonperpendicularity: \begin{verse} $x''' = + x'' \cos {\rm PERP}/2 + y'' \sin {\rm PERP}/2$ \\ $y''' = + x'' \sin {\rm PERP}/2 + y'' \cos {\rm PERP}/2$ \end{verse} \item Orientation: \begin{verse} $x_{2} = + x''' \cos {\rm ORIENT} + y''' \sin {\rm ORIENT}$ \\ $y_{2} = - x''' \sin {\rm ORIENT} + y''' \cos {\rm ORIENT}$ \end{verse} \end{enumerate} \item See also sla\_FITXY, sla\_PXY, sla\_INVF, sla\_XY2XY. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DCS2C}{Spherical to Cartesian} { \action{Spherical coordinates to Cartesian coordinates (double precision).} \call{CALL sla\_DCS2C (A, B, V)} } \args{GIVEN} { \spec{A,B}{D}{spherical coordinates in radians: \radec\ {\it etc.}} } \args{RETURNED} { \spec{V}{D(3)}{\xyz\ unit vector} } \anote{The spherical coordinates are longitude (+ve anticlockwise looking from the +ve latitude pole) and latitude. The Cartesian coordinates are right handed, with the {\it x}-axis at zero longitude and latitude, and the {\it z}-axis at the +ve latitude pole.} %----------------------------------------------------------------------- \routine{SLA\_DD2TF}{Days to Hour,Min,Sec} { \action{Convert an interval in days into hours, minutes, seconds (double precision).} \call{CALL sla\_DD2TF (NDP, DAYS, SIGN, IHMSF)} } \args{GIVEN} { \spec{NDP}{I}{number of decimal places of seconds} \\ \spec{DAYS}{D}{interval in days} } \args{RETURNED} { \spec{SIGN}{C}{`+' or `$-$'} \\ \spec{IHMSF}{I(4)}{hours, minutes, seconds, fraction} } \notes { \begin{enumerate} \item NDP less than zero is interpreted as zero. \item The largest useful value for NDP is determined by the size of DAYS, the format of DOUBLE PRECISION floating-point numbers on the target machine, and the risk of overflowing IHMSF(4). For example, on a VAX computer, for DAYS up to 1D0, the available floating-point precision corresponds roughly to NDP=12. However, the practical limit is NDP=9, set by the capacity of the 32-bit integer IHMSF(4). \item The absolute value of DAYS may exceed 1D0. In cases where it does not, it is up to the caller to test for and handle the case where DAYS is very nearly 1D0 and rounds up to 24~hours, by testing for IHMSF(1)=24 and setting IHMSF(1-4) to zero. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DE2H}{$h,\delta$ to Az,El} { \action{Equatorial to horizon coordinates (double precision).} \call{CALL sla\_DE2H (HA, DEC, PHI, AZ, EL)} } \args{GIVEN} { \spec{HA}{D}{hour angle (radians)} \\ \spec{DEC}{D}{declination (radians)} \\ \spec{PHI}{D}{latitude (radians)} } \args{RETURNED} { \spec{AZ}{D}{azimuth (radians)} \\ \spec{EL}{D}{elevation (radians)} } \notes { \begin{enumerate} \item Azimuth is returned in the range $0\!-\!2\pi$; north is zero, and east is $+\pi/2$. Elevation is returned in the range $\pm\pi$. \item The latitude must be geodetic. In critical applications, corrections for polar motion should be applied. \item In some applications it will be important to specify the correct type of hour angle and declination in order to produce the required type of azimuth and elevation. In particular, it may be important to distinguish between elevation as affected by refraction, which would require the {\it observed} \hadec, and the elevation {\it in vacuo}, which would require the {\it topocentric} \hadec. If the effects of diurnal aberration can be neglected, the {\it apparent} \hadec\ may be used instead of the topocentric \hadec. \item No range checking of arguments is carried out. \item In applications which involve many such calculations, rather than calling the present routine it will be more efficient to use inline code, having previously computed fixed terms such as sine and cosine of latitude, and (for tracking a star) sine and cosine of declination. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DEULER}{Euler Angles to Rotation Matrix} { \action{Form a rotation matrix from the Euler angles -- three successive rotations about specified Cartesian axes (double precision).} \call{CALL sla\_DEULER (ORDER, PHI, THETA, PSI, RMAT)} } \args{GIVEN} { \spec{ORDER}{C}{specifies about which axes the rotations occur} \\ \spec{PHI}{D}{1st rotation (radians)} \\ \spec{THETA}{D}{2nd rotation (radians)} \\ \spec{PSI}{D}{3rd rotation (radians)} } \args{RETURNED} { \spec{RMAT}{D(3,3)}{rotation matrix} } \notes { \begin{enumerate} \item A rotation is positive when the reference frame rotates anticlockwise as seen looking towards the origin from the positive region of the specified axis. \item The characters of ORDER define which axes the three successive rotations are about. A typical value is `ZXZ', indicating that RMAT is to become the direction cosine matrix corresponding to rotations of the reference frame through PHI radians about the old {\it z}-axis, followed by THETA radians about the resulting {\it x}-axis, then PSI radians about the resulting {\it z}-axis. \item The axis names can be any of the following, in any order or combination: X, Y, Z, uppercase or lowercase, 1, 2, 3. Normal axis labelling/numbering conventions apply; the {\it xyz} ($\equiv123$) triad is right-handed. Thus, the `ZXZ' example given above could be written `zxz' or `313' (or even `ZxZ' or `3xZ'). ORDER is terminated by length or by the first unrecognized character. Fewer than three rotations are acceptable, in which case the later angle arguments are ignored. Zero rotations produces a unit RMAT. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DFLTIN}{Decode a Double Precision Number} { \action{Convert free-format input into double precision floating point.} \call{CALL sla\_DFLTIN (STRING, NSTRT, DRESLT, JFLAG)} } \args{GIVEN} { \spec{STRING}{C}{string containing number to be decoded} \\ \spec{NSTRT}{I}{pointer to where decoding is to commence} \\ \spec{DRESLT}{D}{current value of result} } \args{RETURNED} { \spec{NSTRT}{I}{advanced to next number} \\ \spec{DRESLT}{D}{result} \\ \spec{JFLAG}{I}{status: $-$1~=~$-$OK, 0~=~+OK, 1~=~null result, 2~=~error} } \notes { \begin{enumerate} \item The reason sla\_DFLTIN has separate `OK' status values for + and $-$ is to enable minus zero to be detected. This is of crucial importance when decoding mixed-radix numbers. For example, an angle expressed as degrees, arcminutes and arcseconds may have a leading minus sign but a zero degrees field. \item A TAB is interpreted as a space, and lowercase characters are interpreted as uppercase. {\it n.b.}\ The test for TAB is ASCII-specific. \item The basic format is the sequence of fields $\pm n.n x \pm n$, where $\pm$ is a sign character `+' or `$-$', $n$ means a string of decimal digits, `.' is a decimal point, and $x$, which indicates an exponent, means `D' or `E'. Various combinations of these fields can be omitted, and embedded blanks are permissible in certain places. \item Spaces: \begin{itemize} \item Leading spaces are ignored. \item Embedded spaces are allowed only after +, $-$, D or E, and after the decimal point if the first sequence of digits is absent. \item Trailing spaces are ignored; the first signifies end of decoding and subsequent ones are skipped. \end{itemize} \item Delimiters: \begin{itemize} \item Any character other than +,$-$,0-9,.,D,E or space may be used to signal the end of the number and terminate decoding. \item Comma is recognized by sla\_DFLTIN as a special case; it is skipped, leaving the pointer on the next character. See 13, below. \item Decoding will in all cases terminate if end of string is reached. \end{itemize} \item Both signs are optional. The default is +. \item The mantissa $n.n$ defaults to unity. \item The exponent $x\!\pm\!n$ defaults to `D0'. \item The strings of decimal digits may be of any length. \item The decimal point is optional for whole numbers. \item A {\it null result}\/ occurs when the string of characters being decoded does not begin with +,$-$,0-9,.,D or E, or consists entirely of spaces. When this condition is detected, JFLAG is set to 1 and DRESLT is left untouched. \item NSTRT = 1 for the first character in the string. \item On return from sla\_DFLTIN, NSTRT is set ready for the next decode -- following trailing blanks and any comma. If a delimiter other than comma is being used, NSTRT must be incremented before the next call to sla\_DFLTIN, otherwise all subsequent calls will return a null result. \item Errors (JFLAG=2) occur when: \begin{itemize} \item a +, $-$, D or E is left unsatisfied; or \item the decimal point is present without at least one decimal digit before or after it; or \item an exponent more than 100 has been presented. \end{itemize} \item When an error has been detected, NSTRT is left pointing to the character following the last one used before the error came to light. This may be after the point at which a more sophisticated program could have detected the error. For example, sla\_DFLTIN does not detect that `1D999' is unacceptable (on a computer where this is so) until the entire number has been decoded. \item Certain highly unlikely combinations of mantissa and exponent can cause arithmetic faults during the decode, in some cases despite the fact that they together could be construed as a valid number. \item Decoding is left to right, one pass. \item See also sla\_FLOTIN and sla\_INTIN. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DH2E}{Az,El to $h,\delta$} { \action{Horizon to equatorial coordinates (double precision).} \call{CALL sla\_DH2E (AZ, EL, PHI, HA, DEC)} } \args{GIVEN} { \spec{AZ}{D}{azimuth (radians)} \\ \spec{EL}{D}{elevation (radians)} \\ \spec{PHI}{D}{latitude (radians)} } \args{RETURNED} { \spec{HA}{D}{hour angle (radians)} \\ \spec{DEC}{D}{declination (radians)} } \notes { \begin{enumerate} \item The sign convention for azimuth is north zero, east $+\pi/2$. \item HA is returned in the range $\pm\pi$. Declination is returned in the range $\pm\pi$. \item The latitude is (in principle) geodetic. In critical applications, corrections for polar motion should be applied (see sla\_POLMO). \item In some applications it will be important to specify the correct type of elevation in order to produce the required type of \hadec. In particular, it may be important to distinguish between the elevation as affected by refraction, which will yield the {\it observed} \hadec, and the elevation {\it in vacuo}, which will yield the {\it topocentric} \hadec. If the effects of diurnal aberration can be neglected, the topocentric \hadec\ may be used as an approximation to the {\it apparent} \hadec. \item No range checking of arguments is carried out. \item In applications which involve many such calculations, rather than calling the present routine it will be more efficient to use inline code, having previously computed fixed terms such as sine and cosine of latitude. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DIMXV}{Apply 3D Reverse Rotation} { \action{Multiply a 3-vector by the inverse of a rotation matrix (double precision).} \call{CALL sla\_DIMXV (DM, VA, VB)} } \args{GIVEN} { \spec{DM}{D(3,3)}{rotation matrix} \\ \spec{VA}{D(3)}{vector to be rotated} } \args{RETURNED} { \spec{VB}{D(3)}{result vector} } \notes { \begin{enumerate} \item This routine performs the operation: \begin{verse} {\bf b} = {\bf M}$^{T}\cdot${\bf a} \end{verse} where {\bf a} and {\bf b} are the 3-vectors VA and VB respectively, and {\bf M} is the $3\times3$ matrix DM. \item The main function of this routine is apply an inverse rotation; under these circumstances, ${\bf \rm M}$ is {\it orthogonal}, with its inverse the same as its transpose. \item To comply with the ANSI Fortran 77 standard, VA and VB must {\bf not} be the same array. The routine is, in fact, coded so as to work properly on the VAX and many other systems even if this rule is violated, something that is {\bf not}, however, recommended. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DJCAL}{MJD to Gregorian for Output} { \action{Modified Julian Date to Gregorian Calendar Date, expressed in a form convenient for formatting messages (namely rounded to a specified precision, and with the fields stored in a single array).} \call{CALL sla\_DJCAL (NDP, DJM, IYMDF, J)} } \args{GIVEN} { \spec{NDP}{I}{number of decimal places of days in fraction} \\ \spec{DJM}{D}{modified Julian Date (JD$-$2400000.5)} } \args{RETURNED} { \spec{IYMDF}{I(4)}{year, month, day, fraction in Gregorian calendar} \\ \spec{J}{I}{status: nonzero = out of range} } \notes { \begin{enumerate} \item Any date after 4701BC March 1 is accepted. \item NDP should be 4 or less to avoid overflow on machines which use 32-bit integers. \end{enumerate} } \aref{The algorithm is derived from that of Hatcher, {\it Q.\,Jl.\,R.\,astr.\,Soc.}\ (1984) {\bf 25}, 53-55.} %----------------------------------------------------------------------- \routine{SLA\_DJCL}{MJD to Year,Month,Day,Frac} { \action{Modified Julian Date to Gregorian year, month, day, and fraction of a day.} \call{CALL sla\_DJCL (DJM, IY, IM, ID, FD, J)} } \args{GIVEN} { \spec{DJM}{D}{modified Julian Date (JD$-$2400000.5)} } \args{RETURNED} { \spec{IY}{I}{year} \\ \spec{IM}{I}{month} \\ \spec{ID}{I}{day} \\ \spec{FD}{D}{fraction of day} \\ \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 0 = OK} \\ \spec{}{}{\hspace{0.7em} $-$1 = unacceptable date (before 4701BC March 1)} } \aref{The algorithm is derived from that of Hatcher, {\it Q.\,Jl.\,R.\,astr.\,Soc.}\ (1984) {\bf 25}, 53-55.} %----------------------------------------------------------------------- \routine{SLA\_DM2AV}{Rotation Matrix to Axial Vector} { \action{From a rotation matrix, determine the corresponding axial vector (double precision).} \call{CALL sla\_DM2AV (RMAT, AXVEC)} } \args{GIVEN} { \spec{RMAT}{D(3,3)}{rotation matrix} } \args{RETURNED} { \spec{AXVEC}{D(3)}{axial vector (radians)} } \notes { \begin{enumerate} \item A rotation matrix describes a rotation about some arbitrary axis. The axis is called the {\it Euler axis}, and the angle through which the reference frame rotates is called the {\it Euler angle}. The {\it axial vector}\/ returned by this routine has the same direction as the Euler axis, and its magnitude is the Euler angle in radians. \item The magnitude and direction of the axial vector can be separated by means of the routine sla\_DVN. \item The reference frame rotates clockwise as seen looking along the axial vector from the origin. \item If RMAT is null, so is the result. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DMAT}{Solve Simultaneous Equations} { \action{Matrix inversion and solution of simultaneous equations (double precision).} \call{CALL sla\_DMAT (N, A, Y, D, JF, IW)} } \args{GIVEN} { \spec{N}{I}{number of unknowns} \\ \spec{A}{D(N,N)}{matrix} \\ \spec{Y}{D(N)}{vector} } \args{RETURNED} { \spec{A}{D(N,N)}{matrix inverse} \\ \spec{Y}{D(N)}{solution} \\ \spec{D}{D}{determinant} \\ \spec{JF}{I}{singularity flag: 0=OK} \\ \spec{IW}{I(N)}{workspace} } \notes { \begin{enumerate} \item For the set of $n$ simultaneous linear equations in $n$ unknowns: \begin{verse} {\bf A}$\cdot${\bf y} = {\bf x} \end{verse} where: \begin{itemize} \item {\bf A} is a non-singular $n \times n$ matrix, \item {\bf y} is the vector of $n$ unknowns, and \item {\bf x} is the known vector, \end{itemize} sla\_DMAT computes: \begin{itemize} \item the inverse of matrix {\bf A}, \item the determinant of matrix {\bf A}, and \item the vector of $n$ unknowns {\bf y}. \end{itemize} Argument N is the order $n$, A (given) is the matrix {\bf A}, Y (given) is the vector {\bf x} and Y (returned) is the vector {\bf y}. The argument A (returned) is the inverse matrix {\bf A}$^{-1}$, and D is {\it det}\/({\bf A}). \item JF is the singularity flag. If the matrix is non-singular, JF=0 is returned. If the matrix is singular, JF=$-$1 and D=0D0 are returned. In the latter case, the contents of array A on return are undefined. \item The algorithm is Gaussian elimination with partial pivoting. This method is very fast; some much slower algorithms can give better accuracy, but only by a small factor. \item This routine replaces the obsolete sla\_DMATRX. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DMOON}{Approx Moon Pos/Vel} { \action{Approximate geocentric position and velocity of the Moon (double precision).} \call{CALL sla\_DMOON (DATE, PV)} } \args{GIVEN} { \spec{DATE}{D}{TDB (loosely ET) as a Modified Julian Date (JD$-$2400000.5) } } \args{RETURNED} { \spec{PV}{D(6)}{Moon \xyzxyzd, mean equator and equinox of date (AU, AU~s$^{-1}$)} } \notes { \begin{enumerate} \item This routine is a full implementation of the algorithm published by Meeus (see reference). \item Meeus quotes accuracies of \arcseci{10} in longitude, \arcseci{3} in latitude and \arcsec{0}{2} arcsec in HP (equivalent to about 20~km in distance). Comparison with JPL~DE200 over the interval 1960-2025 gives RMS errors of \arcsec{3}{7} and 83~mas/hour in longitude, \arcsec{2}{3} arcsec and 48~mas/hour in latitude, 11~km and 81~mm/s in distance. The maximum errors over the same interval are \arcseci{18} and \arcsec{0}{50}/hour in longitude, \arcseci{11} and \arcsec{0}{24}/hour in latitude, 40~km and 0.29~m/s in distance. \item The original algorithm is expressed in terms of the obsolete timescale {\it Ephemeris Time}. Either TDB or TT can be used, but not UT without incurring significant errors (\arcseci{30} at the present time) due to the Moon's \arcsec{0}{5}/s movement. \item The algorithm is based on pre IAU 1976 standards. However, the result has been moved onto the new (FK5) equinox, an adjustment which is in any case much smaller than the intrinsic accuracy of the procedure. \item Velocity is obtained by a complete analytical differentiation of the Meeus model. \end{enumerate} } \aref{Meeus, {\it l'Astronomie}, June 1984, p348.} %----------------------------------------------------------------------- \routine{SLA\_DMXM}{Multiply $3\times3$ Matrices} { \action{Product of two $3\times3$ matrices (double precision).} \call{CALL sla\_DMXM (A, B, C)} } \args{GIVEN} { \spec{A}{D(3,3)}{matrix {\bf A}} \\ \spec{B}{D(3,3)}{matrix {\bf B}} } \args{RETURNED} { \spec{C}{D(3,3)}{matrix result: {\bf A}$\times${\bf B}} } \anote{To comply with the ANSI Fortran 77 standard, A, B and C must be different arrays. The routine is, in fact, coded so as to work properly on the VAX and many other systems even if this rule is violated, something that is {\bf not}, however, recommended.} %----------------------------------------------------------------------- \routine{SLA\_DMXV}{Apply 3D Rotation} { \action{Multiply a 3-vector by a rotation matrix (double precision).} \call{CALL sla\_DMXV (DM, VA, VB)} } \args{GIVEN} { \spec{DM}{D(3,3)}{rotation matrix} \\ \spec{VA}{D(3)}{vector to be rotated} } \args{RETURNED} { \spec{VB}{D(3)}{result vector} } \notes { \begin{enumerate} \item This routine performs the operation: \begin{verse} {\bf b} = {\bf M}$\cdot${\bf a} \end{verse} where {\bf a} and {\bf b} are the 3-vectors VA and VB respectively, and {\bf M} is the $3\times3$ matrix DM. \item The main function of this routine is apply a rotation; under these circumstances, {\bf M} is a {\it proper real orthogonal}\/ matrix. \item To comply with the ANSI Fortran 77 standard, VA and VB must {\bf not} be the same array. The routine is, in fact, coded so as to work properly on the VAX and many other systems even if this rule is violated, something that is {\bf not}, however, recommended. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DPAV}{Position-Angle Between Two Directions} { \action{Returns the bearing (position angle) of one celestial direction with respect to another (double precision).} \call{D~=~sla\_DPAV (V1, V2)} } \args{GIVEN} { \spec{V1}{D(3)}{direction cosines of one point} \\ \spec{V2}{D(3)}{directions cosines of the other point} } \args{RETURNED} { \spec{sla\_DPAV}{D}{position-angle of 2nd point with respect to 1st} } \notes { \begin{enumerate} \item The coordinate frames correspond to \radec, $[\lambda,\phi]$ {\it etc.}. \item The result is the bearing (position angle), in radians, of point V2 as seen from point V1. It is in the range $\pm \pi$. The sense is such that if V2 is a small distance due east of V1 the result is about $+\pi/2$. Zero is returned if the two points are coincident. \item The routine sla\_DBEAR performs an equivalent function except that the points are specified in the form of spherical coordinates. \end{enumerate} } %------------------------------------------------------------------------------ \routine{SLA\_DR2AF}{Radians to Deg,Min,Sec,Frac} { \action{Convert an angle in radians to degrees, arcminutes, arcseconds, fraction (double precision).} \call{CALL sla\_DR2AF (NDP, ANGLE, SIGN, IDMSF)} } \args{GIVEN} { \spec{NDP}{I}{number of decimal places of arcseconds} \\ \spec{ANGLE}{D}{angle in radians} } \args{RETURNED} { \spec{SIGN}{C}{`+' or `$-$'} \\ \spec{IDMSF}{I(4)}{degrees, arcminutes, arcseconds, fraction} } \notes { \begin{enumerate} \item NDP less than zero is interpreted as zero. \item The largest useful value for NDP is determined by the size of ANGLE, the format of DOUBLE~PRECISION floating-point numbers on the target machine, and the risk of overflowing IDMSF(4). For example, on a VAX computer, for ANGLE up to $2\pi$, the available floating-point precision corresponds roughly to NDP=12. However, the practical limit is NDP=9, set by the capacity of the 32-bit integer IDMSF(4). \item The absolute value of ANGLE may exceed $2\pi$. In cases where it does not, it is up to the caller to test for and handle the case where ANGLE is very nearly $2\pi$ and rounds up to $360^{\circ}$, by testing for IDMSF(1)=360 and setting IDMSF(1-4) to zero. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DR2TF}{Radians to Hour,Min,Sec,Frac} { \action{Convert an angle in radians to hours, minutes, seconds, fraction (double precision).} \call{CALL sla\_DR2TF (NDP, ANGLE, SIGN, IHMSF)} } \args{GIVEN} { \spec{NDP}{I}{number of decimal places of seconds} \\ \spec{ANGLE}{D}{angle in radians} } \args{RETURNED} { \spec{SIGN}{C}{`+' or `$-$'} \\ \spec{IHMSF}{I(4)}{hours, minutes, seconds, fraction} } \notes { \begin{enumerate} \item NDP less than zero is interpreted as zero. \item The largest useful value for NDP is determined by the size of ANGLE, the format of DOUBLE PRECISION floating-point numbers on the target machine, and the risk of overflowing IHMSF(4). For example, on a VAX computer, for ANGLE up to $2\pi$, the available floating-point precision corresponds roughly to NDP=12. However, the practical limit is NDP=9, set by the capacity of the 32-bit integer IHMSF(4). \item The absolute value of ANGLE may exceed $2\pi$. In cases where it does not, it is up to the caller to test for and handle the case where ANGLE is very nearly $2\pi$ and rounds up to 24~hours, by testing for IHMSF(1)=24 and setting IHMSF(1-4) to zero. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DRANGE}{Put Angle into Range $\pm\pi$} { \action{Normalize an angle into the range $\pm\pi$ (double precision).} \call{D~=~sla\_DRANGE (ANGLE)} } \args{GIVEN} { \spec{ANGLE}{D}{angle in radians} } \args{RETURNED} { \spec{sla\_DRANGE}{D}{ANGLE expressed in the range $\pm\pi$.} } %----------------------------------------------------------------------- \routine{SLA\_DRANRM}{Put Angle into Range $0\!-\!2\pi$} { \action{Normalize an angle into the range $0\!-\!2\pi$ (double precision).} \call{D~=~sla\_DRANRM (ANGLE)} } \args{GIVEN} { \spec{ANGLE}{D}{angle in radians} } \args{RETURNED} { \spec{sla\_DRANRM}{D}{ANGLE expressed in the range $0\!-\!2\pi$} } %----------------------------------------------------------------------- \routine{SLA\_DS2C6}{Spherical Pos/Vel to Cartesian} { \action{Conversion of position \& velocity in spherical coordinates to Cartesian coordinates (double precision).} \call{CALL sla\_DS2C6 (A, B, R, AD, BD, RD, V)} } \args{GIVEN} { \spec{A}{D}{longitude (radians) -- for example $\alpha$} \\ \spec{B}{D}{latitude (radians) -- for example $\delta$} \\ \spec{R}{D}{radial coordinate} \\ \spec{AD}{D}{longitude derivative (radians per unit time)} \\ \spec{BD}{D}{latitude derivative (radians per unit time)} \\ \spec{RD}{D}{radial derivative} } \args{RETURNED} { \spec{V}{D(6)}{\xyzxyzd} } %----------------------------------------------------------------------- \routine{SLA\_DS2TP}{Spherical to Tangent Plane} { \action{Projection of spherical coordinates onto the tangent plane (double precision).} \call{CALL sla\_DS2TP (RA, DEC, RAZ, DECZ, XI, ETA, J)} } \args{GIVEN} { \spec{RA,DEC}{D}{spherical coordinates of star (radians)} \\ \spec{RAZ,DECZ}{D}{spherical coordinates of tangent point (radians)} } \args{RETURNED} { \spec{XI,ETA}{D}{tangent plane coordinates (radians)} \\ \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 0 = OK, star on tangent plane} \\ \spec{}{}{\hspace{1.5em} 1 = error, star too far from axis} \\ \spec{}{}{\hspace{1.5em} 2 = error, antistar on tangent plane} \\ \spec{}{}{\hspace{1.5em} 3 = error, antistar too far from axis} } \notes { \begin{enumerate} \item The projection is called the {\it gnomonic}\/ projection; the Cartesian coordinates \xieta\ are called {\it standard coordinates.}\/ The latter are in units of the distance from the tangent plane to the projection point, {\it i.e.}\ radians near the origin. \item When working in \xyz\ rather than spherical coordinates, the equivalent Cartesian routine sla\_DV2TP is available. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DSEP}{Angle Between 2 Points on Sphere} { \action{Angle between two points on a sphere (double precision).} \call{D~=~sla\_DSEP (A1, B1, A2, B2)} } \args{GIVEN} { \spec{A1,B1}{D}{spherical coordinates of one point (radians)} \\ \spec{A2,B2}{D}{spherical coordinates of the other point (radians)} } \args{RETURNED} { \spec{sla\_DSEP}{D}{angle between [A1,B1] and [A2,B2] in radians} } \notes { \begin{enumerate} \item The spherical coordinates are right ascension and declination, longitude and latitude, {\it etc.}, in radians. \item The result is always positive. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DT}{Approximate ET minus UT} { \action{Estimate $\Delta$T, the offset between dynamical time and Universal Time, for a given historical epoch.} \call{D~=~sla\_DT (EPOCH)} } \args{GIVEN} { \spec{EPOCH}{D}{(Julian) epoch ({\it e.g.}\ 1850D0)} } \args{RETURNED} { \spec{sla\_DT}{D}{approximate ET$-$UT (after 1984, TT$-$UT1) in seconds} } \notes { \begin{enumerate} \item Depending on the epoch, one of three parabolic approximations is used: \begin{tabbing} xx \= xxxxxxxxxxxxxxxxxx \= \kill \> before AD 979 \> Stephenson \& Morrison's 390 BC to AD 948 model \\ \> AD 979 to AD 1708 \> Stephenson \& Morrison's AD 948 to AD 1600 model \\ \> after AD 1708 \> McCarthy \& Babcock's post-1650 model \end{tabbing} The breakpoints are chosen to ensure continuity: they occur at places where the adjacent models give the same answer as each other. \item The accuracy is modest, with errors of up to $20^{\rm s}$ during the interval since 1650, rising to perhaps $30^{\rm m}$ by 1000~BC. Comparatively accurate values from AD~1600 are tabulated in the {\it Astronomical Almanac}\/ (see section K8 of the 1995 edition). \item The use of {\tt DOUBLE PRECISION} for both argument and result is simply for compatibility with other SLALIB time routines. \item The models used are based on a lunar tidal acceleration value of \arcsec{-26}{00} per century. \end{enumerate} } \aref{Seidelmann, P.K.\ (ed), 1992. {\it Explanatory Supplement to the Astronomical Almanac,}\/ ISBN~0-935702-68-7. This contains references to the papers by Stephenson \& Morrison and by McCarthy \& Babcock which describe the models used here.} %----------------------------------------------------------------------- \routine{SLA\_DTF2D}{Hour,Min,Sec to Days} { \action{Convert hours, minutes, seconds to days (double precision).} \call{CALL sla\_DTF2D (IHOUR, IMIN, SEC, DAYS, J)} } \args{GIVEN} { \spec{IHOUR}{I}{hours} \\ \spec{IMIN}{I}{minutes} \\ \spec{SEC}{D}{seconds} } \args{RETURNED} { \spec{DAYS}{D}{interval in days} \\ \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 0 = OK} \\ \spec{}{}{\hspace{1.5em} 1 = IHOUR outside range 0-23} \\ \spec{}{}{\hspace{1.5em} 2 = IMIN outside range 0-59} \\ \spec{}{}{\hspace{1.5em} 3 = SEC outside range 0-59.999$\cdots$} } \notes { \begin{enumerate} \item The result is computed even if any of the range checks fail. \item The sign must be dealt with outside this routine. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DTF2R}{Hour,Min,Sec to Radians} { \action{Convert hours, minutes, seconds to radians (double precision).} \call{CALL sla\_DTF2R (IHOUR, IMIN, SEC, RAD, J)} } \args{GIVEN} { \spec{IHOUR}{I}{hours} \\ \spec{IMIN}{I}{minutes} \\ \spec{SEC}{D}{seconds} } \args{RETURNED} { \spec{RAD}{D}{angle in radians} \\ \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 0 = OK} \\ \spec{}{}{\hspace{1.5em} 1 = IHOUR outside range 0-23} \\ \spec{}{}{\hspace{1.5em} 2 = IMIN outside range 0-59} \\ \spec{}{}{\hspace{1.5em} 3 = SEC outside range 0-59.999$\cdots$} } \notes { \begin{enumerate} \item The result is computed even if any of the range checks fail. \item The sign must be dealt with outside this routine. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DTP2S}{Tangent Plane to Spherical} { \action{Transform tangent plane coordinates into spherical coordinates (double precision)} \call{CALL sla\_DTP2S (XI, ETA, RAZ, DECZ, RA, DEC)} } \args{GIVEN} { \spec{XI,ETA}{D}{tangent plane rectangular coordinates (radians)} \\ \spec{RAZ,DECZ}{D}{spherical coordinates of tangent point (radians)} } \args{RETURNED} { \spec{RA,DEC}{D}{spherical coordinates (radians)} } \notes { \begin{enumerate} \item The projection is called the {\it gnomonic}\/ projection; the Cartesian coordinates \xieta\ are called {\it standard coordinates.}\/ The latter are in units of the distance from the tangent plane to the projection point, {\it i.e.}\ radians near the origin. \item When working in \xyz\ rather than spherical coordinates, the equivalent Cartesian routine sla\_DTP2V is available. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DTP2V}{Tangent Plane to Direction Cosines} { \action{Given the tangent-plane coordinates of a star and the direction cosines of the tangent point, determine the direction cosines of the star (double precision).} \call{CALL sla\_DTP2V (XI, ETA, V0, V)} } \args{GIVEN} { \spec{XI,ETA}{D}{tangent plane coordinates of star (radians)} \\ \spec{V0}{D(3)}{direction cosines of tangent point} } \args{RETURNED} { \spec{V}{D(3)}{direction cosines of star} } \notes { \begin{enumerate} \item If vector V0 is not of unit length, the returned vector V will be wrong. \item If vector V0 points at a pole, the returned vector V will be based on the arbitrary assumption that $\alpha=0$ at the tangent point. \item The projection is called the {\it gnomonic}\/ projection; the Cartesian coordinates \xieta\ are called {\it standard coordinates.}\/ The latter are in units of the distance from the tangent plane to the projection point, {\it i.e.}\ radians near the origin. \item This routine is the Cartesian equivalent of the routine sla\_DTP2S. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DTPS2C}{Plate centre from $\xi,\eta$ and $\alpha,\delta$} { \action{From the tangent plane coordinates of a star of known \radec, determine the \radec\ of the tangent point (double precision)} \call{CALL sla\_DTPS2C (XI, ETA, RA, DEC, RAZ1, DECZ1, RAZ2, DECZ2, N)} } \args{GIVEN} { \spec{XI,ETA}{D}{tangent plane rectangular coordinates (radians)} \\ \spec{RA,DEC}{D}{spherical coordinates (radians)} } \args{RETURNED} { \spec{RAZ1,DECZ1}{D}{spherical coordinates of tangent point, solution 1} \\ \spec{RAZ2,DECZ2}{D}{spherical coordinates of tangent point, solution 2} \\ \spec{N}{I}{number of solutions:} \\ \spec{}{}{\hspace{1em} 0 = no solutions returned (note 2)} \\ \spec{}{}{\hspace{1em} 1 = only the first solution is useful (note 3)} \\ \spec{}{}{\hspace{1em} 2 = there are two useful solutions (note 3)} } \notes { \begin{enumerate} \item The RAZ1 and RAZ2 values returned are in the range $0\!-\!2\pi$. \item Cases where there is no solution can only arise near the poles. For example, it is clearly impossible for a star at the pole itself to have a non-zero $\xi$ value, and hence it is meaningless to ask where the tangent point would have to be to bring about this combination of $\xi$ and $\delta$. \item Also near the poles, cases can arise where there are two useful solutions. The argument N indicates whether the second of the two solutions returned is useful. N\,=\,1 indicates only one useful solution, the usual case; under these circumstances, the second solution corresponds to the ``over-the-pole'' case, and this is reflected in the values of RAZ2 and DECZ2 which are returned. \item The DECZ1 and DECZ2 values returned are in the range $\pm\pi$, but in the ordinary, non-pole-crossing, case, the range is $\pm\pi/2$. \item RA, DEC, RAZ1, DECZ1, RAZ2, DECZ2 are all in radians. \item The projection is called the {\it gnomonic}\/ projection; the Cartesian coordinates \xieta\ are called {\it standard coordinates.}\/ The latter are in units of the distance from the tangent plane to the projection point, {\it i.e.}\ radians near the origin. \item When working in \xyz\ rather than spherical coordinates, the equivalent Cartesian routine sla\_DTPV2C is available. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DTPV2C}{Plate centre from $\xi,\eta$ and $x,y,z$} { \action{From the tangent plane coordinates of a star of known direction cosines, determine the direction cosines of the tangent point (double precision)} \call{CALL sla\_DTPV2C (XI, ETA, V, V01, V02, N)} } \args{GIVEN} { \spec{XI,ETA}{D}{tangent plane coordinates of star (radians)} \\ \spec{V}{D(3)}{direction cosines of star} } \args{RETURNED} { \spec{V01}{D(3)}{direction cosines of tangent point, solution 1} \\ \spec{V01}{D(3)}{direction cosines of tangent point, solution 2} \\ \spec{N}{I}{number of solutions:} \\ \spec{}{}{\hspace{1em} 0 = no solutions returned (note 2)} \\ \spec{}{}{\hspace{1em} 1 = only the first solution is useful (note 3)} \\ \spec{}{}{\hspace{1em} 2 = there are two useful solutions (note 3)} } \notes { \begin{enumerate} \item The vector V must be of unit length or the result will be wrong. \item Cases where there is no solution can only arise near the poles. For example, it is clearly impossible for a star at the pole itself to have a non-zero XI value. \item Also near the poles, cases can arise where there are two useful solutions. The argument N indicates whether the second of the two solutions returned is useful. N\,=\,1 indicates only one useful solution, the usual case; under these circumstances, the second solution can be regarded as valid if the vector V02 is interpreted as the ``over-the-pole'' case. \item The projection is called the {\it gnomonic}\/ projection; the Cartesian coordinates \xieta\ are called {\it standard coordinates.}\/ The latter are in units of the distance from the tangent plane to the projection point, {\it i.e.}\ radians near the origin. \item This routine is the Cartesian equivalent of the routine sla\_DTPS2C. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DTT}{TT minus UTC} { \action{Compute $\Delta$TT, the increment to be applied to Coordinated Universal Time UTC to give Terrestrial Time TT.} \call{D~=~sla\_DTT (DJU)} } \args{GIVEN} { \spec{DJU}{D}{UTC date as a modified JD (JD$-$2400000.5)} } \args{RETURNED} { \spec{sla\_DTT}{D}{TT$-$UTC in seconds} } \notes { \begin{enumerate} \item The UTC is specified to be a date rather than a time to indicate that care needs to be taken not to specify an instant which lies within a leap second. Though in most cases UTC can include the fractional part, correct behaviour on the day of a leap second can be guaranteed only up to the end of the second $23^{\rm h}\,59^{\rm m}\,59^{\rm s}$. \item Pre 1972 January 1 a fixed value of 10 + ET$-$TAI is returned. \item TT is one interpretation of the defunct timescale {\it Ephemeris Time}, ET. \item See also the routine sla\_DT, which roughly estimates ET$-$UT for historical epochs. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DV2TP}{Direction Cosines to Tangent Plane} { \action{Given the direction cosines of a star and of the tangent point, determine the star's tangent-plane coordinates (double precision).} \call{CALL sla\_DV2TP (V, V0, XI, ETA, J)} } \args{GIVEN} { \spec{V}{D(3)}{direction cosines of star} \\ \spec{V0}{D(3)}{direction cosines of tangent point} } \args{RETURNED} { \spec{XI,ETA}{D}{tangent plane coordinates (radians)} \\ \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 0 = OK, star on tangent plane} \\ \spec{}{}{\hspace{1.5em} 1 = error, star too far from axis} \\ \spec{}{}{\hspace{1.5em} 2 = error, antistar on tangent plane} \\ \spec{}{}{\hspace{1.5em} 3 = error, antistar too far from axis} } \notes { \begin{enumerate} \item If vector V0 is not of unit length, or if vector V is of zero length, the results will be wrong. \item If V0 points at a pole, the returned $\xi,\eta$ will be based on the arbitrary assumption that $\alpha=0$ at the tangent point. \item The projection is called the {\it gnomonic}\/ projection; the Cartesian coordinates \xieta\ are called {\it standard coordinates.}\/ The latter are in units of the distance from the tangent plane to the projection point, {\it i.e.}\ radians near the origin. \item This routine is the Cartesian equivalent of the routine sla\_DS2TP. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_DVDV}{Scalar Product} { \action{Scalar product of two 3-vectors (double precision).} \call{D~=~sla\_DVDV (VA, VB)} } \args{GIVEN} { \spec{VA}{D(3)}{first vector} \\ \spec{VB}{D(3)}{second vector} } \args{RETURNED} { \spec{sla\_DVDV}{D}{scalar product VA.VB} } %----------------------------------------------------------------------- \routine{SLA\_DVN}{Normalize Vector} { \action{Normalize a 3-vector, also giving the modulus (double precision).} \call{CALL sla\_DVN (V, UV, VM)} } \args{GIVEN} { \spec{V}{D(3)}{vector} } \args{RETURNED} { \spec{UV}{D(3)}{unit vector in direction of V} \\ \spec{VM}{D}{modulus of V} } \anote{If the modulus of V is zero, UV is set to zero as well.} %----------------------------------------------------------------------- \routine{SLA\_DVXV}{Vector Product} { \action{Vector product of two 3-vectors (double precision).} \call{CALL sla\_DVXV (VA, VB, VC)} } \args{GIVEN} { \spec{VA}{D(3)}{first vector} \\ \spec{VB}{D(3)}{second vector} } \args{RETURNED} { \spec{VC}{D(3)}{vector product VA$\times$VB} } %----------------------------------------------------------------------- \routine{SLA\_E2H}{$h,\delta$ to Az,El} { \action{Equatorial to horizon coordinates (single precision).} \call{CALL sla\_DE2H (HA, DEC, PHI, AZ, EL)} } \args{GIVEN} { \spec{HA}{R}{hour angle (radians)} \\ \spec{DEC}{R}{declination (radians)} \\ \spec{PHI}{R}{latitude (radians)} } \args{RETURNED} { \spec{AZ}{R}{azimuth (radians)} \\ \spec{EL}{R}{elevation (radians)} } \notes { \begin{enumerate} \item Azimuth is returned in the range $0\!-\!2\pi$; north is zero, and east is $+\pi/2$. Elevation is returned in the range $\pm\pi$. \item The latitude must be geodetic. In critical applications, corrections for polar motion should be applied. \item In some applications it will be important to specify the correct type of hour angle and declination in order to produce the required type of azimuth and elevation. In particular, it may be important to distinguish between elevation as affected by refraction, which would require the {\it observed} \hadec, and the elevation {\it in vacuo}, which would require the {\it topocentric} \hadec. If the effects of diurnal aberration can be neglected, the {\it apparent} \hadec\ may be used instead of the topocentric \hadec. \item No range checking of arguments is carried out. \item In applications which involve many such calculations, rather than calling the present routine it will be more efficient to use inline code, having previously computed fixed terms such as sine and cosine of latitude, and (for tracking a star) sine and cosine of declination. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_EARTH}{Approx Earth Pos/Vel} { \action{Approximate heliocentric position and velocity of the Earth (single precision).} \call{CALL sla\_EARTH (IY, ID, FD, PV)} } \args{GIVEN} { \spec{IY}{I}{year} \\ \spec{ID}{I}{day in year (1 = Jan 1st)} \\ \spec{FD}{R}{fraction of day} } \args{RETURNED} { \spec{PV}{R(6)}{Earth \xyzxyzd\ (AU, AU~s$^{-1}$)} } \notes { \begin{enumerate} \item The date and time is TDB (loosely ET) in a Julian calendar which has been aligned to the ordinary Gregorian calendar for the interval 1900~March~1 to 2100~February~28. The year and day can be obtained by calling sla\_CALYD or sla\_CLYD. \item The Earth heliocentric 6-vector is referred to the FK4 mean equator and equinox of date. \item Maximum/RMS errors 1950-2050: \begin{itemize} \item 13/5~$\times10^{-5}$~AU = 19200/7600~km in position \item 47/26~$\times10^{-10}$~AU~s$^{-1}$ = 0.0070/0.0039~km~s$^{-1}$ in speed \end{itemize} \item More accurate results are obtainable with the routine sla\_EVP. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_ECLEQ}{Ecliptic to Equatorial} { \action{Transformation from ecliptic longitude and latitude to J2000.0 \radec.} \call{CALL sla\_ECLEQ (DL, DB, DATE, DR, DD)} } \args{GIVEN} { \spec{DL,DB}{D}{ecliptic longitude and latitude (mean of date, IAU 1980 theory, radians)} \\ \spec{DATE}{D}{TDB (formerly ET) as Modified Julian Date (JD$-$2400000.5)} } \args{RETURNED} { \spec{DR,DD}{D}{J2000.0 mean \radec\ (radians)} } %----------------------------------------------------------------------- \routine{SLA\_ECMAT}{Form $\alpha,\delta\rightarrow\lambda,\beta$ Matrix} { \action{Form the equatorial to ecliptic rotation matrix (IAU 1980 theory).} \call{CALL sla\_ECMAT (DATE, RMAT)} } \args{GIVEN} { \spec{DATE}{D}{TDB (formerly ET) as Modified Julian Date (JD$-$2400000.5)} } \args{RETURNED} { \spec{RMAT}{D(3,3)}{rotation matrix} } \notes { \begin{enumerate} \item RMAT is matrix {\bf M} in the expression {\bf v}$_{ecl}$~=~{\bf M}$\cdot${\bf v}$_{equ}$. \item The equator, equinox and ecliptic are mean of date. \end{enumerate} } \aref{Murray, C.A., {\it Vectorial Astrometry}, section 4.3.} %----------------------------------------------------------------------- \routine{SLA\_ECOR}{RV \& Time Corrns to Sun} { \action{Component of Earth orbit velocity and heliocentric light time in a given direction.} \call{CALL sla\_ECOR (RM, DM, IY, ID, FD, RV, TL)} } \args{GIVEN} { \spec{RM,DM}{R}{mean \radec\ of date (radians)} \\ \spec{IY}{I}{year} \\ \spec{ID}{I}{day in year (1 = Jan 1st)} \\ \spec{FD}{R}{fraction of day} } \args{RETURNED} { \spec{RV}{R}{component of Earth orbital velocity (km~s$^{-1}$)} \\ \spec{TL}{R}{component of heliocentric light time (s)} } \notes { \begin{enumerate} \item The date and time is TDB (loosely ET) in a Julian calendar which has been aligned to the ordinary Gregorian calendar for the interval 1900 March 1 to 2100 February 28. The year and day can be obtained by calling sla\_CALYD or sla\_CLYD. \item Sign convention: \begin{itemize} \item The velocity component is +ve when the Earth is receding from the given point on the sky. \item The light time component is +ve when the Earth lies between the Sun and the given point on the sky. \end{itemize} \item Accuracy: \begin{itemize} \item The velocity component is usually within 0.004~km~s$^{-1}$ of the correct value and is never in error by more than 0.007~km~s$^{-1}$. \item The error in light time correction is about \tsec{0}{03} at worst, but is usually better than \tsec{0}{01}. \end{itemize} For applications requiring higher accuracy, see the sla\_EVP routine. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_EG50}{B1950 $\alpha,\delta$ to Galactic} { \action{Transformation from B1950.0 FK4 equatorial coordinates to IAU 1958 galactic coordinates.} \call{CALL sla\_EG50 (DR, DD, DL, DB)} } \args{GIVEN} { \spec{DR,DD}{D}{B1950.0 \radec\ (radians)} } \args{RETURNED} { \spec{DL,DB}{D}{galactic longitude and latitude \gal\ (radians)} } \anote{The equatorial coordinates are B1950.0 FK4. Use the routine sla\_EQGAL if conversion from J2000.0 FK5 coordinates is required.} \aref{Blaauw {\it et al.}, 1960, {\it Mon.Not.R.astr.Soc.}, {\bf 121}, 123.} %----------------------------------------------------------------------- \routine{SLA\_EL2UE}{Conventional to Universal Elements} { \action{Transform conventional osculating orbital elements into ``universal'' form.} \call{CALL sla\_EL2UE (\vtop{ \hbox{DATE, JFORM, EPOCH, ORBINC, ANODE,} \hbox{PERIH, AORQ, E, AORL, DM,} \hbox{U, JSTAT)}}} } \args{GIVEN} { \spec{DATE}{D}{epoch (TT MJD) of osculation (Note~3)} \\ \spec{JFORM}{I}{choice of element set (1-3; Note~6)} \\ \spec{EPOCH}{D}{epoch of elements ($t_0$ or $T$, TT MJD)} \\ \spec{ORBINC}{D}{inclination ($i$, radians)} \\ \spec{ANODE}{D}{longitude of the ascending node ($\Omega$, radians)} \\ \spec{PERIH}{D}{longitude or argument of perihelion ($\varpi$ or $\omega$,} \\ \spec{}{}{\hspace{1.5em} radians)} \\ \spec{AORQ}{D}{mean distance or perihelion distance ($a$ or $q$, AU)} \\ \spec{E}{D}{eccentricity ($e$)} \\ \spec{AORL}{D}{mean anomaly or longitude ($M$ or $L$, radians,} \\ \spec{}{}{\hspace{1.5em} JFORM=1,2 only)} \\ \spec{DM}{D}{daily motion ($n$, radians, JFORM=1 only)} } \args{RETURNED} { \spec{U}{D(13)}{universal orbital elements (Note~1)} \\ \specel {(1)} {combined mass ($M+m$)} \\ \specel {(2)} {total energy of the orbit ($\alpha$)} \\ \specel {(3)} {reference (osculating) epoch ($t_0$)} \\ \specel {(4-6)} {position at reference epoch (${\rm \bf r}_0$)} \\ \specel {(7-9)} {velocity at reference epoch (${\rm \bf v}_0$)} \\ \specel {(10)} {heliocentric distance at reference epoch} \\ \specel {(11)} {${\rm \bf r}_0.{\rm \bf v}_0$} \\ \specel {(12)} {date ($t$)} \\ \specel {(13)} {universal eccentric anomaly ($\psi$) of date, approx} \\ \\ \spec{JSTAT}{I}{status:} \\ \spec{}{}{\hspace{1.95em} 0 = OK} \\ \spec{}{}{\hspace{1.2em} $-$1 = illegal JFORM} \\ \spec{}{}{\hspace{1.2em} $-$2 = illegal E} \\ \spec{}{}{\hspace{1.2em} $-$3 = illegal AORQ} \\ \spec{}{}{\hspace{1.2em} $-$4 = illegal DM} \\ \spec{}{}{\hspace{1.2em} $-$5 = numerical error} } \notes { \begin{enumerate} \item The ``universal'' elements are those which define the orbit for the purposes of the method of universal variables (see reference). They consist of the combined mass of the two bodies, an epoch, and the position and velocity vectors (arbitrary reference frame) at that epoch. The parameter set used here includes also various quantities that can, in fact, be derived from the other information. This approach is taken to avoiding unnecessary computation and loss of accuracy. The supplementary quantities are (i)~$\alpha$, which is proportional to the total energy of the orbit, (ii)~the heliocentric distance at epoch, (iii)~the outwards component of the velocity at the given epoch, (iv)~an estimate of $\psi$, the ``universal eccentric anomaly'' at a given date and (v)~that date. \item The companion routine is sla\_UE2PV. This takes the set of numbers that the present routine outputs and uses them to derive the object's position and velocity. A single prediction requires one call to the present routine followed by one call to sla\_UE2PV; for convenience, the two calls are packaged as the routine sla\_PLANEL. Multiple predictions may be made by again calling the present routine once, but then calling sla\_UE2PV multiple times, which is faster than multiple calls to sla\_PLANEL. \item DATE is the epoch of osculation. It is in the TT timescale (formerly Ephemeris Time, ET) and is a Modified Julian Date (JD$-$2400000.5). \item The supplied orbital elements are with respect to the J2000 ecliptic and equinox. The position and velocity parameters returned in the array U are with respect to the mean equator and equinox of epoch J2000, and are for the perihelion prior to the specified epoch. \item The universal elements returned in the array U are in canonical units (solar masses, AU and canonical days). \item Three different element-format options are supported, as follows. \\ JFORM=1, suitable for the major planets: \begin{tabbing} xxx \= xxxxxxxx \= xx \= \kill \> EPOCH \> = \> epoch of elements $t_0$ (TT MJD) \\ \> ORBINC \> = \> inclination $i$ (radians) \\ \> ANODE \> = \> longitude of the ascending node $\Omega$ (radians) \\ \> PERIH \> = \> longitude of perihelion $\varpi$ (radians) \\ \> AORQ \> = \> mean distance $a$ (AU) \\ \> E \> = \> eccentricity $e$ $( 0 \leq e < 1 )$ \\ \> AORL \> = \> mean longitude $L$ (radians) \\ \> DM \> = \> daily motion $n$ (radians) \end{tabbing} JFORM=2, suitable for minor planets: \begin{tabbing} xxx \= xxxxxxxx \= xx \= \kill \> EPOCH \> = \> epoch of elements $t_0$ (TT MJD) \\ \> ORBINC \> = \> inclination $i$ (radians) \\ \> ANODE \> = \> longitude of the ascending node $\Omega$ (radians) \\ \> PERIH \> = \> argument of perihelion $\omega$ (radians) \\ \> AORQ \> = \> mean distance $a$ (AU) \\ \> E \> = \> eccentricity $e$ $( 0 \leq e < 1 )$ \\ \> AORL \> = \> mean anomaly $M$ (radians) \end{tabbing} JFORM=3, suitable for comets: \begin{tabbing} xxx \= xxxxxxxx \= xx \= \kill \> EPOCH \> = \> epoch of perihelion $T$ (TT MJD) \\ \> ORBINC \> = \> inclination $i$ (radians) \\ \> ANODE \> = \> longitude of the ascending node $\Omega$ (radians) \\ \> PERIH \> = \> argument of perihelion $\omega$ (radians) \\ \> AORQ \> = \> perihelion distance $q$ (AU) \\ \> E \> = \> eccentricity $e$ $( 0 \leq e \leq 10 )$ \end{tabbing} \item Unused elements (DM for JFORM=2, AORL and DM for JFORM=3) are not accessed. \item The algorithm was originally adapted from the EPHSLA program of D.\,H.\,P.\,Jones (private communication, 1996). The method is based on Stumpff's Universal Variables. \end{enumerate} } \aref{Everhart, E. \& Pitkin, E.T., Am.~J.~Phys.~51, 712, 1983.} %------------------------------------------------------------------------------ \routine{SLA\_EPB}{MJD to Besselian Epoch} { \action{Conversion of Modified Julian Date to Besselian Epoch.} \call{D~=~sla\_EPB (DATE)} } \args{GIVEN} { \spec{DATE}{D}{Modified Julian Date (JD$-$2400000.5)} } \args{RETURNED} { \spec{sla\_EPB}{D}{Besselian Epoch} } \aref{Lieske, J.H., 1979, {\it Astr.Astrophys.}\ {\bf 73}, 282.} %----------------------------------------------------------------------- \routine{SLA\_EPB2D}{Besselian Epoch to MJD} { \action{Conversion of Besselian Epoch to Modified Julian Date.} \call{D~=~sla\_EPB2D (EPB)} } \args{GIVEN} { \spec{EPB}{D}{Besselian Epoch} } \args{RETURNED} { \spec{sla\_EPB2D}{D}{Modified Julian Date (JD$-$2400000.5)} } \aref{Lieske, J.H., 1979. {\it Astr.Astrophys.}\ {\bf 73}, 282.} %----------------------------------------------------------------------- \routine{SLA\_EPCO}{Convert Epoch to B or J} { \action{Convert an epoch to Besselian or Julian to match another one.} \call{D~=~sla\_EPCO (K0, K, E)} } \args{GIVEN} { \spec{K0}{C}{form of result: `B'=Besselian, `J'=Julian} \\ \spec{K}{C}{form of given epoch: `B' or `J'} \\ \spec{E}{D}{epoch} } \args{RETURNED} { \spec{sla\_EPCO}{D}{the given epoch converted as necessary} } \notes { \begin{enumerate} \item The result is always either equal to or very close to the given epoch E. The routine is required only in applications where punctilious treatment of heterogeneous mixtures of star positions is necessary. \item K0 and K are not validated. They are interpreted as follows: \begin{itemize} \item If K0 and K are the same, the result is E. \item If K0 is `B' and K isn't, the conversion is J to B. \item In all other cases, the conversion is B to J. \end{itemize} \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_EPJ}{MJD to Julian Epoch} { \action{Convert Modified Julian Date to Julian Epoch.} \call{D~=~sla\_EPJ (DATE)} } \args{GIVEN} { \spec{DATE}{D}{Modified Julian Date (JD$-$2400000.5)} } \args{RETURNED} { \spec{sla\_EPJ}{D}{Julian Epoch} } \aref{Lieske, J.H., 1979.\ {\it Astr.Astrophys.}, {\bf 73}, 282.} %----------------------------------------------------------------------- \routine{SLA\_EPJ2D}{Julian Epoch to MJD} { \action{Convert Julian Epoch to Modified Julian Date.} \call{D~=~sla\_EPJ2D (EPJ)} } \args{GIVEN} { \spec{EPJ}{D}{Julian Epoch} } \args{RETURNED} { \spec{sla\_EPJ2D}{D}{Modified Julian Date (JD$-$2400000.5)} } \aref{Lieske, J.H., 1979.\ {\it Astr.Astrophys.}, {\bf 73}, 282.} %----------------------------------------------------------------------- \routine{SLA\_EQECL}{J2000 $\alpha,\delta$ to Ecliptic} { \action{Transformation from J2000.0 equatorial coordinates to ecliptic longitude and latitude.} \call{CALL sla\_EQECL (DR, DD, DATE, DL, DB)} } \args{GIVEN} { \spec{DR,DD}{D}{J2000.0 mean \radec\ (radians)} \\ \spec{DATE}{D}{TDB (formerly ET) as Modified Julian Date (JD$-$2400000.5)} } \args{RETURNED} { \spec{DL,DB}{D}{ecliptic longitude and latitude (mean of date, IAU 1980 theory, radians)} } %----------------------------------------------------------------------- \routine{SLA\_EQEQX}{Equation of the Equinoxes} { \action{Equation of the equinoxes (IAU 1994).} \call{D~=~sla\_EQEQX (DATE)} } \args{GIVEN} { \spec{DATE}{D}{TDB (formerly ET) as Modified Julian Date (JD$-$2400000.5)} } \args{RETURNED} { \spec{sla\_EQEQX}{D}{The equation of the equinoxes (radians)} } \notes{ \begin{enumerate} \item The equation of the equinoxes is defined here as GAST~$-$~GMST: it is added to a {\it mean}\/ sidereal time to give the {\it apparent}\/ sidereal time. \item The change from the classic ``textbook'' expression $\Delta\psi\,cos\,\epsilon$ occurred with IAU Resolution C7, Recommendation~3 (1994). The new formulation takes into account cross-terms between the various precession and nutation quantities, amounting to about 3~milliarcsec. The transition from the old to the new model officially takes place on 1997 February~27. \end{enumerate} } \aref{Capitaine, N.\ \& Gontier, A.-M.\ (1993), {\it Astron. Astrophys.}, {\bf 275}, 645-650.} %----------------------------------------------------------------------- \routine{SLA\_EQGAL}{J2000 $\alpha,\delta$ to Galactic} { \action{Transformation from J2000.0 FK5 equatorial coordinates to IAU 1958 galactic coordinates.} \call{CALL sla\_EQGAL (DR, DD, DL, DB)} } \args{GIVEN} { \spec{DR,DD}{D}{J2000.0 \radec\ (radians)} } \args{RETURNED} { \spec{DL,DB}{D}{galactic longitude and latitude \gal\ (radians)} } \anote{The equatorial coordinates are J2000.0 FK5. Use the routine sla\_EG50 if conversion from B1950.0 FK4 coordinates is required.} \aref{Blaauw {\it et al.}, 1960, {\it Mon.Not.R.astr.Soc.}, {\bf 121}, 123.} %----------------------------------------------------------------------- \routine{SLA\_ETRMS}{E-terms of Aberration} { \action{Compute the E-terms vector -- the part of the annual aberration which arises from the eccentricity of the Earth's orbit.} \call{CALL sla\_ETRMS (EP, EV)} } \args{GIVEN} { \spec{EP}{D}{Besselian epoch} } \args{RETURNED} { \spec{EV}{D(3)}{E-terms as $[\Delta x, \Delta y, \Delta z\,]$} } \anote{Note the use of the J2000 aberration constant (\arcsec{20}{49552}). This is a reflection of the fact that the E-terms embodied in existing star catalogues were computed from a variety of aberration constants. Rather than adopting one of the old constants the latest value is used here.} \refs { \begin{enumerate} \item Smith, C.A.\ {\it et al.}, 1989. {\it Astr.J.}\ {\bf 97}, 265. \item Yallop, B.D.\ {\it et al.}, 1989. {\it Astr.J.}\ {\bf 97}, 274. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_EULER}{Rotation Matrix from Euler Angles} { \action{Form a rotation matrix from the Euler angles -- three successive rotations about specified Cartesian axes (single precision).} \call{CALL sla\_EULER (ORDER, PHI, THETA, PSI, RMAT)} } \args{GIVEN} { \spec{ORDER}{C*(*)}{specifies about which axes the rotations occur} \\ \spec{PHI}{R}{1st rotation (radians)} \\ \spec{THETA}{R}{2nd rotation (radians)} \\ \spec{PSI}{R}{3rd rotation (radians)} } \args{RETURNED} { \spec{RMAT}{R(3,3)}{rotation matrix} } \notes { \begin{enumerate} \item A rotation is positive when the reference frame rotates anticlockwise as seen looking towards the origin from the positive region of the specified axis. \item The characters of ORDER define which axes the three successive rotations are about. A typical value is `ZXZ', indicating that RMAT is to become the direction cosine matrix corresponding to rotations of the reference frame through PHI radians about the old {\it z}-axis, followed by THETA radians about the resulting {\it x}-axis, then PSI radians about the resulting {\it z}-axis. In detail: \begin{itemize} \item The axis names can be any of the following, in any order or combination: X, Y, Z, uppercase or lowercase, 1, 2, 3. Normal axis labelling/numbering conventions apply; the {\it xyz} ($\equiv123$) triad is right-handed. Thus, the `ZXZ' example given above could be written `zxz' or `313' (or even `ZxZ' or `3xZ'). \item ORDER is terminated by length or by the first unrecognized character. \item Fewer than three rotations are acceptable, in which case the later angle arguments are ignored. \end{itemize} \item Zero rotations produces a unit RMAT. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_EVP}{Earth Position \& Velocity} { \action{Barycentric and heliocentric velocity and position of the Earth.} \call{CALL sla\_EVP (DATE, DEQX, DVB, DPB, DVH, DPH)} } \args{GIVEN} { \spec{DATE}{D}{TDB (formerly ET) as a Modified Julian Date (JD$-$2400000.5)} \\ \spec{DEQX}{D}{Julian Epoch ({\it e.g.}\ 2000D0) of mean equator and equinox of the vectors returned. If DEQX~$<0$, all vectors are referred to the mean equator and equinox (FK5) of date DATE.} } \args{RETURNED} { \spec{DVB}{D(3)}{barycentric \xyzd, AU~s$^{-1}$} \\ \spec{DPB}{D(3)}{barycentric \xyz, AU} \\ \spec{DVH}{D(3)}{heliocentric \xyzd, AU~s$^{-1}$} \\ \spec{DPH}{D(3)}{heliocentric \xyz, AU} } \notes { \begin{enumerate} \item This routine is used when accuracy is more important than CPU time, yet the extra complication of reading a pre-computed ephemeris is not justified. The maximum deviations from the JPL~DE96 ephemeris are as follows: \begin{itemize} \item velocity (barycentric or heliocentric): 420~mm~s$^{-1}$ \item position (barycentric): 6900~km \item position (heliocentric): 1600~km \end{itemize} \item The routine is an adaption of the BARVEL and BARCOR subroutines of P.Stumpff, which are described in {\it Astr.Astrophys.Suppl.Ser.}\ {\bf 41}, 1-8 (1980). Most of the changes are merely cosmetic and do not affect the results at all. However, some adjustments have been made so as to give results that refer to the new (IAU 1976 `FK5') equinox and precession, although the differences these changes make relative to the results from Stumpff's original `FK4' version are smaller than the inherent accuracy of the algorithm. One minor shortcoming in the original routines that has {\bf not} been corrected is that slightly better numerical accuracy could be achieved if the various polynomial evaluations were to be so arranged that the smallest terms were computed first. Note also that one of Stumpff's precession constants differs by \arcsec{0}{001} from the value given in the {\it Explanatory Supplement}. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_FITXY}{Fit Linear Model to Two \xy\ Sets} { \action{Fit a linear model to relate two sets of \xy\ coordinates.} \call{CALL sla\_FITXY (ITYPE,NP,XYE,XYM,COEFFS,J)} } \args{GIVEN} { \spec{ITYPE}{I}{type of model: 4 or 6 (note 1)} \\ \spec{NP}{I}{number of samples (note 2)} \\ \spec{XYE}{D(2,NP)}{expected \xy\ for each sample} \\ \spec{XYM}{D(2,NP)}{measured \xy\ for each sample} } \args{RETURNED} { \spec{COEFFS}{D(6)}{coefficients of model (note 3)} \\ \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 0 = OK} \\ \spec{}{}{\hspace{0.7em} $-$1 = illegal ITYPE} \\ \spec{}{}{\hspace{0.7em} $-$2 = insufficient data} \\ \spec{}{}{\hspace{0.7em} $-$3 = singular solution} } \notes { \begin{enumerate} \item ITYPE, which must be either 4 or 6, selects the type of model fitted. Both allowed ITYPE values produce a model COEFFS which consists of six coefficients, namely the zero points and, for each of XE and YE, the coefficient of XM and YM. For ITYPE=6, all six coefficients are independent, modelling squash and shear as well as origin, scale, and orientation. However, ITYPE=4 selects the {\it solid body rotation}\/ option; the model COEFFS still consists of the same six coefficients, but now two of them are used twice (appropriately signed). Origin, scale and orientation are still modelled, but not squash or shear -- the units of X and Y have to be the same. \item For NC=4, NP must be at least 2. For NC=6, NP must be at least 3. \item The model is returned in the array COEFFS. Naming the six elements of COEFFS $a,b,c,d,e$ \& $f$, the model transforms {\it measured}\/ coordinates $[x_{m},y_{m}\,]$ into {\it expected}\/ coordinates $[x_{e},y_{e}\,]$ as follows: \begin{verse} $x_{e} = a + bx_{m} + cy_{m}$ \\ $y_{e} = d + ex_{m} + fy_{m}$ \end{verse} For the {\it solid body rotation}\/ option (ITYPE=4), the magnitudes of $b$ and $f$, and of $c$ and $e$, are equal. The signs of these coefficients depend on whether there is a sign reversal between $[x_{e},y_{e}]$ and $[x_{m},y_{m}]$; fits are performed with and without a sign reversal and the best one chosen. \item Error status values J=$-$1 and $-$2 leave COEFFS unchanged; if J=$-$3 COEFFS may have been changed. \item See also sla\_PXY, sla\_INVF, sla\_XY2XY, sla\_DCMPF. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_FK425}{FK4 to FK5} { \action{Convert B1950.0 FK4 star data to J2000.0 FK5. This routine converts stars from the old, Bessel-Newcomb, FK4 system to the new, IAU~1976, FK5, Fricke system. The precepts of Smith~{\it et~al.}\ (see reference~1) are followed, using the implementation by Yallop~{\it et~al.}\ (reference~2) of a matrix method due to Standish. Kinoshita's development of Andoyer's post-Newcomb precession is used. The numerical constants from Seidelmann~{\it et~al.}\ (reference~3) are used canonically.} \call{CALL sla\_FK425 (\vtop{ \hbox{R1950,D1950,DR1950,DD1950,P1950,V1950,} \hbox{R2000,D2000,DR2000,DD2000,P2000,V2000)}}} } \args{GIVEN} { \spec{R1950}{D}{B1950.0 $\alpha$ (radians)} \\ \spec{D1950}{D}{B1950.0 $\delta$ (radians)} \\ \spec{DR1950}{D}{B1950.0 proper motion in $\alpha$ (radians per tropical year)} \\ \spec{DD1950}{D}{B1950.0 proper motion in $\delta$ (radians per tropical year)} \\ \spec{P1950}{D}{B1950.0 parallax (arcsec)} \\ \spec{V1950}{D}{B1950.0 radial velocity (km~s$^{-1}$, +ve = moving away)} } \args{RETURNED} { \spec{R2000}{D}{J2000.0 $\alpha$ (radians)} \\ \spec{D2000}{D}{J2000.0 $\delta$ (radians)} \\ \spec{DR2000}{D}{J2000.0 proper motion in $\alpha$ (radians per Julian year)} \\ \spec{DD2000}{D}{J2000.0 proper motion in $\delta$ (radians per Julian year)} \\ \spec{P2000}{D}{J2000.0 parallax (arcsec)} \\ \spec{V2000}{D}{J2000.0 radial velocity (km~s$^{-1}$, +ve = moving away)} } \notes { \begin{enumerate} \item The $\alpha$ proper motions are $\dot{\alpha}$ rather than $\dot{\alpha}\cos\delta$, and are per year rather than per century. \item Conversion from Besselian epoch 1950.0 to Julian epoch 2000.0 only is provided for. Conversions involving other epochs will require use of the appropriate precession, proper motion, and E-terms routines before and/or after FK425 is called. \item In the FK4 catalogue the proper motions of stars within $10^{\circ}$ of the poles do not include the {\it differential E-terms}\/ effect and should, strictly speaking, be handled in a different manner from stars outside these regions. However, given the general lack of homogeneity of the star data available for routine astrometry, the difficulties of handling positions that may have been determined from astrometric fields spanning the polar and non-polar regions, the likelihood that the differential E-terms effect was not taken into account when allowing for proper motion in past astrometry, and the undesirability of a discontinuity in the algorithm, the decision has been made in this routine to include the effect of differential E-terms on the proper motions for all stars, whether polar or not. At epoch J2000, and measuring on the sky rather than in terms of $\Delta\alpha$, the errors resulting from this simplification are less than 1~milliarcsecond in position and 1~milliarcsecond per century in proper motion. \item See also sla\_FK45Z, sla\_FK524, sla\_FK54Z. \end{enumerate} } \refs { \begin{enumerate} \item Smith, C.A.\ {\it et al.}, 1989.\ {\it Astr.J.}\ {\bf 97}, 265. \item Yallop, B.D.\ {\it et al.}, 1989.\ {\it Astr.J.}\ {\bf 97}, 274. \item Seidelmann, P.K.\ (ed), 1992. {\it Explanatory Supplement to the Astronomical Almanac,}\/ ISBN~0-935702-68-7. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_FK45Z}{FK4 to FK5, no P.M. or Parallax} { \action{Convert B1950.0 FK4 star data to J2000.0 FK5 assuming zero proper motion in the FK5 frame. This routine converts stars from the old, Bessel-Newcomb, FK4 system to the new, IAU~1976, FK5, Fricke system, in such a way that the FK5 proper motion is zero. Because such a star has, in general, a non-zero proper motion in the FK4 system, the routine requires the epoch at which the position in the FK4 system was determined. The method is from appendix~2 of reference~1, but using the constants of reference~4.} \call{CALL sla\_FK45Z (R1950,D1950,BEPOCH,R2000,D2000)} } \args{GIVEN} { \spec{R1950}{D}{B1950.0 FK4 $\alpha$ at epoch BEPOCH (radians)} \\ \spec{D1950}{D}{B1950.0 FK4 $\delta$ at epoch BEPOCH (radians)} \\ \spec{BEPOCH}{D}{Besselian epoch ({\it e.g.}\ 1979.3D0)} } \args{RETURNED} { \spec{R2000}{D}{J2000.0 FK5 $\alpha$ (radians)} \\ \spec{D2000}{D}{J2000.0 FK5 $\delta$ (radians)} } \notes { \begin{enumerate} \item The epoch BEPOCH is strictly speaking Besselian, but if a Julian epoch is supplied the result will be affected only to a negligible extent. \item Conversion from Besselian epoch 1950.0 to Julian epoch 2000.0 only is provided for. Conversions involving other epochs will require use of the appropriate precession, proper motion, and E-terms routines before and/or after FK45Z is called. \item In the FK4 catalogue the proper motions of stars within $10^{\circ}$ of the poles do not include the {\it differential E-terms}\/ effect and should, strictly speaking, be handled in a different manner from stars outside these regions. However, given the general lack of homogeneity of the star data available for routine astrometry, the difficulties of handling positions that may have been determined from astrometric fields spanning the polar and non-polar regions, the likelihood that the differential E-terms effect was not taken into account when allowing for proper motion in past astrometry, and the undesirability of a discontinuity in the algorithm, the decision has been made in this routine to include the effect of differential E-terms on the proper motions for all stars, whether polar or not. At epoch 2000, and measuring on the sky rather than in terms of $\Delta\alpha$, the errors resulting from this simplification are less than 1~milliarcsecond in position and 1~milliarcsecond per century in proper motion. \item See also sla\_FK425, sla\_FK524, sla\_FK54Z. \end{enumerate} } \refs { \begin{enumerate} \item Aoki, S., {\it et al.}, 1983.\ {\it Astr.Astrophys.}, {\bf 128}, 263. \item Smith, C.A.\ {\it et al.}, 1989.\ {\it Astr.J.}\ {\bf 97}, 265. \item Yallop, B.D.\ {\it et al.}, 1989.\ {\it Astr.J.}\ {\bf 97}, 274. \item Seidelmann, P.K.\ (ed), 1992. {\it Explanatory Supplement to the Astronomical Almanac,}\/ ISBN~0-935702-68-7. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_FK524}{FK5 to FK4} { \action{Convert J2000.0 FK5 star data to B1950.0 FK4. This routine converts stars from the new, IAU~1976, FK5, Fricke system, to the old, Bessel-Newcomb, FK4 system. The precepts of Smith~{\it et~al.}\ (reference~1) are followed, using the implementation by Yallop~{\it et~al.}\ (reference~2) of a matrix method due to Standish. Kinoshita's development of Andoyer's post-Newcomb precession is used. The numerical constants from Seidelmann~{\it et~al.}\ (reference~3) are used canonically.} \call{CALL sla\_FK524 (\vtop{ \hbox{R2000,D2000,DR2000,DD2000,P2000,V2000,} \hbox{R1950,D1950,DR1950,DD1950,P1950,V1950)}}} } \args{GIVEN} { \spec{R2000}{D}{J2000.0 $\alpha$ (radians)} \\ \spec{D2000}{D}{J2000.0 $\delta$ (radians)} \\ \spec{DR2000}{D}{J2000.0 proper motion in $\alpha$ (radians per Julian year)} \\ \spec{DD2000}{D}{J2000.0 proper motion in $\delta$ (radians per Julian year)} \\ \spec{P2000}{D}{J2000.0 parallax (arcsec)} \\ \spec{V2000}{D}{J2000 radial velocity (km~s$^{-1}$, +ve = moving away)} } \args{RETURNED} { \spec{R1950}{D}{B1950.0 $\alpha$ (radians)} \\ \spec{D1950}{D}{B1950.0 $\delta$ (radians)} \\ \spec{DR1950}{D}{B1950.0 proper motion in $\alpha$ (radians per tropical year)} \\ \spec{DD1950}{D}{B1950.0 proper motion in $\delta$ (radians per tropical year)} \\ \spec{P1950}{D}{B1950.0 parallax (arcsec)} \\ \spec{V1950}{D}{radial velocity (km~s$^{-1}$, +ve = moving away)} } \notes { \begin{enumerate} \item The $\alpha$ proper motions are $\dot{\alpha}$ rather than $\dot{\alpha}\cos\delta$, and are per year rather than per century. \item Note that conversion from Julian epoch 2000.0 to Besselian epoch 1950.0 only is provided for. Conversions involving other epochs will require use of the appropriate precession, proper motion, and E-terms routines before and/or after FK524 is called. \item In the FK4 catalogue the proper motions of stars within $10^{\circ}$ of the poles do not include the {\it differential E-terms}\/ effect and should, strictly speaking, be handled in a different manner from stars outside these regions. However, given the general lack of homogeneity of the star data available for routine astrometry, the difficulties of handling positions that may have been determined from astrometric fields spanning the polar and non-polar regions, the likelihood that the differential E-terms effect was not taken into account when allowing for proper motion in past astrometry, and the undesirability of a discontinuity in the algorithm, the decision has been made in this routine to include the effect of differential E-terms on the proper motions for all stars, whether polar or not. At epoch 2000, and measuring on the sky rather than in terms of $\Delta\alpha$, the errors resulting from this simplification are less than 1~milliarcsecond in position and 1~milliarcsecond per century in proper motion. \item See also sla\_FK425, sla\_FK45Z, sla\_FK54Z. \end{enumerate} } \refs { \begin{enumerate} \item Smith, C.A.\ {\it et al.}, 1989.\ {\it Astr.J.}\ {\bf 97}, 265. \item Yallop, B.D.\ {\it et al.}, 1989.\ {\it Astr.J.}\ {\bf 97}, 274. \item Seidelmann, P.K.\ (ed), 1992. {\it Explanatory Supplement to the Astronomical Almanac,}\/ ISBN~0-935702-68-7. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_FK52H}{FK5 to Hipparcos} { \action{Transform an FK5 (J2000) position and proper motion into the frame of the Hipparcos catalogue.} \call{CALL sla\_FK52H (R5,D5,DR5,DD5,RH,DH,DRH,DDH)} } \args{GIVEN} { \spec{R5}{D}{J2000.0 FK5 $\alpha$ (radians)} \\ \spec{D5}{D}{J2000.0 FK5 $\delta$ (radians)} \\ \spec{DR5}{D}{J2000.0 FK5 proper motion in $\alpha$ (radians per Julian year)} \\ \spec{DD5}{D}{J2000.0 FK5 proper motion in $\delta$ (radians per Julian year)} } \args{RETURNED} { \spec{RH}{D}{Hipparcos $\alpha$ (radians)} \\ \spec{DH}{D}{Hipparcos $\delta$ (radians)} \\ \spec{DRH}{D}{Hipparcos proper motion in $\alpha$ (radians per Julian year)} \\ \spec{DDH}{D}{Hipparcos proper motion in $\delta$ (radians per Julian year)} } \notes { \begin{enumerate} \item The $\alpha$ proper motions are $\dot{\alpha}$ rather than $\dot{\alpha}\cos\delta$, and are per year rather than per century. \item The FK5 to Hipparcos transformation consists of a pure rotation and spin; zonal errors in the FK5 catalogue are not taken into account. \item The adopted epoch J2000.0 FK5 to Hipparcos orientation and spin values are as follows (see reference): \vspace{2ex} ~~~~~~~~~~~~ \begin{tabular}{|r|r|r|} \hline & \multicolumn{1}{|c}{\it orientation} & \multicolumn{1}{|c|}{\it ~~~spin~~~} \\ \hline $x$ & $-19.9$~~~~ & ~$-0.30$~~ \\ $y$ & $-9.1$~~~~ & ~$+0.60$~~ \\ $z$ & $+22.9$~~~~ & ~$+0.70$~~ \\ \hline & {\it mas}~~~~~ & ~{\it mas/y}~ \\ \hline \end{tabular} \vspace{3ex} These orientation and spin components are interpreted as {\it axial vectors.} An axial vector points at the pole of the rotation and its length is the amount of rotation in radians. \item See also sla\_FK5HZ, sla\_H2FK5, sla\_HFK5Z. \end{enumerate} } \aref {Feissel, M.\ \& Mignard, F., 1998., {\it Astron.Astrophys.}\ {\bf 331}, L33-L36.} %----------------------------------------------------------------------- \routine{SLA\_FK54Z}{FK5 to FK4, no P.M. or Parallax} { \action{Convert a J2000.0 FK5 star position to B1950.0 FK4 assuming FK5 zero proper motion and parallax. This routine converts star positions from the new, IAU~1976, FK5, Fricke system to the old, Bessel-Newcomb, FK4 system.} \call{CALL sla\_FK54Z (R2000,D2000,BEPOCH,R1950,D1950,DR1950,DD1950)} } \args{GIVEN} { \spec{R2000}{D}{J2000.0 FK5 $\alpha$ (radians)} \\ \spec{D2000}{D}{J2000.0 FK5 $\delta$ (radians)} \\ \spec{BEPOCH}{D}{Besselian epoch ({\it e.g.}\ 1950D0)} } \args{RETURNED} { \spec{R1950}{D}{B1950.0 FK4 $\alpha$ at epoch BEPOCH (radians)} \\ \spec{D1950}{D}{B1950.0 FK4 $\delta$ at epoch BEPOCH (radians)} \\ \spec{DR1950}{D}{B1950.0 FK4 proper motion in $\alpha$ (radians per tropical year)} \\ \spec{DD1950}{D}{B1950.0 FK4 proper motion in $\delta$ (radians per tropical year)} } \notes { \begin{enumerate} \item The $\alpha$ proper motions are $\dot{\alpha}$ rather than $\dot{\alpha}\cos\delta$, and are per year rather than per century. \item Conversion from Julian epoch 2000.0 to Besselian epoch 1950.0 only is provided for. Conversions involving other epochs will require use of the appropriate precession routines before and after this routine is called. \item Unlike in the sla\_FK524 routine, the FK5 proper motions, the parallax and the radial velocity are presumed zero. \item It was the intention that FK5 should be a close approximation to an inertial frame, so that distant objects have zero proper motion; such objects have (in general) non-zero proper motion in FK4, and this routine returns those {\it fictitious proper motions}. \item The position returned by this routine is in the B1950 reference frame but at Besselian epoch BEPOCH. For comparison with catalogues the BEPOCH argument will frequently be 1950D0. \item See also sla\_FK425, sla\_FK45Z, sla\_FK524. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_FK5HZ}{FK5 to Hipparcos, no P.M.} { \action{Transform an FK5 (J2000) star position into the frame of the Hipparcos catalogue, assuming zero Hipparcos proper motion.} \call{CALL sla\_FK52H (R5,D5,EPOCH,RH,DH)} } \args{GIVEN} { \spec{R5}{D}{J2000.0 FK5 $\alpha$ (radians)} \\ \spec{D5}{D}{J2000.0 FK5 $\delta$ (radians)} \\ \spec{EPOCH}{D}{Julian epoch (TDB)} } \args{RETURNED} { \spec{RH}{D}{Hipparcos $\alpha$ (radians)} \\ \spec{DH}{D}{Hipparcos $\delta$ (radians)} } \notes { \begin{enumerate} \item The $\alpha$ proper motions are $\dot{\alpha}$ rather than $\dot{\alpha}\cos\delta$, and are per year rather than per century. \item The FK5 to Hipparcos transformation consists of a pure rotation and spin; zonal errors in the FK5 catalogue are not taken into account. \item The adopted epoch J2000.0 FK5 to Hipparcos orientation and spin values are as follows (see reference): \vspace{2ex} ~~~~~~~~~~~~ \begin{tabular}{|r|r|r|} \hline & \multicolumn{1}{|c}{\it orientation} & \multicolumn{1}{|c|}{\it ~~~spin~~~} \\ \hline $x$ & $-19.9$~~~~ & ~$-0.30$~~ \\ $y$ & $-9.1$~~~~ & ~$+0.60$~~ \\ $z$ & $+22.9$~~~~ & ~$+0.70$~~ \\ \hline & {\it mas}~~~~~ & ~{\it mas/y}~ \\ \hline \end{tabular} \vspace{3ex} These orientation and spin components are interpreted as {\it axial vectors.} An axial vector points at the pole of the rotation and its length is the amount of rotation in radians. \item See also sla\_FK52H, sla\_H2FK5, sla\_HFK5Z. \end{enumerate} } \aref {Feissel, M.\ \& Mignard, F., 1998., {\it Astron.Astrophys.}\ {\bf 331}, L33-L36.} %----------------------------------------------------------------------- \routine{SLA\_FLOTIN}{Decode a Real Number} { \action{Convert free-format input into single precision floating point.} \call{CALL sla\_FLOTIN (STRING, NSTRT, RESLT, JFLAG)} } \args{GIVEN} { \spec{STRING}{C}{string containing number to be decoded} \\ \spec{NSTRT}{I}{pointer to where decoding is to commence} \\ \spec{RESLT}{R}{current value of result} } \args{RETURNED} { \spec{NSTRT}{I}{advanced to next number} \\ \spec{RESLT}{R}{result} \\ \spec{JFLAG}{I}{status: $-$1~=~$-$OK, 0~=~+OK, 1~=~null result, 2~=~error} } \notes { \begin{enumerate} \item The reason sla\_FLOTIN has separate `OK' status values for + and $-$ is to enable minus zero to be detected. This is of crucial importance when decoding mixed-radix numbers. For example, an angle expressed as degrees, arcminutes and arcseconds may have a leading minus sign but a zero degrees field. \item A TAB is interpreted as a space, and lowercase characters are interpreted as uppercase. {\it n.b.}\ The test for TAB is ASCII-specific. \item The basic format is the sequence of fields $\pm n.n x \pm n$, where $\pm$ is a sign character `+' or `$-$', $n$ means a string of decimal digits, `.' is a decimal point, and $x$, which indicates an exponent, means `D' or `E'. Various combinations of these fields can be omitted, and embedded blanks are permissible in certain places. \item Spaces: \begin{itemize} \item Leading spaces are ignored. \item Embedded spaces are allowed only after +, $-$, D or E, and after the decimal point if the first sequence of digits is absent. \item Trailing spaces are ignored; the first signifies end of decoding and subsequent ones are skipped. \end{itemize} \item Delimiters: \begin{itemize} \item Any character other than +,$-$,0-9,.,D,E or space may be used to signal the end of the number and terminate decoding. \item Comma is recognized by sla\_FLOTIN as a special case; it is skipped, leaving the pointer on the next character. See 13, below. \item Decoding will in all cases terminate if end of string is reached. \end{itemize} \item Both signs are optional. The default is +. \item The mantissa $n.n$ defaults to unity. \item The exponent $x\!\pm\!n$ defaults to `E0'. \item The strings of decimal digits may be of any length. \item The decimal point is optional for whole numbers. \item A {\it null result}\/ occurs when the string of characters being decoded does not begin with +,$-$,0-9,.,D or E, or consists entirely of spaces. When this condition is detected, JFLAG is set to 1 and RESLT is left untouched. \item NSTRT = 1 for the first character in the string. \item On return from sla\_FLOTIN, NSTRT is set ready for the next decode -- following trailing blanks and any comma. If a delimiter other than comma is being used, NSTRT must be incremented before the next call to sla\_FLOTIN, otherwise all subsequent calls will return a null result. \item Errors (JFLAG=2) occur when: \begin{itemize} \item a +, $-$, D or E is left unsatisfied; or \item the decimal point is present without at least one decimal digit before or after it; or \item an exponent more than 100 has been presented. \end{itemize} \item When an error has been detected, NSTRT is left pointing to the character following the last one used before the error came to light. This may be after the point at which a more sophisticated program could have detected the error. For example, sla\_FLOTIN does not detect that `1E999' is unacceptable (on a computer where this is so) until the entire number has been decoded. \item Certain highly unlikely combinations of mantissa and exponent can cause arithmetic faults during the decode, in some cases despite the fact that they together could be construed as a valid number. \item Decoding is left to right, one pass. \item See also sla\_DFLTIN and sla\_INTIN. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_GALEQ}{Galactic to J2000 $\alpha,\delta$} { \action{Transformation from IAU 1958 galactic coordinates to J2000.0 FK5 equatorial coordinates.} \call{CALL sla\_GALEQ (DL, DB, DR, DD)} } \args{GIVEN} { \spec{DL,DB}{D}{galactic longitude and latitude \gal} } \args{RETURNED} { \spec{DR,DD}{D}{J2000.0 \radec} } \notes { \begin{enumerate} \item All arguments are in radians. \item The equatorial coordinates are J2000.0 FK5. Use the routine sla\_GE50 if conversion to B1950.0 FK4 coordinates is required. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_GALSUP}{Galactic to Supergalactic} { \action{Transformation from IAU 1958 galactic coordinates to de Vaucouleurs supergalactic coordinates.} \call{CALL sla\_GALSUP (DL, DB, DSL, DSB)} } \args{GIVEN} { \spec{DL,DB}{D}{galactic longitude and latitude \gal\ (radians)} } \args{RETURNED} { \spec{DSL,DSB}{D}{supergalactic longitude and latitude (radians)} } \refs { \begin{enumerate} \item de Vaucouleurs, de Vaucouleurs, \& Corwin, {\it Second Reference Catalogue of Bright Galaxies}, U.Texas, p8. \item Systems \& Applied Sciences Corp., documentation for the machine-readable version of the above catalogue, Contract NAS 5-26490. \end{enumerate} (These two references give different values for the galactic longitude of the supergalactic origin. Both are wrong; the correct value is $l^{I\!I}=137.37$.) } %----------------------------------------------------------------------- \routine{SLA\_GE50}{Galactic to B1950 $\alpha,\delta$} { \action{Transformation from IAU 1958 galactic coordinates to B1950.0 FK4 equatorial coordinates.} \call{CALL sla\_GE50 (DL, DB, DR, DD)} } \args{GIVEN} { \spec{DL,DB}{D}{galactic longitude and latitude \gal} } \args{RETURNED} { \spec{DR,DD}{D}{B1950.0 \radec} } \notes { \begin{enumerate} \item All arguments are in radians. \item The equatorial coordinates are B1950.0 FK4. Use the routine sla\_GALEQ if conversion to J2000.0 FK5 coordinates is required. \end{enumerate} } \aref{Blaauw {\it et al.}, 1960, {\it Mon.Not.R.astr.Soc.}, {\bf 121}, 123.} %----------------------------------------------------------------------- \routine{SLA\_GEOC}{Geodetic to Geocentric} { \action{Convert geodetic position to geocentric.} \call{CALL sla\_GEOC (P, H, R, Z)} } \args{GIVEN} { \spec{P}{D}{latitude (geodetic, radians)} \\ \spec{H}{D}{height above reference spheroid (geodetic, metres)} } \args{RETURNED} { \spec{R}{D}{distance from Earth axis (AU)} \\ \spec{Z}{D}{distance from plane of Earth equator (AU)} } \notes { \begin{enumerate} \item Geocentric latitude can be obtained by evaluating {\tt ATAN2(Z,R)}. \item IAU 1976 constants are used. \end{enumerate} } \aref{Green, R.M., 1985.\ {\it Spherical Astronomy}, Cambridge U.P., p98.} %----------------------------------------------------------------------- \routine{SLA\_GMST}{UT to GMST} { \action{Conversion from universal time UT1 to Greenwich mean sidereal time.} \call{D~=~sla\_GMST (UT1)} } \args{GIVEN} { \spec{UT1}{D}{universal time (strictly UT1) expressed as modified Julian Date (JD$-$2400000.5)} } \args{RETURNED} { \spec{sla\_GMST}{D}{Greenwich mean sidereal time (radians)} } \notes { \begin{enumerate} \item The IAU~1982 expression (see page~S15 of the 1984 {\it Astronomical Almanac})\/ is used, but rearranged to reduce rounding errors. This expression is always described as giving the GMST at $0^{\rm h}$UT; in fact, it gives the difference between the GMST and the UT, which happens to equal the GMST (modulo 24~hours) at $0^{\rm h}$UT each day. In sla\_GMST, the entire UT is used directly as the argument for the canonical formula, and the fractional part of the UT is added separately; note that the factor $1.0027379\cdots$ does not appear. \item See also the routine sla\_GMSTA, which delivers better numerical precision by accepting the UT date and time as separate arguments. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_GMSTA}{UT to GMST (extra precision)} { \action{Conversion from universal time UT1 to Greenwich Mean sidereal time, with rounding errors minimized.} \call{D~=~sla\_GMSTA (DATE, UT1)} } \args{GIVEN} { \spec{DATE}{D}{UT1 date as Modified Julian Date (integer part of JD$-$2400000.5)} \\ \spec{UT1}{D}{UT1 time (fraction of a day)} } \args{RETURNED} { \spec{sla\_GMST}{D}{Greenwich mean sidereal time (radians)} } \notes { \begin{enumerate} \item The algorithm is derived from the IAU 1982 expression (see page~S15 of the 1984 Astronomical Almanac). \item There is no restriction on how the UT is apportioned between the DATE and UT1 arguments. Either of the two arguments could, for example, be zero and the entire date\,+\,time supplied in the other. However, the routine is designed to deliver maximum accuracy when the DATE argument is a whole number and the UT1 argument lies in the range $[\,0,\,1\,]$, or {\it vice versa}. \item See also the routine sla\_GMST, which accepts the UT1 as a single argument. Compared with sla\_GMST, the extra numerical precision delivered by the present routine is unlikely to be important in an absolute sense, but may be useful when critically comparing algorithms and in applications where two sidereal times close together are differenced. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_GRESID}{Gaussian Residual} { \action{Generate pseudo-random normal deviate or {\it Gaussian residual}.} \call{R~=~sla\_GRESID (S)} } \args{GIVEN} { \spec{S}{R}{standard deviation} } \notes { \begin{enumerate} \item The results of many calls to this routine will be normally distributed with mean zero and standard deviation S. \item The Box-Muller algorithm is used. \item The implementation is machine-dependent. \end{enumerate} } \aref{Ahrens \& Dieter, 1972.\ {\it Comm.A.C.M.}\ {\bf 15}, 873.} %----------------------------------------------------------------------- \routine{SLA\_H2E}{Az,El to $h,\delta$} { \action{Horizon to equatorial coordinates (single precision).} \call{CALL sla\_H2E (AZ, EL, PHI, HA, DEC)} } \args{GIVEN} { \spec{AZ}{R}{azimuth (radians)} \\ \spec{EL}{R}{elevation (radians)} \\ \spec{PHI}{R}{latitude (radians)} } \args{RETURNED} { \spec{HA}{R}{hour angle (radians)} \\ \spec{DEC}{R}{declination (radians)} } \notes { \begin{enumerate} \item The sign convention for azimuth is north zero, east $+\pi/2$. \item HA is returned in the range $\pm\pi$. Declination is returned in the range $\pm\pi$. \item The latitude is (in principle) geodetic. In critical applications, corrections for polar motion should be applied (see sla\_POLMO). \item In some applications it will be important to specify the correct type of elevation in order to produce the required type of \hadec. In particular, it may be important to distinguish between the elevation as affected by refraction, which will yield the {\it observed} \hadec, and the elevation {\it in vacuo}, which will yield the {\it topocentric} \hadec. If the effects of diurnal aberration can be neglected, the topocentric \hadec\ may be used as an approximation to the {\it apparent} \hadec. \item No range checking of arguments is carried out. \item In applications which involve many such calculations, rather than calling the present routine it will be more efficient to use inline code, having previously computed fixed terms such as sine and cosine of latitude. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_H2FK5}{Hipparcos to FK5} { \action{Transform a Hipparcos star position and proper motion into the FK5 (J2000) frame.} \call{CALL sla\_H2FK5 (RH,DH,DRH,DDH,R5,D5,DR5,DD5)} } \args{GIVEN} { \spec{RH}{D}{Hipparcos $\alpha$ (radians)} \\ \spec{DH}{D}{Hipparcos $\delta$ (radians)} \\ \spec{DRH}{D}{Hipparcos proper motion in $\alpha$ (radians per Julian year)} \\ \spec{DDH}{D}{Hipparcos proper motion in $\delta$ (radians per Julian year)} } \args{RETURNED} { \spec{R5}{D}{J2000.0 FK5 $\alpha$ (radians)} \\ \spec{D5}{D}{J2000.0 FK5 $\delta$ (radians)} \\ \spec{DR5}{D}{J2000.0 FK5 proper motion in $\alpha$ (radians per Julian year)} \\ \spec{DD5}{D}{FK5 J2000.0 proper motion in $\delta$ (radians per Julian year)} } \notes { \begin{enumerate} \item The $\alpha$ proper motions are $\dot{\alpha}$ rather than $\dot{\alpha}\cos\delta$, and are per year rather than per century. \item The FK5 to Hipparcos transformation consists of a pure rotation and spin; zonal errors in the FK5 catalogue are not taken into account. \item The adopted epoch J2000.0 FK5 to Hipparcos orientation and spin values are as follows (see reference): \vspace{2ex} ~~~~~~~~~~~~ \begin{tabular}{|r|r|r|} \hline & \multicolumn{1}{|c}{\it orientation} & \multicolumn{1}{|c|}{\it ~~~spin~~~} \\ \hline $x$ & $-19.9$~~~~ & ~$-0.30$~~ \\ $y$ & $-9.1$~~~~ & ~$+0.60$~~ \\ $z$ & $+22.9$~~~~ & ~$+0.70$~~ \\ \hline & {\it mas}~~~~~ & ~{\it mas/y}~ \\ \hline \end{tabular} \vspace{3ex} These orientation and spin components are interpreted as {\it axial vectors.} An axial vector points at the pole of the rotation and its length is the amount of rotation in radians. \item See also sla\_FK52H, sla\_FK5HZ, sla\_HFK5Z. \end{enumerate} } \aref {Feissel, M.\ \& Mignard, F., 1998., {\it Astron.Astrophys.}\ {\bf 331}, L33-L36.} %----------------------------------------------------------------------- \routine{SLA\_HFK5Z}{Hipparcos to FK5, no P.M.} { \action{Transform a Hipparcos star position into the FK5 (J2000) frame assuming zero Hipparcos proper motion.} \call{CALL sla\_HFK5Z (RH,DH,EPOCH,R5,D5,DR5,DD5)} } \args{GIVEN} { \spec{RH}{D}{Hipparcos $\alpha$ (radians)} \\ \spec{DH}{D}{Hipparcos $\delta$ (radians)} \\ \spec{EPOCH}{D}{Julian epoch (TDB)} } \args{RETURNED} { \spec{R5}{D}{J2000.0 FK5 $\alpha$ (radians)} \\ \spec{D5}{D}{J2000.0 FK5 $\delta$ (radians)} \\ \spec{DR5}{D}{J2000.0 FK5 proper motion in $\alpha$ (radians per Julian year)} \\ \spec{DD5}{D}{FK5 J2000.0 proper motion in $\delta$ (radians per Julian year)} } \notes { \begin{enumerate} \item The $\alpha$ proper motions are $\dot{\alpha}$ rather than $\dot{\alpha}\cos\delta$, and are per year rather than per century. \item The FK5 to Hipparcos transformation consists of a pure rotation and spin; zonal errors in the FK5 catalogue are not taken into account. \item The adopted epoch J2000.0 FK5 to Hipparcos orientation and spin values are as follows (see reference): \vspace{2ex} ~~~~~~~~~~~~ \begin{tabular}{|r|r|r|} \hline & \multicolumn{1}{|c}{\it orientation} & \multicolumn{1}{|c|}{\it ~~~spin~~~} \\ \hline $x$ & $-19.9$~~~~ & ~$-0.30$~~ \\ $y$ & $-9.1$~~~~ & ~$+0.60$~~ \\ $z$ & $+22.9$~~~~ & ~$+0.70$~~ \\ \hline & {\it mas}~~~~~ & ~{\it mas/y}~ \\ \hline \end{tabular} \vspace{3ex} These orientation and spin components are interpreted as {\it axial vectors.} An axial vector points at the pole of the rotation and its length is the amount of rotation in radians. The order of the rotations, which are very small, \item It was the intention that Hipparcos should be a close approximation to an inertial frame, so that distant objects have zero proper motion; such objects have (in general) non-zero proper motion in FK5, and this routine returns those {\it fictitious proper motions.} \item The position returned by this routine is in the FK5 J2000 reference frame but at Julian epoch EPOCH. \item See also sla\_FK52H, sla\_FK5HZ, sla\_H2FK5. \end{enumerate} } \aref {Feissel, M.\ \& Mignard, F., 1998., {\it Astron.Astrophys.}\ {\bf 331}, L33-L36.} %----------------------------------------------------------------------- \routine{SLA\_IMXV}{Apply 3D Reverse Rotation} { \action{Multiply a 3-vector by the inverse of a rotation matrix (single precision).} \call{CALL sla\_IMXV (RM, VA, VB)} } \args{GIVEN} { \spec{RM}{R(3,3)}{rotation matrix} \\ \spec{VA}{R(3)}{vector to be rotated} } \args{RETURNED} { \spec{VB}{R(3)}{result vector} } \notes { \begin{enumerate} \item This routine performs the operation: \begin{verse} {\bf b} = {\bf M}$^{T}\cdot${\bf a} \end{verse} where {\bf a} and {\bf b} are the 3-vectors VA and VB respectively, and {\bf M} is the $3\times3$ matrix RM. \item The main function of this routine is apply an inverse rotation; under these circumstances, ${\bf M}$ is {\it orthogonal}, with its inverse the same as its transpose. \item To comply with the ANSI Fortran 77 standard, VA and VB must {\bf not} be the same array. The routine is, in fact, coded so as to work properly on the VAX and many other systems even if this rule is violated, something that is {\bf not}, however, recommended. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_INTIN}{Decode an Integer Number} { \action{Convert free-format input into an integer.} \call{CALL sla\_INTIN (STRING, NSTRT, IRESLT, JFLAG)} } \args{GIVEN} { \spec{STRING}{C}{string containing number to be decoded} \\ \spec{NSTRT}{I}{pointer to where decoding is to commence} \\ \spec{IRESLT}{I}{current value of result} } \args{RETURNED} { \spec{NSTRT}{I}{advanced to next number} \\ \spec{IRESLT}{I}{result} \\ \spec{JFLAG}{I}{status: $-$1 = $-$OK, 0~=~+OK, 1~=~null result, 2~=~error} } \notes { \begin{enumerate} \item The reason sla\_INTIN has separate `OK' status values for + and $-$ is to enable minus zero to be detected. This is of crucial importance when decoding mixed-radix numbers. For example, an angle expressed as degrees, arcminutes and arcseconds may have a leading minus sign but a zero degrees field. \item A TAB is interpreted as a space. {\it n.b.}\ The test for TAB is ASCII-specific. \item The basic format is the sequence of fields $\pm n$, where $\pm$ is a sign character `+' or `$-$', and $n$ means a string of decimal digits. \item Spaces: \begin{itemize} \item Leading spaces are ignored. \item Spaces between the sign and the number are allowed. \item Trailing spaces are ignored; the first signifies end of decoding and subsequent ones are skipped. \end{itemize} \item Delimiters: \begin{itemize} \item Any character other than +,$-$,0-9 or space may be used to signal the end of the number and terminate decoding. \item Comma is recognized by sla\_INTIN as a special case; it is skipped, leaving the pointer on the next character. See 9, below. \item Decoding will in all cases terminate if end of string is reached. \end{itemize} \item The sign is optional. The default is +. \item A {\it null result}\/ occurs when the string of characters being decoded does not begin with +,$-$ or 0-9, or consists entirely of spaces. When this condition is detected, JFLAG is set to 1 and IRESLT is left untouched. \item NSTRT = 1 for the first character in the string. \item On return from sla\_INTIN, NSTRT is set ready for the next decode -- following trailing blanks and any comma. If a delimiter other than comma is being used, NSTRT must be incremented before the next call to sla\_INTIN, otherwise all subsequent calls will return a null result. \item Errors (JFLAG=2) occur when: \begin{itemize} \item there is a + or $-$ but no number; or \item the number is greater than $2^{31}-1$. \end{itemize} \item When an error has been detected, NSTRT is left pointing to the character following the last one used before the error came to light. \item See also sla\_FLOTIN and sla\_DFLTIN. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_INVF}{Invert Linear Model} { \action{Invert a linear model of the type produced by the sla\_FITXY routine.} \call{CALL sla\_INVF (FWDS,BKWDS,J)} } \args{GIVEN} { \spec{FWDS}{D(6)}{model coefficients} } \args{RETURNED} { \spec{BKWDS}{D(6)}{inverse model} \\ \spec{J}{I}{status: 0 = OK, $-$1 = no inverse} } \notes { \begin{enumerate} \item The models relate two sets of \xy\ coordinates as follows. Naming the six elements of FWDS $a,b,c,d,e$ \& $f$, where two sets of coordinates $[x_{1},y_{1}]$ and $[x_{2},y_{2}\,]$ are related thus: \begin{verse} $x_{2} = a + bx_{1} + cy_{1}$ \\ $y_{2} = d + ex_{1} + fy_{1}$ \end{verse} The present routine generates a new set of coefficients $p,q,r,s,t$ \& $u$ (the array BKWDS) such that: \begin{verse} $x_{1} = p + qx_{2} + ry_{2}$ \\ $y_{1} = s + tx_{2} + uy_{2}$ \end{verse} \item Two successive calls to this routine will deliver a set of coefficients equal to the starting values. \item To comply with the ANSI Fortran 77 standard, FWDS and BKWDS must {\bf not} be the same array. The routine is, in fact, coded so as to work properly on the VAX and many other systems even if this rule is violated, something that is {\bf not}, however, recommended. \item See also sla\_FITXY, sla\_PXY, sla\_XY2XY, sla\_DCMPF. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_KBJ}{Select Epoch Prefix} { \action{Select epoch prefix `B' or `J'.} \call{CALL sla\_KBJ (JB, E, K, J)} } \args{GIVEN} { \spec{JB}{I}{sla\_DBJIN prefix status: 0=none, 1=`B', 2=`J'} \\ \spec{E}{D}{epoch -- Besselian or Julian} } \args{RETURNED} { \spec{K}{C}{`B' or `J'} \\ \spec{J}{I}{status: 0=OK} } \anote{The routine is mainly intended for use in conjunction with the sla\_DBJIN routine. If the value of JB indicates that an explicit B or J prefix was detected by sla\_DBJIN, a `B' or `J' is returned to match. If JB indicates that no explicit B or J was supplied, the choice is made on the basis of the epoch itself; B is assumed for E $<1984$, otherwise J.} %----------------------------------------------------------------------- \routine{SLA\_M2AV}{Rotation Matrix to Axial Vector} { \action{From a rotation matrix, determine the corresponding axial vector (single precision).} \call{CALL sla\_M2AV (RMAT, AXVEC)} } \args{GIVEN} { \spec{RMAT}{R(3,3)}{rotation matrix} } \args{RETURNED} { \spec{AXVEC}{R(3)}{axial vector (radians)} } \notes { \begin{enumerate} \item A rotation matrix describes a rotation about some arbitrary axis. The axis is called the {\it Euler axis}, and the angle through which the reference frame rotates is called the {\it Euler angle}. The {\it axial vector}\/ returned by this routine has the same direction as the Euler axis, and its magnitude is the Euler angle in radians. \item The magnitude and direction of the axial vector can be separated by means of the routine sla\_VN. \item The reference frame rotates clockwise as seen looking along the axial vector from the origin. \item If RMAT is null, so is the result. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_MAP}{Mean to Apparent} { \action{Transform star \radec\ from mean place to geocentric apparent. The reference frames and timescales used are post IAU~1976.} \call{CALL sla\_MAP (RM, DM, PR, PD, PX, RV, EQ, DATE, RA, DA)} } \args{GIVEN} { \spec{RM,DM}{D}{mean \radec\ (radians)} \\ \spec{PR,PD}{D}{proper motions: \radec\ changes per Julian year} \\ \spec{PX}{D}{parallax (arcsec)} \\ \spec{RV}{D}{radial velocity (km~s$^{-1}$, +ve if receding)} \\ \spec{EQ}{D}{epoch and equinox of star data (Julian)} \\ \spec{DATE}{D}{TDB for apparent place (JD$-$2400000.5)} } \args{RETURNED} { \spec{RA,DA}{D}{apparent \radec\ (radians)} } \notes { \begin{enumerate} \item EQ is the Julian epoch specifying both the reference frame and the epoch of the position -- usually 2000. For positions where the epoch and equinox are different, use the routine sla\_PM to apply proper motion corrections before using this routine. \item The distinction between the required TDB and TT is always negligible. Moreover, for all but the most critical applications UTC is adequate. \item The $\alpha$ proper motions are $\dot{\alpha}$ rather than $\dot{\alpha}\cos\delta$, and are per year rather than per century. \item This routine may be wasteful for some applications because it recomputes the Earth position/velocity and the precession/nutation matrix each time, and because it allows for parallax and proper motion. Where multiple transformations are to be carried out for one epoch, a faster method is to call the sla\_MAPPA routine once and then either the sla\_MAPQK routine (which includes parallax and proper motion) or sla\_MAPQKZ (which assumes zero parallax and FK5 proper motion). \end{enumerate} } \refs { \begin{enumerate} \item 1984 {\it Astronomical Almanac}, pp B39-B41. \item Lederle \& Schwan, 1984.\ {\it Astr.Astrophys.}\ {\bf 134}, 1-6. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_MAPPA}{Mean to Apparent Parameters} { \action{Compute star-independent parameters in preparation for conversions between mean place and geocentric apparent place. The parameters produced by this routine are required in the parallax, light deflection, aberration, and precession/nutation parts of the mean/apparent transformations. The reference frames and timescales used are post IAU~1976.} \call{CALL sla\_MAPPA (EQ, DATE, AMPRMS)} } \args{GIVEN} { \spec{EQ}{D}{epoch of mean equinox to be used (Julian)} \\ \spec{DATE}{D}{TDB (JD$-$2400000.5)} } \args{RETURNED} { \spec{AMPRMS}{D(21)}{star-independent mean-to-apparent parameters:} \\ \specel {(1)} {time interval for proper motion (Julian years)} \\ \specel {(2-4)} {barycentric position of the Earth (AU)} \\ \specel {(5-7)} {heliocentric direction of the Earth (unit vector)} \\ \specel {(8)} {(gravitational radius of Sun)$\times 2 / $(Sun-Earth distance)} \\ \specel {(9-11)} {{\bf v}: barycentric Earth velocity in units of c} \\ \specel {(12)} {$\sqrt{1-\left|\mbox{\bf v}\right|^2}$} \\ \specel {(13-21)} {precession/nutation $3\times3$ matrix} } \notes { \begin{enumerate} \item For DATE, the distinction between the required TDB and TT is always negligible. Moreover, for all but the most critical applications UTC is adequate. \item The accuracy of the routines using the parameters AMPRMS is limited by the routine sla\_EVP, used here to compute the Earth position and velocity by the methods of Stumpff. The maximum error in the resulting aberration corrections is about 0.3 milliarcsecond. \item The vectors AMPRMS(2-4) and AMPRMS(5-7) are referred to the mean equinox and equator of epoch EQ. \item The parameters produced by this routine are used by sla\_MAPQK and sla\_MAPQKZ. \end{enumerate} } \refs { \begin{enumerate} \item 1984 {\it Astronomical Almanac}, pp B39-B41. \item Lederle \& Schwan, 1984.\ {\it Astr.Astrophys.}\ {\bf 134}, 1-6. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_MAPQK}{Quick Mean to Apparent} { \action{Quick mean to apparent place: transform a star \radec\ from mean place to geocentric apparent place, given the star-independent parameters. The reference frames and timescales used are post IAU 1976.} \call{CALL sla\_MAPQK (RM, DM, PR, PD, PX, RV, AMPRMS, RA, DA)} } \args{GIVEN} { \spec{RM,DM}{D}{mean \radec\ (radians)} \\ \spec{PR,PD}{D}{proper motions: \radec\ changes per Julian year} \\ \spec{PX}{D}{parallax (arcsec)} \\ \spec{RV}{D}{radial velocity (km~s$^{-1}$, +ve if receding)} \\ \spec{AMPRMS}{D(21)}{star-independent mean-to-apparent parameters:} \\ \specel {(1)} {time interval for proper motion (Julian years)} \\ \specel {(2-4)} {barycentric position of the Earth (AU)} \\ \specel {(5-7)} {heliocentric direction of the Earth (unit vector)} \\ \specel {(8)} {(gravitational radius of Sun)$\times 2 / $(Sun-Earth distance)} \\ \specel {(9-11)} {{\bf v}: barycentric Earth velocity in units of c} \\ \specel {(12)} {$\sqrt{1-\left|\mbox{\bf v}\right|^2}$} \\ \specel {(13-21)} {precession/nutation $3\times3$ matrix} } \args{RETURNED} { \spec{RA,DA}{D }{apparent \radec\ (radians)} } \notes { \begin{enumerate} \item Use of this routine is appropriate when efficiency is important and where many star positions, all referred to the same equator and equinox, are to be transformed for one epoch. The star-independent parameters can be obtained by calling the sla\_MAPPA routine. \item If the parallax and proper motions are zero the sla\_MAPQKZ routine can be used instead. \item The vectors AMPRMS(2-4) and AMPRMS(5-7) are referred to the mean equinox and equator of epoch EQ. \item Strictly speaking, the routine is not valid for solar-system sources, though the error will usually be extremely small. However, to prevent gross errors in the case where the position of the Sun is specified, the gravitational deflection term is restrained within about \arcseci{920} of the centre of the Sun's disc. The term has a maximum value of about \arcsec{1}{85} at this radius, and decreases to zero as the centre of the disc is approached. \end{enumerate} } \refs { \begin{enumerate} \item 1984 {\it Astronomical Almanac}, pp B39-B41. \item Lederle \& Schwan, 1984.\ {\it Astr.Astrophys.}\ {\bf 134}, 1-6. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_MAPQKZ}{Quick Mean-Appt, no PM {\it etc.}} { \action{Quick mean to apparent place: transform a star \radec\ from mean place to geocentric apparent place, given the star-independent parameters, and assuming zero parallax and FK5 proper motion. The reference frames and timescales used are post IAU~1976.} \call{CALL sla\_MAPQKZ (RM, DM, AMPRMS, RA, DA)} } \args{GIVEN} { \spec{RM,DM}{D}{mean \radec\ (radians)} \\ \spec{AMPRMS}{D(21)}{star-independent mean-to-apparent parameters:} \\ \specel {(1)} {time interval for proper motion (Julian years)} \\ \specel {(2-4)} {barycentric position of the Earth (AU)} \\ \specel {(5-7)} {heliocentric direction of the Earth (unit vector)} \\ \specel {(8)} {(gravitational radius of Sun)$\times 2 / $(Sun-Earth distance)} \\ \specel {(9-11)} {{\bf v}: barycentric Earth velocity in units of c} \\ \specel {(12)} {$\sqrt{1-\left|\mbox{\bf v}\right|^2}$} \\ \specel {(13-21)} {precession/nutation $3\times3$ matrix} } \args{RETURNED} { \spec{RA,DA}{D}{apparent \radec\ (radians)} } \notes { \begin{enumerate} \item Use of this routine is appropriate when efficiency is important and where many star positions, all with parallax and proper motion either zero or already allowed for, and all referred to the same equator and equinox, are to be transformed for one epoch. The star-independent parameters can be obtained by calling the sla\_MAPPA routine. \item The corresponding routine for the case of non-zero parallax and FK5 proper motion is sla\_MAPQK. \item The vectors AMPRMS(2-4) and AMPRMS(5-7) are referred to the mean equinox and equator of epoch EQ. \item Strictly speaking, the routine is not valid for solar-system sources, though the error will usually be extremely small. However, to prevent gross errors in the case where the position of the Sun is specified, the gravitational deflection term is restrained within about \arcseci{920} of the centre of the Sun's disc. The term has a maximum value of about \arcsec{1}{85} at this radius, and decreases to zero as the centre of the disc is approached. \end{enumerate} } \refs { \begin{enumerate} \item 1984 {\it Astronomical Almanac}, pp B39-B41. \item Lederle \& Schwan, 1984.\ {\it Astr.Astrophys.}\ {\bf 134}, 1-6. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_MOON}{Approx Moon Pos/Vel} { \action{Approximate geocentric position and velocity of the Moon (single precision).} \call{CALL sla\_MOON (IY, ID, FD, PV)} } \args{GIVEN} { \spec{IY}{I}{year} \\ \spec{ID}{I}{day in year (1 = Jan 1st)} \\ \spec{FD}{R }{fraction of day} } \args{RETURNED} { \spec{PV}{R(6)}{Moon \xyzxyzd, mean equator and equinox of date (AU, AU~s$^{-1}$)} } \notes { \begin{enumerate} \item The date and time is TDB (loosely ET) in a Julian calendar which has been aligned to the ordinary Gregorian calendar for the interval 1900 March 1 to 2100 February 28. The year and day can be obtained by calling sla\_CALYD or sla\_CLYD. \item The position is accurate to better than 0.5~arcminute in direction and 1000~km in distance. The velocity is accurate to better than \arcsec{0}{5} per hour in direction and 4~metres per socond in distance. (RMS figures with respect to JPL DE200 for the interval 1960-2025 are \arcseci{14} and \arcsec{0}{2} per hour in longitude, \arcseci{9} and \arcsec{0}{2} per hour in latitude, 350~km and 2~metres per second in distance.) Note that the distance accuracy is comparatively poor because this routine is principally intended for computing topocentric direction. \item This routine is only a partial implementation of the original Meeus algorithm (reference below), which offers 4 times the accuracy in direction and 20 times the accuracy in distance when fully implemented (as it is in sla\_DMOON). \end{enumerate} } \aref{Meeus, {\it l'Astronomie}, June 1984, p348.} %----------------------------------------------------------------------- \routine{SLA\_MXM}{Multiply $3\times3$ Matrices} { \action{Product of two $3\times3$ matrices (single precision).} \call{CALL sla\_MXM (A, B, C)} } \args{GIVEN} { \spec{A}{R(3,3)}{matrix {\bf A}} \\ \spec{B}{R(3,3)}{matrix {\bf B}} } \args{RETURNED} { \spec{C}{R(3,3)}{matrix result: {\bf A}$\times${\bf B}} } \anote{To comply with the ANSI Fortran 77 standard, A, B and C must be different arrays. The routine is, in fact, coded so as to work properly on the VAX and many other systems even if this rule is violated, something that is {\bf not}, however, recommended.} %----------------------------------------------------------------------- \routine{SLA\_MXV}{Apply 3D Rotation} { \action{Multiply a 3-vector by a rotation matrix (single precision).} \call{CALL sla\_MXV (RM, VA, VB)} } \args{GIVEN} { \spec{RM}{R(3,3)}{rotation matrix} \\ \spec{VA}{R(3)}{vector to be rotated} } \args{RETURNED} { \spec{VB}{R(3)}{result vector} } \notes { \begin{enumerate} \item This routine performs the operation: \begin{verse} {\bf b} = {\bf M}$\cdot${\bf a} \end{verse} where {\bf a} and {\bf b} are the 3-vectors VA and VB respectively, and {\bf M} is the $3\times3$ matrix RM. \item The main function of this routine is apply a rotation; under these circumstances, ${\bf M}$ is a {\it proper real orthogonal}\/ matrix. \item To comply with the ANSI Fortran 77 standard, VA and VB must {\bf not} be the same array. The routine is, in fact, coded so as to work properly on the VAX and many other systems even if this rule is violated, something that is {\bf not}, however, recommended. \end{enumerate} } %------------------------------------------------------------------------------ \routine{SLA\_NUT}{Nutation Matrix} { \action{Form the matrix of nutation (IAU 1980 theory) for a given date.} \call{CALL sla\_NUT (DATE, RMATN)} } \args{GIVEN} { \spec{DATE}{D}{TDB (formerly ET) as Modified Julian Date (JD$-$2400000.5)} } \args{RETURNED} { \spec{RMATN}{D(3,3)}{nutation matrix} } \anote{The matrix is in the sense: \begin{verse} {\bf v}$_{true}$ = {\bf M}$\cdot${\bf v}$_{mean}$ \end{verse} where {\bf v}$_{true}$ is the star vector relative to the true equator and equinox of date, {\bf M} is the $3\times3$ matrix RMATN and {\bf v}$_{mean}$ is the star vector relative to the mean equator and equinox of date.} \refs { \begin{enumerate} \item Final report of the IAU Working Group on Nutation, chairman P.K.Seidelmann, 1980. \item Kaplan, G.H., 1981.\ {\it USNO circular No.\ 163}, pA3-6. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_NUTC}{Nutation Components} { \action{Nutation (IAU 1980 theory): longitude \& obliquity components, and mean obliquity.} \call{CALL sla\_NUTC (DATE, DPSI, DEPS, EPS0)} } \args{GIVEN} { \spec{DATE}{D}{TDB (formerly ET) as Modified Julian Date (JD$-$2400000.5)} } \args{RETURNED} { \spec{DPSI,DEPS}{D}{nutation in longitude and obliquity (radians)} \\ \spec{EPS0}{D}{mean obliquity (radians)} } \refs { \begin{enumerate} \item Final report of the IAU Working Group on Nutation, chairman P.K.Seidelmann, 1980. \item Kaplan, G.H., 1981.\ {\it USNO circular no.\ 163}, pA3-6. \end{enumerate} } %------------------------------------------------------------------------------ \routine{SLA\_OAP}{Observed to Apparent} { \action{Observed to apparent place.} \call{CALL sla\_OAP (\vtop{ \hbox{TYPE, OB1, OB2, DATE, DUT, ELONGM, PHIM,} \hbox{HM, XP, YP, TDK, PMB, RH, WL, TLR, RAP, DAP)}}} } \args{GIVEN} { \spec{TYPE}{C*(*)}{type of coordinates -- `R', `H' or `A' (see below)} \\ \spec{OB1}{D}{observed Az, HA or RA (radians; Az is N=0, E=$90^{\circ}$)} \\ \spec{OB2}{D}{observed zenith distance or $\delta$ (radians)} \\ \spec{DATE}{D }{UTC date/time (Modified Julian Date, JD$-$2400000.5)} \\ \spec{DUT}{D}{$\Delta$UT: UT1$-$UTC (UTC seconds)} \\ \spec{ELONGM}{D}{observer's mean longitude (radians, east +ve)} \\ \spec{PHIM}{D}{observer's mean geodetic latitude (radians)} \\ \spec{HM}{D}{observer's height above sea level (metres)} \\ \spec{XP,YP}{D}{polar motion \xy\ coordinates (radians)} \\ \spec{TDK}{D}{local ambient temperature (degrees K; std=273.155D0)} \\ \spec{PMB}{D}{local atmospheric pressure (mB; std=1013.25D0)} \\ \spec{RH}{D}{local relative humidity (in the range 0D0\,--\,1D0)} \\ \spec{WL}{D}{effective wavelength ($\mu{\rm m}$, {\it e.g.}\ 0.55D0)} \\ \spec{TLR}{D}{tropospheric lapse rate (degrees K per metre, {\it e.g.}\ 0.0065D0)} } \args{RETURNED} { \spec{RAP,DAP}{D}{geocentric apparent \radec} } \notes { \begin{enumerate} \item Only the first character of the TYPE argument is significant. `R' or `r' indicates that OBS1 and OBS2 are the observed Right Ascension and Declination; `H' or `h' indicates that they are Hour Angle (west +ve) and Declination; anything else (`A' or `a' is recommended) indicates that OBS1 and OBS2 are Azimuth (north zero, east is $90^{\circ}$) and Zenith Distance. (Zenith distance is used rather than elevation in order to reflect the fact that no allowance is made for depression of the horizon.) \item The accuracy of the result is limited by the corrections for refraction. Providing the meteorological parameters are known accurately and there are no gross local effects, the predicted azimuth and elevation should be within about \arcsec{0}{1} for $\zeta<70^{\circ}$. Even at a topocentric zenith distance of $90^{\circ}$, the accuracy in elevation should be better than 1~arcminute; useful results are available for a further $3^{\circ}$, beyond which the sla\_REFRO routine returns a fixed value of the refraction. The complementary routines sla\_AOP (or sla\_AOPQK) and sla\_OAP (or sla\_OAPQK) are self-consistent to better than 1~microarcsecond all over the celestial sphere. \item It is advisable to take great care with units, as even unlikely values of the input parameters are accepted and processed in accordance with the models used. \item {\it Observed}\/ \azel\ means the position that would be seen by a perfect theodolite located at the observer. This is related to the observed \hadec\ via the standard rotation, using the geodetic latitude (corrected for polar motion), while the observed HA and RA are related simply through the local apparent ST. {\it Observed}\/ \radec\ or \hadec\ thus means the position that would be seen by a perfect equatorial located at the observer and with its polar axis aligned to the Earth's axis of rotation ({\it n.b.}\ not to the refracted pole). By removing from the observed place the effects of atmospheric refraction and diurnal aberration, the geocentric apparent \radec\ is obtained. \item Frequently, {\it mean}\/ rather than {\it apparent}\, \radec\ will be required, in which case further transformations will be necessary. The sla\_AMP {\it etc.}\ routines will convert the apparent \radec\ produced by the present routine into an FK5 J2000 mean place, by allowing for the Sun's gravitational lens effect, annual aberration, nutation and precession. Should FK4 B1950 coordinates be needed, the routines sla\_FK524 {\it etc.}\ will also need to be applied. \item To convert to apparent \radec\ the coordinates read from a real telescope, corrections would have to be applied for encoder zero points, gear and encoder errors, tube flexure, the position of the rotator axis and the pointing axis relative to it, non-perpendicularity between the mounting axes, and finally for the tilt of the azimuth or polar axis of the mounting (with appropriate corrections for mount flexures). Some telescopes would, of course, exhibit other properties which would need to be accounted for at the appropriate point in the sequence. \item The star-independent apparent-to-observed-place parameters in AOPRMS may be computed by means of the sla\_AOPPA routine. If nothing has changed significantly except the time, the sla\_AOPPAT routine may be used to perform the requisite partial recomputation of AOPRMS. \item The DATE argument is UTC expressed as an MJD. This is, strictly speaking, wrong, because of leap seconds. However, as long as the $\Delta$UT and the UTC are consistent there are no difficulties, except during a leap second. In this case, the start of the 61st second of the final minute should begin a new MJD day and the old pre-leap $\Delta$UT should continue to be used. As the 61st second completes, the MJD should revert to the start of the day as, simultaneously, the $\Delta$UT changes by one second to its post-leap new value. \item The $\Delta$UT (UT1$-$UTC) is tabulated in IERS circulars and elsewhere. It increases by exactly one second at the end of each UTC leap second, introduced in order to keep $\Delta$UT within $\pm$\tsec{0}{9}. \item IMPORTANT -- TAKE CARE WITH THE LONGITUDE SIGN CONVENTION. The longitude required by the present routine is {\bf east-positive}, in accordance with geographical convention (and right-handed). In particular, note that the longitudes returned by the sla\_OBS routine are west-positive (as in the {\it Astronomical Almanac}\/ before 1984) and must be reversed in sign before use in the present routine. \item The polar coordinates XP,YP can be obtained from IERS circulars and equivalent publications. The maximum amplitude is about \arcsec{0}{3}. If XP,YP values are unavailable, use XP=YP=0D0. See page B60 of the 1988 {\it Astronomical Almanac}\/ for a definition of the two angles. \item The height above sea level of the observing station, HM, can be obtained from the {\it Astronomical Almanac}\/ (Section J in the 1988 edition), or via the routine sla\_OBS. If P, the pressure in mB, is available, an adequate estimate of HM can be obtained from the following expression: \begin{quote} {\tt HM=-29.3D0*TSL*LOG(P/1013.25D0)} \end{quote} where TSL is the approximate sea-level air temperature in degrees K (see {\it Astrophysical Quantities}, C.W.Allen, 3rd~edition, \S 52). Similarly, if the pressure P is not known, it can be estimated from the height of the observing station, HM as follows: \begin{quote} {\tt P=1013.25D0*EXP(-HM/(29.3D0*TSL))} \end{quote} Note, however, that the refraction is proportional to the pressure and that an accurate P value is important for precise work. \item The azimuths {\it etc.}\ used by the present routine are with respect to the celestial pole. Corrections from the terrestrial pole can be computed using sla\_POLMO. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_OAPQK}{Quick Observed to Apparent} { \action{Quick observed to apparent place.} \call{CALL sla\_OAPQK (TYPE, OB1, OB2, AOPRMS, RAP, DAP)} } \args{GIVEN} { \spec{TYPE}{C*(*)}{type of coordinates -- `R', `H' or `A' (see below)} \\ \spec{OB1}{D}{observed Az, HA or RA (radians; Az is N=0, E=$90^{\circ}$)} \\ \spec{OB2}{D}{observed zenith distance or $\delta$ (radians)} \\ \spec{AOPRMS}{D(14)}{star-independent apparent-to-observed parameters:} \\ \specel {(1)} {geodetic latitude (radians)} \\ \specel {(2,3)} {sine and cosine of geodetic latitude} \\ \specel {(4)} {magnitude of diurnal aberration vector} \\ \specel {(5)} {height (HM)} \\ \specel {(6)} {ambient temperature (TDK)} \\ \specel {(7)} {pressure (PMB)} \\ \specel {(8)} {relative humidity (RH)} \\ \specel {(9)} {wavelength (WL)} \\ \specel {(10)} {lapse rate (TLR)} \\ \specel {(11,12)} {refraction constants A and B (radians)} \\ \specel {(13)} {longitude + eqn of equinoxes + ``sidereal $\Delta$UT'' (radians)} \\ \specel {(14)} {local apparent sidereal time (radians)} } \args{RETURNED} { \spec{RAP,DAP}{D}{geocentric apparent \radec} } \notes { \begin{enumerate} \item Only the first character of the TYPE argument is significant. `R' or `r' indicates that OBS1 and OBS2 are the observed Right Ascension and Declination; `H' or `h' indicates that they are Hour Angle (west +ve) and Declination; anything else (`A' or `a' is recommended) indicates that OBS1 and OBS2 are Azimuth (north zero, east is $90^{\circ}$) and Zenith Distance. (Zenith distance is used rather than elevation in order to reflect the fact that no allowance is made for depression of the horizon.) \item The accuracy of the result is limited by the corrections for refraction. Providing the meteorological parameters are known accurately and there are no gross local effects, the predicted azimuth and elevation should be within about \arcsec{0}{1} for $\zeta<70^{\circ}$. Even at a topocentric zenith distance of $90^{\circ}$, the accuracy in elevation should be better than 1~arcminute; useful results are available for a further $3^{\circ}$, beyond which the sla\_REFRO routine returns a fixed value of the refraction. The complementary routines sla\_AOP (or sla\_AOPQK) and sla\_OAP (or sla\_OAPQK) are self-consistent to better than 1~microarcsecond all over the celestial sphere. \item It is advisable to take great care with units, as even unlikely values of the input parameters are accepted and processed in accordance with the models used. \item {\it Observed}\/ \azel\ means the position that would be seen by a perfect theodolite located at the observer. This is related to the observed \hadec\ via the standard rotation, using the geodetic latitude (corrected for polar motion), while the observed HA and RA are related simply through the local apparent ST. {\it Observed}\/ \radec\ or \hadec\ thus means the position that would be seen by a perfect equatorial located at the observer and with its polar axis aligned to the Earth's axis of rotation ({\it n.b.}\ not to the refracted pole). By removing from the observed place the effects of atmospheric refraction and diurnal aberration, the geocentric apparent \radec\ is obtained. \item Frequently, {\it mean}\/ rather than {\it apparent}\, \radec\ will be required, in which case further transformations will be necessary. The sla\_AMP {\it etc.}\ routines will convert the apparent \radec\ produced by the present routine into an FK5 J2000 mean place, by allowing for the Sun's gravitational lens effect, annual aberration, nutation and precession. Should FK4 B1950 coordinates be needed, the routines sla\_FK524 {\it etc.}\ will also need to be applied. \item To convert to apparent \radec\ the coordinates read from a real telescope, corrections would have to be applied for encoder zero points, gear and encoder errors, tube flexure, the position of the rotator axis and the pointing axis relative to it, non-perpendicularity between the mounting axes, and finally for the tilt of the azimuth or polar axis of the mounting (with appropriate corrections for mount flexures). Some telescopes would, of course, exhibit other properties which would need to be accounted for at the appropriate point in the sequence. \item The star-independent apparent-to-observed-place parameters in AOPRMS may be computed by means of the sla\_AOPPA routine. If nothing has changed significantly except the time, the sla\_AOPPAT routine may be used to perform the requisite partial recomputation of AOPRMS. \item The azimuths {\it etc.}\ used by the present routine are with respect to the celestial pole. Corrections from the terrestrial pole can be computed using sla\_POLMO. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_OBS}{Observatory Parameters} { \action{Look up an entry in a standard list of groundbased observing stations parameters.} \call{CALL sla\_OBS (N, C, NAME, W, P, H)} } \args{GIVEN} { \spec{N}{I}{number specifying observing station} } \args{GIVEN or RETURNED} { \spec{C}{C*(*)}{identifier specifying observing station} } \args{RETURNED} { \spec{NAME}{C*(*)}{name of specified observing station} \\ \spec{W}{D}{longitude (radians, west +ve)} \\ \spec{P}{D}{geodetic latitude (radians, north +ve)} \\ \spec{H}{D}{height above sea level (metres)} } \notes { \begin{enumerate} \item Station identifiers C may be up to 10 characters long, and station names NAME may be up to 40 characters long. \item C and N are {\it alternative}\/ ways of specifying the observing station. The C option, which is the most generally useful, may be selected by specifying an N value of zero or less. If N is 1 or more, the parameters of the Nth station in the currently supported list are interrogated, and the station identifier C is returned as well as NAME, W, P and H. \item If the station parameters are not available, either because the station identifier C is not recognized, or because an N value greater than the number of stations supported is given, a name of `?' is returned and W, P and H are left in their current states. \item Programs can obtain a list of all currently supported stations by calling the routine repeatedly, with N=1,2,3... When NAME=`?' is seen, the list of stations has been exhausted. The stations at the time of writing are listed below. \item Station numbers, identifiers, names and other details are subject to change and should not be hardwired into application programs. \item All station identifiers C are uppercase only; lower case characters must be converted to uppercase by the calling program. The station names returned may contain both upper- and lowercase. All characters up to the first space are checked; thus an abbreviated ID will return the parameters for the first station in the list which matches the abbreviation supplied, and no station in the list will ever contain embedded spaces. C must not have leading spaces. \item IMPORTANT -- BEWARE OF THE LONGITUDE SIGN CONVENTION. The longitude returned by sla\_OBS is {\bf west-positive}, following the pre-1984 {\it Astronomical Almanac}. However, this sign convention is left-handed and is the opposite of the one now used; elsewhere in SLALIB the preferable east-positive convention is used. In particular, note that for use in sla\_AOP, sla\_AOPPA and sla\_OAP the sign of the longitude must be reversed. \item Users are urged to inform the author of any improvements they would like to see made. For example: \begin{itemize} \item typographical corrections \item more accurate parameters \item better station identifiers or names \item additional stations \end{itemize} \end{enumerate} Stations supported by sla\_OBS at the time of writing: \begin{tabbing} xxxxxxxxxxxxxxxxx \= \kill {\it ID} \> {\it NAME} \\ \\ AAT \> Anglo-Australian 3.9m Telescope \\ ANU2.3 \> Siding Spring 2.3 metre \\ APO3.5 \> Apache Point 3.5m \\ ARECIBO \> Arecibo 1000 foot \\ ATCA \> Australia Telescope Compact Array \\ BLOEMF \> Bloemfontein 1.52 metre \\ BOSQALEGRE \> Bosque Alegre 1.54 metre \\ CAMB1MILE \> Cambridge 1 mile \\ CAMB5KM \> Cambridge 5km \\ CATALINA61 \> Catalina 61 inch \\ CFHT \> Canada-France-Hawaii 3.6m Telescope \\ CSO \> Caltech Sub-mm Observatory, Mauna Kea \\ DAO72 \> DAO Victoria BC 1.85 metre \\ DUNLAP74 \> David Dunlap 74 inch \\ DUPONT \> Du Pont 2.5m Telescope, Las Campanas \\ EFFELSBERG \> Effelsberg 100 metre \\ ESO3.6 \> ESO 3.6 metre \\ ESONTT \> ESO 3.5 metre NTT \\ ESOSCHM \> ESO 1 metre Schmidt, La Silla \\ FCRAO \> Five College Radio Astronomy Obs \\ FLAGSTF61 \> USNO 61 inch astrograph, Flagstaff \\ GBVA140 \> Greenbank 140 foot \\ GBVA300 \> Greenbank 300 foot \\ GEMININ \> Gemini North 8-m telescope \\ HARVARD \> Harvard College Observatory 1.55m \\ HPROV1.52 \> Haute Provence 1.52 metre \\ HPROV1.93 \> Haute Provence 1.93 metre \\ IRTF \> NASA IR Telescope Facility, Mauna Kea \\ JCMT \> JCMT 15 metre \\ JODRELL1 \> Jodrell Bank 250 foot \\ KECK1 \> Keck 10m Telescope 1 \\ KECK2 \> Keck 10m Telescope 2 \\ KISO \> Kiso 1.05 metre Schmidt, Japan \\ KOTTAMIA \> Kottamia 74 inch \\ KPNO158 \> Kitt Peak 158 inch \\ KPNO36FT \> Kitt Peak 36 foot \\ KPNO84 \> Kitt Peak 84 inch \\ KPNO90 \> Kitt Peak 90 inch \\ LICK120 \> Lick 120 inch \\ LOWELL72 \> Perkins 72 inch, Lowell \\ LPO1 \> Jacobus Kapteyn 1m Telescope \\ LPO2.5 \> Isaac Newton 2.5m Telescope \\ LPO4.2 \> William Herschel 4.2m Telescope \\ MAUNAK88 \> Mauna Kea 88 inch \\ MCDONLD2.1 \> McDonald 2.1 metre \\ MCDONLD2.7 \> McDonald 2.7 metre \\ MMT \> MMT, Mt Hopkins \\ MOPRA \> ATNF Mopra Observatory \\ MTEKAR \> Mt Ekar 1.82 metre \\ MTHOP1.5 \> Mt Hopkins 1.5 metre \\ MTLEMMON60 \> Mt Lemmon 60 inch \\ NOBEYAMA \> Nobeyama 45 metre \\ OKAYAMA \> Okayama 1.88 metre \\ PALOMAR200 \> Palomar 200 inch \\ PALOMAR48 \> Palomar 48-inch Schmidt \\ PALOMAR60 \> Palomar 60 inch \\ PARKES \> Parkes 64 metre \\ QUEBEC1.6 \> Quebec 1.6 metre \\ SAAO74 \> Sutherland 74 inch \\ SANPM83 \> San Pedro Martir 83 inch \\ ST.ANDREWS \> St Andrews University Observatory \\ STEWARD90 \> Steward 90 inch \\ STROMLO74 \> Mount Stromlo 74 inch \\ SUBARU \> Subaru 8 metre \\ SUGARGROVE \> Sugar Grove 150 foot \\ TAUTNBG \> Tautenburg 2 metre \\ TAUTSCHM \> Tautenberg 1.34 metre Schmidt \\ TIDBINBLA \> Tidbinbilla 64 metre \\ TOLOLO1.5M \> Cerro Tololo 1.5 metre \\ TOLOLO4M \> Cerro Tololo 4 metre \\ UKIRT \> UK Infra Red Telescope \\ UKST \> UK 1.2 metre Schmidt, Siding Spring \\ USSR6 \> USSR 6 metre \\ USSR600 \> USSR 600 foot \\ VLA \> Very Large Array \end{tabbing} } %----------------------------------------------------------------------- \routine{SLA\_PA}{$h,\delta$ to Parallactic Angle} { \action{Hour angle and declination to parallactic angle (double precision).} \call{D~=~sla\_PA (HA, DEC, PHI)} } \args{GIVEN} { \spec{HA}{D}{hour angle in radians (geocentric apparent)} \\ \spec{DEC}{D}{declination in radians (geocentric apparent)} \\ \spec{PHI}{D}{latitude in radians (geodetic)} } \args{RETURNED} { \spec{sla\_PA}{D}{parallactic angle (radians, in the range $\pm \pi$)} } \notes { \begin{enumerate} \item The parallactic angle at a point in the sky is the position angle of the vertical, {\it i.e.}\ the angle between the direction to the pole and to the zenith. In precise applications care must be taken only to use geocentric apparent \hadec\ and to consider separately the effects of atmospheric refraction and telescope mount errors. \item At the pole a zero result is returned. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_PAV}{Position-Angle Between Two Directions} { \action{Returns the bearing (position angle) of one celestial direction with respect to another (single precision).} \call{R~=~sla\_PAV (V1, V2)} } \args{GIVEN} { \spec{V1}{R(3)}{direction cosines of one point} \\ \spec{V2}{R(3)}{directions cosines of the other point} } \args{RETURNED} { \spec{sla\_PAV}{R}{position-angle of 2nd point with respect to 1st} } \notes { \begin{enumerate} \item The coordinate frames correspond to \radec, $[\lambda,\phi]$ {\it etc.}. \item The result is the bearing (position angle), in radians, of point V2 as seen from point V1. It is in the range $\pm \pi$. The sense is such that if V2 is a small distance due east of V1 the result is about $+\pi/2$. Zero is returned if the two points are coincident. \item The routine sla\_BEAR performs an equivalent function except that the points are specified in the form of spherical coordinates. \end{enumerate} } %------------------------------------------------------------------------------ \routine{SLA\_PCD}{Apply Radial Distortion} { \action{Apply pincushion/barrel distortion to a tangent-plane \xy.} \call{CALL sla\_PCD (DISCO,X,Y)} } \args{GIVEN} { \spec{DISCO}{D}{pincushion/barrel distortion coefficient} \\ \spec{X,Y}{D}{tangent-plane \xy} } \args{RETURNED} { \spec{X,Y}{D}{distorted \xy} } \notes { \begin{enumerate} \item The distortion is of the form $\rho = r (1 + c r^{2})$, where $r$ is the radial distance from the tangent point, $c$ is the DISCO argument, and $\rho$ is the radial distance in the presence of the distortion. \item For {\it pincushion}\/ distortion, C is +ve; for {\it barrel}\/ distortion, C is $-$ve. \item For X,Y in units of one projection radius (in the case of a photographic plate, the focal length), the following DISCO values apply: \vspace{2ex} \hspace{5em} \begin{tabular}{|l|c|} \hline Geometry & DISCO \\ \hline \hline astrograph & 0.0 \\ \hline Schmidt & $-$0.3333 \\ \hline AAT PF doublet & +147.069 \\ \hline AAT PF triplet & +178.585 \\ \hline AAT f/8 & +21.20 \\ \hline JKT f/8 & +14.6 \\ \hline \end{tabular} \vspace{2ex} \item There is a companion routine, sla\_UNPCD, which performs an approximately inverse operation. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_PDA2H}{H.A.\ for a Given Azimuth} { \action{Hour Angle corresponding to a given azimuth (double precision).} \call{CALL sla\_PDA2H (P, D, A, H1, J1, H2, J2)} } \args{GIVEN} { \spec{P}{D}{latitude} \\ \spec{D}{D}{declination} \\ \spec{A}{D}{azimuth} } \args{RETURNED} { \spec{H1}{D}{hour angle: first solution if any} \\ \spec{J1}{I}{flag: 0 = solution 1 is valid} \\ \spec{H2}{D}{hour angle: second solution if any} \\ \spec{J2}{I}{flag: 0 = solution 2 is valid} } %----------------------------------------------------------------------- \routine{SLA\_PDQ2H}{H.A.\ for a Given P.A.} { \action{Hour Angle corresponding to a given parallactic angle (double precision).} \call{CALL sla\_PDQ2H (P, D, Q, H1, J1, H2, J2)} } \args{GIVEN} { \spec{P}{D}{latitude} \\ \spec{D}{D}{declination} \\ \spec{Q}{D}{azimuth} } \args{RETURNED} { \spec{H1}{D}{hour angle: first solution if any} \\ \spec{J1}{I}{flag: 0 = solution 1 is valid} \\ \spec{H2}{D}{hour angle: second solution if any} \\ \spec{J2}{I}{flag: 0 = solution 2 is valid} } %----------------------------------------------------------------------- \routine{SLA\_PERMUT}{Next Permutation} { \action{Generate the next permutation of a specified number of items.} \call{CALL sla\_PERMUT (N, ISTATE, IORDER, J)} } \args{GIVEN} { \spec{N}{I}{number of items: there will be N! permutations} \\ \spec{ISTATE}{I(N)}{state, ISTATE(1)$=-1$ to initialize} } \args{RETURNED} { \spec{ISTATE}{I(N)}{state, updated ready for next time} \\ \spec{IORDER}{I(N)}{next permutation of numbers 1,2,\ldots,N} \\ \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} $-$1 = illegal N (zero or less is illegal)} \\ \spec{}{}{\hspace{2.3em} 0 = OK} \\ \spec{}{}{\hspace{1.5em} $+$1 = no more permutations available} } \notes { \begin{enumerate} \item This routine returns, in the IORDER array, the integers 1 to N inclusive, in an order that depends on the current contents of the ISTATE array. Before calling the routine for the first time, the caller must set the first element of the ISTATE array to $-1$ (any negative number will do) to cause the ISTATE array to be fully initialized. \item The first permutation to be generated is: \begin{verse} IORDER(1)=N, IORDER(2)=N-1, ..., IORDER(N)=1 \end{verse} This is also the permutation returned for the ``finished'' (J=1) case. The final permutation to be generated is: \begin{verse} IORDER(1)=1, IORDER(2)=2, ..., IORDER(N)=N \end{verse} \item If the ``finished'' (J=1) status is ignored, the routine continues to deliver permutations, the pattern repeating every~N!\,~calls. \end{enumerate} } %------------------------------------------------------------------------------ \routine{SLA\_PERTEL}{Perturbed Orbital Elements} { \action{Update the osculating elements of an asteroid or comet by applying planetary perturbations.} \call{CALL sla\_PERTEL (\vtop{ \hbox{JFORM, DATE0, DATE1,} \hbox{EPOCH0, ORBI0, ANODE0, PERIH0, AORQ0, E0, AM0,} \hbox{EPOCH1, ORBI1, ANODE1, PERIH1, AORQ1, E1, AM1,} \hbox{JSTAT)}}} } \args{GIVEN (format and dates)} { \spec{JFORM}{I}{choice of element set (2 or 3; Note~1)} \\ \spec{DATE0}{D}{date of osculation (TT MJD) for the given} \\ \spec{}{}{\hspace{1.5em} elements} \\ \spec{DATE1}{D}{date of osculation (TT MJD) for the updated} \\ \spec{}{}{\hspace{1.5em} elements} } \args{GIVEN (the unperturbed elements)} { \spec{EPOCH0}{D}{epoch of the given element set ($t_0$ or $T$, TT MJD;} \\ \spec{}{}{\hspace{1.5em} Note~2)} \\ \spec{ORBI0}{D}{inclination ($i$, radians)} \\ \spec{ANODE0}{D}{longitude of the ascending node ($\Omega$, radians)} \\ \spec{PERIH0}{D}{argument of perihelion ($\omega$, radians)} \\ \spec{AORQ0}{D}{mean distance or perihelion distance ($a$ or $q$, AU)} \\ \spec{E0}{D}{eccentricity ($e$)} \\ \spec{AM0}{D}{mean anomaly ($M$, radians, JFORM=2 only)} } \args{RETURNED (the updated elements)} { \spec{EPOCH1}{D}{epoch of the updated element set ($t_0$ or $T$,} \\ \spec{}{}{\hspace{1.5em} TT MJD; Note~2)} \\ \spec{ORBI1}{D}{inclination ($i$, radians)} \\ \spec{ANODE1}{D}{longitude of the ascending node ($\Omega$, radians)} \\ \spec{PERIH1}{D}{argument of perihelion ($\omega$, radians)} \\ \spec{AORQ1}{D}{mean distance or perihelion distance ($a$ or $q$, AU)} \\ \spec{E1}{D}{eccentricity ($e$)} \\ \spec{AM1}{D}{mean anomaly ($M$, radians, JFORM=2 only)} } \args{RETURNED (status flag)} { \spec{JSTAT}{I}{status:} \\ \spec{}{}{\hspace{0.5em}+102 = warning, distant epoch} \\ \spec{}{}{\hspace{0.5em}+101 = warning, large timespan ($>100$ years)} \\ \spec{}{}{\hspace{-1.3em}+1 to +8 = coincident with major planet (Note~6)} \\ \spec{}{}{\hspace{1.95em} 0 = OK} \\ \spec{}{}{\hspace{1.2em} $-$1 = illegal JFORM} \\ \spec{}{}{\hspace{1.2em} $-$2 = illegal E0} \\ \spec{}{}{\hspace{1.2em} $-$3 = illegal AORQ0} \\ \spec{}{}{\hspace{1.2em} $-$4 = internal error} \\ \spec{}{}{\hspace{1.2em} $-$5 = numerical error} } \notes { \begin{enumerate} \item Two different element-format options are supported, as follows. \\ JFORM=2, suitable for minor planets: \begin{tabbing} xxx \= xxxxxxxx \= xx \= \kill \> EPOCH \> = \> epoch of elements $t_0$ (TT MJD) \\ \> ORBINC \> = \> inclination $i$ (radians) \\ \> ANODE \> = \> longitude of the ascending node $\Omega$ (radians) \\ \> PERIH \> = \> argument of perihelion $\omega$ (radians) \\ \> AORQ \> = \> mean distance $a$ (AU) \\ \> E \> = \> eccentricity $e$ $( 0 \leq e < 1 )$ \\ \> AORL \> = \> mean anomaly $M$ (radians) \end{tabbing} JFORM=3, suitable for comets: \begin{tabbing} xxx \= xxxxxxxx \= xx \= \kill \> EPOCH \> = \> epoch of perihelion $T$ (TT MJD) \\ \> ORBINC \> = \> inclination $i$ (radians) \\ \> ANODE \> = \> longitude of the ascending node $\Omega$ (radians) \\ \> PERIH \> = \> argument of perihelion $\omega$ (radians) \\ \> AORQ \> = \> perihelion distance $q$ (AU) \\ \> E \> = \> eccentricity $e$ $( 0 \leq e \leq 10 )$ \end{tabbing} \item DATE0, DATE1, EPOCH0 and EPOCH1 are all instants of time in the TT timescale (formerly Ephemeris Time, ET), expressed as Modified Julian Dates (JD$-$2400000.5). \begin{itemize} \item DATE0 is the instant at which the given ({\it i.e.}\ unperturbed) osculating elements are correct. \item DATE1 is the specified instant at which the updated osculating elements are correct. \item EPOCH0 and EPOCH1 will be the same as DATE0 and DATE1 (respectively) for the JFORM=2 case, normally used for minor planets. For the JFORM=3 case, the two epochs will refer to perihelion passage and so will not, in general, be the same as DATE0 and/or DATE1 though they may be similar to one another. \end{itemize} \item The elements are with respect to the J2000 ecliptic and mean equinox. \item Unused elements (AM0 and AM1 for JFORM=3) are not accessed. \item See the sla\_PERTUE routine for details of the algorithm used. \item This routine is not intended to be used for major planets, which is why JFORM=1 is not available and why there is no opportunity to specify either the longitude of perihelion or the daily motion. However, if JFORM=2 elements are somehow obtained for a major planet and supplied to the routine, sensible results will, in fact, be produced. This happens because the sla\_PERTUE routine that is called to perform the calculations checks the separation between the body and each of the planets and interprets a suspiciously small value (0.001~AU) as an attempt to apply it to the planet concerned. If this condition is detected, the contribution from that planet is ignored, and the status is set to the planet number (Mercury=1,\ldots,Neptune=8) as a warning. \end{enumerate} } \aref{Sterne, Theodore E., {\it An Introduction to Celestial Mechanics,}\/ Interscience Publishers, 1960. Section 6.7, p199.} %------------------------------------------------------------------------------ \routine{SLA\_PERTUE}{Perturbed Universal Elements} { \action{Update the universal elements of an asteroid or comet by applying planetary perturbations.} \call{CALL sla\_PERTUE (DATE, U, JSTAT)} } \args{GIVEN} { \spec{DATE1}{D}{final epoch (TT MJD) for the updated elements} } \args{GIVEN and RETURNED} { \spec{U}{D(13)}{universal elements (updated in place)} \\ \specel {(1)} {combined mass ($M+m$)} \\ \specel {(2)} {total energy of the orbit ($\alpha$)} \\ \specel {(3)} {reference (osculating) epoch ($t_0$)} \\ \specel {(4-6)} {position at reference epoch (${\rm \bf r}_0$)} \\ \specel {(7-9)} {velocity at reference epoch (${\rm \bf v}_0$)} \\ \specel {(10)} {heliocentric distance at reference epoch} \\ \specel {(11)} {${\rm \bf r}_0.{\rm \bf v_0}$} \\ \specel {(12)} {date ($t$)} \\ \specel {(13)} {universal eccentric anomaly ($\psi$) of date, approx} } \args{RETURNED} { \spec{JSTAT}{I}{status:} \\ \spec{}{}{\hspace{0.5em}+102 = warning, distant epoch} \\ \spec{}{}{\hspace{0.5em}+101 = warning, large timespan ($>100$ years)} \\ \spec{}{}{\hspace{-1.3em}+1 to +8 = coincident with major planet (Note~5)} \\ \spec{}{}{\hspace{1.95em} 0 = OK} \\ \spec{}{}{\hspace{1.2em} $-$1 = numerical error} } \notes { \begin{enumerate} \setlength{\parskip}{\medskipamount} \item The ``universal'' elements are those which define the orbit for the purposes of the method of universal variables (see reference 2). They consist of the combined mass of the two bodies, an epoch, and the position and velocity vectors (arbitrary reference frame) at that epoch. The parameter set used here includes also various quantities that can, in fact, be derived from the other information. This approach is taken to avoiding unnecessary computation and loss of accuracy. The supplementary quantities are (i)~$\alpha$, which is proportional to the total energy of the orbit, (ii)~the heliocentric distance at epoch, (iii)~the outwards component of the velocity at the given epoch, (iv)~an estimate of $\psi$, the ``universal eccentric anomaly'' at a given date and (v)~that date. \item The universal elements are with respect to the J2000 equator and equinox. \item The epochs DATE, U(3) and U(12) are all Modified Julian Dates (JD$-$2400000.5). \item The algorithm is a simplified form of Encke's method. It takes as a basis the unperturbed motion of the body, and numerically integrates the perturbing accelerations from the major planets. The expression used is essentially Sterne's 6.7-2 (reference 1). Everhart and Pitkin (reference 2) suggest rectifying the orbit at each integration step by propagating the new perturbed position and velocity as the new universal variables. In the present routine the orbit is rectified less frequently than this, in order to gain a slight speed advantage. However, the rectification is done directly in terms of position and velocity, as suggested by Everhart and Pitkin, bypassing the use of conventional orbital elements. The $f(q)$ part of the full Encke method is not used. The purpose of this part is to avoid subtracting two nearly equal quantities when calculating the ``indirect member'', which takes account of the small change in the Sun's attraction due to the slightly displaced position of the perturbed body. A simpler, direct calculation in double precision proves to be faster and not significantly less accurate. Apart from employing a variable timestep, and occasionally ``rectifying the orbit'' to keep the indirect member small, the integration is done in a fairly straightforward way. The acceleration estimated for the middle of the timestep is assumed to apply throughout that timestep; it is also used in the extrapolation of the perturbations to the middle of the next timestep, to predict the new disturbed position. There is no iteration within a timestep. Measures are taken to reach a compromise between execution time and accuracy. The starting-point is the goal of achieving arcsecond accuracy for ordinary minor planets over a ten-year timespan. This goal dictates how large the timesteps can be, which in turn dictates how frequently the unperturbed motion has to be recalculated from the osculating elements. Within predetermined limits, the timestep for the numerical integration is varied in length in inverse proportion to the magnitude of the net acceleration on the body from the major planets. The numerical integration requires estimates of the major-planet motions. Approximate positions for the major planets (Pluto alone is omitted) are obtained from the routine sla\_PLANET. Two levels of interpolation are used, to enhance speed without significantly degrading accuracy. At a low frequency, the routine sla\_PLANET is called to generate updated position+velocity ``state vectors''. The only task remaining to be carried out at the full frequency ({\it i.e.}\ at each integration step) is to use the state vectors to extrapolate the planetary positions. In place of a strictly linear extrapolation, some allowance is made for the curvature of the orbit by scaling back the radius vector as the linear extrapolation goes off at a tangent. Various other approximations are made. For example, perturbations by Pluto and the minor planets are neglected, relativistic effects are not taken into account and the Earth-Moon system is treated as a single body. In the interests of simplicity, the background calculations for the major planets are carried out {\it en masse.} The mean elements and state vectors for all the planets are refreshed at the same time, without regard for orbit curvature, mass or proximity. \item This routine is not intended to be used for major planets. However, if major-planet elements are supplied, sensible results will, in fact, be produced. This happens because the routine checks the separation between the body and each of the planets and interprets a suspiciously small value (0.001~AU) as an attempt to apply the routine to the planet concerned. If this condition is detected, the contribution from that planet is ignored, and the status is set to the planet number (Mercury=1,\ldots,Neptune=8) as a warning. \end{enumerate} } \refs{ \begin{enumerate} \item Sterne, Theodore E., {\it An Introduction to Celestial Mechanics,}\/ Interscience Publishers, 1960. Section 6.7, p199. \item Everhart, E. \& Pitkin, E.T., Am.~J.~Phys.~51, 712, 1983. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_PLANEL}{Planet Position from Elements} { \action{Heliocentric position and velocity of a planet, asteroid or comet, starting from orbital elements.} \call{CALL sla\_PLANEL (\vtop{ \hbox{DATE, JFORM, EPOCH, ORBINC, ANODE, PERIH,} \hbox{AORQ, E, AORL, DM, PV, JSTAT)}}} } \args{GIVEN} { \spec{DATE}{D}{Modified Julian Date (JD$-$2400000.5)} \\ \spec{JFORM}{I}{choice of element set (1-3, see Note~3, below)} \\ \spec{EPOCH}{D}{epoch of elements ($t_0$ or $T$, TT MJD)} \\ \spec{ORBINC}{D}{inclination ($i$, radians)} \\ \spec{ANODE}{D}{longitude of the ascending node ($\Omega$, radians)} \\ \spec{PERIH}{D}{longitude or argument of perihelion ($\varpi$ or $\omega$,} \\ \spec{}{}{\hspace{1.5em} radians)} \\ \spec{AORQ}{D}{mean distance or perihelion distance ($a$ or $q$, AU)} \\ \spec{E}{D}{eccentricity ($e$)} \\ \spec{AORL}{D}{mean anomaly or longitude ($M$ or $L$, radians,} \\ \spec{}{}{\hspace{1.5em} JFORM=1,2 only)} \\ \spec{DM}{D}{daily motion ($n$, radians, JFORM=1 only)} } \args{RETURNED} { \spec{PV}{D(6)}{heliocentric \xyzxyzd, equatorial, J2000} \\ \spec{}{}{\hspace{1.5em} (AU, AU/s)} \\ \spec{JSTAT}{I}{status:} \\ \spec{}{}{\hspace{2.3em} 0 = OK} \\ \spec{}{}{\hspace{1.5em} $-$1 = illegal JFORM} \\ \spec{}{}{\hspace{1.5em} $-$2 = illegal E} \\ \spec{}{}{\hspace{1.5em} $-$3 = illegal AORQ} \\ \spec{}{}{\hspace{1.5em} $-$4 = illegal DM} \\ \spec{}{}{\hspace{1.5em} $-$5 = numerical error} } \notes { \begin{enumerate} \item DATE is the instant for which the prediction is required. It is in the TT timescale (formerly Ephemeris Time, ET) and is a Modified Julian Date (JD$-$2400000.5). \item The elements are with respect to the J2000 ecliptic and equinox. \item Three different element-format options are available, as follows. \\ JFORM=1, suitable for the major planets: \begin{tabbing} xxx \= xxxxxxxx \= xx \= \kill \> EPOCH \> = \> epoch of elements $t_0$ (TT MJD) \\ \> ORBINC \> = \> inclination $i$ (radians) \\ \> ANODE \> = \> longitude of the ascending node $\Omega$ (radians) \\ \> PERIH \> = \> longitude of perihelion $\varpi$ (radians) \\ \> AORQ \> = \> mean distance $a$ (AU) \\ \> E \> = \> eccentricity $e$ $( 0 \leq e < 1 )$ \\ \> AORL \> = \> mean longitude $L$ (radians) \\ \> DM \> = \> daily motion $n$ (radians) \end{tabbing} JFORM=2, suitable for minor planets: \begin{tabbing} xxx \= xxxxxxxx \= xx \= \kill \> EPOCH \> = \> epoch of elements $t_0$ (TT MJD) \\ \> ORBINC \> = \> inclination $i$ (radians) \\ \> ANODE \> = \> longitude of the ascending node $\Omega$ (radians) \\ \> PERIH \> = \> argument of perihelion $\omega$ (radians) \\ \> AORQ \> = \> mean distance $a$ (AU) \\ \> E \> = \> eccentricity $e$ $( 0 \leq e < 1 )$ \\ \> AORL \> = \> mean anomaly $M$ (radians) \end{tabbing} JFORM=3, suitable for comets: \begin{tabbing} xxx \= xxxxxxxx \= xx \= \kill \> EPOCH \> = \> epoch of perihelion $T$ (TT MJD) \\ \> ORBINC \> = \> inclination $i$ (radians) \\ \> ANODE \> = \> longitude of the ascending node $\Omega$ (radians) \\ \> PERIH \> = \> argument of perihelion $\omega$ (radians) \\ \> AORQ \> = \> perihelion distance $q$ (AU) \\ \> E \> = \> eccentricity $e$ $( 0 \leq e \leq 10 )$ \end{tabbing} \item Unused elements (DM for JFORM=2, AORL and DM for JFORM=3) are not accessed. \item The reference frame for the result is equatorial and is with respect to the mean equinox and ecliptic of epoch J2000. \item The algorithm was originally adapted from the EPHSLA program of D.\,H.\,P.\,Jones (private communication, 1996). The method is based on Stumpff's Universal Variables. \end{enumerate} } \aref{Everhart, E. \& Pitkin, E.T., Am.~J.~Phys.~51, 712, 1983.} %------------------------------------------------------------------------------ \routine{SLA\_PLANET}{Planetary Ephemerides} { \action{Approximate heliocentric position and velocity of a planet.} \call{CALL sla\_PLANET (DATE, NP, PV, JSTAT)} } \args{GIVEN} { \spec{DATE}{D}{Modified Julian Date (JD$-$2400000.5)} \\ \spec{NP}{I}{planet:} \\ \spec{}{}{\hspace{1.5em} 1\,=\,Mercury} \\ \spec{}{}{\hspace{1.5em} 2\,=\,Venus} \\ \spec{}{}{\hspace{1.5em} 3\,=\,Earth-Moon Barycentre} \\ \spec{}{}{\hspace{1.5em} 4\,=\,Mars} \\ \spec{}{}{\hspace{1.5em} 5\,=\,Jupiter} \\ \spec{}{}{\hspace{1.5em} 6\,=\,Saturn} \\ \spec{}{}{\hspace{1.5em} 7\,=\,Uranus} \\ \spec{}{}{\hspace{1.5em} 8\,=\,Neptune} \\ \spec{}{}{\hspace{1.5em} 9\,=\,Pluto} } \args{RETURNED} { \spec{PV}{D(6)}{heliocentric \xyzxyzd, equatorial, J2000} \\ \spec{}{}{\hspace{1.5em} (AU, AU/s)} \\ \spec{JSTAT}{I}{status:} \\ \spec{}{}{\hspace{1.5em} $+$1 = warning: date outside of range} \\ \spec{}{}{\hspace{2.3em} 0 = OK} \\ \spec{}{}{\hspace{1.5em} $-$1 = illegal NP (outside 1-9)} \\ \spec{}{}{\hspace{1.5em} $-$2 = solution didn't converge} } \notes { \begin{enumerate} \item The epoch, DATE, is in the TDB timescale and is in the form of a Modified Julian Date (JD$-$2400000.5). \item The reference frame is equatorial and is with respect to the mean equinox and ecliptic of epoch J2000. \item If a planet number, NP, outside the range 1-9 is supplied, an error status is returned (JSTAT~=~$-1$) and the PV vector is set to zeroes. \item The algorithm for obtaining the mean elements of the planets from Mercury to Neptune is due to J.\,L.\,Simon, P.\,Bretagnon, J.\,Chapront, M.\,Chapront-Touze, G.\,Francou and J.\,Laskar (Bureau des Longitudes, Paris, France). The (completely different) algorithm for calculating the ecliptic coordinates of Pluto is by Meeus. \item Comparisons of the present routine with the JPL DE200 ephemeris give the following RMS errors over the interval 1960-2025: \begin{tabbing} xxxxx \= xxxxxxxxxxxxxxxxx \= xxxxxxxxxxxxxx \= \kill \> \> {\it position (km)} \> {\it speed (metre/sec)} \\ \\ \> Mercury \> \hspace{2em}334 \> \hspace{2.5em}0.437 \\ \> Venus \> \hspace{1.5em}1060 \> \hspace{2.5em}0.855 \\ \> EMB \> \hspace{1.5em}2010 \> \hspace{2.5em}0.815 \\ \> Mars \> \hspace{1.5em}7690 \> \hspace{2.5em}1.98 \\ \> Jupiter \> \hspace{1em}71700 \> \hspace{2.5em}7.70 \\ \> Saturn \> \hspace{0.5em}199000 \> \hspace{2em}19.4 \\ \> Uranus \> \hspace{0.5em}564000 \> \hspace{2em}16.4 \\ \> Neptune \> \hspace{0.5em}158000 \> \hspace{2em}14.4 \\ \> Pluto \> \hspace{1em}36400 \> \hspace{2.5em}0.137 \end{tabbing} From comparisons with DE102, Simon {\it et al.}\/ quote the following longitude accuracies over the interval 1800-2200: \begin{tabbing} xxxxx \= xxxxxxxxxxxxxxxxxxxx \= \kill \> Mercury \> \hspace{0.5em}\arcseci{4} \\ \> Venus \> \hspace{0.5em}\arcseci{5} \\ \> EMB \> \hspace{0.5em}\arcseci{6} \\ \> Mars \> \arcseci{17} \\ \> Jupiter \> \arcseci{71} \\ \> Saturn \> \arcseci{81} \\ \> Uranus \> \arcseci{86} \\ \> Neptune \> \arcseci{11} \end{tabbing} In the case of Pluto, Meeus quotes an accuracy of \arcsec{0}{6} in longitude and \arcsec{0}{2} in latitude for the period 1885-2099. For all except Pluto, over the period 1000-3000, the accuracy is better than 1.5 times that over 1800-2200. Outside the interval 1000-3000 the accuracy declines. For Pluto the accuracy declines rapidly outside the period 1885-2099. Outside these ranges (1885-2099 for Pluto, 1000-3000 for the rest) a ``date out of range'' warning status ({\tt JSTAT=+1}) is returned. \item The algorithms for (i)~Mercury through Neptune and (ii)~Pluto are completely independent. In the Mercury through Neptune case, the present SLALIB implementation differs from the original Simon {\it et al.}\/ Fortran code in the following respects: \begin{itemize} \item The date is supplied as a Modified Julian Date rather a Julian Date (${\rm MJD} = ({\rm JD} - 2400000.5$). \item The result is returned only in equatorial Cartesian form; the ecliptic longitude, latitude and radius vector are not returned. \item The velocity is in AU per second, not AU per day. \item Different error/warning status values are used. \item Kepler's Equation is not solved inline. \item Polynomials in T are nested to minimize rounding errors. \item Explicit double-precision constants are used to avoid mixed-mode expressions. \item There are other, cosmetic, changes to comply with Starlink/SLALIB style guidelines. \end{itemize} None of the above changes affects the result significantly. \item NP\,=\,3 the result is for the Earth-Moon Barycentre. To obtain the heliocentric position and velocity of the Earth, either use the SLALIB routine sla\_EVP or call sla\_DMOON and subtract 0.012150581 times the geocentric Moon vector from the EMB vector produced by the present routine. (The Moon vector should be precessed to J2000 first, but this can be omitted for modern epochs without introducing significant inaccuracy.) \end{enumerate} \refs { \begin{enumerate} \item Simon {\it et al.,}\/ Astron.\ Astrophys.\ {\bf 282}, 663 (1994). \item Meeus, J., {\it Astronomical Algorithms,}\/ Willmann-Bell (1991). \end{enumerate} } } %------------------------------------------------------------------------------ \routine{SLA\_PLANTE}{\radec\ of Planet from Elements} { \action{Topocentric apparent \radec\ of a Solar-System object whose heliocentric orbital elements are known.} \call{CALL sla\_PLANTE (\vtop{ \hbox{DATE, ELONG, PHI, JFORM, EPOCH, ORBINC, ANODE, PERIH,} \hbox{AORQ, E, AORL, DM, RA, DEC, R, JSTAT)}}} } \args{GIVEN} { \spec{DATE}{D}{MJD of observation (JD$-$2400000.5)} \\ \spec{ELONG,PHI}{D}{observer's longitude (east +ve) and latitude} \\ \spec{}{}{\hspace{1.5em} radians)} \\ \spec{JFORM}{I}{choice of element set (1-3, see Note~4, below)} \\ \spec{EPOCH}{D}{epoch of elements ($t_0$ or $T$, TT MJD)} \\ \spec{ORBINC}{D}{inclination ($i$, radians)} \\ \spec{ANODE}{D}{longitude of the ascending node ($\Omega$, radians)} \\ \spec{PERIH}{D}{longitude or argument of perihelion ($\varpi$ or $\omega$,} \\ \spec{}{}{\hspace{1.5em} radians)} \\ \spec{AORQ}{D}{mean distance or perihelion distance ($a$ or $q$, AU)} \\ \spec{E}{D}{eccentricity ($e$)} \\ \spec{AORL}{D}{mean anomaly or longitude ($M$ or $L$,} \\ \spec{}{}{\hspace{1.5em} radians, JFORM=1,2 only)} \\ \spec{DM}{D}{daily motion ($n$, radians, JFORM=1 only)} } \args{RETURNED} { \spec{RA,DEC}{D}{topocentric apparent \radec\ (radians)} \\ \spec{R}{D}{distance from observer (AU)} \\ \spec{JSTAT}{I}{status:} \\ \spec{}{}{\hspace{2.3em} 0 = OK} \\ \spec{}{}{\hspace{1.5em} $-$1 = illegal JFORM} \\ \spec{}{}{\hspace{1.5em} $-$2 = illegal E} \\ \spec{}{}{\hspace{1.5em} $-$3 = illegal AORQ} \\ \spec{}{}{\hspace{1.5em} $-$4 = illegal DM} \\ \spec{}{}{\hspace{1.5em} $-$5 = numerical error} } \notes { \begin{enumerate} \item DATE is the instant for which the prediction is required. It is in the TT timescale (formerly Ephemeris Time, ET) and is a Modified Julian Date (JD$-$2400000.5). \item The longitude and latitude allow correction for geocentric parallax. This is usually a small effect, but can become important for Earth-crossing asteroids. Geocentric positions can be generated by appropriate use of the routines sla\_EVP and sla\_PLANEL. \item The elements are with respect to the J2000 ecliptic and equinox. \item Three different element-format options are available, as follows. \\ JFORM=1, suitable for the major planets: \begin{tabbing} xxx \= xxxxxxx \= xx \= \kill \> EPOCH \> = \> epoch of elements $t_0$ (TT MJD) \\ \> ORBINC \> = \> inclination $i$ (radians) \\ \> ANODE \> = \> longitude of the ascending node $\Omega$ (radians) \\ \> PERIH \> = \> longitude of perihelion $\varpi$ (radians) \\ \> AORQ \> = \> mean distance $a$ (AU) \\ \> E \> = \> eccentricity $e$ \\ \> AORL \> = \> mean longitude $L$ (radians) \\ \> DM \> = \> daily motion $n$ (radians) \end{tabbing} JFORM=2, suitable for minor planets: \begin{tabbing} xxx \= xxxxxxx \= xx \= \kill \> EPOCH \> = \> epoch of elements $t_0$ (TT MJD) \\ \> ORBINC \> = \> inclination $i$ (radians) \\ \> ANODE \> = \> longitude of the ascending node $\Omega$ (radians) \\ \> PERIH \> = \> argument of perihelion $\omega$ (radians) \\ \> AORQ \> = \> mean distance $a$ (AU) \\ \> E \> = \> eccentricity $e$ \\ \> AORL \> = \> mean anomaly $M$ (radians) \end{tabbing} JFORM=3, suitable for comets: \begin{tabbing} xxx \= xxxxxxx \= xx \= \kill \> EPOCH \> = \> epoch of perihelion $T$ (TT MJD) \\ \> ORBINC \> = \> inclination $i$ (radians) \\ \> ANODE \> = \> longitude of the ascending node $\Omega$ (radians) \\ \> PERIH \> = \> argument of perihelion $\omega$ (radians) \\ \> AORQ \> = \> perihelion distance $q$ (AU) \\ \> E \> = \> eccentricity $e$ \end{tabbing} \item Unused elements (DM for JFORM=2, AORL and DM for JFORM=3) are not accessed. \end{enumerate} } %------------------------------------------------------------------------------ \routine{SLA\_PM}{Proper Motion} { \action{Apply corrections for proper motion to a star \radec.} \call{CALL sla\_PM (R0, D0, PR, PD, PX, RV, EP0, EP1, R1, D1)} } \args{GIVEN} { \spec{R0,D0}{D}{\radec\ at epoch EP0 (radians)} \\ \spec{PR,PD}{D}{proper motions: rate of change of \radec\ (radians per year)} \\ \spec{PX}{D}{parallax (arcsec)} \\ \spec{RV}{D}{radial velocity (km~s$^{-1}$, +ve if receding)} \\ \spec{EP0}{D}{start epoch in years ({\it e.g.}\ Julian epoch)} \\ \spec{EP1}{D}{end epoch in years (same system as EP0)} } \args{RETURNED} { \spec{R1,D1}{D}{\radec\ at epoch EP1 (radians)} } \anote{The $\alpha$ proper motions are $\dot{\alpha}$ rather than $\dot{\alpha}\cos\delta$, and are in the same coordinate system as R0,D0.} \refs { \begin{enumerate} \item 1984 {\it Astronomical Almanac}, pp B39-B41. \item Lederle \& Schwan, 1984.\ {\it Astr. Astrophys.}\ {\bf 134}, 1-6. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_POLMO}{Polar Motion} { \action{Polar motion: correct site longitude and latitude for polar motion and calculate azimuth difference between celestial and terrestrial poles.} \call{CALL sla\_POLMO (ELONGM, PHIM, XP, YP, ELONG, PHI, DAZ)} } \args{GIVEN} { \spec{ELONGM}{D}{mean longitude of the site (radians, east +ve)} \\ \spec{PHIM}{D}{mean geodetic latitude of the site (radians)} \\ \spec{XP}{D}{polar motion $x$-coordinate (radians)} \\ \spec{YP}{D}{polar motion $y$-coordinate (radians)} } \args{RETURNED} { \spec{ELONG}{D}{true longitude of the site (radians, east +ve)} \\ \spec{PHI}{D}{true geodetic latitude of the site (radians)} \\ \spec{DAZ}{D}{azimuth correction (terrestrial$-$celestial, radians)} } \notes { \begin{enumerate} \item ``Mean'' longitude and latitude are the (fixed) values for the site's location with respect to the IERS terrestrial reference frame; the latitude is geodetic. TAKE CARE WITH THE LONGITUDE SIGN CONVENTION. The longitudes used by the present routine are east-positive, in accordance with geographical convention (and right-handed). In particular, note that the longitudes returned by the sla\_OBS routine are west-positive, following astronomical usage, and must be reversed in sign before use in the present routine. \item XP and YP are the (changing) coordinates of the Celestial Ephemeris Pole with respect to the IERS Reference Pole. XP is positive along the meridian at longitude $0^\circ$, and YP is positive along the meridian at longitude $270^\circ$ ({\it i.e.}\ $90^\circ$ west). Values for XP,YP can be obtained from IERS circulars and equivalent publications; the maximum amplitude observed so far is about \arcsec{0}{3}. \item ``True'' longitude and latitude are the (moving) values for the site's location with respect to the celestial ephemeris pole and the meridian which corresponds to the Greenwich apparent sidereal time. The true longitude and latitude link the terrestrial coordinates with the standard celestial models (for precession, nutation, sidereal time {\it etc}). \item The azimuths produced by sla\_AOP and sla\_AOPQK are with respect to due north as defined by the Celestial Ephemeris Pole, and can therefore be called ``celestial azimuths''. However, a telescope fixed to the Earth measures azimuth essentially with respect to due north as defined by the IERS Reference Pole, and can therefore be called ``terrestrial azimuth''. Uncorrected, this would manifest itself as a changing ``azimuth zero-point error''. The value DAZ is the correction to be added to a celestial azimuth to produce a terrestrial azimuth. \item The present routine is rigorous. For most practical purposes, the following simplified formulae provide an adequate approximation: \\[2ex] \hspace*{1em}\begin{tabular}{lll} {\tt ELONG} & {\tt =} & {\tt ELONGM+XP*COS(ELONGM)-YP*SIN(ELONGM)} \\ {\tt PHI } & {\tt =} & {\tt PHIM+(XP*SIN(ELONGM)+YP*COS(ELONGM))*TAN(PHIM)} \\ {\tt DAZ } & {\tt =} & {\tt -SQRT(XP*XP+YP*YP)*COS(ELONGM-ATAN2(XP,YP))/COS(PHIM)} \\ \end{tabular} \\[2ex] An alternative formulation for DAZ is:\\[2ex] \hspace*{1em}\begin{tabular}{lll} {\tt X } & {\tt =} & {\tt COS(ELONGM)*COS(PHIM)} \\ {\tt Y } & {\tt =} & {\tt SIN(ELONGM)*COS(PHIM)} \\ {\tt DAZ} & {\tt =} & {\tt ATAN2(-X*YP-Y*XP,X*X+Y*Y)} \\ \end{tabular} \end{enumerate} } \aref{Seidelmann, P.K.\ (ed), 1992. {\it Explanatory Supplement to the Astronomical Almanac,}\/ ISBN~0-935702-68-7, sections 3.27, 4.25, 4.52.} %----------------------------------------------------------------------- \routine{SLA\_PREBN}{Precession Matrix (FK4)} { \action{Generate the matrix of precession between two epochs, using the old, pre IAU~1976, Bessel-Newcomb model, in Andoyer's formulation.} \call{CALL sla\_PREBN (BEP0, BEP1, RMATP)} } \args{GIVEN} { \spec{BEP0}{D}{beginning Besselian epoch} \\ \spec{BEP1}{D}{ending Besselian epoch} } \args{RETURNED} { \spec{RMATP}{D(3,3)}{precession matrix} } \anote{The matrix is in the sense: \begin{verse} {\bf v}$_{1}$ = {\bf M}$\cdot${\bf v}$_{0}$ \end{verse} where {\bf v}$_{1}$ is the star vector relative to the mean equator and equinox of epoch BEP1, {\bf M} is the $3\times3$ matrix RMATP and {\bf v}$_{0}$ is the star vector relative to the mean equator and equinox of epoch BEP0.} \aref{Smith {\it et al.}, 1989.\ {\it Astr.J.}\ {\bf 97}, 269.} %----------------------------------------------------------------------- \routine{SLA\_PREC}{Precession Matrix (FK5)} { \action{Form the matrix of precession between two epochs (IAU 1976, FK5).} \call{CALL sla\_PREC (EP0, EP1, RMATP)} } \args{GIVEN} { \spec{EP0}{D}{beginning epoch} \\ \spec{EP1}{D}{ending epoch} } \args{RETURNED} { \spec{RMATP}{D(3,3)}{precession matrix} } \notes { \begin{enumerate} \item The epochs are TDB Julian epochs. \item The matrix is in the sense: \begin{verse} {\bf v}$_{1}$ = {\bf M}$\cdot${\bf v}$_{0}$ \end{verse} where {\bf v}$_{1}$ is the star vector relative to the mean equator and equinox of epoch EP1, {\bf M} is the $3\times3$ matrix RMATP and {\bf v}$_{0}$ is the star vector relative to the mean equator and equinox of epoch EP0. \item Though the matrix method itself is rigorous, the precession angles are expressed through canonical polynomials which are valid only for a limited time span. There are also known errors in the IAU precession rate. The absolute accuracy of the present formulation is better than \arcsec{0}{1} from 1960\,AD to 2040\,AD, better than \arcseci{1} from 1640\,AD to 2360\,AD, and remains below \arcseci{3} for the whole of the period 500\,BC to 3000\,AD. The errors exceed \arcseci{10} outside the range 1200\,BC to 3900\,AD, exceed \arcseci{100} outside 4200\,BC to 5600\,AD and exceed \arcseci{1000} outside 6800\,BC to 8200\,AD. The SLALIB routine sla\_PRECL implements a more elaborate model which is suitable for problems spanning several thousand years. \end{enumerate} } \refs { \begin{enumerate} \item Lieske, J.H., 1979.\ {\it Astr.Astrophys.}\ {\bf 73}, 282; equations 6 \& 7, p283. \item Kaplan, G.H., 1981.\ {\it USNO circular no.\ 163}, pA2. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_PRECES}{Precession} { \action{Precession -- either the old ``FK4'' (Bessel-Newcomb, pre~IAU~1976) or new ``FK5'' (Fricke, post~IAU~1976) as required.} \call{CALL sla\_PRECES (SYSTEM, EP0, EP1, RA, DC)} } \args{GIVEN} { \spec{SYSTEM}{C}{precession to be applied: `FK4' or `FK5'} \\ \spec{EP0,EP1}{D}{starting and ending epoch} \\ \spec{RA,DC}{D}{\radec, mean equator \& equinox of epoch EP0} } \args{RETURNED} { \spec{RA,DC}{D}{\radec, mean equator \& equinox of epoch EP1} } \notes { \begin{enumerate} \item Lowercase characters in SYSTEM are acceptable. \item The epochs are Besselian if SYSTEM=`FK4' and Julian if `FK5'. For example, to precess coordinates in the old system from equinox 1900.0 to 1950.0 the call would be: \begin{quote} {\tt CALL sla\_PRECES ('FK4', 1900D0, 1950D0, RA, DC)} \end{quote} \item This routine will {\bf NOT} correctly convert between the old and the new systems -- for example conversion from B1950 to J2000. For these purposes see sla\_FK425, sla\_FK524, sla\_FK45Z and sla\_FK54Z. \item If an invalid SYSTEM is supplied, values of $-$99D0,$-$99D0 are returned for both RA and DC. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_PRECL}{Precession Matrix (latest)} { \action{Form the matrix of precession between two epochs, using the model of Simon {\it et al}.\ (1994), which is suitable for long periods of time.} \call{CALL sla\_PRECL (EP0, EP1, RMATP)} } \args{GIVEN} { \spec{EP0}{D}{beginning epoch} \\ \spec{EP1}{D}{ending epoch} } \args{RETURNED} { \spec{RMATP}{D(3,3)}{precession matrix} } \notes { \begin{enumerate} \item The epochs are TDB Julian epochs. \item The matrix is in the sense: \begin{verse} {\bf v}$_{1}$ = {\bf M}$\cdot${\bf v}$_{0}$ \end{verse} where {\bf v}$_{1}$ is the star vector relative to the mean equator and equinox of epoch EP1, {\bf M} is the $3\times3$ matrix RMATP and {\bf v}$_{0}$ is the star vector relative to the mean equator and equinox of epoch EP0. \item The absolute accuracy of the model is limited by the uncertainty in the general precession, about \arcsec{0}{3} per 1000~years. The remainder of the formulation provides a precision of 1~milliarcsecond over the interval from 1000\,AD to 3000\,AD, \arcsec{0}{1} from 1000\,BC to 5000\,AD and \arcseci{1} from 4000\,BC to 8000\,AD. \end{enumerate} } \aref{Simon, J.L.\ {\it et al}., 1994.\ {\it Astr.Astrophys.}\ {\bf 282}, 663.} %----------------------------------------------------------------------- \routine{SLA\_PRENUT}{Precession/Nutation Matrix} { \action{Form the matrix of precession and nutation (IAU~1976, FK5).} \call{CALL sla\_PRENUT (EPOCH, DATE, RMATPN)} } \args{GIVEN} { \spec{EPOCH}{D}{Julian Epoch for mean coordinates} \\ \spec{DATE}{D}{Modified Julian Date (JD$-$2400000.5) for true coordinates} } \args{RETURNED} { \spec{RMATPN}{D(3,3)}{combined precession/nutation matrix} } \notes { \begin{enumerate} \item The epoch and date are TDB. \item The matrix is in the sense: \begin{verse} {\bf v}$_{true}$ = {\bf M}$\cdot${\bf v}$_{mean}$ \end{verse} where {\bf v}$_{true}$ is the star vector relative to the true equator and equinox of epoch DATE, {\bf M} is the $3\times3$ matrix RMATPN and {\bf v}$_{mean}$ is the star vector relative to the mean equator and equinox of epoch EPOCH. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_PV2EL}{Orbital Elements from Position/Velocity} { \action{Heliocentric osculating elements obtained from instantaneous position and velocity.} \call{CALL sla\_PV2EL (\vtop{ \hbox{PV, DATE, PMASS, JFORMR, JFORM, EPOCH, ORBINC,} \hbox{ANODE, PERIH, AORQ, E, AORL, DM, JSTAT)}}} } \args{GIVEN} { \spec{PV}{D(6)}{heliocentric \xyzxyzd, equatorial, J2000} \\ \spec{}{}{\hspace{1.5em} (AU, AU/s; Note~1)} \\ \spec{DATE}{D}{date (TT Modified Julian Date = JD$-$2400000.5)} \\ \spec{PMASS}{D}{mass of the planet (Sun = 1; Note~2)} \\ \spec{JFORMR}{I}{requested element set (1-3; Note~3)} } \args{RETURNED} { \spec{JFORM}{I}{element set actually returned (1-3; Note~4)} \\ \spec{EPOCH}{D}{epoch of elements ($t_0$ or $T$, TT MJD)} \\ \spec{ORBINC}{D}{inclination ($i$, radians)} \\ \spec{ANODE}{D}{longitude of the ascending node ($\Omega$, radians)} \\ \spec{PERIH}{D}{longitude or argument of perihelion ($\varpi$ or $\omega$,} \\ \spec{}{}{\hspace{1.5em} radians)} \\ \spec{AORQ}{D}{mean distance or perihelion distance ($a$ or $q$, AU)} \\ \spec{E}{D}{eccentricity ($e$)} \\ \spec{AORL}{D}{mean anomaly or longitude ($M$ or $L$, radians,} \\ \spec{}{}{\hspace{1.5em} JFORM=1,2 only)} \\ \spec{DM}{D}{daily motion ($n$, radians, JFORM=1 only)} \\ \spec{JSTAT}{I}{status:} \\ \spec{}{}{\hspace{2.3em} 0 = OK} \\ \spec{}{}{\hspace{1.5em} $-$1 = illegal PMASS} \\ \spec{}{}{\hspace{1.5em} $-$2 = illegal JFORMR} \\ \spec{}{}{\hspace{1.5em} $-$3 = position/velocity out of allowed range} } \notes { \begin{enumerate} \item The PV 6-vector is with respect to the mean equator and equinox of epoch J2000. The orbital elements produced are with respect to the J2000 ecliptic and mean equinox. \item The mass, PMASS, is important only for the larger planets. For most purposes ({\it e.g.}~asteroids) use 0D0. Values less than zero are illegal. \item Three different element-format options are supported, as follows. \\ JFORM=1, suitable for the major planets: \begin{tabbing} xxx \= xxxxxxxx \= xx \= \kill \> EPOCH \> = \> epoch of elements $t_0$ (TT MJD) \\ \> ORBINC \> = \> inclination $i$ (radians) \\ \> ANODE \> = \> longitude of the ascending node $\Omega$ (radians) \\ \> PERIH \> = \> longitude of perihelion $\varpi$ (radians) \\ \> AORQ \> = \> mean distance $a$ (AU) \\ \> E \> = \> eccentricity $e$ $( 0 \leq e < 1 )$ \\ \> AORL \> = \> mean longitude $L$ (radians) \\ \> DM \> = \> daily motion $n$ (radians) \end{tabbing} JFORM=2, suitable for minor planets: \begin{tabbing} xxx \= xxxxxxxx \= xx \= \kill \> EPOCH \> = \> epoch of elements $t_0$ (TT MJD) \\ \> ORBINC \> = \> inclination $i$ (radians) \\ \> ANODE \> = \> longitude of the ascending node $\Omega$ (radians) \\ \> PERIH \> = \> argument of perihelion $\omega$ (radians) \\ \> AORQ \> = \> mean distance $a$ (AU) \\ \> E \> = \> eccentricity $e$ $( 0 \leq e < 1 )$ \\ \> AORL \> = \> mean anomaly $M$ (radians) \end{tabbing} JFORM=3, suitable for comets: \begin{tabbing} xxx \= xxxxxxxx \= xx \= \kill \> EPOCH \> = \> epoch of perihelion $T$ (TT MJD) \\ \> ORBINC \> = \> inclination $i$ (radians) \\ \> ANODE \> = \> longitude of the ascending node $\Omega$ (radians) \\ \> PERIH \> = \> argument of perihelion $\omega$ (radians) \\ \> AORQ \> = \> perihelion distance $q$ (AU) \\ \> E \> = \> eccentricity $e$ $( 0 \leq e \leq 10 )$ \end{tabbing} \item It may not be possible to generate elements in the form requested through JFORMR. The caller is notified of the form of elements actually returned by means of the JFORM argument: \begin{tabbing} xx \= xxxxxxxxxx \= xxxxxxxxxxx \= \kill \> JFORMR \> JFORM \> meaning \\ \\ \> ~~~~~1 \> ~~~~~1 \> OK: elements are in the requested format \\ \> ~~~~~1 \> ~~~~~2 \> never happens \\ \> ~~~~~1 \> ~~~~~3 \> orbit not elliptical \\ \> ~~~~~2 \> ~~~~~1 \> never happens \\ \> ~~~~~2 \> ~~~~~2 \> OK: elements are in the requested format \\ \> ~~~~~2 \> ~~~~~3 \> orbit not elliptical \\ \> ~~~~~3 \> ~~~~~1 \> never happens \\ \> ~~~~~3 \> ~~~~~2 \> never happens \\ \> ~~~~~3 \> ~~~~~3 \> OK: elements are in the requested format \end{tabbing} \item The arguments returned for each value of JFORM ({\it cf}\/ Note~5: JFORM may not be the same as JFORMR) are as follows: \begin{tabbing} xxx \= xxxxxxxxxxxx \= xxxxxx \= xxxxxx \= \kill \> JFORM \> 1 \> 2 \> 3 \\ \\ \> EPOCH \> $t_0$ \> $t_0$ \> $T$ \\ \> ORBINC \> $i$ \> $i$ \> $i$ \\ \> ANODE \> $\Omega$ \> $\Omega$ \> $\Omega$ \\ \> PERIH \> $\varpi$ \> $\omega$ \> $\omega$ \\ \> AORQ \> $a$ \> $a$ \> $q$ \\ \> E \> $e$ \> $e$ \> $e$ \\ \> AORL \> $L$ \> $M$ \> - \\ \> DM \> $n$ \> - \> - \end{tabbing} where: \begin{tabbing} xxx \= xxxxxxxx \= xxx \= \kill \> $t_0$ \> is the epoch of the elements (MJD, TT) \\ \> $T$ \> is the epoch of perihelion (MJD, TT) \\ \> $i$ \> is the inclination (radians) \\ \> $\Omega$ \> is the longitude of the ascending node (radians) \\ \> $\varpi$ \> is the longitude of perihelion (radians) \\ \> $\omega$ \> is the argument of perihelion (radians) \\ \> $a$ \> is the mean distance (AU) \\ \> $q$ \> is the perihelion distance (AU) \\ \> $e$ \> is the eccentricity \\ \> $L$ \> is the longitude (radians, $0-2\pi$) \\ \> $M$ \> is the mean anomaly (radians, $0-2\pi$) \\ \> $n$ \> is the daily motion (radians) \\ \> - \> means no value is set \end{tabbing} \item At very small inclinations, the longitude of the ascending node ANODE becomes indeterminate and under some circumstances may be set arbitrarily to zero. Similarly, if the orbit is close to circular, the true anomaly becomes indeterminate and under some circumstances may be set arbitrarily to zero. In such cases, the other elements are automatically adjusted to compensate, and so the elements remain a valid description of the orbit. \end{enumerate} } \aref{Sterne, Theodore E., {\it An Introduction to Celestial Mechanics,}\/ Interscience Publishers, 1960.} %----------------------------------------------------------------------- \routine{SLA\_PV2UE}{Position/Velocity to Universal Elements} { \action{Construct a universal element set based on an instantaneous position and velocity.} \call{CALL sla\_PV2UE (PV, DATE, PMASS, U, JSTAT)} } \args{GIVEN} { \spec{PV}{D(6)}{heliocentric \xyzxyzd, equatorial, J2000} \\ \spec{}{}{\hspace{1.5em} (AU, AU/s; Note~1)} \\ \spec{DATE}{D}{date (TT Modified Julian Date = JD$-$2400000.5)} \\ \spec{PMASS}{D}{mass of the planet (Sun = 1; Note~2)} } \args{RETURNED} { \spec{U}{D(13)}{universal orbital elements (Note~3)} \\ \specel {(1)} {combined mass ($M+m$)} \\ \specel {(2)} {total energy of the orbit ($\alpha$)} \\ \specel {(3)} {reference (osculating) epoch ($t_0$)} \\ \specel {(4-6)} {position at reference epoch (${\rm \bf r}_0$)} \\ \specel {(7-9)} {velocity at reference epoch (${\rm \bf v}_0$)} \\ \specel {(10)} {heliocentric distance at reference epoch} \\ \specel {(11)} {${\rm \bf r}_0.{\rm \bf v}_0$} \\ \specel {(12)} {date ($t$)} \\ \specel {(13)} {universal eccentric anomaly ($\psi$) of date, approx} \\ \spec{JSTAT}{I}{status:} \\ \spec{}{}{\hspace{1.95em} 0 = OK} \\ \spec{}{}{\hspace{1.2em} $-$1 = illegal PMASS} \\ \spec{}{}{\hspace{1.2em} $-$2 = too close to Sun} \\ \spec{}{}{\hspace{1.2em} $-$3 = too slow} } \notes { \begin{enumerate} \item The PV 6-vector can be with respect to any chosen inertial frame, and the resulting universal-element set will be with respect to the same frame. A common choice will be mean equator and ecliptic of epoch J2000. \item The mass, PMASS, is important only for the larger planets. For most purposes ({\it e.g.}~asteroids) use 0D0. Values less than zero are illegal. \item The ``universal'' elements are those which define the orbit for the purposes of the method of universal variables (see reference). They consist of the combined mass of the two bodies, an epoch, and the position and velocity vectors (arbitrary reference frame) at that epoch. The parameter set used here includes also various quantities that can, in fact, be derived from the other information. This approach is taken to avoiding unnecessary computation and loss of accuracy. The supplementary quantities are (i)~$\alpha$, which is proportional to the total energy of the orbit, (ii)~the heliocentric distance at epoch, (iii)~the outwards component of the velocity at the given epoch, (iv)~an estimate of $\psi$, the ``universal eccentric anomaly'' at a given date and (v)~that date. \end{enumerate} } \aref{Everhart, E. \& Pitkin, E.T., Am.~J.~Phys.~51, 712, 1983.} %----------------------------------------------------------------------- \routine{SLA\_PVOBS}{Observatory Position \& Velocity} { \action{Position and velocity of an observing station.} \call{CALL sla\_PVOBS (P, H, STL, PV)} } \args{GIVEN} { \spec{P}{D}{latitude (geodetic, radians)} \\ \spec{H}{D}{height above reference spheroid (geodetic, metres)} \\ \spec{STL}{D}{local apparent sidereal time (radians)} } \args{RETURNED} { \spec{PV}{D(6)}{\xyzxyzd\ (AU, AU~s$^{-1}$, true equator and equinox of date)} } \anote{IAU 1976 constants are used.} %----------------------------------------------------------------------- \routine{SLA\_PXY}{Apply Linear Model} { \action{Given arrays of {\it expected}\/ and {\it measured}\, \xy\ coordinates, and a linear model relating them (as produced by sla\_FITXY), compute the array of {\it predicted}\/ coordinates and the RMS residuals.} \call{CALL sla\_PXY (NP,XYE,XYM,COEFFS,XYP,XRMS,YRMS,RRMS)} } \args{GIVEN} { \spec{NP}{I}{number of samples} \\ \spec{XYE}{D(2,NP)}{expected \xy\ for each sample} \\ \spec{XYM}{D(2,NP)}{measured \xy\ for each sample} \\ \spec{COEFFS}{D(6)}{coefficients of model (see below)} } \args{RETURNED} { \spec{XYP}{D(2,NP)}{predicted \xy\ for each sample} \\ \spec{XRMS}{D}{RMS in X} \\ \spec{YRMS}{D}{RMS in Y} \\ \spec{RRMS}{D }{total RMS (vector sum of XRMS and YRMS)} } \notes { \begin{enumerate} \item The model is supplied in the array COEFFS. Naming the six elements of COEFFS $a,b,c,d,e$ \& $f$, the model transforms {\it measured}\/ coordinates $[x_{m},y_{m}\,]$ into {\it predicted}\/ coordinates $[x_{p},y_{p}\,]$ as follows: \begin{verse} $x_{p} = a + bx_{m} + cy_{m}$ \\ $y_{p} = d + ex_{m} + fy_{m}$ \end{verse} \item The residuals are $(x_{p}-x_{e})$ and $(y_{p}-y_{e})$. \item If NP is less than or equal to zero, no coordinates are transformed, and the RMS residuals are all zero. \item See also sla\_FITXY, sla\_INVF, sla\_XY2XY, sla\_DCMPF \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_RANDOM}{Random Number} { \action{Generate pseudo-random real number in the range $0 \leq x < 1$.} \call{R~=~sla\_RANDOM (SEED)} } \args{GIVEN} { \spec{SEED}{R}{an arbitrary real number} } \args{RETURNED} { \spec{SEED}{R}{a new arbitrary value} \\ \spec{sla\_RANDOM}{R}{Pseudo-random real number $0 \leq x < 1$.} } \anote{The implementation is machine-dependent.} %----------------------------------------------------------------------- \routine{SLA\_RANGE}{Put Angle into Range $\pm\pi$} { \action{Normalize an angle into the range $\pm\pi$ (single precision).} \call{R~=~sla\_RANGE (ANGLE)} } \args{GIVEN} { \spec{ANGLE}{R}{angle in radians} } \args{RETURNED} { \spec{sla\_RANGE}{R}{ANGLE expressed in the range $\pm\pi$.} } %----------------------------------------------------------------------- \routine{SLA\_RANORM}{Put Angle into Range $0\!-\!2\pi$} { \action{Normalize an angle into the range $0\!-\!2\pi$ (single precision).} \call{R~=~sla\_RANORM (ANGLE)} } \args{GIVEN} { \spec{ANGLE}{R}{angle in radians} } \args{RETURNED} { \spec{sla\_RANORM}{R}{ANGLE expressed in the range $0\!-\!2\pi$} } %----------------------------------------------------------------------- \routine{SLA\_RCC}{Barycentric Coordinate Time} { \call{D~=~sla\_RCC (TDB, UT1, WL, U, V)} \action{The relativistic clock correction TDB$-$TT, the difference between {\it proper time}\, on Earth and {\it coordinate time}\/ in the solar system barycentric space-time frame of reference. The proper time is TT; the coordinate time is {\it an implementation}\/ of TDB.} } \args{GIVEN} { \spec{TDB}{D}{coordinate time (MJD: JD$-$2400000.5)} \\ \spec{UT1}{D}{universal time (fraction of one day)} \\ \spec{WL}{D}{clock longitude (radians west)} \\ \spec{U}{D}{clock distance from Earth spin axis (km)} \\ \spec{V}{D}{clock distance north of Earth equatorial plane (km)} } \args{RETURNED} { \spec{sla\_RCC}{D}{TDB$-$TT (sec)} } \notes { \begin{enumerate} \item TDB may be considered to be the coordinate time in the solar system barycentre frame of reference, and TT is the proper time given by clocks at mean sea level on the Earth. \item The result has a main (annual) sinusoidal term of amplitude approximately 1.66ms, plus planetary terms up to about 20$\mu$s, and lunar and diurnal terms up to 2$\mu$s. The variation arises from the transverse Doppler effect and the gravitational red-shift as the observer varies in speed and moves through different gravitational potentials. \item The argument TDB is, strictly, the barycentric coordinate time; however, the terrestrial proper time (TT) can in practice be used. \item The geocentric model is that of Fairhead \& Bretagnon (1990), in its full form. It was supplied by Fairhead (private communication) as a Fortran subroutine. A number of coding changes were made to this subroutine in order match the calling sequence of previous versions of the present routine, to comply with Starlink programming standards and to avoid compilation problems on certain machines. On the supported computer types, the numerical results are essentially unaffected by the changes. The topocentric model is from Moyer (1981) and Murray (1983). During the interval 1950-2050, the absolute accuracy of the geocentric model is better than $\pm3$~nanoseconds relative to direct numerical integrations using the JPL DE200/LE200 solar system ephemeris. \item The IAU definition of TDB is that it must differ from TT only by periodic terms. Though practical, this is an imprecise definition which ignores the existence of very long-period and secular effects in the dynamics of the solar system. As a consequence, different implementations of TDB will, in general, differ in zero-point and will drift linearly relative to one other. \end{enumerate} } \refs { \begin{enumerate} \item Fairhead, L.\ \& Bretagnon, P., 1990.\ {\it Astr.Astrophys.}\ {\bf 229}, 240-247. \item Moyer, T.D., 1981.\ {\it Cel.Mech.}\ {\bf 23}, 33. \item Murray, C.A., 1983,\ {\it Vectorial Astrometry}, Adam Hilger. \end{enumerate} } %------------------------------------------------------------------------------ \routine{SLA\_RDPLAN}{Apparent \radec\ of Planet} { \action{Approximate topocentric apparent \radec\ and angular size of a planet.} \call{CALL sla\_RDPLAN (DATE, NP, ELONG, PHI, RA, DEC, DIAM)} } \args{GIVEN} { \spec{DATE}{D}{MJD of observation (JD$-$2400000.5)} \\ \spec{NP}{I}{planet:} \\ \spec{}{}{\hspace{1.5em} 1\,=\,Mercury} \\ \spec{}{}{\hspace{1.5em} 2\,=\,Venus} \\ \spec{}{}{\hspace{1.5em} 3\,=\,Moon} \\ \spec{}{}{\hspace{1.5em} 4\,=\,Mars} \\ \spec{}{}{\hspace{1.5em} 5\,=\,Jupiter} \\ \spec{}{}{\hspace{1.5em} 6\,=\,Saturn} \\ \spec{}{}{\hspace{1.5em} 7\,=\,Uranus} \\ \spec{}{}{\hspace{1.5em} 8\,=\,Neptune} \\ \spec{}{}{\hspace{1.5em} 9\,=\,Pluto} \\ \spec{}{}{\hspace{0.44em} else\,=\,Sun} \\ \spec{ELONG,PHI}{D}{observer's longitude (east +ve) and latitude (radians)} } \args{RETURNED} { \spec{RA,DEC}{D}{topocentric apparent \radec\ (radians)} \\ \spec{DIAM}{D}{angular diameter (equatorial, radians)} } \notes { \begin{enumerate} \item The date is in a dynamical timescale (TDB, formerly ET) and is in the form of a Modified Julian Date (JD$-$2400000.5). For all practical purposes, TT can be used instead of TDB, and for many applications UT will do (except for the Moon). \item The longitude and latitude allow correction for geocentric parallax. This is a major effect for the Moon, but in the context of the limited accuracy of the present routine its effect on planetary positions is small (negligible for the outer planets). Geocentric positions can be generated by appropriate use of the routines sla\_DMOON and sla\_PLANET. \item The direction accuracy (arcsec, 1000-3000\,AD) is of order: \begin{tabbing} xxxxxxx \= xxxxxxxxxxxxxxxxxx \= \kill \> Sun \> \hspace{0.5em}5 \\ \> Mercury \> \hspace{0.5em}2 \\ \> Venus \> 10 \\ \> Moon \> 30 \\ \> Mars \> 50 \\ \> Jupiter \> 90 \\ \> Saturn \> 90 \\ \> Uranus \> 90 \\ \> Neptune \> 10 \\ \> Pluto \> \hspace{0.5em}1~~~(1885-2099\,AD only) \end{tabbing} The angular diameter accuracy is about 0.4\% for the Moon, and 0.01\% or better for the Sun and planets. For more information on accuracy, refer to the routines sla\_PLANET and sla\_DMOON, which the present routine uses. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_REFCO}{Refraction Constants} { \action{Determine the constants $a$ and $b$ in the atmospheric refraction model $\Delta \zeta = a \tan \zeta + b \tan^{3} \zeta$, where $\zeta$ is the {\it observed}\/ zenith distance ({\it i.e.}\ affected by refraction) and $\Delta \zeta$ is what to add to $\zeta$ to give the {\it topocentric}\, ({\it i.e.\ in vacuo}) zenith distance.} \call{CALL sla\_REFCO (HM, TDK, PMB, RH, WL, PHI, TLR, EPS, REFA, REFB)} } \args{GIVEN} { \spec{HM}{D}{height of the observer above sea level (metre)} \\ \spec{TDK}{D}{ambient temperature at the observer (degrees K)} \\ \spec{PMB}{D}{pressure at the observer (mB)} \\ \spec{RH}{D}{relative humidity at the observer (range 0\,--\,1)} \\ \spec{WL}{D}{effective wavelength of the source ($\mu{\rm m}$)} \\ \spec{PHI}{D}{latitude of the observer (radian, astronomical)} \\ \spec{TLR}{D}{temperature lapse rate in the troposphere (degrees K per metre)} \\ \spec{EPS}{D}{precision required to terminate iteration (radian)} } \args{RETURNED} { \spec{REFA}{D}{$\tan \zeta$ coefficient (radians)} \\ \spec{REFB}{D}{$\tan^{3} \zeta$ coefficient (radians)} } \notes { \begin{enumerate} \item Suggested values for the TLR and EPS arguments are 0.0065D0 and 1D$-$8 respectively. \item The radio refraction is chosen by specifying WL $>100$~$\mu{\rm m}$. \item The routine is a slower but more accurate alternative to the sla\_REFCOQ routine. The constants it produces give perfect agreement with sla\_REFRO at zenith distances $\tan^{-1} 1$ ($45^\circ$) and $\tan^{-1} 4$ ($\sim 76^\circ$). At other zenith distances, the model achieves: \arcsec{0}{5} accuracy for $\zeta<80^{\circ}$, \arcsec{0}{01} accuracy for $\zeta<60^{\circ}$, and \arcsec{0}{001} accuracy for $\zeta<45^{\circ}$. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_REFCOQ}{Refraction Constants (fast)} { \action{Determine the constants $a$ and $b$ in the atmospheric refraction model $\Delta \zeta = a \tan \zeta + b \tan^{3} \zeta$, where $\zeta$ is the {\it observed}\/ zenith distance ({\it i.e.}\ affected by refraction) and $\Delta \zeta$ is what to add to $\zeta$ to give the {\it topocentric}\, ({\it i.e.\ in vacuo}) zenith distance. (This is a fast alternative to the sla\_REFCO routine -- see notes.)} \call{CALL sla\_REFCOQ (TDK, PMB, RH, WL, REFA, REFB)} } \args{GIVEN} { \spec{TDK}{D}{ambient temperature at the observer (degrees K)} \\ \spec{PMB}{D}{pressure at the observer (mB)} \\ \spec{RH}{D}{relative humidity at the observer (range 0\,--\,1)} \\ \spec{WL}{D}{effective wavelength of the source ($\mu{\rm m}$)} } \args{RETURNED} { \spec{REFA}{D}{$\tan \zeta$ coefficient (radians)} \\ \spec{REFB}{D}{$\tan^{3} \zeta$ coefficient (radians)} } \notes { \begin{enumerate} \item The radio refraction is chosen by specifying WL $>100$~$\mu{\rm m}$. \item The model is an approximation, for moderate zenith distances, to the predictions of the sla\_REFRO routine. The approximation is maintained across a range of conditions, and applies to both optical/IR and radio. \item The algorithm is a fast alternative to the sla\_REFCO routine. The latter calls the sla\_REFRO routine itself: this involves integrations through a model atmosphere, and is costly in processor time. However, the model which is produced is precisely correct for two zenith distances ($45^\circ$ and $\sim\!76^\circ$) and at other zenith distances is limited in accuracy only by the $\Delta \zeta = a \tan \zeta + b \tan^{3} \zeta$ formulation itself. The present routine is not as accurate, though it satisfies most practical requirements. \item The model omits the effects of (i)~height above sea level (apart from the reduced pressure itself), (ii)~latitude ({\it i.e.}\ the flattening of the Earth) and (iii)~variations in tropospheric lapse rate. \item The model has been tested using the following range of conditions: \begin{itemize} \item [$\cdot$] lapse rates 0.0055, 0.0065, 0.0075~degrees K per metre \item [$\cdot$] latitudes $0^\circ$, $25^\circ$, $50^\circ$, $75^\circ$ \item [$\cdot$] heights 0, 2500, 5000 metres above sea level \item [$\cdot$] pressures mean for height $-10$\% to $+5$\% in steps of $5$\% \item [$\cdot$] temperatures $-10^\circ$ to $+20^\circ$ with respect to $280^\circ$K at sea level \item [$\cdot$] relative humidity 0, 0.5, 1 \item [$\cdot$] wavelength 0.4, 0.6, \ldots\ $2\mu{\rm m}$, + radio \item [$\cdot$] zenith distances $15^\circ$, $45^\circ$, $75^\circ$ \end{itemize} For the above conditions, the comparison with sla\_REFRO was as follows: \vspace{2ex} ~~~~~~~~~~ \begin{tabular}{|r|r|r|} \hline & {\it worst} & {\it RMS} \\ \hline optical/IR & 62 & 8 \\ radio & 319 & 49 \\ \hline & mas & mas \\ \hline \end{tabular} \vspace{3ex} For this particular set of conditions: \begin{itemize} \item [$\cdot$] lapse rate $6.5^\circ K km^{-1}$ \item [$\cdot$] latitude $50^\circ$ \item [$\cdot$] sea level \item [$\cdot$] pressure 1005\,mB \item [$\cdot$] temperature $7^\circ$C \item [$\cdot$] humidity 80\% \item [$\cdot$] wavelength 5740\,\.{A} \end{itemize} the results were as follows: \vspace{2ex} ~~~~~~~~~~ \begin{tabular}{|r|r|r|r|} \hline \multicolumn{1}{|c}{$\zeta$} & \multicolumn{1}{|c}{sla\_REFRO} & \multicolumn{1}{|c}{sla\_REFCOQ} & \multicolumn{1}{|c|}{Saastamoinen} \\ \hline 10 & 10.27 & 10.27 & 10.27 \\ 20 & 21.19 & 21.20 & 21.19 \\ 30 & 33.61 & 33.61 & 33.60 \\ 40 & 48.82 & 48.83 & 48.81 \\ 45 & 58.16 & 58.18 & 58.16 \\ 50 & 69.28 & 69.30 & 69.27 \\ 55 & 82.97 & 82.99 & 82.95 \\ 60 & 100.51 & 100.54 & 100.50 \\ 65 & 124.23 & 124.26 & 124.20 \\ 70 & 158.63 & 158.68 & 158.61 \\ 72 & 177.32 & 177.37 & 177.31 \\ 74 & 200.35 & 200.38 & 200.32 \\ 76 & 229.45 & 229.43 & 229.42 \\ 78 & 267.44 & 267.29 & 267.41 \\ 80 & 319.13 & 318.55 & 319.10 \\ \hline deg & arcsec & arcsec & arcsec \\ \hline \end{tabular} \vspace{3ex} The values for Saastamoinen's formula (which includes terms up to $\tan^5$) are taken from Hohenkerk and Sinclair (1985). The results from the much slower but more accurate sla\_REFCO routine have not been included in the tabulation as they are identical to those in the sla\_REFRO column to the \arcsec{0}{01} resolution used. \item Outlandish input parameters are silently limited to mathematically safe values. Zero pressure is permissible, and causes zeroes to be returned. \item The algorithm draws on several sources, as follows: \begin{itemize} \item The formula for the saturation vapour pressure of water as a function of temperature and temperature is taken from expressions A4.5-A4.7 of Gill (1982). \item The formula for the water vapour pressure, given the saturation pressure and the relative humidity is from Crane (1976), expression 2.5.5. \item The refractivity of air is a function of temperature, total pressure, water-vapour pressure and, in the case of optical/IR but not radio, wavelength. The formulae for the two cases are developed from the Essen and Froome expressions adopted in Resolution 1 of the 12th International Geodesy Association General Assembly (1963). \end{itemize} The above three items are as used in the sla\_REFRO routine. \begin{itemize} \item The formula for $\beta~(=H_0/r_0)$ is an adaption of expression 9 from Stone (1996). The adaptations, arrived at empirically, consist of (i)~a small adjustment to the coefficient and (ii)~a humidity term for the radio case only. \item The formulae for the refraction constants as a function of $n-1$ and $\beta$ are from Green (1987), expression 4.31. \end{itemize} \end{enumerate} } \refs { \begin{enumerate} \item Crane, R.K., Meeks, M.L.\ (ed), ``Refraction Effects in the Neutral Atmosphere'', {\it Methods of Experimental Physics: Astrophysics 12B,}\/ Academic Press, 1976. \item Gill, Adrian E., {\it Atmosphere-Ocean Dynamics,}\/ Academic Press, 1982. \item Hohenkerk, C.Y., \& Sinclair, A.T., NAO Technical Note No.~63, 1985. \item International Geodesy Association General Assembly, Bulletin G\'{e}od\'{e}sique {\bf 70} p390, 1963. \item Stone, Ronald C., P.A.S.P.~{\bf 108} 1051-1058, 1996. \item Green, R.M., {\it Spherical Astronomy,}\/ Cambridge University Press, 1987. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_REFRO}{Refraction} { \action{Atmospheric refraction, for radio or optical/IR wavelengths.} \call{CALL sla\_REFRO (ZOBS, HM, TDK, PMB, RH, WL, PHI, TLR, EPS, REF)} } \args{GIVEN} { \spec{ZOBS}{D}{observed zenith distance of the source (radians)} \\ \spec{HM}{D}{height of the observer above sea level (metre)} \\ \spec{TDK}{D}{ambient temperature at the observer (degrees K)} \\ \spec{PMB}{D}{pressure at the observer (mB)} \\ \spec{RH}{D}{relative humidity at the observer (range 0\,--\,1)} \\ \spec{WL}{D}{effective wavelength of the source ($\mu{\rm m}$)} \\ \spec{PHI}{D}{latitude of the observer (radian, astronomical)} \\ \spec{TLR}{D}{temperature lapse rate in the troposphere (degrees K per metre)} \\ \spec{EPS}{D}{precision required to terminate iteration (radian)} } \args{RETURNED} { \spec{REF}{D}{refraction: {\it in vacuo}\/ ZD minus observed ZD (radians)} } \notes { \begin{enumerate} \item A suggested value for the TLR argument is 0.0065D0. The refraction is significantly affected by TLR, and if studies of the local atmosphere have been carried out a better TLR value may be available. \item A suggested value for the EPS argument is 1D$-$8. The result is usually at least two orders of magnitude more computationally precise than the supplied EPS value. \item The routine computes the refraction for zenith distances up to and a little beyond $90^\circ$ using the method of Hohenkerk \& Sinclair (NAO Technical Notes 59 and 63, subsequently adopted in the {\it Explanatory Supplement to the Astronomical Almanac,}\/ 1992 -- see section 3.281). \item The code is based on the AREF optical/IR refraction subroutine of C.\,Hohenkerk (HMNAO, September 1984), with extensions to support the radio case. The modifications to the original HMNAO optical/IR refraction code which affect the results are: \begin{itemize} \item Murray's values for the gas constants have been used ({\it Vectorial Astrometry,}\/ Adam Hilger, 1983). \item A better model for $P_s(T)$ has been adopted (taken from Gill, {\it Atmosphere-Ocean Dynamics,}\/ Academic Press, 1982). \item More accurate expressions for $Pw_o$ have been adopted (again from Gill 1982). \item Provision for radio wavelengths has been added using expressions devised by A.\,T.\,Sinclair, RGO (private communication 1989), based on the Essen \& Froome refractivity formula adopted in Resolution~1 of the 12th International Geodesy Association General Assembly (Bulletin G\'{e}od\'{e}sique {\bf 70} p390, 1963). \end{itemize} None of the changes significantly affects the optical/IR results with respect to the algorithm given in the 1992 {\it Explanatory Supplement.}\/ For example, at $70^\circ$ zenith distance the present routine agrees with the ES algorithm to better than \arcsec{0}{05} for any reasonable combination of parameters. However, the improved water-vapour expressions do make a significant difference in the radio band, at $70^\circ$ zenith distance reaching almost \arcseci{4} for a hot, humid, low-altitude site during a period of low pressure. \item The radio refraction is chosen by specifying WL $>100$~$\mu{\rm m}$. Because the algorithm takes no account of the ionosphere, the accuracy deteriorates at low frequencies, below about 30\,MHz. \item Before use, the value of ZOBS is expressed in the range $\pm\pi$. If this ranged ZOBS is negative, the result REF is computed from its absolute value before being made negative to match. In addition, if it has an absolute value greater than $93^\circ$, a fixed REF value equal to the result for ZOBS~$=93^\circ$ is returned, appropriately signed. \item As in the original Hohenkerk and Sinclair algorithm, fixed values of the water vapour polytrope exponent, the height of the tropopause, and the height at which refraction is negligible are used. \item The radio refraction has been tested against work done by Iain~Coulson, JACH, (private communication 1995) for the James Clerk Maxwell Telescope, Mauna Kea. For typical conditions, agreement at the \arcsec{0}{1} level is achieved for moderate ZD, worsening to perhaps \arcsec{0}{5}\,--\,\arcsec{1}{0} at ZD $80^\circ$. At hot and humid sea-level sites the accuracy will not be as good. \item It should be noted that the relative humidity RH is formally defined in terms of ``mixing ratio'' rather than pressures or densities as is often stated. It is the mass of water per unit mass of dry air divided by that for saturated air at the same temperature and pressure (see Gill 1982). The familiar $\nu=p_w/p_s$ or $\nu=\rho_w/\rho_s$ expressions can differ from the formal definition by several percent, significant in the radio case. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_REFV}{Apply Refraction to Vector} { \action{Adjust an unrefracted Cartesian vector to include the effect of atmospheric refraction, using the simple $\Delta \zeta = a \tan \zeta + b \tan^{3} \zeta$ model.} \call{CALL sla\_REFV (VU, REFA, REFB, VR)} } \args{GIVEN} { \spec{VU}{D}{unrefracted position of the source (\azel\ 3-vector)} \\ \spec{REFA}{D}{$\tan \zeta$ coefficient (radians)} \\ \spec{REFB}{D}{$\tan^{3} \zeta$ coefficient (radians)} } \args{RETURNED} { \spec{VR}{D}{refracted position of the source (\azel\ 3-vector)} } \notes { \begin{enumerate} \item This routine applies the adjustment for refraction in the opposite sense to the usual one -- it takes an unrefracted ({\it in vacuo}\/) position and produces an observed (refracted) position, whereas the $\Delta \zeta = a \tan \zeta + b \tan^{3} \zeta$ model strictly applies to the case where an observed position is to have the refraction removed. The unrefracted to refracted case is harder, and requires an inverted form of the text-book refraction models; the algorithm used here is equivalent to one iteration of the Newton-Raphson method applied to the above formula. \item Though optimized for speed rather than precision, the present routine achieves consistency with the refracted-to-unrefracted $\Delta \zeta = a \tan \zeta + b \tan^{3} \zeta$ model at better than 1~microarcsecond within $30^\circ$ of the zenith and remains within 1~milliarcsecond to $\zeta=70^\circ$. The inherent accuracy of the model is, of course, far worse than this -- see the documentation for sla\_REFCO for more information. \item At low elevations (below about $3^\circ$) the refraction correction is held back to prevent arithmetic problems and wildly wrong results. Over a wide range of observer heights and corresponding temperatures and pressures, the following levels of accuracy are achieved, relative to numerical integration through a model atmosphere: \begin{center} \begin{tabular}{ccl} $\zeta_{obs}$ & {\it error} \\ \\ $80^\circ$ & \arcsec{0}{4} \\ $81^\circ$ & \arcsec{0}{8} \\ $82^\circ$ & \arcsec{1}{6} \\ $83^\circ$ & \arcseci{3} \\ $84^\circ$ & \arcseci{7} \\ $85^\circ$ & \arcseci{17} \\ $86^\circ$ & \arcseci{45} \\ $87^\circ$ & \arcseci{150} \\ $88^\circ$ & \arcseci{340} \\ $89^\circ$ & \arcseci{620} \\ $90^\circ$ & \arcseci{1100} \\ $91^\circ$ & \arcseci{1900} & $<$ high-altitude \\ $92^\circ$ & \arcseci{3200} & $<$ sites only \\ \end{tabular} \end{center} \item See also the routine sla\_REFZ, which performs the adjustment to the zenith distance rather than in \xyz . The present routine is faster than sla\_REFZ and, except very low down, is equally accurate for all practical purposes. However, beyond about $\zeta=84^\circ$ sla\_REFZ should be used, and for the utmost accuracy iterative use of sla\_REFRO should be considered. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_REFZ}{Apply Refraction to ZD} { \action{Adjust an unrefracted zenith distance to include the effect of atmospheric refraction, using the simple $\Delta \zeta = a \tan \zeta + b \tan^{3} \zeta$ model.} \call{CALL sla\_REFZ (ZU, REFA, REFB, ZR)} } \args{GIVEN} { \spec{ZU}{D}{unrefracted zenith distance of the source (radians)} \\ \spec{REFA}{D}{$\tan \zeta$ coefficient (radians)} \\ \spec{REFB}{D}{$\tan^{3} \zeta$ coefficient (radians)} } \args{RETURNED} { \spec{ZR}{D}{refracted zenith distance (radians)} } \notes { \begin{enumerate} \item This routine applies the adjustment for refraction in the opposite sense to the usual one -- it takes an unrefracted ({\it in vacuo}\/) position and produces an observed (refracted) position, whereas the $\Delta \zeta = a \tan \zeta + b \tan^{3} \zeta$ model strictly applies to the case where an observed position is to have the refraction removed. The unrefracted to refracted case is harder, and requires an inverted form of the text-book refraction models; the formula used here is based on the Newton-Raphson method. For the utmost numerical consistency with the refracted to unrefracted model, two iterations are carried out, achieving agreement at the $10^{-11}$~arcsecond level for $\zeta=80^\circ$. The inherent accuracy of the model is, of course, far worse than this -- see the documentation for sla\_REFCO for more information. \item At $\zeta=83^\circ$, the rapidly-worsening $\Delta \zeta = a \tan \zeta + b \tan^{3} \zeta$ model is abandoned and an empirical formula takes over: \[\Delta \zeta = F \left( \frac{0^\circ\hspace{-0.37em}.\hspace{0.02em}55445 - 0^\circ\hspace{-0.37em}.\hspace{0.02em}01133 E + 0^\circ\hspace{-0.37em}.\hspace{0.02em}00202 E^2} {1 + 0.28385 E +0.02390 E^2} \right) \] where $E=90^\circ-\zeta_{true}$ and $F$ is a factor chosen to meet the $\Delta \zeta = a \tan \zeta + b \tan^{3} \zeta$ formula at $\zeta=83^\circ$. Over a wide range of observer heights and corresponding temperatures and pressures, the following levels of accuracy are achieved, relative to numerical integration through a model atmosphere: \begin{center} \begin{tabular}{ccl} $\zeta_{obs}$ & {\it error} \\ \\ $80^\circ$ & \arcsec{0}{4} \\ $81^\circ$ & \arcsec{0}{8} \\ $82^\circ$ & \arcsec{1}{5} \\ $83^\circ$ & \arcsec{3}{2} \\ $84^\circ$ & \arcsec{4}{9} \\ $85^\circ$ & \arcsec{5}{8} \\ $86^\circ$ & \arcsec{6}{1} \\ $87^\circ$ & \arcsec{7}{1} \\ $88^\circ$ & \arcseci{11} \\ $89^\circ$ & \arcseci{21} \\ $90^\circ$ & \arcseci{43} \\ $91^\circ$ & \arcseci{92} & $<$ high-altitude \\ $92^\circ$ & \arcseci{220} & $<$ sites only \\ \end{tabular} \end{center} \item See also the routine sla\_REFV, which performs the adjustment in \xyz , and with the emphasis on speed rather than numerical accuracy. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_RVEROT}{RV Corrn to Earth Centre} { \action{Velocity component in a given direction due to Earth rotation.} \call{R~=~sla\_RVEROT (PHI, RA, DA, ST)} } \args{GIVEN} { \spec{PHI}{R}{geodetic latitude of observing station (radians)} \\ \spec{RA,DA}{R}{apparent \radec\ (radians)} \\ \spec{ST}{R}{local apparent sidereal time (radians)} } \args{RETURNED} { \spec{sla\_RVEROT}{R}{Component of Earth rotation in direction RA,DA (km~s$^{-1}$)} } \notes { \begin{enumerate} \item Sign convention: the result is positive when the observatory is receding from the given point on the sky. \item Accuracy: the simple algorithm used assumes a spherical Earth and an observing station at sea level; for actual observing sites, the error is unlikely to be greater than 0.0005~km~s$^{-1}$. For applications requiring greater precision, use the routine sla\_PVOBS. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_RVGALC}{RV Corrn to Galactic Centre} { \action{Velocity component in a given direction due to the rotation of the Galaxy.} \call{R~=~sla\_RVGALC (R2000, D2000)} } \args{GIVEN} { \spec{R2000,D2000}{R}{J2000.0 mean \radec\ (radians)} } \args{RETURNED} { \spec{sla\_RVGALC}{R}{Component of dynamical LSR motion in direction R2000,D2000 (km~s$^{-1}$)} } \notes { \begin{enumerate} \item Sign convention: the result is positive when the LSR is receding from the given point on the sky. \item The Local Standard of Rest used here is a point in the vicinity of the Sun which is in a circular orbit around the Galactic centre. Sometimes called the {\it dynamical}\/ LSR, it is not to be confused with a {\it kinematical}\/ LSR, which is the mean standard of rest of star catalogues or stellar populations. \item The dynamical LSR velocity due to Galactic rotation is assumed to be 220~km~s$^{-1}$ towards $l^{I\!I}=90^{\circ}$, $b^{I\!I}=0$. \end{enumerate} } \aref{Kerr \& Lynden-Bell (1986), MNRAS, 221, p1023.} %----------------------------------------------------------------------- \routine{SLA\_RVLG}{RV Corrn to Local Group} { \action{Velocity component in a given direction due to the combination of the rotation of the Galaxy and the motion of the Galaxy relative to the mean motion of the local group.} \call{R~=~sla\_RVLG (R2000, D2000)} } \args{GIVEN} { \spec{R2000,D2000}{R}{J2000.0 mean \radec\ (radians)} } \args{RETURNED} { \spec{sla\_RVLG}{R}{Component of {\bf solar} ({\it n.b.}) motion in direction R2000,D2000 (km~s$^{-1}$)} } \anote{Sign convention: the result is positive when the Sun is receding from the given point on the sky.} \aref{{\it IAU Trans.}\ 1976.\ {\bf 16B}, p201.} %----------------------------------------------------------------------- \routine{SLA\_RVLSRD}{RV Corrn to Dynamical LSR} { \action{Velocity component in a given direction due to the Sun's motion with respect to the ``dynamical'' Local Standard of Rest.} \call{R~=~sla\_RVLSRD (R2000, D2000)} } \args{GIVEN} { \spec{R2000,D2000}{R}{J2000.0 mean \radec\ (radians)} } \args{RETURNED} { \spec{sla\_RVLSRD}{R}{Component of {\it peculiar}\/ solar motion in direction R2000,D2000 (km~s$^{-1}$)} } \notes { \begin{enumerate} \item Sign convention: the result is positive when the Sun is receding from the given point on the sky. \item The Local Standard of Rest used here is the {\it dynamical}\/ LSR, a point in the vicinity of the Sun which is in a circular orbit around the Galactic centre. The Sun's motion with respect to the dynamical LSR is called the {\it peculiar}\/ solar motion. \item There is another type of LSR, called a {\it kinematical}\/ LSR. A kinematical LSR is the mean standard of rest of specified star catalogues or stellar populations, and several slightly different kinematical LSRs are in use. The Sun's motion with respect to an agreed kinematical LSR is known as the {\it standard}\/ solar motion. The dynamical LSR is seldom used by observational astronomers, who conventionally use a kinematical LSR such as the one implemented in the routine sla\_RVLSRK. \item The peculiar solar motion is from Delhaye (1965), in {\it Stars and Stellar Systems}, vol~5, p73: in Galactic Cartesian coordinates (+9,+12,+7)~km~s$^{-1}$. This corresponds to about 16.6~km~s$^{-1}$ towards Galactic coordinates $l^{I\!I}=53^{\circ},b^{I\!I}=+25^{\circ}$. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_RVLSRK}{RV Corrn to Kinematical LSR} { \action{Velocity component in a given direction due to the Sun's motion with respect to a kinematical Local Standard of Rest.} \call{R~=~sla\_RVLSRK (R2000, D2000)} } \args{GIVEN} { \spec{R2000,D2000}{R}{J2000.0 mean \radec\ (radians)} } \args{RETURNED} { \spec{sla\_RVLSRK}{R}{Component of {\it standard}\/ solar motion in direction R2000,D2000 (km~s$^{-1}$)} } \notes { \begin{enumerate} \item Sign convention: the result is positive when the Sun is receding from the given point on the sky. \item The Local Standard of Rest used here is one of several {\it kinematical}\/ LSRs in common use. A kinematical LSR is the mean standard of rest of specified star catalogues or stellar populations. The Sun's motion with respect to a kinematical LSR is known as the {\it standard}\/ solar motion. \item There is another sort of LSR, seldom used by observational astronomers, called the {\it dynamical}\/ LSR. This is a point in the vicinity of the Sun which is in a circular orbit around the Galactic centre. The Sun's motion with respect to the dynamical LSR is called the {\it peculiar}\/ solar motion. To obtain a radial velocity correction with respect to the dynamical LSR use the routine sla\_RVLSRD. \item The adopted standard solar motion is 20~km~s$^{-1}$ towards $\alpha=18^{\rm h},\delta=+30^{\circ}$ (1900). \end{enumerate} } \refs { \begin{enumerate} \item Delhaye (1965), in {\it Stars and Stellar Systems}, vol~5, p73. \item {\it Methods of Experimental Physics}\/ (ed Meeks), vol~12, part~C, sec~6.1.5.2, p281. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_S2TP}{Spherical to Tangent Plane} { \action{Projection of spherical coordinates onto the tangent plane (single precision).} \call{CALL sla\_S2TP (RA, DEC, RAZ, DECZ, XI, ETA, J)} } \args{GIVEN} { \spec{RA,DEC}{R}{spherical coordinates of star (radians)} \\ \spec{RAZ,DECZ}{R}{spherical coordinates of tangent point (radians)} } \args{RETURNED} { \spec{XI,ETA}{R}{tangent plane coordinates (radians)} \\ \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 0 = OK, star on tangent plane} \\ \spec{}{}{\hspace{1.5em} 1 = error, star too far from axis} \\ \spec{}{}{\hspace{1.5em} 2 = error, antistar on tangent plane} \\ \spec{}{}{\hspace{1.5em} 3 = error, antistar too far from axis} } \notes { \begin{enumerate} \item The projection is called the {\it gnomonic}\/ projection; the Cartesian coordinates \xieta\ are called {\it standard coordinates.}\/ The latter are in units of the distance from the tangent plane to the projection point, {\it i.e.}\ radians near the origin. \item When working in \xyz\ rather than spherical coordinates, the equivalent Cartesian routine sla\_V2TP is available. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_SEP}{Angle Between 2 Points on Sphere} { \action{Angle between two points on a sphere (single precision).} \call{R~=~sla\_SEP (A1, B1, A2, B2)} } \args{GIVEN} { \spec{A1,B1}{R}{spherical coordinates of one point (radians)} \\ \spec{A2,B2}{R}{spherical coordinates of the other point (radians)} } \args{RETURNED} { \spec{sla\_SEP}{R}{angle between [A1,B1] and [A2,B2] in radians} } \notes { \begin{enumerate} \item The spherical coordinates are right ascension and declination, longitude and latitude, {\it etc.}\ in radians. \item The result is always positive. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_SMAT}{Solve Simultaneous Equations} { \action{Matrix inversion and solution of simultaneous equations (single precision).} \call{CALL sla\_SMAT (N, A, Y, D, JF, IW)} } \args{GIVEN} { \spec{N}{I}{number of unknowns} \\ \spec{A}{R(N,N)}{matrix} \\ \spec{Y}{R(N)}{vector} } \args{RETURNED} { \spec{A}{R(N,N)}{matrix inverse} \\ \spec{Y}{R(N)}{solution} \\ \spec{D}{R}{determinant} \\ \spec{JF}{I}{singularity flag: 0=OK} \\ \spec{IW}{I(N)}{workspace} } \notes { \begin{enumerate} \item For the set of $n$ simultaneous linear equations in $n$ unknowns: \begin{verse} {\bf A}$\cdot${\bf y} = {\bf x} \end{verse} where: \begin{itemize} \item {\bf A} is a non-singular $n \times n$ matrix, \item {\bf y} is the vector of $n$ unknowns, and \item {\bf x} is the known vector, \end{itemize} sla\_SMAT computes: \begin{itemize} \item the inverse of matrix {\bf A}, \item the determinant of matrix {\bf A}, and \item the vector of $n$ unknowns {\bf y}. \end{itemize} Argument N is the order $n$, A (given) is the matrix {\bf A}, Y (given) is the vector {\bf x} and Y (returned) is the vector {\bf y}. The argument A (returned) is the inverse matrix {\bf A}$^{-1}$, and D is {\it det}\/({\bf A}). \item JF is the singularity flag. If the matrix is non-singular, JF=0 is returned. If the matrix is singular, JF=$-$1 and D=0.0 are returned. In the latter case, the contents of array A on return are undefined. \item The algorithm is Gaussian elimination with partial pivoting. This method is very fast; some much slower algorithms can give better accuracy, but only by a small factor. \item This routine replaces the obsolete sla\_SMATRX. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_SUBET}{Remove E-terms} { \action{Remove the E-terms (elliptic component of annual aberration) from a pre IAU~1976 catalogue \radec\ to give a mean place.} \call{CALL sla\_SUBET (RC, DC, EQ, RM, DM)} } \args{GIVEN} { \spec{RC,DC}{D}{\radec\ with E-terms included (radians)} \\ \spec{EQ}{D}{Besselian epoch of mean equator and equinox} } \args{RETURNED} { \spec{RM,DM}{D}{\radec\ without E-terms (radians)} } \anote{Most star positions from pre-1984 optical catalogues (or obtained by astrometry with respect to such stars) have the E-terms built-in. This routine converts such a position to a formal mean place (allowing, for example, comparison with a pulsar timing position).} \aref{{\it Explanatory Supplement to the Astronomical Ephemeris}, section 2D, page 48.} %----------------------------------------------------------------------- \routine{SLA\_SUPGAL}{Supergalactic to Galactic} { \action{Transformation from de Vaucouleurs supergalactic coordinates to IAU 1958 galactic coordinates.} \call{CALL sla\_GALSUP (DL, DB, DSL, DSB)} } \args{GIVEN} { \spec{DSL,DSB}{D}{supergalactic longitude and latitude (radians)} } \args{RETURNED} { \spec{DL,DB}{D}{galactic longitude and latitude \gal\ (radians)} } \refs { \begin{enumerate} \item de Vaucouleurs, de Vaucouleurs, \& Corwin, {\it Second Reference Catalogue of Bright Galaxies}, U.Texas, p8. \item Systems \& Applied Sciences Corp., documentation for the machine-readable version of the above catalogue, Contract NAS 5-26490. \end{enumerate} (These two references give different values for the galactic longitude of the supergalactic origin. Both are wrong; the correct value is $l^{I\!I}=137.37$.) } %------------------------------------------------------------------------------ \routine{SLA\_SVD}{Singular Value Decomposition} { \action{Singular value decomposition. This routine expresses a given matrix {\bf A} as the product of three matrices {\bf U}, {\bf W}, {\bf V}$^{T}$: \begin{tabbing} XXXXXX \= \kill \> {\bf A} = {\bf U} $\cdot$ {\bf W} $\cdot$ {\bf V}$^{T}$ \end{tabbing} where: \begin{tabbing} XXXXXX \= XXXX \= \kill \> {\bf A} \> is any $m$ (rows) $\times n$ (columns) matrix, where $m \geq n$ \\ \> {\bf U} \> is an $m \times n$ column-orthogonal matrix \\ \> {\bf W} \> is an $n \times n$ diagonal matrix with $w_{ii} \geq 0$ \\ \> {\bf V}$^{T}$ \> is the transpose of an $n \times n$ orthogonal matrix \end{tabbing} } \call{CALL sla\_SVD (M, N, MP, NP, A, W, V, WORK, JSTAT)} } \args{GIVEN} { \spec{M,N}{I}{$m$, $n$, the numbers of rows and columns in matrix {\bf A}} \\ \spec{MP,NP}{I}{physical dimensions of array containing matrix {\bf A}} \\ \spec{A}{D(MP,NP)}{array containing $m \times n$ matrix {\bf A}} } \args{RETURNED} { \spec{A}{D(MP,NP)}{array containing $m \times n$ column-orthogonal matrix {\bf U}} \\ \spec{W}{D(N)}{$n \times n$ diagonal matrix {\bf W} (diagonal elements only)} \\ \spec{V}{D(NP,NP)}{array containing $n \times n$ orthogonal matrix {\bf V} ({\it n.b.}\ not {\bf V}$^{T}$)} \\ \spec{WORK}{D(N)}{workspace} \\ \spec{JSTAT}{I}{0~=~OK, $-$1~=~array A wrong shape, $>$0~=~index of W for which convergence failed (see note~3, below)} } \notes { \begin{enumerate} \item M and N are the {\it logical}\/ dimensions of the matrices and vectors concerned, which can be located in arrays of larger {\it physical}\/ dimensions, given by MP and NP. \item V contains matrix V, not the transpose of matrix V. \item If the status JSTAT is greater than zero, this need not necessarily be treated as a failure. It means that, due to chance properties of the matrix A, the QR transformation phase of the routine did not fully converge in a predefined number of iterations, something that very seldom occurs. When this condition does arise, it is possible that the elements of the diagonal matrix W have not been correctly found. However, in practice the results are likely to be trustworthy. Applications should report the condition as a warning, but then proceed normally. \end{enumerate} } \refs{The algorithm is an adaptation of the routine SVD in the {\it EISPACK}\, library (Garbow~{\it et~al.}\ 1977, {\it EISPACK Guide Extension}, Springer Verlag), which is a FORTRAN~66 implementation of the Algol routine SVD of Wilkinson \& Reinsch 1971 ({\it Handbook for Automatic Computation}, vol~2, ed Bauer~{\it et~al.}, Springer Verlag). These references give full details of the algorithm used here. A good account of the use of SVD in least squares problems is given in {\it Numerical Recipes}\/ (Press~{\it et~al.}\ 1987, Cambridge University Press), which includes another variant of the EISPACK code.} %----------------------------------------------------------------------- \routine{SLA\_SVDCOV}{Covariance Matrix from SVD} { \action{From the {\bf W} and {\bf V} matrices from the SVD factorization of a matrix (as obtained from the sla\_SVD routine), obtain the covariance matrix.} \call{CALL sla\_SVDCOV (N, NP, NC, W, V, WORK, CVM)} } \args{GIVEN} { \spec{N}{I}{$n$, the number of rows and columns in matrices {\bf W} and {\bf V}} \\ \spec{NP}{I}{first dimension of array containing $n \times n$ matrix {\bf V}} \\ \spec{NC}{I}{first dimension of array CVM} \\ \spec{W}{D(N)}{$n \times n$ diagonal matrix {\bf W} (diagonal elements only)} \\ \spec{V}{D(NP,NP)}{array containing $n \times n$ orthogonal matrix {\bf V}} } \args{RETURNED} { \spec{WORK}{D(N)}{workspace} \\ \spec{CVM}{D(NC,NC)}{array to receive covariance matrix} } \aref{{\it Numerical Recipes}, section 14.3.} %----------------------------------------------------------------------- \routine{SLA\_SVDSOL}{Solution Vector from SVD} { \action{From a given vector and the SVD of a matrix (as obtained from the sla\_SVD routine), obtain the solution vector. This routine solves the equation: \begin{tabbing} XXXXXX \= \kill \> {\bf A} $\cdot$ {\bf x} = {\bf b} \end{tabbing} where: \begin{tabbing} XXXXXX \= XXXX \= \kill \> {\bf A} \> is a given $m$ (rows) $\times n$ (columns) matrix, where $m \geq n$ \\ \> {\bf x} \> is the $n$-vector we wish to find, and \\ \> {\bf b} \> is a given $m$-vector \end{tabbing} by means of the {\it Singular Value Decomposition}\/ method (SVD).} \call{CALL sla\_SVDSOL (M, N, MP, NP, B, U, W, V, WORK, X)} } \args{GIVEN} { \spec{M,N}{I}{$m$, $n$, the numbers of rows and columns in matrix {\bf A}} \\ \spec{MP,NP}{I}{physical dimensions of array containing matrix {\bf A}} \\ \spec{B}{D(M)}{known vector {\bf b}} \\ \spec{U}{D(MP,NP)}{array containing $m \times n$ matrix {\bf U}} \\ \spec{W}{D(N)}{$n \times n$ diagonal matrix {\bf W} (diagonal elements only)} \\ \spec{V}{D(NP,NP)}{array containing $n \times n$ orthogonal matrix {\bf V}} } \args{RETURNED} { \spec{WORK}{D(N)}{workspace} \\ \spec{X}{D(N)}{unknown vector {\bf x}} } \notes { \begin{enumerate} \item In the Singular Value Decomposition method (SVD), the matrix {\bf A} is first factorized (for example by the routine sla\_SVD) into the following components: \begin{tabbing} XXXXXX \= \kill \> {\bf A} = {\bf U} $\cdot$ {\bf W} $\cdot$ {\bf V}$^{T}$ \end{tabbing} where: \begin{tabbing} XXXXXX \= XXXX \= \kill \> {\bf A} \> is any $m$ (rows) $\times n$ (columns) matrix, where $m > n$ \\ \> {\bf U} \> is an $m \times n$ column-orthogonal matrix \\ \> {\bf W} \> is an $n \times n$ diagonal matrix with $w_{ii} \geq 0$ \\ \> {\bf V}$^{T}$ \> is the transpose of an $n \times n$ orthogonal matrix \end{tabbing} Note that $m$ and $n$ are the {\it logical}\/ dimensions of the matrices and vectors concerned, which can be located in arrays of larger {\it physical}\/ dimensions MP and NP. The solution is then found from the expression: \begin{tabbing} XXXXXX \= \kill \> {\bf x} = {\bf V} $\cdot~[diag(1/${\bf W}$_{j})] \cdot (${\bf U}$^{T} \cdot${\bf b}) \end{tabbing} \item If matrix {\bf A} is square, and if the diagonal matrix {\bf W} is not altered, the method is equivalent to conventional solution of simultaneous equations. \item If $m > n$, the result is a least-squares fit. \item If the solution is poorly determined, this shows up in the SVD factorization as very small or zero {\bf W}$_{j}$ values. Where a {\bf W}$_{j}$ value is small but non-zero it can be set to zero to avoid ill effects. The present routine detects such zero {\bf W}$_{j}$ values and produces a sensible solution, with highly correlated terms kept under control rather than being allowed to elope to infinity, and with meaningful values for the other terms. \end{enumerate} } \aref{{\it Numerical Recipes}, section 2.9.} %----------------------------------------------------------------------- \routine{SLA\_TP2S}{Tangent Plane to Spherical} { \action{Transform tangent plane coordinates into spherical coordinates (single precision)} \call{CALL sla\_TP2S (XI, ETA, RAZ, DECZ, RA, DEC)} } \args{GIVEN} { \spec{XI,ETA}{R}{tangent plane rectangular coordinates (radians)} \\ \spec{RAZ,DECZ}{R}{spherical coordinates of tangent point (radians)} } \args{RETURNED} { \spec{RA,DEC}{R}{spherical coordinates (radians)} } \notes { \begin{enumerate} \item The projection is called the {\it gnomonic}\/ projection; the Cartesian coordinates \xieta\ are called {\it standard coordinates.}\/ The latter are in units of the distance from the tangent plane to the projection point, {\it i.e.}\ radians near the origin. \item When working in \xyz\ rather than spherical coordinates, the equivalent Cartesian routine sla\_TP2V is available. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_TP2V}{Tangent Plane to Direction Cosines} { \action{Given the tangent-plane coordinates of a star and the direction cosines of the tangent point, determine the direction cosines of the star (single precision).} \call{CALL sla\_TP2V (XI, ETA, V0, V)} } \args{GIVEN} { \spec{XI,ETA}{R}{tangent plane coordinates of star (radians)} \\ \spec{V0}{R(3)}{direction cosines of tangent point} } \args{RETURNED} { \spec{V}{R(3)}{direction cosines of star} } \notes { \begin{enumerate} \item If vector V0 is not of unit length, the returned vector V will be wrong. \item If vector V0 points at a pole, the returned vector V will be based on the arbitrary assumption that $\alpha=0$ at the tangent point. \item The projection is called the {\it gnomonic}\/ projection; the Cartesian coordinates \xieta\ are called {\it standard coordinates.}\/ The latter are in units of the distance from the tangent plane to the projection point, {\it i.e.}\ radians near the origin. \item This routine is the Cartesian equivalent of the routine sla\_TP2S. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_TPS2C}{Plate centre from $\xi,\eta$ and $\alpha,\delta$} { \action{From the tangent plane coordinates of a star of known \radec, determine the \radec\ of the tangent point (single precision)} \call{CALL sla\_TPS2C (XI, ETA, RA, DEC, RAZ1, DECZ1, RAZ2, DECZ2, N)} } \args{GIVEN} { \spec{XI,ETA}{R}{tangent plane rectangular coordinates (radians)} \\ \spec{RA,DEC}{R}{spherical coordinates (radians)} } \args{RETURNED} { \spec{RAZ1,DECZ1}{R}{spherical coordinates of tangent point, solution 1} \\ \spec{RAZ2,DECZ2}{R}{spherical coordinates of tangent point, solution 2} \\ \spec{N}{I}{number of solutions:} \\ \spec{}{}{\hspace{1em} 0 = no solutions returned (note 2)} \\ \spec{}{}{\hspace{1em} 1 = only the first solution is useful (note 3)} \\ \spec{}{}{\hspace{1em} 2 = there are two useful solutions (note 3)} } \notes { \begin{enumerate} \item The RAZ1 and RAZ2 values returned are in the range $0\!-\!2\pi$. \item Cases where there is no solution can only arise near the poles. For example, it is clearly impossible for a star at the pole itself to have a non-zero $\xi$ value, and hence it is meaningless to ask where the tangent point would have to be to bring about this combination of $\xi$ and $\delta$. \item Also near the poles, cases can arise where there are two useful solutions. The argument N indicates whether the second of the two solutions returned is useful. N\,=\,1 indicates only one useful solution, the usual case; under these circumstances, the second solution corresponds to the ``over-the-pole'' case, and this is reflected in the values of RAZ2 and DECZ2 which are returned. \item The DECZ1 and DECZ2 values returned are in the range $\pm\pi$, but in the ordinary, non-pole-crossing, case, the range is $\pm\pi/2$. \item RA, DEC, RAZ1, DECZ1, RAZ2, DECZ2 are all in radians. \item The projection is called the {\it gnomonic}\/ projection; the Cartesian coordinates \xieta\ are called {\it standard coordinates.}\/ The latter are in units of the distance from the tangent plane to the projection point, {\it i.e.}\ radians near the origin. \item When working in \xyz\ rather than spherical coordinates, the equivalent Cartesian routine sla\_TPV2C is available. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_TPV2C}{Plate centre from $\xi,\eta$ and $x,y,z$} { \action{From the tangent plane coordinates of a star of known direction cosines, determine the direction cosines of the tangent point (single precision)} \call{CALL sla\_TPV2C (XI, ETA, V, V01, V02, N)} } \args{GIVEN} { \spec{XI,ETA}{R}{tangent plane coordinates of star (radians)} \\ \spec{V}{R(3)}{direction cosines of star} } \args{RETURNED} { \spec{V01}{R(3)}{direction cosines of tangent point, solution 1} \\ \spec{V01}{R(3)}{direction cosines of tangent point, solution 2} \\ \spec{N}{I}{number of solutions:} \\ \spec{}{}{\hspace{1em} 0 = no solutions returned (note 2)} \\ \spec{}{}{\hspace{1em} 1 = only the first solution is useful (note 3)} \\ \spec{}{}{\hspace{1em} 2 = there are two useful solutions (note 3)} } \notes { \begin{enumerate} \item The vector V must be of unit length or the result will be wrong. \item Cases where there is no solution can only arise near the poles. For example, it is clearly impossible for a star at the pole itself to have a non-zero XI value. \item Also near the poles, cases can arise where there are two useful solutions. The argument N indicates whether the second of the two solutions returned is useful. N\,=\,1 indicates only one useful solution, the usual case; under these circumstances, the second solution can be regarded as valid if the vector V02 is interpreted as the ``over-the-pole'' case. \item The projection is called the {\it gnomonic}\/ projection; the Cartesian coordinates \xieta\ are called {\it standard coordinates.}\/ The latter are in units of the distance from the tangent plane to the projection point, {\it i.e.}\ radians near the origin. \item This routine is the Cartesian equivalent of the routine sla\_TPS2C. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_UE2EL}{Universal to Conventional Elements} { \action{Transform universal elements into conventional heliocentric osculating elements.} \call{CALL sla\_UE2EL (\vtop{ \hbox{U, JFORMR,} \hbox{JFORM, EPOCH, ORBINC, ANODE, PERIH,} \hbox{AORQ, E, AORL, DM, JSTAT)}}} } \args{GIVEN} { \spec{U}{D(13)}{universal orbital elements (updated; Note~1)} \\ \specel {(1)} {combined mass ($M+m$)} \\ \specel {(2)} {total energy of the orbit ($\alpha$)} \\ \specel {(3)} {reference (osculating) epoch ($t_0$)} \\ \specel {(4-6)} {position at reference epoch (${\rm \bf r}_0$)} \\ \specel {(7-9)} {velocity at reference epoch (${\rm \bf v}_0$)} \\ \specel {(10)} {heliocentric distance at reference epoch} \\ \specel {(11)} {${\rm \bf r}_0.{\rm \bf v}_0$} \\ \specel {(12)} {date ($t$)} \\ \specel {(13)} {universal eccentric anomaly ($\psi$) of date, approx} \\ \\ \spec{JFORMR}{I}{requested element set (1-3; Note~3)} } \args{RETURNED} { \spec{JFORM}{I}{element set actually returned (1-3; Note~4)} \\ \spec{EPOCH}{D}{epoch of elements ($t_0$ or $T$, TT MJD)} \\ \spec{ORBINC}{D}{inclination ($i$, radians)} \\ \spec{ANODE}{D}{longitude of the ascending node ($\Omega$, radians)} \\ \spec{PERIH}{D}{longitude or argument of perihelion ($\varpi$ or $\omega$,} \\ \spec{}{}{\hspace{1.5em} radians)} \\ \spec{AORQ}{D}{mean distance or perihelion distance ($a$ or $q$, AU)} \\ \spec{E}{D}{eccentricity ($e$)} \\ \spec{AORL}{D}{mean anomaly or longitude ($M$ or $L$, radians,} \\ \spec{}{}{\hspace{1.5em} JFORM=1,2 only)} \\ \spec{DM}{D}{daily motion ($n$, radians, JFORM=1 only)} \\ \spec{JSTAT}{I}{status:} \\ \spec{}{}{\hspace{2.3em} 0 = OK} \\ \spec{}{}{\hspace{1.5em} $-$1 = illegal PMASS} \\ \spec{}{}{\hspace{1.5em} $-$2 = illegal JFORMR} \\ \spec{}{}{\hspace{1.5em} $-$3 = position/velocity out of allowed range} } \notes { \begin{enumerate} \setlength{\parskip}{\medskipamount} \item The ``universal'' elements are those which define the orbit for the purposes of the method of universal variables (see reference 2). They consist of the combined mass of the two bodies, an epoch, and the position and velocity vectors (arbitrary reference frame) at that epoch. The parameter set used here includes also various quantities that can, in fact, be derived from the other information. This approach is taken to avoiding unnecessary computation and loss of accuracy. The supplementary quantities are (i)~$\alpha$, which is proportional to the total energy of the orbit, (ii)~the heliocentric distance at epoch, (iii)~the outwards component of the velocity at the given epoch, (iv)~an estimate of $\psi$, the ``universal eccentric anomaly'' at a given date and (v)~that date. \item The universal elements are with respect to the mean equator and equinox of epoch J2000. The orbital elements produced are with respect to the J2000 ecliptic and mean equinox. \item Three different element-format options are supported, as follows. \\ JFORM=1, suitable for the major planets: \begin{tabbing} xxx \= xxxxxxxx \= xx \= \kill \> EPOCH \> = \> epoch of elements $t_0$ (TT MJD) \\ \> ORBINC \> = \> inclination $i$ (radians) \\ \> ANODE \> = \> longitude of the ascending node $\Omega$ (radians) \\ \> PERIH \> = \> longitude of perihelion $\varpi$ (radians) \\ \> AORQ \> = \> mean distance $a$ (AU) \\ \> E \> = \> eccentricity $e$ $( 0 \leq e < 1 )$ \\ \> AORL \> = \> mean longitude $L$ (radians) \\ \> DM \> = \> daily motion $n$ (radians) \end{tabbing} JFORM=2, suitable for minor planets: \begin{tabbing} xxx \= xxxxxxxx \= xx \= \kill \> EPOCH \> = \> epoch of elements $t_0$ (TT MJD) \\ \> ORBINC \> = \> inclination $i$ (radians) \\ \> ANODE \> = \> longitude of the ascending node $\Omega$ (radians) \\ \> PERIH \> = \> argument of perihelion $\omega$ (radians) \\ \> AORQ \> = \> mean distance $a$ (AU) \\ \> E \> = \> eccentricity $e$ $( 0 \leq e < 1 )$ \\ \> AORL \> = \> mean anomaly $M$ (radians) \end{tabbing} JFORM=3, suitable for comets: \begin{tabbing} xxx \= xxxxxxxx \= xx \= \kill \> EPOCH \> = \> epoch of perihelion $T$ (TT MJD) \\ \> ORBINC \> = \> inclination $i$ (radians) \\ \> ANODE \> = \> longitude of the ascending node $\Omega$ (radians) \\ \> PERIH \> = \> argument of perihelion $\omega$ (radians) \\ \> AORQ \> = \> perihelion distance $q$ (AU) \\ \> E \> = \> eccentricity $e$ $( 0 \leq e \leq 10 )$ \end{tabbing} \item It may not be possible to generate elements in the form requested through JFORMR. The caller is notified of the form of elements actually returned by means of the JFORM argument: \begin{tabbing} xx \= xxxxxxxxxx \= xxxxxxxxxxx \= \kill \> JFORMR \> JFORM \> meaning \\ \\ \> ~~~~~1 \> ~~~~~1 \> OK: elements are in the requested format \\ \> ~~~~~1 \> ~~~~~2 \> never happens \\ \> ~~~~~1 \> ~~~~~3 \> orbit not elliptical \\ \> ~~~~~2 \> ~~~~~1 \> never happens \\ \> ~~~~~2 \> ~~~~~2 \> OK: elements are in the requested format \\ \> ~~~~~2 \> ~~~~~3 \> orbit not elliptical \\ \> ~~~~~3 \> ~~~~~1 \> never happens \\ \> ~~~~~3 \> ~~~~~2 \> never happens \\ \> ~~~~~3 \> ~~~~~3 \> OK: elements are in the requested format \end{tabbing} \item The arguments returned for each value of JFORM ({\it cf}\/ Note~5: JFORM may not be the same as JFORMR) are as follows: \begin{tabbing} xxx \= xxxxxxxxxxxx \= xxxxxx \= xxxxxx \= \kill \> JFORM \> 1 \> 2 \> 3 \\ \\ \> EPOCH \> $t_0$ \> $t_0$ \> $T$ \\ \> ORBINC \> $i$ \> $i$ \> $i$ \\ \> ANODE \> $\Omega$ \> $\Omega$ \> $\Omega$ \\ \> PERIH \> $\varpi$ \> $\omega$ \> $\omega$ \\ \> AORQ \> $a$ \> $a$ \> $q$ \\ \> E \> $e$ \> $e$ \> $e$ \\ \> AORL \> $L$ \> $M$ \> - \\ \> DM \> $n$ \> - \> - \end{tabbing} where: \begin{tabbing} xxx \= xxxxxxxx \= xxx \= \kill \> $t_0$ \> is the epoch of the elements (MJD, TT) \\ \> $T$ \> is the epoch of perihelion (MJD, TT) \\ \> $i$ \> is the inclination (radians) \\ \> $\Omega$ \> is the longitude of the ascending node (radians) \\ \> $\varpi$ \> is the longitude of perihelion (radians) \\ \> $\omega$ \> is the argument of perihelion (radians) \\ \> $a$ \> is the mean distance (AU) \\ \> $q$ \> is the perihelion distance (AU) \\ \> $e$ \> is the eccentricity \\ \> $L$ \> is the longitude (radians, $0-2\pi$) \\ \> $M$ \> is the mean anomaly (radians, $0-2\pi$) \\ \> $n$ \> is the daily motion (radians) \\ \> - \> means no value is set \end{tabbing} \item At very small inclinations, the longitude of the ascending node ANODE becomes indeterminate and under some circumstances may be set arbitrarily to zero. Similarly, if the orbit is close to circular, the true anomaly becomes indeterminate and under some circumstances may be set arbitrarily to zero. In such cases, the other elements are automatically adjusted to compensate, and so the elements remain a valid description of the orbit. \end{enumerate} } \refs{ \begin{enumerate} \item Sterne, Theodore E., {\it An Introduction to Celestial Mechanics,}\/ Interscience Publishers, 1960. Section 6.7, p199. \item Everhart, E. \& Pitkin, E.T., Am.~J.~Phys.~51, 712, 1983. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_UE2PV}{Pos/Vel from Universal Elements} { \action{Heliocentric position and velocity of a planet, asteroid or comet, starting from orbital elements in the ``universal variables'' form.} \call{CALL sla\_UE2PV (DATE, U, PV, JSTAT)} } \args{GIVEN} { \spec{DATE}{D}{date (TT Modified Julian Date = JD$-$2400000.5)} } \args{GIVEN and RETURNED} { \spec{U}{D(13)}{universal orbital elements (updated; Note~1)} \\ \specel {(1)} {combined mass ($M+m$)} \\ \specel {(2)} {total energy of the orbit ($\alpha$)} \\ \specel {(3)} {reference (osculating) epoch ($t_0$)} \\ \specel {(4-6)} {position at reference epoch (${\rm \bf r}_0$)} \\ \specel {(7-9)} {velocity at reference epoch (${\rm \bf v}_0$)} \\ \specel {(10)} {heliocentric distance at reference epoch} \\ \specel {(11)} {${\rm \bf r}_0.{\rm \bf v}_0$} \\ \specel {(12)} {date ($t$)} \\ \specel {(13)} {universal eccentric anomaly ($\psi$) of date, approx} } \args{RETURNED} { \spec{PV}{D(6)}{heliocentric \xyzxyzd, equatorial, J2000} \\ \spec{}{}{\hspace{1.5em} (AU, AU/s; Note~1)} \\ \spec{JSTAT}{I}{status:} \\ \spec{}{}{\hspace{1.95em} 0 = OK} \\ \spec{}{}{\hspace{1.2em} $-$1 = radius vector zero} \\ \spec{}{}{\hspace{1.2em} $-2$ = failed to converge} } \notes { \begin{enumerate} \setlength{\parskip}{\medskipamount} \item The ``universal'' elements are those which define the orbit for the purposes of the method of universal variables (see reference). They consist of the combined mass of the two bodies, an epoch, and the position and velocity vectors (arbitrary reference frame) at that epoch. The parameter set used here includes also various quantities that can, in fact, be derived from the other information. This approach is taken to avoiding unnecessary computation and loss of accuracy. The supplementary quantities are (i)~$\alpha$, which is proportional to the total energy of the orbit, (ii)~the heliocentric distance at epoch, (iii)~the outwards component of the velocity at the given epoch, (iv)~an estimate of $\psi$, the ``universal eccentric anomaly'' at a given date and (v)~that date. \item The companion routine is sla\_EL2UE. This takes the conventional orbital elements and transforms them into the set of numbers needed by the present routine. A single prediction requires one one call to sla\_EL2UE followed by one call to the present routine; for convenience, the two calls are packaged as the routine sla\_PLANEL. Multiple predictions may be made by again calling sla\_EL2UE once, but then calling the present routine multiple times, which is faster than multiple calls to sla\_PLANEL. It is not obligatory to use sla\_EL2UE to obtain the parameters. However, it should be noted that because sla\_EL2UE performs its own validation, no checks on the contents of the array U are made by the present routine. \item DATE is the instant for which the prediction is required. It is in the TT timescale (formerly Ephemeris Time, ET) and is a Modified Julian Date (JD$-$2400000.5). \item The universal elements supplied in the array U are in canonical units (solar masses, AU and canonical days). The position and velocity are not sensitive to the choice of reference frame. The sla\_EL2UE routine in fact produces coordinates with respect to the J2000 equator and equinox. \item The algorithm was originally adapted from the EPHSLA program of D.\,H.\,P.\,Jones (private communication, 1996). The method is based on Stumpff's Universal Variables. \end{enumerate} } \aref{Everhart, E. \& Pitkin, E.T., Am.~J.~Phys.~51, 712, 1983.} %----------------------------------------------------------------------- \routine{SLA\_UNPCD}{Remove Radial Distortion} { \action{Remove pincushion/barrel distortion from a distorted \xy\ to give tangent-plane \xy.} \call{CALL sla\_UNPCD (DISCO,X,Y)} } \args{GIVEN} { \spec{DISCO}{D}{pincushion/barrel distortion coefficient} \\ \spec{X,Y}{D}{distorted \xy} } \args{RETURNED} { \spec{X,Y}{D}{tangent-plane \xy} } \notes { \begin{enumerate} \item The distortion is of the form $\rho = r (1 + c r^{2})$, where $r$ is the radial distance from the tangent point, $c$ is the DISCO argument, and $\rho$ is the radial distance in the presence of the distortion. \item For {\it pincushion}\/ distortion, C is +ve; for {\it barrel}\/ distortion, C is $-$ve. \item For X,Y in units of one projection radius (in the case of a photographic plate, the focal length), the following DISCO values apply: \vspace{2ex} \hspace{5em} \begin{tabular}{|l|c|} \hline Geometry & DISCO \\ \hline \hline astrograph & 0.0 \\ \hline Schmidt & $-$0.3333 \\ \hline AAT PF doublet & +147.069 \\ \hline AAT PF triplet & +178.585 \\ \hline AAT f/8 & +21.20 \\ \hline JKT f/8 & +14.6 \\ \hline \end{tabular} \vspace{2ex} \item The present routine is an approximate inverse to the companion routine sla\_PCD, obtained from two iterations of Newton's method. The mismatch between the sla\_PCD and sla\_UNPCD is negligible for astrometric applications; to reach 1~milliarcsec at the edge of the AAT triplet or Schmidt field would require field diameters of \degree{2}{4} and $42^{\circ}$ respectively. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_V2TP}{Direction Cosines to Tangent Plane} { \action{Given the direction cosines of a star and of the tangent point, determine the star's tangent-plane coordinates (single precision).} \call{CALL sla\_V2TP (V, V0, XI, ETA, J)} } \args{GIVEN} { \spec{V}{R(3)}{direction cosines of star} \\ \spec{V0}{R(3)}{direction cosines of tangent point} } \args{RETURNED} { \spec{XI,ETA}{R}{tangent plane coordinates (radians)} \\ \spec{J}{I}{status:} \\ \spec{}{}{\hspace{1.5em} 0 = OK, star on tangent plane} \\ \spec{}{}{\hspace{1.5em} 1 = error, star too far from axis} \\ \spec{}{}{\hspace{1.5em} 2 = error, antistar on tangent plane} \\ \spec{}{}{\hspace{1.5em} 3 = error, antistar too far from axis} } \notes { \begin{enumerate} \item If vector V0 is not of unit length, or if vector V is of zero length, the results will be wrong. \item If V0 points at a pole, the returned $\xi,\eta$ will be based on the arbitrary assumption that $\alpha=0$ at the tangent point. \item The projection is called the {\it gnomonic}\/ projection; the Cartesian coordinates \xieta\ are called {\it standard coordinates.}\/ The latter are in units of the distance from the tangent plane to the projection point, {\it i.e.}\ radians near the origin. \item This routine is the Cartesian equivalent of the routine sla\_S2TP. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_VDV}{Scalar Product} { \action{Scalar product of two 3-vectors (single precision).} \call{R~=~sla\_VDV (VA, VB)} } \args{GIVEN} { \spec{VA}{R(3)}{first vector} \\ \spec{VB}{R(3)}{second vector} } \args{RETURNED} { \spec{sla\_VDV}{R}{scalar product VA.VB} } %----------------------------------------------------------------------- \routine{SLA\_VN}{Normalize Vector} { \action{Normalize a 3-vector, also giving the modulus (single precision).} \call{CALL sla\_VN (V, UV, VM)} } \args{GIVEN} { \spec{V}{R(3)}{vector} } \args{RETURNED} { \spec{UV}{R(3)}{unit vector in direction of V} \\ \spec{VM}{R}{modulus of V} } \anote{If the modulus of V is zero, UV is set to zero as well.} %----------------------------------------------------------------------- \routine{SLA\_VXV}{Vector Product} { \action{Vector product of two 3-vectors (single precision).} \call{CALL sla\_VXV (VA, VB, VC)} } \args{GIVEN} { \spec{VA}{R(3)}{first vector} \\ \spec{VB}{R(3)}{second vector} } \args{RETURNED} { \spec{VC}{R(3)}{vector product VA$\times$VB} } %----------------------------------------------------------------------- \routine{SLA\_WAIT}{Time Delay} { \action{Wait for a specified interval.} \call{CALL sla\_WAIT (DELAY)} } \args{GIVEN} { \spec{DELAY}{R}{delay in seconds} } \notes { \begin{enumerate} \item The implementation is machine-specific. \item The delay actually requested is restricted to the range 100ns-200s in the present implementation. \item There is no guarantee of accuracy, though on almost all types of computer the program will certainly not resume execution {\it before}\/ the stated interval has elapsed. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_XY2XY}{Apply Linear Model to an \xy} { \action{Transform one \xy\ into another using a linear model of the type produced by the sla\_FITXY routine.} \call{CALL sla\_XY2XY (X1,Y1,COEFFS,X2,Y2)} } \args{GIVEN} { \spec{X1,Y1}{D}{\xy\ before transformation} \\ \spec{COEFFS}{D(6)}{transformation coefficients (see note)} } \args{RETURNED} { \spec{X2,Y2}{D}{\xy\ after transformation} } \notes { \begin{enumerate} \item The model relates two sets of \xy\ coordinates as follows. Naming the six elements of COEFFS $a,b,c,d,e$ \& $f$, the present routine performs the transformation: \begin{verse} $x_{2} = a + bx_{1} + cy_{1}$ \\ $y_{2} = d + ex_{1} + fy_{1}$ \end{verse} \item See also sla\_FITXY, sla\_PXY, sla\_INVF, sla\_DCMPF. \end{enumerate} } %----------------------------------------------------------------------- \routine{SLA\_ZD}{$h,\delta$ to Zenith Distance} { \action{Hour angle and declination to zenith distance (double precision).} \call{D~=~sla\_ZD (HA, DEC, PHI)} } \args{GIVEN} { \spec{HA}{D}{hour angle in radians} \\ \spec{DEC}{D}{declination in radians} \\ \spec{PHI}{D}{latitude in radians} } \args{RETURNED} { \spec{sla\_ZD}{D}{zenith distance (radians, $0\!-\!\pi$)} } \notes { \begin{enumerate} \item The latitude must be geodetic. In critical applications, corrections for polar motion should be applied (see sla\_POLMO). \item In some applications it will be important to specify the correct type of hour angle and declination in order to produce the required type of zenith distance. In particular, it may be important to distinguish between the zenith distance as affected by refraction, which would require the {\it observed}\/ \hadec, and the zenith distance {\it in vacuo}, which would require the {\it topocentric}\/ \hadec. If the effects of diurnal aberration can be neglected, the {\it apparent}\/ \hadec\ may be used instead of the {\it topocentric}\/ \hadec. \item No range checking of arguments is done. \item In applications which involve many zenith distance calculations, rather than calling the present routine it will be more efficient to use inline code, having previously computed fixed terms such as sine and cosine of latitude, and perhaps sine and cosine of declination. \end{enumerate} } \pagebreak \section{EXPLANATION AND EXAMPLES} To guide the writer of positional-astronomy applications software, this final chapter puts the SLALIB routines into the context of astronomical phenomena and techniques, and presents a few ``cookbook'' examples of the SLALIB calls in action. The astronomical content of the chapter is not, of course, intended to be a substitute for specialist text-books on positional astronomy, but may help bridge the gap between such books and the SLALIB routines. For further reading, the following cover a wide range of material and styles: \begin{itemize} \item {\it Explanatory Supplement to the Astronomical Almanac}, ed.\ P.\,Kenneth~Seidelmann (1992), University Science Books. \item {\it Vectorial Astrometry}, C.\,A.\,Murray (1983), Adam Hilger. \item {\it Spherical Astronomy}, Robin~M.\,Green (1985), Cambridge University Press. \item {\it Spacecraft Attitude Determination and Control}, ed.\ James~R.\,Wertz (1986), Reidel. \item {\it Practical Astronomy with your Calculator}, Peter~Duffett-Smith (1981), Cambridge University Press. \end{itemize} Also of considerable value, though out of date in places, are: \begin{itemize} \item {\it Explanatory Supplement to the Astronomical Ephemeris and the American Ephemeris and Nautical Almanac}, RGO/USNO (1974), HMSO. \item {\it Textbook on Spherical Astronomy}, W.\,M.\,Smart (1977), Cambridge University Press. \end{itemize} Only brief details of individual SLALIB routines are given here, and readers will find it useful to refer to the subprogram specifications elsewhere in this document. The source code for the SLALIB routines (available in both Fortran and C) is also intended to be used as documentation. \subsection {Spherical Trigonometry} Celestial phenomena occur at such vast distances from the observer that for most practical purposes there is no need to work in 3D; only the direction of a source matters, not how far away it is. Things can therefore be viewed as if they were happening on the inside of sphere with the observer at the centre -- the {\it celestial sphere}. Problems involving positions and orientations in the sky can then be solved by using the formulae of {\it spherical trigonometry}, which apply to {\it spherical triangles}, the sides of which are {\it great circles}. Positions on the celestial sphere may be specified by using a spherical polar coordinate system, defined in terms of some fundamental plane and a line in that plane chosen to represent zero longitude. Mathematicians usually work with the co-latitude, with zero at the principal pole, whereas most astronomical coordinate systems use latitude, reckoned plus and minus from the equator. Astronomical coordinate systems may be either right-handed ({\it e.g.}\ right ascension and declination \radec, Galactic longitude and latitude \gal) or left-handed ({\it e.g.}\ hour angle and declination \hadec). In some cases different conventions have been used in the past, a fruitful source of mistakes. Azimuth and geographical longitude are examples; azimuth is now generally reckoned north through east (making a left-handed system); geographical longitude is now usually taken to increase eastwards (a right-handed system) but astronomers used to employ a west-positive convention. In reports and program comments it is wise to spell out what convention is being used, if there is any possibility of confusion. When applying spherical trigonometry formulae, attention must be paid to rounding errors (for example it is a bad idea to find a small angle through its cosine) and to the possibility of problems close to poles. Also, if a formulation relies on inspection to establish the quadrant of the result, it is an indication that a vector-related method might be preferable. As well as providing many routines which work in terms of specific spherical coordinates such as \radec, SLALIB provides two routines which operate directly on generic spherical coordinates: sla\_SEP computes the separation between two points (the distance along a great circle) and sla\_BEAR computes the bearing (or {\it position angle}) of one point seen from the other. The routines sla\_DSEP and sla\_DBEAR are double precision equivalents. As a simple demonstration of SLALIB, we will use these facilities to estimate the distance from London to Sydney and the initial compass heading: \goodbreak \begin{verbatim} IMPLICIT NONE * Degrees to radians REAL D2R PARAMETER (D2R=0.01745329252) * Longitudes and latitudes (radians) for London and Sydney REAL AL,BL,AS,BS PARAMETER (AL=-0.2*D2R,BL=51.5*D2R,AS=151.2*D2R,BS=-33.9*D2R) * Earth radius in km (spherical approximation) REAL RKM PARAMETER (RKM=6375.0) REAL sla_SEP,sla_BEAR * Distance and initial heading (N=0, E=90) WRITE (*,'(1X,I5,'' km,'',I4,'' deg'')') : NINT(sla_SEP(AL,BL,AS,BS)*RKM),NINT(sla_BEAR(AL,BL,AS,BS)/D2R) END \end{verbatim} \goodbreak (The result is 17011~km, $61^\circ$.) The routines sla\_PAV and sla\_DPAV are equivalents of sla\_BEAR and sla\_DBEAR but starting from direction-cosines instead of spherical coordinates. \subsubsection{Formatting angles} SLALIB has routines for decoding decimal numbers from character form and for converting angles to and from sexagesimal form (hours, minutes, seconds or degrees, arcminutes, arcseconds). These apparently straightforward operations contain hidden traps which the SLALIB routines avoid. There are five routines for decoding numbers from a character string, such as might be entered using a keyboard. They all work in the same style, and successive calls can work their way along a single string decoding a sequence of numbers of assorted types. Number fields can be separated by spaces or commas, and can be defaulted to previous values or to preset defaults. Three of the routines decode single numbers: sla\_INTIN (integer), sla\_FLOTIN (single precision floating point) and sla\_DFLTIN (double precision). A minus sign can be detected even when the number is zero; this avoids the frequently-encountered ``minus zero'' bug, where declinations {\it etc.}\ in the range $0^{\circ}$ to $-1^{\circ}$ mysteriously migrate to the range $0^{\circ}$ to $+1^{\circ}$. Here is an example (in Fortran) where we wish to read two numbers, and integer {\tt IX} and a real, {\tt Y}, with {\tt X} defaulting to zero and {\tt Y} defaulting to {\tt X}: \goodbreak \begin{verbatim} DOUBLE PRECISION Y CHARACTER*80 A INTEGER IX,I,J * Input the string to be decoded READ (*,'(A)') A * Preset IX to its default value IX = 0 * Point to the start of the string I = 1 * Decode an integer CALL sla_INTIN(A,I,IX,J) IF (J.GT.1) GO TO ... (bad IX) * Preset Y to its default value Y = DBLE(IX) * Decode a double precision number CALL sla_DFLTIN(A,I,Y,J) IF (J.GT.1) GO TO ... (bad Y) \end{verbatim} \goodbreak Two additional routines decode a 3-field sexagesimal number: sla\_AFIN (degrees, arcminutes, arcseconds to single precision radians) and sla\_DAFIN (the same but double precision). They also work using other units such as hours {\it etc}.\ if you multiply the result by the appropriate factor. An example Fortran program which uses sla\_DAFIN was given earlier, in section 1.2. SLALIB provides four routines for expressing an angle in radians in a preferred range. The function sla\_RANGE expresses an angle in the range $\pm\pi$; sla\_RANORM expresses an angle in the range $0-2\pi$. The functions sla\_DRANGE and sla\_DRANRM are double precision versions. Several routines (sla\_CTF2D, sla\_CR2AF {\it etc.}) are provided to convert angles to and from sexagesimal form (hours, minute, seconds or degrees, arcminutes and arcseconds). They avoid the common ``converting from integer to real at the wrong time'' bug, which produces angles like \hms{24}{59}{59}{999}. Here is a program which displays an hour angle stored in radians: \goodbreak \begin{verbatim} DOUBLE PRECISION HA CHARACTER SIGN INTEGER IHMSF(4) : CALL sla_DR2TF(3,HA,SIGN,IHMSF) WRITE (*,'(1X,A,3I3.2,''.'',I3.3)') SIGN,IHMSF \end{verbatim} \goodbreak \subsection {Vectors and Matrices} As an alternative to employing a spherical polar coordinate system, the direction of an object can be defined in terms of the sum of any three vectors as long as they are different and not coplanar. In practice, three vectors at right angles are usually chosen, forming a system of {\it Cartesian coordinates}. The {\it x}- and {\it y}-axes lie in the fundamental plane ({\it e.g.}\ the equator in the case of \radec), with the {\it x}-axis pointing to zero longitude. The {\it z}-axis is normal to the fundamental plane and points towards positive latitudes. The {\it y}-axis can lie in either of the two possible directions, depending on whether the coordinate system is right-handed or left-handed. The three axes are sometimes called a {\it triad}. For most applications involving arbitrarily distant objects such as stars, the vector which defines the direction concerned is constrained to have unit length. The {\it x}-, {\it y-} and {\it z-}components can be regarded as the scalar (dot) product of this vector onto the three axes of the triad in turn. Because the vector is a unit vector, each of the three dot-products is simply the cosine of the angle between the unit vector and the axis concerned, and the {\it x}-, {\it y-} and {\it z-}components are sometimes called {\it direction cosines}. For some applications involving objects with the Solar System, unit vectors are inappropriate, and it is necessary to use vectors scaled in length-units such as AU, km {\it etc.} In these cases the origin of the coordinate system may not be the observer, but instead might be the Sun, the Solar-System barycentre, the centre of the Earth {\it etc.} But whatever the application, the final direction in which the observer sees the object can be expressed as direction cosines. But where has this got us? Instead of two numbers -- a longitude and a latitude -- we now have three numbers to look after -- the {\it x}-, {\it y-} and {\it z-}components -- whose quadratic sum we have somehow to contrive to be unity. And, in addition to this apparent redundancy, most people find it harder to visualize problems in terms of \xyz\ than in $[\,\theta,\phi~]$. Despite these objections, the vector approach turns out to have significant advantages over the spherical trigonometry approach: \begin{itemize} \item Vector formulae tend to be much more succinct; one vector operation is the equivalent of strings of sines and cosines. \item The formulae are as a rule rigorous, even at the poles. \item Accuracy is maintained all over the celestial sphere. When one Cartesian component is nearly unity and therefore insensitive to direction, the others become small and therefore more precise. \item Formulations usually deliver the quadrant of the result without the need for any inspection (except within the library function ATAN2). \end{itemize} A number of important transformations in positional astronomy turn out to be nothing more than changes of coordinate system, something which is especially convenient if the vector approach is used. A direction with respect to one triad can be expressed relative to another triad simply by multiplying the \xyz\ column vector by the appropriate $3\times3$ orthogonal matrix (a tensor of Rank~2, or {\it dyadic}). The three rows of this {\it rotation matrix}\/ are the vectors in the old coordinate system of the three new axes, and the transformation amounts to obtaining the dot-product of the direction-vector with each of the three new axes. Precession, nutation, \hadec\ to \azel, \radec\ to \gal\ and so on are typical examples of the technique. A useful property of the rotation matrices is that they can be inverted simply by taking the transpose. The elements of these vectors and matrices are assorted combinations of the sines and cosines of the various angles involved (hour angle, declination and so on, depending on which transformation is being applied). If you write out the matrix multiplications in full you get expressions which are essentially the same as the equivalent spherical trigonometry formulae. Indeed, many of the standard formulae of spherical trigonometry are most easily derived by expressing the problem initially in terms of vectors. \subsubsection{Using vectors} SLALIB provides conversions between spherical and vector form (sla\_CS2C, sla\_CC2S {\it etc.}), plus an assortment of standard vector and matrix operations (sla\_VDV, sla\_MXV {\it etc.}). There are also routines (sla\_EULER {\it etc.}) for creating a rotation matrix from three {\it Euler angles}\/ (successive rotations about specified Cartesian axes). Instead of Euler angles, a rotation matrix can be expressed as an {\it axial vector}\/ (the pole of the rotation, and the amount of rotation), and routines are provided for this (sla\_AV2M, sla\_M2AV {\it etc.}). Here is an example where spherical coordinates {\tt P1} and {\tt Q1} undergo a coordinate transformation and become {\tt P2} and {\tt Q2}; the transformation consists of a rotation of the coordinate system through angles {\tt A}, {\tt B} and {\tt C} about the {\it z}, new {\it y}\/ and new {\it z}\/ axes respectively: \goodbreak \begin{verbatim} REAL A,B,C,R(3,3),P1,Q1,V1(3),V2(3),P2,Q2 : * Create rotation matrix CALL sla_EULER('ZYZ',A,B,C,R) * Transform position (P,Q) from spherical to Cartesian CALL sla_CS2C(P1,Q1,V1) * Multiply by rotation matrix CALL sla_MXV(R,V1,V2) * Back to spherical CALL sla_CC2S(V2,P2,Q2) \end{verbatim} \goodbreak Small adjustments to the direction of a position vector are often most conveniently described in terms of $[\,\Delta x,\Delta y, \Delta z\,]$. Adding the correction vector needs careful handling if the position vector is to remain of length unity, an advisable precaution which ensures that the \xyz\ components are always available to mean the cosines of the angles between the vector and the axis concerned. Two types of shifts are commonly used, the first where a small vector of arbitrary direction is added to the unit vector, and the second where there is a displacement in the latitude coordinate (declination, elevation {\it etc.}) alone. For a shift produced by adding a small \xyz\ vector ${\bf D}$ to a unit vector ${\bf V1}$, the resulting vector ${\bf V2}$ has direction $<{\bf V1}+{\bf D}>$ but is no longer of unit length. A better approximation is available if the result is multiplied by a scaling factor of $(1-{\bf D}\cdot{\bf V1})$, where the dot means scalar product. In Fortran: \goodbreak \begin{verbatim} F = (1D0-(DX*V1X+DY*V1Y+DZ*V1Z)) V2X = F*(V1X+DX) V2Y = F*(V1Y+DY) V2Z = F*(V1Z+DZ) \end{verbatim} \goodbreak \noindent The correction for diurnal aberration (discussed later) is an example of this form of shift. As an example of the second kind of displacement we will apply a small change in elevation $\delta E$ to an \azel\ direction vector. The direction of the result can be obtained by making the allowable approximation ${\tan \delta E\approx\delta E}$ and adding a adjustment vector of length $\delta E$ normal to the direction vector in the vertical plane containing the direction vector. The $z$-component of the adjustment vector is $\delta E \cos E$, and the horizontal component is $\delta E \sin E$ which has then to be resolved into $x$ and $y$ in proportion to their current sizes. To approximate a unit vector more closely, a correction factor of $\cos \delta E$ can then be applied, which is nearly $(1-\delta E^2 /2)$ for small $\delta E$. Expressed in Fortran, for initial vector {\tt V1X,V1Y,V1Z}, change in elevation {\tt DEL} (+ve $\equiv$ upwards), and result vector {\tt V2X,V2Y,V2Z}: \goodbreak \begin{verbatim} COSDEL = 1D0-DEL*DEL/2D0 R1 = SQRT(V1X*V1X+V1Y*V1Y) F = COSDEL*(R1-DEL*V1Z)/R1 V2X = F*V1X V2Y = F*V1Y V2Z = COSDEL*(V1Z+DEL*R1) \end{verbatim} \goodbreak An example of this type of shift is the correction for atmospheric refraction (see later). Depending on the relationship between $\delta E$ and $E$, special handling at the pole (the zenith for our example) may be required. SLALIB includes routines for the case where both a position and a velocity are involved. The routines sla\_CS2C6 and sla\_CC62S convert from $[\theta,\phi,\dot{\theta},\dot{\phi}]$ to \xyzxyzd\ and back; sla\_DCS26 and sla\_DC62S are double precision equivalents. \subsection {Celestial Coordinate Systems} SLALIB has routines to perform transformations of celestial positions between different spherical coordinate systems, including those shown in the following table: \begin{center} \begin{tabular}{|l|c|c|c|c|c|c|} \hline {\it system} & {\it symbols} & {\it longitude} & {\it latitude} & {\it x-y plane} & {\it long.\ zero} & {\it RH/LH} \\ \hline \hline horizon & -- & azimuth & elevation & horizontal & north & L \\ \hline equatorial & $\alpha,\delta$ & R.A.\ & Dec.\ & equator & equinox & R \\ \hline local equ.\ & $h,\delta$ & H.A.\ & Dec.\ & equator & meridian & L \\ \hline ecliptic & $\lambda,\beta$ & ecl.\ long.\ & ecl.\ lat.\ & ecliptic & equinox & R \\ \hline galactic & $l^{I\!I},b^{I\!I}$ & gal.\ long.\ & gal.\ lat.\ & gal.\ equator & gal.\ centre & R \\ \hline supergalactic & SGL,SGB & SG long.\ & SG lat.\ & SG equator & node w.\ gal.\ equ.\ & R \\ \hline \end{tabular} \end{center} Transformations between \hadec\ and \azel\ can be performed by calling sla\_E2H and sla\_H2E, or, in double precision, sla\_DE2H and sla\_DH2E. There is also a routine for obtaining zenith distance alone for a given \hadec, sla\_ZD, and one for determining the parallactic angle, sla\_PA. Three routines are included which relate to altazimuth telescope mountings. For a given \hadec\ and latitude, sla\_ALTAZ returns the azimuth, elevation and parallactic angle, plus velocities and accelerations for sidereal tracking. The routines sla\_PDA2H and sla\_PDQ2H predict at what hour angle a given azimuth or parallactic angle will be reached. The routines sla\_EQECL and sla\_ECLEQ transform between ecliptic coordinates and \radec\/; there is also a routine for generating the equatorial to ecliptic rotation matrix for a given date: sla\_ECMAT. For conversion between Galactic coordinates and \radec\ there are two sets of routines, depending on whether the \radec\ is old-style, B1950, or new-style, J2000; sla\_EG50 and sla\_GE50 are \radec\ to \gal\ and {\it vice versa}\/ for the B1950 case, while sla\_EQGAL and sla\_GALEQ are the J2000 equivalents. Finally, the routines sla\_GALSUP and sla\_SUPGAL transform \gal\ to de~Vaucouleurs supergalactic longitude and latitude and {\it vice versa.} It should be appreciated that the table, above, constitutes a gross oversimplification. Apparently simple concepts such as equator, equinox {\it etc.}\ are apt to be very hard to pin down precisely (polar motion, orbital perturbations \ldots) and some have several interpretations, all subtly different. The various frames move in complicated ways with respect to one another or to the stars (themselves in motion). And in some instances the coordinate system is slightly distorted, so that the ordinary rules of spherical trigonometry no longer strictly apply. These {\it caveats}\/ apply particularly to the bewildering variety of different \radec\ systems that are in use. Figure~1 shows how some of these systems are related, to one another and to the direction in which a celestial source actually appears in the sky. At the top of the diagram are the various sorts of {\it mean place}\/ found in star catalogues and papers;\footnote{One frame not included in Figure~1 is that of the Hipparcos catalogue. This is currently the best available implementation in the optical of the {\it International Celestial Reference System}\/ (ICRS), which is based on extragalactic radio sources observed by VLBI. The distinction between FK5 J2000 and Hipparcos coordinates only becomes important when accuracies of 50~mas or better are required. More details are given in Section~4.14.} at the bottom is the {\it observed}\/ \azel, where a perfect theodolite would be pointed to see the source; and in the body of the diagram are the intermediate processing steps and coordinate systems. To help understand this diagram, and the SLALIB routines that can be used to carry out the various calculations, we will look at the coordinate systems involved, and the astronomical phenomena that affect them. \begin{figure} \begin{center} \begin{tabular}{|cccccc|} \hline & & & & & \\ \hspace{5em} & \hspace{5em} & \hspace{5em} & \hspace{5em} & \hspace{5em} & \hspace{5em} \\ \multicolumn{2}{|c}{\hspace{0em}\fbox{\parbox{8.5em}{\center \vspace{-2ex} mean \radec, FK4, \\ any equinox \vspace{0.5ex}}}} & \multicolumn{2}{c}{\hspace{0em}\fbox{\parbox{8.5em}{\center \vspace{-2ex} mean \radec, FK4, no $\mu$, any equinox \vspace{0.5ex}}}} & \multicolumn{2}{c|}{\hspace{0em}\fbox{\parbox{8.5em}{\center \vspace{-2ex} mean \radec, FK5, \\ any equinox \vspace{0.5ex}}}} \\ & \multicolumn{2}{|c|}{} & \multicolumn{2}{c|}{} & \\ \multicolumn{2}{|c}{space motion} & \multicolumn{1}{c|}{} & & \multicolumn{2}{c|}{space motion} \\ \multicolumn{2}{|c}{-- E-terms} & \multicolumn{2}{c}{-- E-terms} & \multicolumn{1}{c|}{} & \\ \multicolumn{2}{|c}{precess to B1950} & \multicolumn{2}{c}{precess to B1950} & \multicolumn{2}{c|}{precess to J2000} \\ \multicolumn{2}{|c}{+ E-terms} & \multicolumn{2}{c}{+ E-terms} & \multicolumn{1}{c|}{} & \\ \multicolumn{2}{|c}{FK4 to FK5, no $\mu$} & \multicolumn{2}{c}{FK4 to FK5, no $\mu$} & \multicolumn{1}{c|}{} & \\ \multicolumn{2}{|c}{parallax} & \multicolumn{1}{c|}{} & & \multicolumn{2}{c|}{parallax} \\ & \multicolumn{2}{|c|}{} & \multicolumn{2}{c|}{} & \\ \cline{2-5} \multicolumn{3}{|c|}{} & & & \\ & \multicolumn{4}{c}{\fbox{\parbox{18em}{\center \vspace{-2ex} FK5, J2000, current epoch, geocentric \vspace{0.5ex}}}} & \\ \multicolumn{3}{|c|}{} & & & \\ & \multicolumn{4}{c}{light deflection} & \\ & \multicolumn{4}{c}{annual aberration} & \\ & \multicolumn{4}{c}{precession/nutation} & \\ \multicolumn{3}{|c|}{} & & & \\ & \multicolumn{4}{c}{\fbox{Apparent \radec}} & \\ \multicolumn{3}{|c|}{} & & & \\ & \multicolumn{4}{c}{Earth rotation} & \\ \multicolumn{3}{|c|}{} & & & \\ & \multicolumn{4}{c}{\fbox{Apparent \hadec}} & \\ \multicolumn{3}{|c|}{} & & & \\ & \multicolumn{4}{c}{diurnal aberration} & \\ \multicolumn{3}{|c|}{} & & & \\ & \multicolumn{4}{c}{\fbox{Topocentric \hadec}} & \\ \multicolumn{3}{|c|}{} & & & \\ & \multicolumn{4}{c}{\hadec\ to \azel} & \\ \multicolumn{3}{|c|}{} & & & \\ & \multicolumn{4}{c}{\fbox{Topocentric \azel}} & \\ \multicolumn{3}{|c|}{} & & & \\ & \multicolumn{4}{c}{refraction} & \\ \multicolumn{3}{|c|}{} & & & \\ & \multicolumn{4}{c}{\fbox{Observed \azel}} & \\ & & & & & \\ & & & & & \\ \hline \end{tabular} \end{center} \vspace{-0.5ex} \caption{Relationship Between Celestial Coordinates} Star positions are published or catalogued using one of the mean \radec\ systems shown at the top. The ``FK4'' systems were used before about 1980 and are usually equinox B1950. The ``FK5'' system, equinox J2000, is now preferred, or rather its modern equivalent, the International Celestial Reference Frame (in the optical, the Hipparcos catalogue). The figure relates a star's mean \radec\ to the actual line-of-sight to the star. Note that for the conventional choices of equinox, namely B1950 or J2000, all of the precession and E-terms corrections are superfluous. \end{figure} \subsection{Precession and Nutation} {\it Right ascension and declination}, (\radec), are the names of the longitude and latitude in a spherical polar coordinate system based on the Earth's axis of rotation. The zero point of $\alpha$ is the point of intersection of the {\it celestial equator}\/ and the {\it ecliptic}\/ (the apparent path of the Sun through the year) where the Sun moves into the northern hemisphere. This point is called the {\it first point of Aries}, the {\it vernal equinox}\/ (with apologies to southern-hemisphere readers) or simply the {\it equinox}.\footnote{With the introduction of the International Celestial Reference System (ICRS), the connection between (i)~star coordinates and (ii)~the Earth's orientation and orbit has been broken. However, the orientation of the International Celestial Reference Frame (ICRF) axes was, for convenience, chosen to match J2000 FK5, and for most practical purposes ICRF coordinates (for example entries in the Hipparcos catalogue) can be regarded as synonymous with J2000 FK5. See Section 4.14 for further details.} This simple picture is unfortunately complicated by the difficulty of defining a suitable equator and equinox. One problem is that the Sun's apparent motion is not completely regular, due to the ellipticity of the Earth's orbit and its continuous disturbance by the Moon and planets. This is dealt with by separating the motion into (i)~a smooth and steady {\it mean Sun}\/ and (ii)~a set of periodic corrections and perturbations; only the former is involved in establishing reference frames and timescales. A second, far larger problem, is that the celestial equator and the ecliptic are both moving with respect to the stars. These motions arise because of the gravitational interactions between the Earth and the other solar-system bodies. By far the largest effect is the so-called ``precession of the equinoxes'', where the Earth's rotation axis sweeps out a cone centred on the ecliptic pole, completing one revolution in about 26,000 years. The cause of the motion is the torque exerted on the distorted and spinning Earth by the Sun and the Moon. Consider the effect of the Sun alone, at or near the northern summer solstice. The Sun `sees' the top (north pole) of the Earth tilted towards it (by about \degree{23}{5}, the {\it obliquity of the ecliptic}\/), and sees the nearer part of the Earth's equatorial bulge below centre and the further part above centre. Although the Earth is in free fall, the gravitational force on the nearer part of the equatorial bulge is greater than that on the further part, and so there is a net torque acting as if to eliminate the tilt. Six months later the same thing is happening in reverse, except that the torque is still trying to eliminate the tilt. In between (at the equinoxes) the torque shrinks to zero. A torque acting on a spinning body is gyroscopically translated into a precessional motion of the spin axis at right-angles to the torque, and this happens to the Earth. The motion varies during the year, going through two maxima, but always acts in the same direction. The Moon produces the same effect, adding a contribution to the precession which peaks twice per month. The Moon's proximity to the Earth more than compensates for its smaller mass and gravitational attraction, so that it in fact contributes most of the precessional effect. The complex interactions between the three bodies produce a precessional motion that is wobbly rather than completely smooth. However, the main 26,000-year component is on such a grand scale that it dwarfs the remaining terms, the biggest of which has an amplitude of only \arcseci{17} and a period of about 18.6~years. This difference of scale makes it convenient to treat these two components of the motion separately. The main 26,000-year effect is called {\it luni-solar precession}; the smaller, faster, periodic terms are called the {\it nutation}. Note that precession and nutation are simply different frequency components of the same physical effect. It is a common misconception that precession is caused by the Sun and nutation is caused by the Moon. In fact the Moon is responsible for two-thirds of the precession, and, while it is true that much of the complex detail of the nutation is a reflection of the intricacies of the lunar orbit, there are nonetheless important solar terms in the nutation. In addition to and quite separate from the precession/nutation effect, the orbit of the Earth-Moon system is not fixed in orientation, a result of the attractions of the planets. This slow (about \arcsec{0}{5}~per~year) secular rotation of the ecliptic about a slowly-moving diameter is called, confusingly, {\it planetary precession}\/ and, along with the luni-solar precession is included in the {\it general precession}. The equator and ecliptic as affected by general precession are what define the various ``mean'' \radec\ reference frames. The models for precession and nutation come from a combination of observation and theory, and are subject to continuous refinement. Nutation models in particular have reached a high degree of sophistication, taking into account such things as the non-rigidity of the Earth and the effects of the planets; SLALIB's nutation model (IAU~1980) involves 106 terms in each of $\psi$ (longitude) and $\epsilon$ (obliquity), some as small as \arcsec{0}{0001}. \subsubsection{SLALIB support for precession and nutation} SLALIB offers a choice of three precession models: \begin{itemize} \item The old Bessel-Newcomb, pre IAU~1976, ``FK4'' model, used for B1950 star positions and other pre-1984.0 purposes (sla\_PREBN). \item The new Fricke, IAU~1976, ``FK5'' model, used for J2000 star positions and other post-1984.0 purposes (sla\_PREC). \item A model published by Simon {\it et al.}\ which is more accurate than the IAU~1976 model and which is suitable for long periods of time (sla\_PRECL). \end{itemize} In each case, the named SLALIB routine generates the $(3\times3)$ {\it precession matrix}\/ for a given start and finish time. For example, here is the Fortran code for generating the rotation matrix which describes the precession between the epochs J2000 and J1985.372 (IAU 1976 model): \goodbreak \begin{verbatim} DOUBLE PRECISION PMAT(3,3) : CALL sla_PREC(2000D0,1985.372D0,PMAT) \end{verbatim} \goodbreak It is instructive to examine the resulting matrix: \goodbreak \begin{verbatim} +0.9999936402 +0.0032709208 +0.0014214694 -0.0032709208 +0.9999946505 -0.0000023247 -0.0014214694 -0.0000023248 +0.9999989897 \end{verbatim} \goodbreak Note that the diagonal elements are close to unity, and the other elements are small. This shows that over an interval as short as 15~years the precession isn't going to move a position vector very far (in this case about \degree{0}{2}). For convenience, a direct \radec\ to \radec\ precession routine is also provided (sla\_PRECES), suitable for either the old or the new system (but not a mixture of the two). SLALIB provides only one nutation model, the new, IAU~1980 model, implemented in the routine sla\_NUTC. This returns the components of nutation in longitude and latitude (and also provides the obliquity) from which a nutation matrix can be generated by calling sla\_DEULER (and from which the {\it equation of the equinoxes}, described later, can be found). Alternatively, the nutation matrix can be generated in a single call by using sla\_NUT. A rotation matrix for applying the entire precession/nutation transformation in one go can be generated by calling sla\_PRENUT. \subsection{Mean Places} The main effect of the precession/nutation is a steady increase of about \arcseci{50}/year in the ecliptic longitudes of the stars. It is therefore essential, when reporting the position of an astronomical target, to qualify the coordinates with a date, or {\it epoch}. Specifying the epoch ties down the equator and equinox which define the \radec\ coordinate system that is being used. \footnote{An equinox is, however, not required for coordinates in the International Celestial Reference System. Such coordinates must be labelled simply ``ICRS'', or the specific catalogue can be mentioned, such as ``Hipparcos''; constructions such as ``Hipparcos, J2000'' are redundant and misleading.} For simplicity, only the smooth and steady ``general precession'' part of the complete precession/nutation effect is included, thereby defining what is called the {\it mean}\/ equator and equinox for the epoch concerned. We say a star has a mean place of (for example) \hms{12}{07}{58}{09}~\dms{-19}{44}{37}{1} ``with respect to the mean equator and equinox of epoch J2000''. The short way of saying this is ``\radec\ equinox J2000'' ({\bf not} ``\radec\ epoch J2000'', which means something different to do with proper motion). \subsection{Epoch} The word ``epoch'' just means a moment in time, and can be supplied in a variety of forms, using different calendar systems and timescales. For the purpose of specifying the epochs associated with the mean place of a star, two conventions exist. Both sorts of epoch superficially resemble years AD but are not tied to the civil (Gregorian) calendar; to distinguish them from ordinary calendar-years there is often a ``.0'' suffix (as in ``1950.0''), although any other fractional part is perfectly legal ({\it e.g.}\ 1987.5). The older system, {\it Besselian epoch}, is defined in such a way that its units are tropical years of about 365.2422~days and its timescale is the obsolete {\it Ephemeris Time}. The start of the Besselian year is the moment when the ecliptic longitude of the mean Sun is $280^{\circ}$; this happens near the start of the calendar year (which is why $280^{\circ}$ was chosen). The new system, {\it Julian epoch}, was adopted as part of the IAU~1976 revisions (about which more will be said in due course) and came formally into use at the beginning of 1984. It uses the Julian year of exactly 365.25~days; Julian epoch 2000 is defined to be 2000~January~1.5 in the TT timescale. For specifying mean places, various standard epochs are in use, the most common ones being Besselian epoch 1950.0 and Julian epoch 2000.0. To distinguish the two systems, Besselian epochs are now prefixed ``B'' and Julian epochs are prefixed ``J''. Epochs without an initial letter can be assumed to be Besselian if before 1984.0, otherwise Julian. These details are supported by the SLALIB routines sla\_DBJIN (decodes numbers from a character string, accepting an optional leading B or J), sla\_KBJ (decides whether B or J depending on prefix or range) and sla\_EPCO (converts one epoch to match another). SLALIB has four routines for converting Besselian and Julian epochs into other forms. The functions sla\_EPB2D and sla\_EPJ2D convert Besselian and Julian epochs into MJD; the functions sla\_EPB and sla\_EPJ do the reverse. For example, to express B1950 as a Julian epoch: \goodbreak \begin{verbatim} DOUBLE PRECISION sla_EPJ,sla_EPB2D : WRITE (*,'(1X,''J'',F10.5)') sla_EPJ(sla_EPB2D(1950D0)) \end{verbatim} \goodbreak (The answer is J1949.99979.) \subsection{Proper Motion} Stars in catalogues usually have, in addition to the \radec\ coordinates, a {\it proper motion} $[\mu_\alpha,\mu_\delta]$. This is an intrinsic motion of the star across the background. Very few stars have a proper motion which exceeds \arcseci{1}/year, and most are far below this level. A star observed as part of normal astronomy research will, as a rule, have a proper motion which is unknown. Mean \radec\ and rate of change are not sufficient to pin down a star; the epoch at which the \radec\ was or will be correct is also needed. Note the distinction between the epoch which specifies the coordinate system and the epoch at which the star passed through the given \radec. The full specification for a star is \radec, proper motions, equinox and epoch (plus something to identify which set of models for the precession {\it etc.}\ is being used -- see the next section). For convenience, coordinates given in star catalogues are almost always adjusted to make the equinox and epoch the same -- for example B1950 in the case of the SAO~catalogue. SLALIB provides one routine to handle proper motion on its own, sla\_PM. Proper motion is also allowed for in various other routines as appropriate, for example sla\_MAP and sla\_FK425. Note that in all SLALIB routines which involve proper motion the units are radians per year and the $\alpha$ component is in the form $\dot{\alpha}$ ({\it i.e.}\ big numbers near the poles). Some star catalogues have proper motion per century, and in some catalogues the $\alpha$ component is in the form $\dot{\alpha}\cos\delta$ ({\it i.e.}\ angle on the sky). \subsection{Parallax and Radial Velocity} For the utmost accuracy and the nearest stars, allowance can be made for {\it annual parallax}\/ and for the effects of perspective on the proper motion. Parallax is appreciable only for nearby stars; even the nearest, Proxima Centauri, is displaced from its average position by less than an arcsecond as the Earth revolves in its orbit. For stars with a known parallax, knowledge of the radial velocity allows the proper motion to be expressed as an actual space motion in 3~dimensions. The proper motion is, in fact, a snapshot of the transverse component of the space motion, and in the case of nearby stars will change with time due to perspective. SLALIB does not provide facilities for handling parallax and radial-velocity on their own, but their contribution is allowed for in such routines as sla\_PM, sla\_MAP and sla\_FK425. Catalogue mean places do not include the effects of parallax and are therefore {\it barycentric}; when pointing telescopes {\it etc.}\ it is usually most efficient to apply the slowly-changing parallax correction to the mean place of the target early on and to work with the {\it geocentric}\/ mean place. This latter approach is implied in Figure~1. \subsection{Aberration} The finite speed of light combined with the motion of the observer around the Sun during the year causes apparent displacements of the positions of the stars. The effect is called the {\it annual aberration} (or ``stellar'' aberration). Its maximum size, about \arcsec{20}{5}, occurs for stars $90^{\circ}$ from the point towards which the Earth is headed as it orbits the Sun; a star exactly in line with the Earth's motion is not displaced. To receive the light of a star, the telescope has to be offset slightly in the direction of the Earth's motion. A familiar analogy is the need to tilt your umbrella forward when on the move, to avoid getting wet. This Newtonian model is, in fact, highly misleading in the context of light as opposed to rain, but happens to give the same answer as a relativistic treatment to first order (better than 1~milliarcsecond). Before the IAU 1976 resolutions, different values for the approximately \arcsec{20}{5} {\it aberration constant}\/ were employed at different times, and this can complicate comparisons between different catalogues. Another complication comes from the so-called {\it E-terms of aberration}, that small part of the annual aberration correction that is a function of the eccentricity of the Earth's orbit. The E-terms, maximum amplitude about \arcsec{0}{3}, happen to be approximately constant for a given star, and so they used to be incorporated in the catalogue \radec\/ to reduce the labour of converting to and from apparent place. The E-terms can be removed from a catalogue \radec\/ by calling sla\_SUBET or applied (for example to allow a pulsar timing-position to be plotted on a B1950 finding chart) by calling sla\_ADDET; the E-terms vector itself can be obtained by calling sla\_ETRMS. Star positions post IAU 1976 are free of these distortions, and to apply corrections for annual aberration involves the actual barycentric velocity of the Earth rather than the use of canonical circular-orbit models. The annual aberration is the aberration correction for an imaginary observer at the Earth's centre. The motion of a real observer around the Earth's rotation axis in the course of the day makes a small extra contribution to the total aberration effect called the {\it diurnal aberration}. Its maximum amplitude is about \arcsec{0}{2}. No SLALIB routine is provided for calculating the aberration on its own, though the required velocity vectors can be generated using sla\_EVP and sla\_GEOC. Annual and diurnal aberration are allowed for where required, for example in sla\_MAP {\it etc}.\ and sla\_AOP {\it etc}. Note that this sort of aberration is different from the {\it planetary aberration}, which is the apparent displacement of a solar-system body, with respect to the ephemeris position, as a consequence of the motion of {\it both}\/ the Earth and the source. The planetary aberration can be computed either by correcting the position of the solar-system body for light-time, followed by the ordinary stellar aberration correction, or more directly by expressing the position and velocity of the source in the observer's frame and correcting for light-time alone. \subsection{Different Sorts of Mean Place} A particularly confusing aspect of published mean places is that they are sensitive to the precise way they were determined. A mean place is not directly observable, even with fundamental instruments such as transit circles, and to produce a mean place will involve relying on some existing star catalogue, for example the fundamental catalogues FK4 and FK5, and applying given mathematical models of precession, nutation, aberration and so on. Note in particular that no star catalogue, even a fundamental catalogue such as FK4 or FK5, defines a coordinate system, strictly speaking; it is merely a list of star positions and proper motions. However, once the stars from a given catalogue are used as position calibrators, {\it e.g.}\ for transit-circle observations or for plate reductions, then a broader sense of there being a coordinate grid naturally arises, and such phrases as ``in the system of the FK4'' can legitimately be employed. However, there is no formal link between the two concepts -- no ``standard least squares fit'' between reality and the inevitably flawed catalogues.\footnote{This was true until the inception of the International Celestial Reference System, which is based on the idea of axes locked into the distant background. The coordinates of the extragalactic sources which realize these axes have no individual significance; there is a ``no net rotation'' condition which has to be satisfied each time any revisions take place.} All such catalogues suffer at some level from systematic, zonal distortions of both the star positions and of the proper motions, and include measurement errors peculiar to individual stars. Many of these complications are of little significance except to specialists. However, observational astronomers cannot escape exposure to at least the two main varieties of mean place, loosely called FK4 and FK5, and should be aware of certain pitfalls. For most practical purposes the more recent system, FK5, is free of surprises and tolerates naive use well. FK4, in contrast, contains two important traps: \begin{itemize} \item The FK4 system rotates at about \arcsec{0}{5} per century relative to distant galaxies. This is manifested as a systematic distortion in the proper motions of all FK4-derived catalogues, which will in turn pollute any astrometry done using those catalogues. For example, FK4-based astrometry of a QSO using plates taken decades apart will reveal a non-zero {\it fictitious proper motion}, and any FK4 star which happens to have zero proper motion is, in fact, slowly moving against the distant background. The FK4 frame rotates because it was established before the nature of the Milky Way, and hence the existence of systematic motions of nearby stars, had been recognized. \item Star positions in the FK4 system are part-corrected for annual aberration (see above) and embody the so-called E-terms of aberration. \end{itemize} The change from the old FK4-based system to FK5 occurred at the beginning of 1984 as part of a package of resolutions made by the IAU in 1976, along with the adoption of J2000 as the reference epoch. Star positions in the newer, FK5, system are free from the E-terms, and the system is a much better approximation to an inertial frame (about five times better). It may occasionally be convenient to specify the FK4 fictitious proper motion directly. In FK4, the centennial proper motion of (for example) a QSO is: $\mu_\alpha=-$\tsec{0}{015869}$ +(($\tsec{0}{029032}$~\sin \alpha +$\tsec{0}{000340}$~\cos \alpha ) \sin \delta -$\tsec{0}{000105}$~\cos \alpha -$\tsec{0}{000083}$~\sin \alpha ) \sec \delta $ \\ $\mu_\delta\,=+$\arcsec{0}{43549}$~\cos \alpha -$\arcsec{0}{00510}$~\sin \alpha + ($\arcsec{0}{00158}$~\sin \alpha -$\arcsec{0}{00125}$~\cos \alpha ) \sin \delta -$\arcsec{0}{00066}$~\cos \delta $ \subsection{Mean Place Transformations} Figure~1 is based upon three varieties of mean \radec\ all of which are of practical significance to observing astronomers in the present era: \begin{itemize} \item Old style (FK4) with known proper motion in the FK4 system, and with parallax and radial velocity either known or assumed zero. \item Old style (FK4) with zero proper motion in FK5, and with parallax and radial velocity assumed zero. \item New style (FK5) with proper motion, parallax and radial velocity either known or assumed zero. \end{itemize} The figure outlines the steps required to convert positions in any of these systems to a J2000 \radec\ for the current epoch, as might be required in a telescope-control program for example. Most of the steps can be carried out by calling a single SLALIB routines; there are other SLALIB routines which offer set-piece end-to-end transformation routines for common cases. Note, however, that SLALIB does not set out to provide the capability for arbitrary transformations of star-catalogue data between all possible systems of mean \radec. Only in the (common) cases of FK4, equinox and epoch B1950, to FK5, equinox and epoch J2000, and {\it vice versa}\/ are proper motion, parallax and radial velocity transformed along with the star position itself, the focus of SLALIB support. As an example of using SLALIB to transform mean places, here is a program which implements the top-left path of Figure~1. An FK4 \radec\ of arbitrary equinox and epoch and with known proper motion and parallax is transformed into an FK5 J2000 \radec\ for the current epoch. As a test star we will use $\alpha=$\hms{16}{09}{55}{13}, $\delta=$\dms{-75}{59}{27}{2}, equinox 1900, epoch 1963.087, $\mu_\alpha=$\tsec{-0}{0312}$/y$, $\mu_\delta=$\arcsec{+0}{103}$/y$, parallax = \arcsec{0}{062}, radial velocity = $-34.22$~km/s. The epoch of observation is 1994.35. \goodbreak \begin{verbatim} IMPLICIT NONE DOUBLE PRECISION AS2R,S2R PARAMETER (AS2R=4.8481368110953599D-6,S2R=7.2722052166430399D-5) INTEGER J,I DOUBLE PRECISION R0,D0,EQ0,EP0,PR,PD,PX,RV,EP1,R1,D1,R2,D2,R3,D3, : R4,D4,R5,D5,R6,D6,EP1D,EP1B,W(3),EB(3),PXR,V(3) DOUBLE PRECISION sla_EPB,sla_EPJ2D * RA, Dec etc of example star CALL sla_DTF2R(16,09,55.13D0,R0,J) CALL sla_DAF2R(75,59,27.2D0,D0,J) D0=-D0 EQ0=1900D0 EP0=1963.087D0 PR=-0.0312D0*S2R PD=+0.103D0*AS2R PX=0.062D0 RV=-34.22D0 EP1=1994.35D0 * Epoch of observation as MJD and Besselian epoch EP1D=sla_EPJ2D(EP1) EP1B=sla_EPB(EP1D) * Space motion to the current epoch CALL sla_PM(R0,D0,PR,PD,PX,RV,EP0,EP1B,R1,D1) * Remove E-terms of aberration for the original equinox CALL sla_SUBET(R1,D1,EQ0,R2,D2) * Precess to B1950 R3=R2 D3=D2 CALL sla_PRECES('FK4',EQ0,1950D0,R3,D3) * Add E-terms for the standard equinox B1950 CALL sla_ADDET(R3,D3,1950D0,R4,D4) * Transform to J2000, no proper motion CALL sla_FK45Z(R4,D4,EP1B,R5,D5) * Parallax CALL sla_EVP(sla_EPJ2D(EP1),2000D0,W,EB,W,W) PXR=PX*AS2R CALL sla_DCS2C(R5,D5,V) DO I=1,3 V(I)=V(I)-PXR*EB(I) END DO CALL sla_DCC2S(V,R6,D6) : \end{verbatim} \goodbreak It is interesting to look at how the \radec\ changes during the course of the calculation: \begin{tabbing} xxxxxxxxxxxxxx \= xxxxxxxxxxxxxxxxxxxxxxxxx \= x \= \kill \> {\tt 16 09 55.130 -75 59 27.20} \> \> {\it original equinox and epoch} \\ \> {\tt 16 09 54.155 -75 59 23.98} \> \> {\it with space motion} \\ \> {\tt 16 09 54.229 -75 59 24.18} \> \> {\it with old E-terms removed} \\ \> {\tt 16 16 28.213 -76 06 54.57} \> \> {\it precessed to 1950.0} \\ \> {\tt 16 16 28.138 -76 06 54.37} \> \> {\it with new E-terms} \\ \> {\tt 16 23 07.901 -76 13 58.87} \> \> {\it J2000, current epoch} \\ \> {\tt 16 23 07.907 -76 13 58.92} \> \> {\it including parallax} \end{tabbing} Other remarks about the above (unusually complicated) example: \begin{itemize} \item If the original equinox and epoch were B1950, as is quite likely, then it would be unnecessary to treat space motions and E-terms explicitly. Transformation to FK5 J2000 could be accomplished simply by calling sla\_FK425, after which a call to sla\_PM and the parallax code would complete the work. \item The rigorous treatment of the E-terms has only a small effect on the result. Such refinements are, nevertheless, worthwhile in order to facilitate comparisons and to increase the chances that star positions from different suppliers are compatible. \item The FK4 to FK5 transformations, sla\_FK425 and sla\_FK45Z, are not as is sometimes assumed simply 50 years of precession, though this indeed accounts for most of the change. The transformations also include adjustments to the equinox, a revised precession model, elimination of the E-terms, a change to the proper-motion time unit and so on. The reason there are two routines rather than just one is that the FK4 frame rotates relative to the background, whereas the FK5 frame is a much better approximation to an inertial frame, and zero proper motion in FK4 does not, therefore, mean zero proper motion in FK5. SLALIB also provides two routines, sla\_FK524 and sla\_FK54Z, to perform the inverse transformations. \item Some star catalogues (FK4 itself is one) were constructed using slightly different procedures for the polar regions compared with elsewhere. SLALIB ignores this inhomogeneity and always applies the standard transformations irrespective of location on the celestial sphere. \end{itemize} \subsection {Mean Place to Apparent Place} The {\it geocentric apparent place}\/ of a source, or {\it apparent place}\/ for short, is the \radec\ if viewed from the centre of the Earth, with respect to the true equator and equinox of date. Transformation of an FK5 mean \radec, equinox J2000, current epoch, to apparent place involves the following effects: \goodbreak \begin{itemize} \item Light deflection -- the gravitational lens effect of the sun. \item Annual aberration. \item Precession/nutation. \end{itemize} The {\it light deflection}\/ is seldom significant. Its value at the limb of the Sun is about \arcsec{1}{74}; it falls off rapidly with distance from the Sun and has shrunk to about \arcsec{0}{02} at an elongation of $20^\circ$. As already described, the {\it annual aberration}\/ is a function of the Earth's velocity relative to the solar system barycentre (available through the SLALIB routine sla\_EVP) and produces shifts of up to about \arcsec{20}{5}. The {\it precession/nutation}, from J2000 to the current epoch, is expressed by a rotation matrix which is available through the SLALIB routine sla\_PRENUT. The whole mean-to-apparent transformation can be done using the SLALIB routine sla\_MAP. As a demonstration, here is a program which lists the {\it North Polar Distance}\/ ($90^\circ-\delta$) of Polaris for the decade of closest approach to the Pole: \goodbreak \begin{verbatim} IMPLICIT NONE DOUBLE PRECISION PI,PIBY2,D2R,S2R,AS2R PARAMETER (PI=3.141592653589793238462643D0) PARAMETER (D2R=PI/180D0, : PIBY2=PI/2D0, : S2R=PI/(12D0*3600D0), : AS2R=PI/(180D0*3600D0)) DOUBLE PRECISION RM,DM,PR,PD,DATE,RA,DA INTEGER J,IDS,IDE,ID,IYMDF(4),I DOUBLE PRECISION sla_EPJ2D CALL sla_DTF2R(02,31,49.8131D0,RM,J) CALL sla_DAF2R(89,15,50.661D0,DM,J) PR=+21.7272D0*S2R/100D0 PD=-1.571D0*AS2R/100D0 WRITE (*,'(1X,'// : '''Polaris north polar distance (deg) 2096-2105''/)') WRITE (*,'(4X,''Date'',7X''NPD''/)') CALL sla_CLDJ(2096,1,1,DATE,J) IDS=NINT(DATE) CALL sla_CLDJ(2105,12,31,DATE,J) IDE=NINT(DATE) DO ID=IDS,IDE,10 DATE=DBLE(ID) CALL sla_DJCAL(0,DATE,IYMDF,J) CALL sla_MAP(RM,DM,PR,PD,0D0,0D0,2000D0,DATE,RA,DA) WRITE (*,'(1X,I4,2I3.2,F9.5)') (IYMDF(I),I=1,3),(PIBY2-DA)/D2R END DO END \end{verbatim} \goodbreak For cases where the transformation has to be repeated for different times or for more than one star, the straightforward sla\_MAP approach is apt to be wasteful as both the Earth velocity and the precession/nutation matrix can be re-calculated relatively infrequently without ill effect. A more efficient method is to perform the target-independent calculations only when necessary, by calling sla\_MAPPA, and then to use either sla\_MAPQKZ, when only the \radec\/ is known, or sla\_MAPQK, when full catalogue positions, including proper motion, parallax and radial velocity, are available. How frequently to call sla\_MAPPA depends on the accuracy objectives; once per night will deliver sub-arcsecond accuracy for example. The routines sla\_AMP and sla\_AMPQK allow the reverse transformation, from apparent to mean place. \subsection{Apparent Place to Observed Place} The {\it observed place}\/ of a source is its position as seen by a perfect theodolite at the location of the observer. Transformation of an apparent \radec\ to observed place involves the following effects: \goodbreak \begin{itemize} \item \radec\ to \hadec. \item Diurnal aberration. \item \hadec\ to \azel. \item Refraction. \end{itemize} The transformation from apparent \radec\ to apparent \hadec\ is made by allowing for {\it Earth rotation}\/ through the {\it sidereal time}, $\theta$: \[ h = \theta - \alpha \] For this equation to work, $\alpha$ must be the apparent right ascension for the time of observation, and $\theta$ must be the {\it local apparent sidereal time}. The latter is obtained as follows: \begin{enumerate} \item from civil time obtain the coordinated universal time, UTC (more later on this); \item add the UT1$-$UTC (typically a few tenths of a second) to give the UT; \item from the UT compute the Greenwich mean sidereal time (using sla\_GMST); \item add the observer's (east) longitude, giving the local mean sidereal time; \item add the equation of the equinoxes (using sla\_EQEQX). \end{enumerate} The {\it equation of the equinoxes}\/~($=\Delta\psi\cos\epsilon$ plus small terms) is the effect of nutation on the sidereal time. Its value is typically a second or less. It is interesting to note that if the object of the exercise is to transform a mean place all the way into an observed place (very often the case), then the equation of the equinoxes and the longitude component of nutation can both be omitted, removing a great deal of computation. However, SLALIB follows the normal convention and works {\it via}\/ the apparent place. Note that for very precise work the observer's longitude should be corrected for {\it polar motion}. This can be done with sla\_POLMO. The corrections are always less than about \arcsec{0}{3}, and are futile unless the position of the observer's telescope is known to better than a few metres. Tables of observed and predicted UT1$-$UTC corrections and polar motion data are published every few weeks by the International Earth Rotation Service. The transformation from apparent \hadec\ to {\it topocentric}\/ \hadec\ consists of allowing for {\it diurnal aberration}. This effect, maximum amplitude \arcsec{0}{2}, was described earlier. There is no specific SLALIB routine for computing the diurnal aberration, though the routines sla\_AOP {\it etc.}\ include it, and the required velocity vector can be determined by calling sla\_GEOC. The next stage is the major coordinate rotation from local equatorial coordinates \hadec\ into horizon coordinates. The SLALIB routines sla\_E2H {\it etc.}\ can be used for this. For high-precision applications the mean geodetic latitude should be corrected for polar motion. \subsubsection{Refraction} The final correction is for atmospheric refraction. This effect, which depends on local meteorological conditions and the effective colour of the source/detector combination, increases the observed elevation of the source by a significant effect even at moderate zenith distances, and near the horizon by over \degree{0}{5}. The amount of refraction can by computed by calling the SLALIB routine sla\_REFRO; however, this requires as input the observed zenith distance, which is what we are trying to predict. For high precision it is therefore necessary to iterate, using the topocentric zenith distance as the initial estimate of the observed zenith distance. The full sla\_REFRO refraction calculation is onerous, and for zenith distances of less than, say, $75^{\circ}$ the following model can be used instead: \[ \zeta _{vac} \approx \zeta _{obs} + A \tan \zeta _{obs} + B \tan ^{3}\zeta _{obs} \] where $\zeta _{vac}$ is the topocentric zenith distance (i.e.\ {\it in vacuo}), $\zeta _{obs}$ is the observed zenith distance (i.e.\ affected by refraction), and $A$ and $B$ are constants, about \arcseci{60} and \arcsec{-0}{06} respectively for a sea-level site. The two constants can be calculated for a given set of conditions by calling either sla\_REFCO or sla\_REFCOQ. sla\_REFCO works by calling sla\_REFRO for two zenith distances and fitting $A$ and $B$ to match. The calculation is onerous, but delivers accurate results whatever the conditions. sla\_REFCOQ uses a direct formulation of $A$ and $B$ and is much faster; it is slightly less accurate than sla\_REFCO but more than adequate for most practical purposes. Like the full refraction model, the two-term formulation works in the wrong direction for our purposes, predicting the {\it in vacuo}\/ (topocentric) zenith distance given the refracted (observed) zenith distance, rather than {\it vice versa}. The obvious approach of interchanging $\zeta _{vac}$ and $\zeta _{obs}$ and reversing the signs, though approximately correct, gives avoidable errors which are just significant in some applications; for example about \arcsec{0}{2} at $70^\circ$ zenith distance. A much better result can easily be obtained, by using one Newton-Raphson iteration as follows: \[ \zeta _{obs} \approx \zeta _{vac} - \frac{A \tan \zeta _{vac} + B \tan ^{3}\zeta _{vac}} {1 + ( A + 3 B \tan ^{2}\zeta _{vac} ) \sec ^{2}\zeta _{vac}}\] The effect of refraction can be applied to an unrefracted zenith distance by calling sla\_REFZ or to an unrefracted \xyz\ by calling sla\_REFV. Over most of the sky these two routines deliver almost identical results, but beyond $\zeta=83^\circ$ sla\_REFV becomes unacceptably inaccurate while sla\_REFZ remains usable. (However sla\_REFV is significantly faster, which may be important in some applications.) SLALIB also provides a routine for computing the airmass, the function sla\_AIRMAS. The refraction ``constants'' returned by sla\_REFCO and sla\_REFCOQ are slightly affected by colour, especially at the blue end of the spectrum. Where values for more than one wavelength are needed, rather than calling sla\_REFCO several times it is more efficient to call sla\_REFCO just once, for a selected ``base'' wavelength, and then to call sla\_ATMDSP once for each wavelength of interest. All the SLALIB refraction routines work for radio wavelengths as well as the optical/IR band. The radio refraction is very dependent on humidity, and an accurate value must be supplied. There is no wavelength dependence, however. The choice of optical/IR or radio is made by specifying a wavelength greater than $100\mu m$ for the radio case. \subsubsection{Efficiency considerations} The complete apparent place to observed place transformation can be carried out by calling sla\_AOP. For improved efficiency in cases of more than one star or a sequence of times, the target-independent calculations can be done once by calling sla\_AOPPA, the time can be updated by calling sla\_AOPPAT, and sla\_AOPQK can then be used to perform the apparent-to-observed transformation. The reverse transformation is available through sla\_OAP and sla\_OAPQK. ({\it n.b.}\ These routines use accurate but computationally-expensive refraction algorithms for zenith distances beyond about $76^\circ$. For many purposes, in-line code tailored to the accuracy requirements of the application will be preferable, for example ignoring UT1$-$UTC, omitting diurnal aberration and using sla\_REFZ to apply the refraction.) \subsection{The Hipparcos Catalogue and the ICRS} With effect from the beginning of 1998, the IAU adopted a new reference system to replace FK5 J2000. The new system, called the International Celestial Reference System (ICRS), differs profoundly from all predecessors in that the link with solar-system dynamics was broken; the ICRS axes are defined in terms of the directions of a set of extragalactic sources, not in terms of the mean equator and equinox at a given reference epoch. Although the ICRS and FK5 coordinates of any given object are almost the same, the orientation of the new frame was essentially arbitrary, and the close match to FK5 J2000 was contrived purely for reasons of continuity and convenience. A distinction is made between the reference {\it system}\/ (the ICRS) and {\it frame}\/ (ICRF). The ICRS is the set of prescriptions and conventions together with the modelling required to define, at any time, a triad of axes. The ICRF is a practical realization, and currently consists of a catalogue of equatorial coordinates for 608 extragalactic radio sources observed by VLBI. The best optical realization of the ICRF currently available is the Hipparcos catalogue. The extragalactic sources were not directly observable by the Hipparcos satellite and so the link from Hipparcos to ICRF was established through a variety of indirect techniques: VLBI and conventional interferometry of radio stars, photographic astrometry and so on. The Hipparcos frame is aligned to the ICRF to within about 0.5~mas and 0.5~mas/year (at epoch 1991.25). The Hipparcos catalogue includes all of the FK5 stars, which has enabled the orientation and spin of the latter to be studied. At epoch J2000, the misalignment of the FK5 frame with respect to Hipparcos (and hence ICRS) are about 32~mas and 1~mas/year respectively. Consequently, for many practical purposes, including pointing telescopes, the IAU 1976-1982 conventions on reference frames and Earth orientation remain adequate and there is no need to change to Hipparcos coordinates, new precession/nutation models and so on. However, for the most exacting astrometric applications, SLALIB provides some support for Hipparcos coordinates in the form of four new routines: sla\_FK52H and sla\_H2FK5, which transform FK5 positions and proper motions to the Hipparcos frame and {\it vice versa,}\/ and sla\_FK5HZ and sla\_HFK5Z, where the transformations are for stars whose Hipparcos proper motion is zero. Further information on the ICRS can be found in the paper by M.\,Feissel and F.\,Mignard, Astron.\,Astrophys. 331, L33-L36 (1988). \subsection{Timescales} SLALIB provides for conversion between several timescales, and involves use of one or two others. The full list is as follows: \begin{itemize} \item TAI: International Atomic Time \item UTC: Coordinated Universal Time \item UT: Universal Time \item GMST: Greenwich Mean Sidereal Time \item LAST: Local Apparent Sidereal Time \item TT: Terrestrial Time \item TDB: Barycentric Dynamical Time. \end{itemize} Three obsolete timescales should be mentioned here to avoid confusion. \begin{itemize} \item GMT: Greenwich Mean Time -- can mean either UTC or UT. \item ET: Ephemeris Time -- more or less the same as either TT or TDB. \item TDT: Terrestrial Dynamical Time -- former name of TT. \end{itemize} \subsubsection{Atomic Time: TAI} {\it International Atomic Time}\/ TAI is a laboratory timescale. Its unit is the SI second, which is defined in terms of a defined number of wavelengths of the radiation produced by a certain electronic transition in the caesium 133 atom. It is realized through a changing population of high-precision atomic clocks held at standards institutes in various countries. There is an elaborate process of continuous intercomparison, leading to a weighted average of all the clocks involved. Though TAI shares the same second as the more familiar UTC, the two timescales are noticeably separated in epoch because of the build-up of leap seconds. At the time of writing, UTC lags about half a minute behind TAI. For any given date, the difference TAI$-$UTC can be obtained by calling the SLALIB routine sla\_DAT. Note, however, that an up-to-date copy of the routine must be used if the most recent leap seconds are required. For applications where this is critical, mechanisms independent of SLALIB and under local control must be set up; in such cases sla\_DAT can be useful as an independent check, for test dates within the range of the available version. Up-to-date information on TAI$-$UTC is available from {\tt ftp://maia.usno.navy.mil/ser7/tai-utc.dat}. \subsubsection{Universal Time: UTC, UT1} {\it Coordinated Universal Time}\/ UTC is the basis of civil timekeeping. Most time zones differ from UTC by an integer number of hours, though a few ({\it e.g.}\ parts of Canada and Australia) differ by $n+0.5$~hours. The UTC second is the same as the SI second, as for TAI. In the long term, UTC keeps in step with the Sun. It does so even though the Earth's rotation is slightly variable (due to large scale movements of water and atmosphere among other things) by occasionally introducing a {\it leap second}. {\it Universal Time}\/ UT, or more specifically UT1, is in effect the mean solar time. It is continuous ({\it i.e.}\ there are no leap seconds) but has a variable rate because of the Earth's non-uniform rotation period. It is needed for computing the sidereal time, an essential part of pointing a telescope at a celestial source. To obtain UT1, you have to look up the value of UT1$-$UTC for the date concerned in tables published by the International Earth Rotation Service; this quantity, kept in the range $\pm$\tsec{0}{9} by means of UTC leap seconds, is then added to the UTC. The quantity UT1$-$UTC, which typically changes by 1 or 2~ms per day, can only be obtained by observation, though seasonal trends are known and the IERS listings are able to predict some way into the future with adequate accuracy for pointing telescopes. UTC leap seconds are introduced as necessary, usually at the end of December or June. On the average the solar day is slightly longer than the nominal 86,400~SI~seconds and so leap seconds are always positive; however, provision exists for negative leap seconds if needed. The form of a leap second can be seen from the following description of the end of June~1994: \hspace{3em} \begin{tabular}{clrccc} \\ & & & UTC & UT1$-$UTC & UT1 \\ \\ 1994 & June & 30 & 23 59 58 & $-0.218$ & 23 59 57.782 \\ & & & 23 59 59 & $-0.218$ & 23 59 58.782 \\ & & & 23 59 60 & $-0.218$ & 23 59 59.782 \\ & July & 1 & 00 00 00 & $+0.782$ & 00 00 00.782 \\ & & & 00 00 01 & $+0.782$ & 00 00 01.782 \\ \end{tabular} Note that UTC has to be expressed as hours, minutes and seconds (or at least in seconds for a given date) if leap seconds are to be taken into account. It is improper to express a UTC as a Julian Date, for example, because there will be an ambiguity during a leap second (in the above example, 1994~June~30 \hms{23}{59}{60}{0} and 1994~July~1 \hms{00}{00}{00}{0} would {\it both}\/ come out as MJD~49534.00000). Although in the vast majority of cases this won't matter, there are potential problems in on-line data acquisition systems and in applications involving taking the difference between two times. Note that although the routines sla\_DAT and sla\_DTT expect UTC in the form of an MJD, the meaning here is really a whole-number {\it date}\/ rather than a time. Though the routines will accept a fractional part and will almost always function correctly, on a day which ends with a leap second incorrect results would be obtained during the leap second itself because by then the MJD would have moved into the next day. \subsubsection{Sidereal Time: GMST, LAST} Sidereal Time is the ``time of day'' relative to the stars rather than to the Sun. After one sidereal day the stars come back to the same place in the sky, apart from sub-arcsecond precession effects. Because the Earth rotates faster relative to the stars than to the Sun by one day per year, the sidereal second is shorter than the solar second; the ratio is about 0.9973. The {\it Greenwich Mean Sidereal Time}\/ GMST is linked to UT1 by a numerical formula which is implemented in the SLALIB routines sla\_GMST and sla\_GMSTA. There are, of course, no leap seconds in GMST, but the second changes in length along with the UT1 second, and also varies over long periods of time because of slow changes in the Earth's orbit. This makes the timescale unsuitable for everything except predicting the apparent directions of celestial sources. The {\it Local Apparent Sidereal Time}\/ LAST is the apparent right ascension of the local meridian, from which the hour angle of any star can be determined knowing its $\alpha$. It can be obtained from the GMST by adding the east longitude (corrected for polar motion in precise work) and the {\it equation of the equinoxes}. The latter, already described, is an aspect of the nutation effect and can be predicted by calling the SLALIB routine sla\_EQEQX or, neglecting certain very small terms, by calling sla\_NUTC and using the expression $\Delta\psi\cos\epsilon$. \subsubsection{Dynamical Time: TT, TDB} Dynamical time is the independent variable in the theories which describe the motions of bodies in the solar system. When you use published formulae which model the position of the Earth in its orbit, for example, or look up the Moon's position in a precomputed ephemeris, the date and time you use must be in terms of one of the dynamical timescales. It is a common but understandable mistake to use UT directly, in which case the results will be about 1~minute out (in the present era). It is not hard to see why such timescales are necessary. UTC would clearly be unsuitable as the argument of an ephemeris because of leap seconds. A solar-system ephemeris based on UT1 or sidereal time would somehow have to include the unpredictable variations of the Earth's rotation. TAI would work, but eventually the ephemeris and the ensemble of atomic clocks would drift apart. In effect, the ephemeris {\it is}\/ a clock, with the bodies of the solar system the hands. Only two of the dynamical timescales are of any great importance to observational astronomers, TT and TDB. (The obsolete timescale ET, ephemeris time, was more or less the same as TT.) {\it Terrestrial Time}\/ TT is the theoretical timescale of apparent geocentric ephemerides of solar system bodies. It applies, in principle, to an Earthbound clock, at sea-level, and for practical purposes it is tied to Atomic Time TAI through the formula TT~$=$~TAI~$+$~\tsec{32}{184}. In practice, therefore, the units of TT are ordinary SI seconds, and the offset of \tsec{32}{184} with respect to TAI is fixed. The SLALIB routine sla\_DTT returns TT$-$UTC for a given UTC ({\it n.b.}\ sla\_DTT calls sla\_DAT, and the latter must be an up-to-date version if recent leap seconds are to be taken into account). {\it Barycentric Dynamical Time}\/ TDB differs from TT by an amount which cycles back and forth by a millisecond or two due to relativistic effects. The variation is negligible for most purposes, but unless taken into account would swamp long-term analysis of pulse arrival times from the millisecond pulsars. It is a consequence of the TT clock being on the Earth rather than in empty space: the ellipticity of the Earth's orbit means that the TT clock's speed and gravitational potential vary slightly during the course of the year, and as a consequence its rate as seen from an outside observer varies due to transverse Doppler effect and gravitational redshift. By definition, TDB and TT differ only by periodic terms, and the main effect is a sinusoidal variation of amplitude \tsec{0}{0016}; the largest planetary terms are nearly two orders of magnitude smaller. The SLALIB routine sla\_RCC provides a model of TDB-TT accurate to a few nanoseconds. There are other dynamical timescales, not supported by SLALIB routines, which include allowance also for the secular terms. These timescales gain on TT and TDB by about \tsec{0}{0013}/day. For most purposes the more accessible TT is the timescale to use, for example when calling sla\_PRENUT to generate a precession/nutation matrix or when calling sla\_EVP to predict the Earth's position and velocity. For some purposes TDB is the correct timescale, for example when interrogating the JPL planetary ephemeris (see {\it Starlink User Note~87}\/), though in most cases TT will be near enough and will involve less computation. Investigations of topocentric solar-system phenomena such as occultations and eclipses require solar time as well as dynamical time. TT/TDB/ET is all that is required in order to compute the geocentric circumstances, but if horizon coordinates or geocentric parallax are to be tackled UT is also needed. A rough estimate of $\Delta {\rm T} = {\rm ET} - {\rm UT}$ is available via the routine sla\_DT. For a given epoch ({\it e.g.}\ 1650) this returns an approximation to $\Delta {\rm T}$ in seconds. \subsection{Calendars} The ordinary {\it Gregorian Calendar Date}, together with a time of day, can be used to express an epoch in any desired timescale. For many purposes, however, a continuous count of days is more convenient, and for this purpose the system of {\it Julian Day Number}\/ can be used. JD zero is located about 7000~years ago, well before the historical era, and is formally defined in terms of Greenwich noon; Julian Day Number 2449444 began at noon on 1994 April~1. {\it Julian Date}\/ is the same system but with a fractional part appended; Julian Date 2449443.5 was the midnight on which 1994 April~1 commenced. Because of the unwieldy size of Julian Dates and the awkwardness of the half-day offset, it is accepted practice to remove the leading `24' and the trailing `.5', producing what is called the {\it Modified Julian Date}: MJD~=~JD$-2400000.5$. SLALIB routines use MJD, as opposed to JD, throughout, largely to avoid loss of precision. 1994 April~1 commenced at MJD~49443.0. Despite JD (and hence MJD) being defined in terms of (in effect) UT, the system can be used in conjunction with other timescales such as TAI, TT and TDB (and even sidereal time through the concept of {\it Greenwich Sidereal Date}). However, it is improper to express a UTC as a JD or MJD because of leap seconds. SLALIB has six routines for converting to and from dates in the Gregorian calendar. The routines sla\_CLDJ and sla\_CALDJ both convert a calendar date into an MJD, the former interpreting years between 0 and 99 as 1st century and the latter as late 20th or early 21st century. The routines sla\_DJCL and sla\_DJCAL both convert an MJD into calendar year, month, day and fraction of a day; the latter performs rounding to a specified precision, important to avoid dates like `{\tt 94 04 01.***}' appearing in messages. Some of SLALIB's low-precision ephemeris routines (sla\_EARTH, sla\_MOON and sla\_ECOR) work in terms of year plus day-in-year (where day~1~=~January~1st, at least for the modern era). This form of date can be generated by calling sla\_CALYD (which defaults years 0-99 into 1950-2049) or sla\_CLYD (which covers the full range from prehistoric times). \subsection{Geocentric Coordinates} The location of the observer on the Earth is significant in a number of ways. The most obvious, of course, is the effect of latitude on the observed \azel\ of a star. Less obvious is the need to allow for geocentric parallax when finding the Moon with a telescope (and when doing high-precision work involving the Sun or planets), and the need to correct observed radial velocities and apparent pulsar periods for the effects of the Earth's rotation. The SLALIB routine sla\_OBS supplies details of groundbased observatories from an internal list. This is useful when writing applications that apply to more than one observatory; the user can enter a brief name, or browse through a list, and be spared the trouble of typing in the full latitude, longitude {\it etc}. The following Fortran code returns the full name, longitude and latitude of a specified observatory: \goodbreak \begin{verbatim} CHARACTER IDENT*10,NAME*40 DOUBLE PRECISION W,P,H : CALL sla_OBS(0,IDENT,NAME,W,P,H) IF (NAME.EQ.'?') ... (not recognized) \end{verbatim} \goodbreak (Beware of the longitude sign convention, which is west +ve for historical reasons.) The following lists all the supported observatories: \goodbreak \begin{verbatim} : INTEGER N : N=1 NAME=' ' DO WHILE (NAME.NE.'?') CALL sla_OBS(N,IDENT,NAME,W,P,H) IF (NAME.NE.'?') THEN WRITE (*,'(1X,I3,4X,A,4X,A)') N,IDENT,NAME N=N+1 END IF END DO \end{verbatim} \goodbreak The routine sla\_GEOC converts a {\it geodetic latitude}\/ (one referred to the local horizon) to a geocentric position, taking into account the Earth's oblateness and also the height above sea level of the observer. The results are expressed in vector form, namely as the distance of the observer from the spin axis and equator respectively. The {\it geocentric latitude}\/ can be found be evaluating ATAN2 of the two numbers. A full 3-D vector description of the position and velocity of the observer is available through the routine sla\_PVOBS. For a specified geodetic latitude, height above sea level, and local sidereal time, sla\_PVOBS generates a 6-element vector containing the position and velocity with respect to the true equator and equinox of date ({\it i.e.}\ compatible with apparent \radec). For some applications it will be necessary to convert to a mean \radec\ frame (notably FK5, J2000) by multiplying elements 1-3 and 4-6 respectively with the appropriate precession matrix. (In theory an additional correction to the velocity vector is needed to allow for differential precession, but this correction is always negligible.) See also the discussion of the routine sla\_RVEROT, later. \subsection{Ephemerides} SLALIB includes routines for generating positions and velocities of Solar-System bodies. The accuracy objectives are modest, and the SLALIB facilities do not attempt to compete with precomputed ephemerides such as those provided by JPL, or with models containing thousands of terms. It is also worth noting that SLALIB's very accurate star coordinate conversion routines are not strictly applicable to solar-system cases, though they are adequate for most practical purposes. Earth/Sun ephemerides can be generated using the routine sla\_EVP, which predicts Earth position and velocity with respect to both the solar-system barycentre and the Sun. Maximum velocity error is 0.42~metres per second; maximum heliocentric position error is 1600~km (about \arcseci{2}), with barycentric position errors about 4 times worse. (The Sun's position as seen from the Earth can, of course, be obtained simply by reversing the signs of the Cartesian components of the Earth\,:\,Sun vector.) Geocentric Moon ephemerides are available from sla\_DMOON, which predicts the Moon's position and velocity with respect to the Earth's centre. Direction accuracy is usually better than 10~km (\arcseci{5}) and distance accuracy a little worse. Lower-precision but faster predictions for the Sun and Moon can be made by calling sla\_EARTH and sla\_MOON. Both are single precision and accept dates in the form of year, day-in-year and fraction of day (starting from a calendar date you need to call sla\_CLYD or sla\_CALYD to get the required year and day). The sla\_EARTH routine returns the heliocentric position and velocity of the Earth's centre for the mean equator and equinox of date. The accuracy is better than 20,000~km in position and 10~metres per second in speed. The position and velocity of the Moon with respect to the Earth's centre for the mean equator and ecliptic of date can be obtained by calling sla\_MOON. The positional accuracy is better than \arcseci{30} in direction and 1000~km in distance. Approximate ephemerides for all the major planets can be generated by calling sla\_PLANET or sla\_RDPLAN. These routines offer arcminute accuracy (much better for the inner planets and for Pluto) over a span of several millennia (but only $\pm100$ years for Pluto). The routine sla\_PLANET produces heliocentric position and velocity in the form of equatorial \xyzxyzd\ for the mean equator and equinox of J2000. The vectors produced by sla\_PLANET can be used in a variety of ways according to the requirements of the application concerned. The routine sla\_RDPLAN uses sla\_PLANET and sla\_DMOON to deal with the common case of predicting a planet's apparent \radec\ and angular size as seen by a terrestrial observer. Note that in predicting the position in the sky of a solar-system body it is necessary to allow for geocentric parallax. This correction is {\it essential}\/ in the case of the Moon, where the observer's position on the Earth can affect the Moon's \radec\ by up to $1^\circ$. The calculation can most conveniently be done by calling sla\_PVOBS and subtracting the resulting 6-vector from the one produced by sla\_DMOON, as is demonstrated by the following example: \goodbreak \begin{verbatim} * Demonstrate the size of the geocentric parallax correction * in the case of the Moon. The test example is for the AAT, * before midnight, in summer, near first quarter. IMPLICIT NONE CHARACTER NAME*40,SH,SD INTEGER J,I,IHMSF(4),IDMSF(4) DOUBLE PRECISION SLONGW,SLAT,H,DJUTC,FDUTC,DJUT1,DJTT,STL, : RMATN(3,3),PMM(6),PMT(6),RM,DM,PVO(6),TL DOUBLE PRECISION sla_DTT,sla_GMST,sla_EQEQX,sla_DRANRM * Get AAT longitude and latitude in radians and height in metres CALL sla_OBS(0,'AAT',NAME,SLONGW,SLAT,H) * UTC (1992 January 13, 11 13 59) to MJD CALL sla_CLDJ(1992,1,13,DJUTC,J) CALL sla_DTF2D(11,13,59.0D0,FDUTC,J) DJUTC=DJUTC+FDUTC * UT1 (UT1-UTC value of -0.152 sec is from IERS Bulletin B) DJUT1=DJUTC+(-0.152D0)/86400D0 * TT DJTT=DJUTC+sla_DTT(DJUTC)/86400D0 * Local apparent sidereal time STL=sla_GMST(DJUT1)-SLONGW+sla_EQEQX(DJTT) * Geocentric position/velocity of Moon (mean of date) CALL sla_DMOON(DJTT,PMM) * Nutation to true equinox of date CALL sla_NUT(DJTT,RMATN) CALL sla_DMXV(RMATN,PMM,PMT) CALL sla_DMXV(RMATN,PMM(4),PMT(4)) * Report geocentric HA,Dec CALL sla_DCC2S(PMT,RM,DM) CALL sla_DR2TF(2,sla_DRANRM(STL-RM),SH,IHMSF) CALL sla_DR2AF(1,DM,SD,IDMSF) WRITE (*,'(1X,'' geocentric:'',2X,A,I2.2,2I3.2,''.'',I2.2,'// : '1X,A,I2.2,2I3.2,''.'',I1)') : SH,IHMSF,SD,IDMSF * Geocentric position of observer (true equator and equinox of date) CALL sla_PVOBS(SLAT,H,STL,PVO) * Place origin at observer DO I=1,6 PMT(I)=PMT(I)-PVO(I) END DO * Allow for planetary aberration TL=499.004782D0*SQRT(PMT(1)**2+PMT(2)**2+PMT(3)**2) DO I=1,3 PMT(I)=PMT(I)-TL*PMT(I+3) END DO * Report topocentric HA,Dec CALL sla_DCC2S(PMT,RM,DM) CALL sla_DR2TF(2,sla_DRANRM(STL-RM),SH,IHMSF) CALL sla_DR2AF(1,DM,SD,IDMSF) WRITE (*,'(1X,''topocentric:'',2X,A,I2.2,2I3.2,''.'',I2.2,'// : '1X,A,I2.2,2I3.2,''.'',I1)') : SH,IHMSF,SD,IDMSF END \end{verbatim} \goodbreak The output produced is as follows: \goodbreak \begin{verbatim} geocentric: +03 06 55.59 +15 03 39.0 topocentric: +03 09 23.79 +15 40 51.5 \end{verbatim} \goodbreak (An easier but less instructive method of estimating the topocentric apparent place of the Moon is to call the routine sla\_RDPLAN.) As an example of using sla\_PLANET, the following program estimates the geocentric separation between Venus and Jupiter during a close conjunction in 2\,BC, which is a star-of-Bethlehem candidate: \goodbreak \begin{verbatim} * Compute time and minimum geocentric apparent separation * between Venus and Jupiter during the close conjunction of 2 BC. IMPLICIT NONE DOUBLE PRECISION SEPMIN,DJD0,FD,DJD,DJDM,DF,PV(6),RMATP(3,3), : PVM(6),PVE(6),TL,RV,DV,RJ,DJ,SEP INTEGER IHOUR,IMIN,J,I,IHMIN,IMMIN DOUBLE PRECISION sla_EPJ,sla_DSEP * Search for closest approach on the given day DJD0=1720859.5D0 SEPMIN=1D10 DO IHOUR=20,22 DO IMIN=0,59 CALL sla_DTF2D(IHOUR,IMIN,0D0,FD,J) * Julian date and MJD DJD=DJD0+FD DJDM=DJD-2400000.5D0 * Earth to Moon (mean of date) CALL sla_DMOON(DJDM,PV) * Precess Moon position to J2000 CALL sla_PRECL(sla_EPJ(DJDM),2000D0,RMATP) CALL sla_DMXV(RMATP,PV,PVM) * Sun to Earth-Moon Barycentre (mean J2000) CALL sla_PLANET(DJDM,3,PVE,J) * Correct from EMB to Earth DO I=1,3 PV(I)=PVE(I)-0.012150581D0*PVM(I) END DO * Sun to Venus CALL sla_PLANET(DJDM,2,PV,J) * Earth to Venus DO I=1,6 PV(I)=PV(I)-PVE(I) END DO * Light time to Venus (sec) TL=499.004782D0*SQRT((PV(1)-PVE(1))**2+ : (PV(2)-PVE(2))**2+ : (PV(3)-PVE(3))**2) * Extrapolate backwards in time by that much DO I=1,3 PV(I)=PV(I)-TL*PV(I+3) END DO * To RA,Dec CALL sla_DCC2S(PV,RV,DV) * Same for Jupiter CALL sla_PLANET(DJDM,5,PV,J) DO I=1,6 PV(I)=PV(I)-PVE(I) END DO TL=499.004782D0*SQRT((PV(1)-PVE(1))**2+ : (PV(2)-PVE(2))**2+ : (PV(3)-PVE(3))**2) DO I=1,3 PV(I)=PV(I)-TL*PV(I+3) END DO CALL sla_DCC2S(PV,RJ,DJ) * Separation (arcsec) SEP=sla_DSEP(RV,DV,RJ,DJ) * Keep if smallest so far IF (SEP.LT.SEPMIN) THEN IHMIN=IHOUR IMMIN=IMIN SEPMIN=SEP END IF END DO END DO * Report WRITE (*,'(1X,I2.2,'':'',I2.2,F6.1)') IHMIN,IMMIN, : 206264.8062D0*SEPMIN END \end{verbatim} \goodbreak The output produced (the Ephemeris Time on the day in question, and the closest approach in arcseconds) is as follows: \goodbreak \begin{verbatim} 21:19 33.7 \end{verbatim} \goodbreak For comparison, accurate predictions based on the JPL DE\,102 ephemeris give a separation about \arcseci{8} less than the above estimate, occurring about half an hour earlier (see {\it Sky and Telescope,}\/ April~1987, p\,357). The following program demonstrates sla\_RDPLAN. \begin{verbatim} * For a given date, time and geographical location, output * a table of planetary positions and diameters. IMPLICIT NONE CHARACTER PNAMES(0:9)*7,B*80,S INTEGER I,NP,IY,J,IM,ID,IHMSF(4),IDMSF(4) DOUBLE PRECISION R2AS,FD,DJM,ELONG,PHI,RA,DEC,DIAM PARAMETER (R2AS=206264.80625D0) DATA PNAMES / 'Sun','Mercury','Venus','Moon','Mars','Jupiter', : 'Saturn','Uranus','Neptune', 'Pluto' / * Loop until 'end' typed B=' ' DO WHILE (B.NE.'END'.AND.B.NE.'end') * Get date, time and observer's location PRINT *,'Date? (Y,M,D, Gregorian)' READ (*,'(A)') B IF (B.NE.'END'.AND.B.NE.'end') THEN I=1 CALL sla_INTIN(B,I,IY,J) CALL sla_INTIN(B,I,IM,J) CALL sla_INTIN(B,I,ID,J) PRINT *,'Time? (H,M,S, dynamical)' READ (*,'(A)') B I=1 CALL sla_DAFIN(B,I,FD,J) FD=FD*2.3873241463784300365D0 CALL sla_CLDJ(IY,IM,ID,DJM,J) DJM=DJM+FD PRINT *,'Longitude? (D,M,S, east +ve)' READ (*,'(A)') B I=1 CALL sla_DAFIN(B,I,ELONG,J) PRINT *,'Latitude? (D,M,S, (geodetic)' READ (*,'(A)') B I=1 CALL sla_DAFIN(B,I,PHI,J) * Loop planet by planet DO NP=0,8 * Get RA,Dec and diameter CALL sla_RDPLAN(DJM,NP,ELONG,PHI,RA,DEC,DIAM) * One line of report CALL sla_DR2TF(2,RA,S,IHMSF) CALL sla_DR2AF(1,DEC,S,IDMSF) WRITE (*, : '(1X,A,2X,3I3.2,''.'',I2.2,2X,A,I2.2,2I3.2,''.'',I1,F8.1)') : PNAMES(NP),IHMSF,S,IDMSF,R2AS*DIAM * Next planet END DO PRINT *,' ' END IF * Next case END DO END \end{verbatim} Entering the following data (for 1927~June~29 at $5^{\rm h}\,25^{\rm m}$~ET and the position of Preston, UK.): \begin{verbatim} 1927 6 29 5 25 -2 42 53 46 \end{verbatim} produces the following report: \begin{verbatim} Sun 06 28 14.03 +23 17 17.5 1887.8 Mercury 08 08 58.62 +19 20 57.3 9.3 Venus 09 38 53.64 +15 35 32.9 22.8 Moon 06 28 18.30 +23 18 37.3 1903.9 Mars 09 06 49.34 +17 52 26.7 4.0 Jupiter 00 11 12.06 -00 10 57.5 41.1 Saturn 16 01 43.34 -18 36 55.9 18.2 Uranus 00 13 33.53 +00 39 36.0 3.5 Neptune 09 49 35.75 +13 38 40.8 2.2 Pluto 07 05 29.50 +21 25 04.2 .1 \end{verbatim} Inspection of the Sun and Moon data reveals that a total solar eclipse is in progress. SLALIB also provides for the case where orbital elements (with respect to the J2000 equinox and ecliptic) are available. This allows predictions to be made for minor-planets and (if you ignore non-gravitational effects) comets. Furthermore, if major-planet elements for an epoch close to the date in question are available, more accurate predictions can be made than are offered by sla\_RDPLAN and sla\_PLANET. The SLALIB planetary-prediction routines that work with orbital elements are sla\_PLANTE (the orbital-elements equivalent of sla\_RDPLAN), which predicts the topocentric \radec, and sla\_PLANEL (the orbital-elements equivalent of sla\_PLANET), which predicts the heliocentric \xyzxyzd\ with respect to the J2000 equinox and equator. In addition, the routine sla\_PV2EL does the inverse of sla\_PLANEL, transforming \xyzxyzd\ into {\it osculating elements.} Osculating elements describe the unperturbed 2-body orbit. This is a good approximation to the actual orbit for a few weeks either side of the specified epoch, outside which perturbations due to the other bodies of the Solar System lead to increasing errors. Given a minor planet's osculating elements for a particular date, predictions for a date even just 100 days earlier or later are likely to be in error by several arcseconds. These errors can be reduced if new elements are generated which take account of the perturbations of the major planets, and this is what the routine sla\_PERTEL does. Once sla\_PERTEL has been called, to provide osculating elements close to the required date, the elements can be passed to sla\_PLANEL or sla\_PLANTE in the normal way. Predictions of arcsecond accuracy over a span of a decade or more are available using this technique. Three different combinations of orbital elements are provided for, matching the usual conventions for major planets, minor planets and comets respectively. The choice is made through the argument {\tt JFORM}:\\ \hspace{4em} \begin{tabular}{|c|c|c|} \hline {\tt JFORM=1} & {\tt JFORM=2} & {\tt JFORM=3} \\ \hline \hline $t_0$ & $t_0$ & $T$ \\ \hline $i$ & $i$ & $i$ \\ \hline $\Omega$ & $\Omega$ & $\Omega$ \\ \hline $\varpi$ & $\omega$ & $\omega$ \\ \hline $a$ & $a$ & $q$ \\ \hline $e$ & $e$ & $e$ \\ \hline $L$ & $M$ & \\ \hline $n$ & & \\ \hline \end{tabular}\\[5ex] The symbols have the following meanings: \begin{tabbing} xxxxxxx \= xxxx \= \kill \> $t_0$ \> epoch at which the elements were correct \\ \> $T$ \> epoch of perihelion passage \\ \> $i$ \> inclination of the orbit \\ \> $\Omega$ \> longitude of the ascending node \\ \> $\varpi$ \> longitude of perihelion ($\varpi = \Omega + \omega$) \\ \> $\omega$ \> argument of perihelion \\ \> $a$ \> semi-major axis of the orbital ellipse \\ \> $q$ \> perihelion distance \\ \> $e$ \> orbital eccentricity \\ \> $L$ \> mean longitude ($L = \varpi + M$) \\ \> $M$ \> mean anomaly \\ \> $n$ \> mean motion \\ \end{tabbing} The mean motion, $n$, tells sla\_PLANEL the mass of the planet. If it is not available, it should be claculated from $n^2 a^3 = k^2 (1+m)$, where $k = 0.01720209895$ and m is the mass of the planet ($M_\odot = 1$); $a$ is in AU. Conventional elements are not the only way of specifying an orbit. The \xyzxyzd\ state vector is an equally valid specification, and the so-called {\it method of universal variables}\/ allows orbital calculations to be made directly, bypassing angular quantities and avoiding Kepler's Equation. The universal-variables approach has various advantages, including better handling of near-parabolic cases and greater efficiency. SLALIB uses universal variables for its internal calculations and also offers a number of routines which applications can call. The universal elements are the \xyzxyzd\ and its epoch, plus the mass of the body. The SLALIB routines supplement these elements with certain redundant values in order to avoid unnecessary recomputation when the elements are next used. The routines sla\_EL2UE and sla\_UE2EL transform conventional elements into the universal form and {\it vice versa.} The routine sla\_PV2UE takes an \xyzxyzd\ and forms the set of universal elements; sla\_UE2PV takes a set of universal elements and predicts the \xyzxyzd\ for a specified epoch. The routine sla\_PERTUE provides updated universal elements, taking into account perturbations from the major planets. \subsection{Radial Velocity and Light-Time Corrections} When publishing high-resolution spectral observations it is necessary to refer them to a specified standard of rest. This involves knowing the component in the direction of the source of the velocity of the observer. SLALIB provides a number of routines for this purpose, allowing observations to be referred to the Earth's centre, the Sun, a Local Standard of Rest (either dynamical or kinematical), the centre of the Galaxy, and the mean motion of the Local Group. The routine sla\_RVEROT corrects for the diurnal rotation of the observer around the Earth's axis. This is always less than 0.5~km/s. No specific routine is provided to correct a radial velocity from geocentric to heliocentric, but this can easily be done by calling sla\_EVP as follows (array declarations {\it etc}.\ omitted): \goodbreak \begin{verbatim} : * Star vector, J2000 CALL sla_DCS2C(RM,DM,V) * Earth/Sun velocity and position, J2000 CALL sla_EVP(TDB,2000D0,DVB,DPB,DVH,DPH) * Radial velocity correction due to Earth orbit (km/s) VCORB = -sla_DVDV(V,DVH)*149.597870D6 : \end{verbatim} \goodbreak The maximum value of this correction is the Earth's orbital speed of about 30~km/s. A related routine, sla\_ECOR, computes the light-time correction with respect to the Sun. It would be used when reducing observations of a rapid variable-star for instance. Note, however, that the accuracy objectives for pulsar work are beyond the scope of these SLALIB routines, and even the superior sla\_EVP routine is unsuitable for arrival-time calculations of better than 25~millisecond accuracy. To remove the intrinsic $\sim20$~km/s motion of the Sun relative to other stars in the solar neighbourhood, a velocity correction to a {\it local standard of rest}\/ (LSR) is required. There are opportunities for mistakes here. There are two sorts of LSR, {\it dynamical}\/ and {\it kinematical}, and multiple definitions exist for the latter. The dynamical LSR is a point near the Sun which is in a circular orbit around the Galactic centre; the Sun has a ``peculiar'' motion relative to the dynamical LSR. A kinematical LSR is the mean standard of rest of specified star catalogues or stellar populations, and its precise definition depends on which catalogues or populations were used and how the analysis was carried out. The Sun's motion with respect to a kinematical LSR is called the ``standard'' solar motion. Radial velocity corrections to the dynamical LSR are produced by the routine sla\_RVLSRD and to the adopted kinematical LSR by sla\_RVLSRK. See the individual specifications for these routines for the precise definition of the LSR in each case. For extragalactic sources, the centre of the Galaxy can be used as a standard of rest. The radial velocity correction from the dynamical LSR to the Galactic centre can be obtained by calling sla\_RVGALC. Its maximum value is 220~km/s. For very distant sources it is appropriate to work relative to the mean motion of the Local Group. The routine for computing the radial velocity correction in this case is sla\_RVLG. Note that in this case the correction is with respect to the dynamical LSR, not the Galactic centre as might be expected. This conforms to the IAU definition, and confers immunity from revisions of the Galactic rotation speed. \subsection{Focal-Plane Astrometry} The relationship between the position of a star image in the focal plane of a telescope and the star's celestial coordinates is usually described in terms of the {\it tangent plane}\/ or {\it gnomonic}\/ projection. This is the projection produced by a pin-hole camera and is a good approximation to the projection geometry of a traditional large {\it f}\/-ratio astrographic refractor. SLALIB includes a group of routines which transform star positions between their observed places on the celestial sphere and their \xy\ coordinates in the tangent plane. The spherical coordinate system does not have to be \radec\ but usually is. The so-called {\it standard coordinates}\/ of a star are the tangent plane \xy, in radians, with respect to an origin at the tangent point, with the $y$-axis pointing north and the $x$-axis pointing east (in the direction of increasing $\alpha$). The factor relating the standard coordinates to the actual \xy\ coordinates in, say, millimetres is simply the focal length of the telescope. Given the \radec\ of the {\it plate centre}\/ (the tangent point) and the \radec\ of a star within the field, the standard coordinates can be determined by calling sla\_S2TP (single precision) or sla\_DS2TP (double precision). The reverse transformation, where the \xy\ is known and we wish to find the \radec, is carried out by calling sla\_TP2S or sla\_DTP2S. Occasionally we know the both the \xy\ and the \radec\ of a star and need to deduce the \radec\ of the tangent point; this can be done by calling sla\_TPS2C or sla\_DTPS2C. (All of these transformations apply not just to \radec\ but to other spherical coordinate systems, of course.) Equivalent (and faster) routines are provided which work directly in \xyz\ instead of spherical coordinates: sla\_V2TP and sla\_DV2TP, sla\_TP2V and sla\_DTP2V, sla\_TPV2C and sla\_DTPV2C. Even at the best of times, the tangent plane projection is merely an approximation. Some telescopes and cameras exhibit considerable pincushion or barrel distortion and some have a curved focal surface. For example, neither Schmidt cameras nor (especially) large reflecting telescopes with wide-field corrector lenses are adequately modelled by tangent-plane geometry. In such cases, however, it is still possible to do most of the work using the (mathematically convenient) tangent-plane projection by inserting an extra step which applies or removes the distortion peculiar to the system concerned. A simple $r_1=r_0(1+Kr_0^2)$ law works well in the majority of cases; $r_0$ is the radial distance in the tangent plane, $r_1$ is the radial distance after adding the distortion, and $K$ is a constant which depends on the telescope ($\theta$ is unaffected). The routine sla\_PCD applies the distortion to an \xy\ and sla\_UNPCD removes it. For \xy\ in radians, $K$ values range from $-1/3$ for the tiny amount of barrel distortion in Schmidt geometry to several hundred for the serious pincushion distortion produced by wide-field correctors in big reflecting telescopes (the AAT prime focus triplet corrector is about $K=+178.6$). SLALIB includes a group of routines which can be put together to build a simple plate-reduction program. The heart of the group is sla\_FITXY, which fits a linear model to relate two sets of \xy\ coordinates, in the case of a plate reduction the measured positions of the images of a set of reference stars and the standard coordinates derived from their catalogue positions. The model is of the form: \[x_{p} = a + bx_{m} + cy_{m}\] \[y_{p} = d + ex_{m} + fy_{m}\] where the {\it p}\/ subscript indicates ``predicted'' coordinates (the model's approximation to the ideal ``expected'' coordinates) and the {\it m}\/ subscript indicates ``measured coordinates''. The six coefficients {\it a--f}\/ can optionally be constrained to represent a ``solid body rotation'' free of any squash or shear distortions. Without this constraint the model can, to some extent, accommodate effects like refraction, allowing mean places to be used directly and avoiding the extra complications of a full mean-apparent-observed transformation for each star. Having obtained the linear model, sla\_PXY can be used to process the set of measured and expected coordinates, giving the predicted coordinates and determining the RMS residuals in {\it x}\/ and {\it y}. The routine sla\_XY2XY transforms one \xy\ into another using the linear model. A model can be inverted by calling sla\_INVF, and decomposed into zero points, scales, $x/y$ nonperpendicularity and orientation by calling sla\_DCMPF. \subsection{Numerical Methods} SLALIB contains a small number of simple, general-purpose numerical-methods routines. They have no specific connection with positional astronomy but have proved useful in applications to do with simulation and fitting. At the heart of many simulation programs is the generation of pseudo-random numbers, evenly distributed in a given range: sla\_RANDOM does this. Pseudo-random normal deviates, or ``Gaussian residuals'', are often required to simulate noise and can be generated by means of the function sla\_GRESID. Neither routine will pass super-sophisticated statistical tests, but they work adequately for most practical purposes and avoid the need to call non-standard library routines peculiar to one sort of computer. Applications which perform a least-squares fit using a traditional normal-equations methods can accomplish the required matrix-inversion by calling either sla\_SMAT (single precision) or sla\_DMAT (double). A generally better way to perform such fits is to use singular value decomposition. SLALIB provides a routine to do the decomposition itself, sla\_SVD, and two routines to use the results: sla\_SVDSOL generates the solution, and sla\_SVDCOV produces the covariance matrix. A simple demonstration of the use of the SLALIB SVD routines is given below. It generates 500 simulated data points and fits them to a model which has 4 unknown coefficients. (The arrays in the example are sized to accept up to 1000 points and 20 unknowns.) The model is: \[ y = C_{1} +C_{2}x +C_{3}sin{x} +C_{4}cos{x} \] The test values for the four coefficients are $C_1\!=\!+50.0$, $C_2\!=\!-2.0$, $C_3\!=\!-10.0$ and $C_4\!=\!+25.0$. Gaussian noise, $\sigma=5.0$, is added to each ``observation''. \goodbreak \begin{verbatim} IMPLICIT NONE * Sizes of arrays, physical and logical INTEGER MP,NP,NC,M,N PARAMETER (MP=1000,NP=10,NC=20,M=500,N=4) * The unknowns we are going to solve for DOUBLE PRECISION C1,C2,C3,C4 PARAMETER (C1=50D0,C2=-2D0,C3=-10D0,C4=25D0) * Arrays DOUBLE PRECISION A(MP,NP),W(NP),V(NP,NP), : WORK(NP),B(MP),X(NP),CVM(NC,NC) DOUBLE PRECISION VAL,BF1,BF2,BF3,BF4,SD2,D,VAR REAL sla_GRESID INTEGER I,J * Fill the design matrix DO I=1,M * Dummy independent variable VAL=DBLE(I)/10D0 * The basis functions BF1=1D0 BF2=VAL BF3=SIN(VAL) BF4=COS(VAL) * The observed value, including deliberate Gaussian noise B(I)=C1*BF1+C2*BF2+C3*BF3+C4*BF4+DBLE(sla_GRESID(5.0)) * Fill one row of the design matrix A(I,1)=BF1 A(I,2)=BF2 A(I,3)=BF3 A(I,4)=BF4 END DO * Factorize the design matrix, solve and generate covariance matrix CALL sla_SVD(M,N,MP,NP,A,W,V,WORK,J) CALL sla_SVDSOL(M,N,MP,NP,B,A,W,V,WORK,X) CALL sla_SVDCOV(N,NP,NC,W,V,WORK,CVM) * Compute the variance SD2=0D0 DO I=1,M VAL=DBLE(I)/10D0 BF1=1D0 BF2=VAL BF3=SIN(VAL) BF4=COS(VAL) D=B(I)-(X(1)*BF1+X(2)*BF2+X(3)*BF3+X(4)*BF4) SD2=SD2+D*D END DO VAR=SD2/DBLE(M) * Report the RMS and the solution WRITE (*,'(1X,''RMS ='',F5.2/)') SQRT(VAR) DO I=1,N WRITE (*,'(1X,''C'',I1,'' ='',F7.3,'' +/-'',F6.3)') : I,X(I),SQRT(VAR*CVM(I,I)) END DO END \end{verbatim} \goodbreak The program produces the following output: \goodbreak \begin{verbatim} RMS = 4.88 C1 = 50.192 +/- 0.439 C2 = -2.002 +/- 0.015 C3 = -9.771 +/- 0.310 C4 = 25.275 +/- 0.310 \end{verbatim} \goodbreak In this above example, essentially identical results would be obtained if the more commonplace normal-equations method had been used, and the large $1000\times20$ array would have been avoided. However, the SVD method comes into its own when the opportunity is taken to edit the W-matrix (the so-called ``singular values'') in order to control possible ill-conditioning. The procedure involves replacing with zeroes any W-elements smaller than a nominated value, for example 0.001 times the largest W-element. Small W-elements indicate ill-conditioning, which in the case of the normal-equations method would produce spurious large coefficient values and possible arithmetic overflows. Using SVD, the effect on the solution of setting suspiciously small W-elements to zero is to restrain the offending coefficients from moving very far. The fact that action was taken can be reported to show the program user that something is amiss. Furthermore, if element W(J) was set to zero, the row numbers of the two biggest elements in the Jth column of the V-matrix identify the pair of solution coefficients that are dependent. A more detailed description of SVD and its use in least-squares problems would be out of place here, and the reader is urged to refer to the relevant sections of the book {\it Numerical Recipes} (Press {\it et al.}, Cambridge University Press, 1987). The routines sla\_COMBN and sla\_PERMUT are useful for problems which involve combinations (different subsets) and permutations (different orders). Both return the next in a sequence of results, cycling through all the possible results as the routine is called repeatedly. \pagebreak \section{SUMMARY OF CALLS} The basic trigonometrical and numerical facilities are supplied in both single and double precision versions. Most of the more esoteric position and time routines use double precision arguments only, even in cases where single precision would normally be adequate in practice. Certain routines with modest accuracy objectives are supplied in single precision versions only. In the calling sequences which follow, no attempt has been made to distinguish between single and double precision argument names, and frequently the same name is used on different occasions to mean different things. However, none of the routines uses a mixture of single and double precision arguments; each routine is either wholly single precision or wholly double precision. In the classified list, below, {\it subroutine}\/ subprograms are those whose names and argument lists are preceded by `CALL', whereas {\it function}\/ subprograms are those beginning `R=' (when the result is REAL) or `D=' (when the result is DOUBLE~PRECISION). The list is, of course, merely for quick reference; inexperienced users {\bf must} refer to the detailed specifications given later. In particular, {\bf don't guess} whether arguments are single or double precision; the result could be a program that happens to works on one sort of machine but not on another. \callhead{String Decoding} \begin{callset} \subp{CALL sla\_INTIN (STRING, NSTRT, IRESLT, JFLAG)} Convert free-format string into integer \subq{CALL sla\_FLOTIN (STRING, NSTRT, RESLT, JFLAG)} {CALL sla\_DFLTIN (STRING, NSTRT, DRESLT, JFLAG)} Convert free-format string into floating-point number \subq{CALL sla\_AFIN (STRING, NSTRT, RESLT, JFLAG)} {CALL sla\_DAFIN (STRING, NSTRT, DRESLT, JFLAG)} Convert free-format string from deg,arcmin,arcsec to radians \end{callset} \callhead{Sexagesimal Conversions} \begin{callset} \subq{CALL sla\_CTF2D (IHOUR, IMIN, SEC, DAYS, J)} {CALL sla\_DTF2D (IHOUR, IMIN, SEC, DAYS, J)} Hours, minutes, seconds to days \subq{CALL sla\_CD2TF (NDP, DAYS, SIGN, IHMSF)} {CALL sla\_DD2TF (NDP, DAYS, SIGN, IHMSF)} Days to hours, minutes, seconds \subq{CALL sla\_CTF2R (IHOUR, IMIN, SEC, RAD, J)} {CALL sla\_DTF2R (IHOUR, IMIN, SEC, RAD, J)} Hours, minutes, seconds to radians \subq{CALL sla\_CR2TF (NDP, ANGLE, SIGN, IHMSF)} {CALL sla\_DR2TF (NDP, ANGLE, SIGN, IHMSF)} Radians to hours, minutes, seconds \subq{CALL sla\_CAF2R (IDEG, IAMIN, ASEC, RAD, J)} {CALL sla\_DAF2R (IDEG, IAMIN, ASEC, RAD, J)} Degrees, arcminutes, arcseconds to radians \subq{CALL sla\_CR2AF (NDP, ANGLE, SIGN, IDMSF)} {CALL sla\_DR2AF (NDP, ANGLE, SIGN, IDMSF)} Radians to degrees, arcminutes, arcseconds \end{callset} \callhead{Angles, Vectors and Rotation Matrices} \begin{callset} \subq{R~=~sla\_RANGE (ANGLE)} {D~=~sla\_DRANGE (ANGLE)} Normalize angle into range $\pm\pi$ \subq{R~=~sla\_RANORM (ANGLE)} {D~=~sla\_DRANRM (ANGLE)} Normalize angle into range $0\!-\!2\pi$ \subq{CALL sla\_CS2C (A, B, V)} {CALL sla\_DCS2C (A, B, V)} Spherical coordinates to \xyz \subq{CALL sla\_CC2S (V, A, B)} {CALL sla\_DCC2S (V, A, B)} \xyz\ to spherical coordinates \subq{R~=~sla\_VDV (VA, VB)} {D~=~sla\_DVDV (VA, VB)} Scalar product of two 3-vectors \subq{CALL sla\_VXV (VA, VB, VC)} {CALL sla\_DVXV (VA, VB, VC)} Vector product of two 3-vectors \subq{CALL sla\_VN (V, UV, VM)} {CALL sla\_DVN (V, UV, VM)} Normalize a 3-vector also giving the modulus \subq{R~=~sla\_SEP (A1, B1, A2, B2)} {D~=~sla\_DSEP (A1, B1, A2, B2)} Angle between two points on a sphere \subq{R~=~sla\_BEAR (A1, B1, A2, B2)} {D~=~sla\_DBEAR (A1, B1, A2, B2)} Direction of one point on a sphere seen from another \subq{R~=~sla\_PAV (V1, V2)} {D~=~sla\_DPAV (V1, V2)} Position-angle of one \xyz\ with respect to another \subq{CALL sla\_EULER (ORDER, PHI, THETA, PSI, RMAT)} {CALL sla\_DEULER (ORDER, PHI, THETA, PSI, RMAT)} Form rotation matrix from three Euler angles \subq{CALL sla\_AV2M (AXVEC, RMAT)} {CALL sla\_DAV2M (AXVEC, RMAT)} Form rotation matrix from axial vector \subq{CALL sla\_M2AV (RMAT, AXVEC)} {CALL sla\_DM2AV (RMAT, AXVEC)} Determine axial vector from rotation matrix \subq{CALL sla\_MXV (RM, VA, VB)} {CALL sla\_DMXV (DM, VA, VB)} Rotate vector forwards \subq{CALL sla\_IMXV (RM, VA, VB)} {CALL sla\_DIMXV (DM, VA, VB)} Rotate vector backwards \subq{CALL sla\_MXM (A, B, C)} {CALL sla\_DMXM (A, B, C)} Product of two 3x3 matrices \subq{CALL sla\_CS2C6 (A, B, R, AD, BD, RD, V)} {CALL sla\_DS2C6 (A, B, R, AD, BD, RD, V)} Conversion of position and velocity in spherical coordinates to Cartesian coordinates \subq{CALL sla\_CC62S (V, A, B, R, AD, BD, RD)} {CALL sla\_DC62S (V, A, B, R, AD, BD, RD)} Conversion of position and velocity in Cartesian coordinates to spherical coordinates \end{callset} \callhead{Calendars} \begin{callset} \subp{CALL sla\_CLDJ (IY, IM, ID, DJM, J)} Gregorian Calendar to Modified Julian Date \subp{CALL sla\_CALDJ (IY, IM, ID, DJM, J)} Gregorian Calendar to Modified Julian Date, permitting century default \subp{CALL sla\_DJCAL (NDP, DJM, IYMDF, J)} Modified Julian Date to Gregorian Calendar, in a form convenient for formatted output \subp{CALL sla\_DJCL (DJM, IY, IM, ID, FD, J)} Modified Julian Date to Gregorian Year, Month, Day, Fraction \subp{CALL sla\_CALYD (IY, IM, ID, NY, ND, J)} Calendar to year and day in year, permitting century default \subp{CALL sla\_CLYD (IY, IM, ID, NY, ND, J)} Calendar to year and day in year \subp{D~=~sla\_EPB (DATE)} Modified Julian Date to Besselian Epoch \subp{D~=~sla\_EPB2D (EPB)} Besselian Epoch to Modified Julian Date \subp{D~=~sla\_EPJ (DATE)} Modified Julian Date to Julian Epoch \subp{D~=~sla\_EPJ2D (EPJ)} Julian Epoch to Modified Julian Date \end{callset} \callhead{Timescales} \begin{callset} \subp{D~=~sla\_GMST (UT1)} Conversion from Universal Time to sidereal time \subp{D~=~sla\_GMSTA (DATE, UT1)} Conversion from Universal Time to sidereal time, rounding errors minimized \subp{D~=~sla\_EQEQX (DATE)} Equation of the equinoxes \subp{D~=~sla\_DAT (DJU)} Offset of Atomic Time from Coordinated Universal Time: TAI$-$UTC \subp{D~=~sla\_DT (EPOCH)} Approximate offset between dynamical time and universal time \subp{D~=~sla\_DTT (DJU)} Offset of Terrestrial Time from Coordinated Universal Time: TT$-$UTC \subp{D~=~sla\_RCC (TDB, UT1, WL, U, V)} Relativistic clock correction: TDB$-$TT \end{callset} \callhead{Precession and Nutation} \begin{callset} \subp{CALL sla\_NUT (DATE, RMATN)} Nutation matrix \subp{CALL sla\_NUTC (DATE, DPSI, DEPS, EPS0)} Longitude and obliquity components of nutation, and mean obliquity \subp{CALL sla\_PREC (EP0, EP1, RMATP)} Precession matrix (IAU) \subp{CALL sla\_PRECL (EP0, EP1, RMATP)} Precession matrix (suitable for long periods) \subp{CALL sla\_PRENUT (EPOCH, DATE, RMATPN)} Combined precession/nutation matrix \subp{CALL sla\_PREBN (BEP0, BEP1, RMATP)} Precession matrix, old system \subp{CALL sla\_PRECES (SYSTEM, EP0, EP1, RA, DC)} Precession, in either the old or the new system \end{callset} \callhead{Proper Motion} \begin{callset} \subp{CALL sla\_PM (R0, D0, PR, PD, PX, RV, EP0, EP1, R1, D1)} Adjust for proper motion \end{callset} \callhead{FK4/FK5/Hipparcos Conversions} \begin{callset} \subp{CALL sla\_FK425 (\vtop {\hbox{R1950, D1950, DR1950, DD1950, P1950, V1950,} \hbox{R2000, D2000, DR2000, DD2000, P2000, V2000)}}} Convert B1950.0 FK4 star data to J2000.0 FK5 \subp{CALL sla\_FK45Z (R1950, D1950, EPOCH, R2000, D2000)} Convert B1950.0 FK4 position to J2000.0 FK5 assuming zero FK5 proper motion and no parallax \subp{CALL sla\_FK524 (\vtop {\hbox{R2000, D2000, DR2000, DD2000, P2000, V2000,} \hbox{R1950, D1950, DR1950, DD1950, P1950, V1950)}}} Convert J2000.0 FK5 star data to B1950.0 FK4 \subp{CALL sla\_FK54Z (R2000, D2000, BEPOCH, R1950, D1950, DR1950, DD1950)} Convert J2000.0 FK5 position to B1950.0 FK4 assuming zero FK5 proper motion and no parallax \subp{CALL sla\_FK52H (R5, D5, DR5, DD5, RH, DH, DRH, DDH)} Convert J2000.0 FK5 star data to Hipparcos \subp{CALL sla\_FK5HZ (R5, D5, EPOCH, RH, DH )} Convert J2000.0 FK5 position to Hipparcos assuming zero Hipparcos proper motion \subp{CALL sla\_H2FK5 (RH, DH, DRH, DDH, R5, D5, DR5, DD5)} Convert Hipparcos star data to J2000.0 FK5 \subp{CALL sla\_HFK5Z (RH, DH, EPOCH, R5, D5, DR5, DD5)} Convert Hipparcos position to J2000.0 FK5 assuming zero Hipparcos proper motion \subp{CALL sla\_DBJIN (STRING, NSTRT, DRESLT, J1, J2)} Like sla\_DFLTIN but with extensions to accept leading `B' and `J' \subp{CALL sla\_KBJ (JB, E, K, J)} Select epoch prefix `B' or `J' \subp{D~=~sla\_EPCO (K0, K, E)} Convert an epoch into the appropriate form -- `B' or `J' \end{callset} \callhead{Elliptic Aberration} \begin{callset} \subp{CALL sla\_ETRMS (EP, EV)} E-terms \subp{CALL sla\_SUBET (RC, DC, EQ, RM, DM)} Remove the E-terms \subp{CALL sla\_ADDET (RM, DM, EQ, RC, DC)} Add the E-terms \end{callset} \callhead{Geographical and Geocentric Coordinates} \begin{callset} \subp{CALL sla\_OBS (NUMBER, ID, NAME, WLONG, PHI, HEIGHT)} Interrogate list of observatory parameters \subp{CALL sla\_GEOC (P, H, R, Z)} Convert geodetic position to geocentric \subp{CALL sla\_POLMO (ELONGM, PHIM, XP, YP, ELONG, PHI, DAZ)} Polar motion \subp{CALL sla\_PVOBS (P, H, STL, PV)} Position and velocity of observatory \end{callset} \callhead{Apparent and Observed Place} \begin{callset} \subp{CALL sla\_MAP (RM, DM, PR, PD, PX, RV, EQ, DATE, RA, DA)} Mean place to geocentric apparent place \subp{CALL sla\_MAPPA (EQ, DATE, AMPRMS)} Precompute mean to apparent parameters \subp{CALL sla\_MAPQK (RM, DM, PR, PD, PX, RV, AMPRMS, RA, DA)} Mean to apparent using precomputed parameters \subp{CALL sla\_MAPQKZ (RM, DM, AMPRMS, RA, DA)} Mean to apparent using precomputed parameters, for zero proper motion, parallax and radial velocity \subp{CALL sla\_AMP (RA, DA, DATE, EQ, RM, DM)} Geocentric apparent place to mean place \subp{CALL sla\_AMPQK (RA, DA, AOPRMS, RM, DM)} Apparent to mean using precomputed parameters \subp{CALL sla\_AOP (\vtop {\hbox{RAP, DAP, UTC, DUT, ELONGM, PHIM, HM, XP, YP,} \hbox{TDK, PMB, RH, WL, TLR, AOB, ZOB, HOB, DOB, ROB)}}} Apparent place to observed place \subp{CALL sla\_AOPPA (\vtop {\hbox{UTC, DUT, ELONGM, PHIM, HM, XP, YP,} \hbox{TDK, PMB, RH, WL, TLR, AOPRMS)}}} Precompute apparent to observed parameters \subp{CALL sla\_AOPPAT (UTC, AOPRMS)} Update sidereal time in apparent to observed parameters \subp{CALL sla\_AOPQK (RAP, DAP, AOPRMS, AOB, ZOB, HOB, DOB, ROB)} Apparent to observed using precomputed parameters \subp{CALL sla\_OAP (\vtop {\hbox{TYPE, OB1, OB2, UTC, DUT, ELONGM, PHIM, HM, XP, YP,} \hbox{TDK, PMB, RH, WL, TLR, RAP, DAP)}}} Observed to apparent \subp{CALL sla\_OAPQK (TYPE, OB1, OB2, AOPRMS, RA, DA)} Observed to apparent using precomputed parameters \end{callset} \callhead{Azimuth and Elevation} \begin{callset} \subp{CALL sla\_ALTAZ (\vtop {\hbox{HA, DEC, PHI,} \hbox{AZ, AZD, AZDD, EL, ELD, ELDD, PA, PAD, PADD)}}} Positions, velocities {\it etc.}\ for an altazimuth mount \subq{CALL sla\_E2H (HA, DEC, PHI, AZ, EL)} {CALL sla\_DE2H (HA, DEC, PHI, AZ, EL)} \hadec\ to \azel \subq{CALL sla\_H2E (AZ, EL, PHI, HA, DEC)} {CALL sla\_DH2E (AZ, EL, PHI, HA, DEC)} \azel\ to \hadec \subp{CALL sla\_PDA2H (P, D, A, H1, J1, H2, J2)} Hour Angle corresponding to a given azimuth \subp{CALL sla\_PDQ2H (P, D, Q, H1, J1, H2, J2)} Hour Angle corresponding to a given parallactic angle \subp{D~=~sla\_PA (HA, DEC, PHI)} \hadec\ to parallactic angle \subp{D~=~sla\_ZD (HA, DEC, PHI)} \hadec\ to zenith distance \end{callset} \callhead{Refraction and Air Mass} \begin{callset} \subp{CALL sla\_REFRO (ZOBS, HM, TDK, PMB, RH, WL, PHI, TLR, EPS, REF)} Change in zenith distance due to refraction \subp{CALL sla\_REFCO (HM, TDK, PMB, RH, WL, PHI, TLR, EPS, REFA, REFB)} Constants for simple refraction model (accurate) \subp{CALL sla\_REFCOQ (TDK, PMB, RH, WL, REFA, REFB)} Constants for simple refraction model (fast) \subp{CALL sla\_ATMDSP ( TDK, PMB, RH, WL1, REFA1, REFB1, WL2, REFA2, REFB2 )} Adjust refraction constants for colour \subp{CALL sla\_REFZ (ZU, REFA, REFB, ZR)} Unrefracted to refracted ZD, simple model \subp{CALL sla\_REFV (VU, REFA, REFB, VR)} Unrefracted to refracted \azel\ vector, simple model \subp{D~=~sla\_AIRMAS (ZD)} Air mass \end{callset} \callhead{Ecliptic Coordinates} \begin{callset} \subp{CALL sla\_ECMAT (DATE, RMAT)} Equatorial to ecliptic rotation matrix \subp{CALL sla\_EQECL (DR, DD, DATE, DL, DB)} J2000.0 `FK5' to ecliptic coordinates \subp{CALL sla\_ECLEQ (DL, DB, DATE, DR, DD)} Ecliptic coordinates to J2000.0 `FK5' \end{callset} \callhead{Galactic Coordinates} \begin{callset} \subp{CALL sla\_EG50 (DR, DD, DL, DB)} B1950.0 `FK4' to galactic \subp{CALL sla\_GE50 (DL, DB, DR, DD)} Galactic to B1950.0 `FK4' \subp{CALL sla\_EQGAL (DR, DD, DL, DB)} J2000.0 `FK5' to galactic \subp{CALL sla\_GALEQ (DL, DB, DR, DD)} Galactic to J2000.0 `FK5' \end{callset} \callhead{Supergalactic Coordinates} \begin{callset} \subp{CALL sla\_GALSUP (DL, DB, DSL, DSB)} Galactic to supergalactic \subp{CALL sla\_SUPGAL (DSL, DSB, DL, DB)} Supergalactic to galactic \end{callset} \callhead{Ephemerides} \begin{callset} \subp{CALL sla\_DMOON (DATE, PV)} Approximate geocentric position and velocity of the Moon \subp{CALL sla\_EARTH (IY, ID, FD, PV)} Approximate heliocentric position and velocity of the Earth \subp{CALL sla\_EVP (DATE, DEQX, DVB, DPB, DVH, DPH)} Barycentric and heliocentric velocity and position of the Earth \subp{CALL sla\_MOON (IY, ID, FD, PV)} Approximate geocentric position and velocity of the Moon \subp{CALL sla\_PLANET (DATE, NP, PV, JSTAT)} Approximate heliocentric position and velocity of a planet \subp{CALL sla\_RDPLAN (DATE, NP, ELONG, PHI, RA, DEC, DIAM)} Approximate topocentric apparent place of a planet \subp{CALL sla\_PLANEL (\vtop {\hbox{DATE, JFORM, EPOCH, ORBINC, ANODE, PERIH,} \hbox{AORQ, E, AORL, DM, PV, JSTAT)}}} Heliocentric position and velocity of a planet, asteroid or comet, starting from orbital elements \subp{CALL sla\_PLANTE (\vtop {\hbox{DATE, ELONG, PHI, JFORM, EPOCH, ORBINC, ANODE,} \hbox{PERIH, AORQ, E, AORL, DM, RA, DEC, R, JSTAT)}}} Topocentric apparent place of a Solar-System object whose heliocentric orbital elements are known \subp{CALL sla\_PV2EL (\vtop {\hbox{PV, DATE, PMASS, JFORMR, JFORM, EPOCH, ORBINC,} \hbox{ANODE, PERIH, AORQ, E, AORL, DM, JSTAT)}}} Orbital elements of a planet from instantaneous position and velocity \subp{CALL sla\_PERTEL (\vtop {\hbox{JFORM, DATE0, DATE1,} \hbox{EPOCH0, ORBI0, ANODE0, PERIH0, AORQ0, E0, AM0,} \hbox{EPOCH1, ORBI1, ANODE1, PERIH1, AORQ1, E1, AM1,} \hbox{JSTAT)}}} Update elements by applying perturbations \subp{CALL sla\_EL2UE (\vtop {\hbox{DATE, JFORM, EPOCH, ORBINC, ANODE,} \hbox{PERIH, AORQ, E, AORL, DM,} \hbox{U, JSTAT)}}} Transform conventional elements to universal elements \subp{CALL sla\_UE2EL (\vtop {\hbox{U, JFORMR,} \hbox{JFORM, EPOCH, ORBINC, ANODE, PERIH,} \hbox{AORQ, E, AORL, DM, JSTAT)}}} Transform universal elements to conventional elements \subp{CALL sla\_PV2UE (PV, DATE, PMASS, U, JSTAT)} Package a position and velocity for use as universal elements \subp{CALL sla\_UE2PV (DATE, U, PV, JSTAT)} Extract the position and velocity from universal elements \subp{CALL sla\_PERTUE (DATE, U, JSTAT)} Update universal elements by applying perturbations \subp{R~=~sla\_RVEROT (PHI, RA, DA, ST)} Velocity component due to rotation of the Earth \subp{CALL sla\_ECOR (RM, DM, IY, ID, FD, RV, TL)} Components of velocity and light time due to Earth orbital motion \subp{R~=~sla\_RVLSRD (R2000, D2000)} Velocity component due to solar motion wrt dynamical LSR \subp{R~=~sla\_RVLSRK (R2000, D2000)} Velocity component due to solar motion wrt kinematical LSR \subp{R~=~sla\_RVGALC (R2000, D2000)} Velocity component due to rotation of the Galaxy \subp{R~=~sla\_RVLG (R2000, D2000)} Velocity component due to rotation and translation of the Galaxy, relative to the mean motion of the local group \end{callset} \callhead{Astrometry} \begin{callset} \subq{CALL sla\_S2TP (RA, DEC, RAZ, DECZ, XI, ETA, J)} {CALL sla\_DS2TP (RA, DEC, RAZ, DECZ, XI, ETA, J)} Transform spherical coordinates into tangent plane \subq{CALL sla\_V2TP (V, V0, XI, ETA, J)} {CALL sla\_DV2TP (V, V0, XI, ETA, J)} Transform \xyz\ into tangent plane coordinates \subq{CALL sla\_DTP2S (XI, ETA, RAZ, DECZ, RA, DEC)} {CALL sla\_TP2S (XI, ETA, RAZ, DECZ, RA, DEC)} Transform tangent plane coordinates into spherical coordinates \subq{CALL sla\_DTP2V (XI, ETA, V0, V)} {CALL sla\_TP2V (XI, ETA, V0, V)} Transform tangent plane coordinates into \xyz \subq{CALL sla\_DTPS2C (XI, ETA, RA, DEC, RAZ1, DECZ1, RAZ2, DECZ2, N)} {CALL sla\_TPS2C (XI, ETA, RA, DEC, RAZ1, DECZ1, RAZ2, DECZ2, N)} Get plate centre from star \radec\ and tangent plane coordinates \subq{CALL sla\_DTPV2C (XI, ETA, V, V01, V02, N)} {CALL sla\_TPV2C (XI, ETA, V, V01, V02, N)} Get plate centre from star \xyz\ and tangent plane coordinates \subp{CALL sla\_PCD (DISCO, X, Y)} Apply pincushion/barrel distortion \subp{CALL sla\_UNPCD (DISCO, X, Y)} Remove pincushion/barrel distortion \subp{CALL sla\_FITXY (ITYPE, NP, XYE, XYM, COEFFS, J)} Fit a linear model to relate two sets of \xy\ coordinates \subp{CALL sla\_PXY (NP, XYE, XYM, COEFFS, XYP, XRMS, YRMS, RRMS)} Compute predicted coordinates and residuals \subp{CALL sla\_INVF (FWDS, BKWDS, J)} Invert a linear model \subp{CALL sla\_XY2XY (X1, Y1, COEFFS, X2, Y2)} Transform one \xy \subp{CALL sla\_DCMPF (COEFFS, XZ, YZ, XS, YS, PERP, ORIENT)} Decompose a linear fit into scales {\it etc.} \end{callset} \callhead{Numerical Methods} \begin{callset} \subp{CALL sla\_COMBN (NSEL, NCAND, LIST, J)} Next combination (subset from a specified number of items) \subp{CALL sla\_PERMUT (N, ISTATE, IORDER, J)} Next permutation of a specified number of items \subq{CALL sla\_SMAT (N, A, Y, D, JF, IW)} {CALL sla\_DMAT (N, A, Y, D, JF, IW)} Matrix inversion and solution of simultaneous equations \subp{CALL sla\_SVD (M, N, MP, NP, A, W, V, WORK, JSTAT)} Singular value decomposition of a matrix \subp{CALL sla\_SVDSOL (M, N, MP, NP, B, U, W, V, WORK, X)} Solution from given vector plus SVD \subp{CALL sla\_SVDCOV (N, NP, NC, W, V, WORK, CVM)} Covariance matrix from SVD \subp{R~=~sla\_RANDOM (SEED)} Generate pseudo-random real number in the range {$0 \leq x < 1$} \subp{R~=~sla\_GRESID (S)} Generate pseudo-random normal deviate ($\equiv$ `Gaussian residual') \end{callset} \callhead{Real-time} \begin{callset} \subp{CALL sla\_WAIT (DELAY)} Interval wait \end{callset} \end{document}