Index: /trunk/doc/pslib/psLibSDRS.tex
===================================================================
--- /trunk/doc/pslib/psLibSDRS.tex	(revision 1766)
+++ /trunk/doc/pslib/psLibSDRS.tex	(revision 1767)
@@ -1,3 +1,3 @@
-%%% $Id: psLibSDRS.tex,v 1.118 2004-09-09 23:48:55 jhoblitt Exp $
+%%% $Id: psLibSDRS.tex,v 1.119 2004-09-10 00:17:59 price Exp $
 \documentclass[panstarrs,spec]{panstarrs}
 
@@ -176,4 +176,6 @@
 \item Set the error codes for PSLib.
 \item Seed the random number generator.
+\item Read the \code{psTimeTable} configuration file and set up the
+  appropriate \code{psTimeTable}s and predictions.
 \end{itemize}
 
@@ -3231,4 +3233,153 @@
 Time math is only done on the \code{psTime} TAI type.
 
+\subsubsection{Time Tables}
+
+The offset of UTC from UT1, $\Delta$UT = UT1-UTC, as well as the polar
+motion, $x_p$ and $y_p$, may be determined from table lookups.  Tables
+are available covering different time periods and with different time
+resolution, and so it is important to be able to utilise multiple
+tables.  Some tables may be found at:
+
+\begin{itemize}
+\item \code{ftp://maia.usno.navy.mil/ser7/ser7.dat}
+\item \code{ftp://maia.usno.navy.mil/ser7/finals.all} with explanatory
+  guide at \code{ftp://maia.usno.navy.mil/ser7/readme.finals} . See also
+  the web page \code{http://maia.usno.navy.mil/}.
+\item \code{http://hpiers.obspm.fr/eoppc/eop/eopc01/eopc01.1900-2004}
+  (contains estimates prior to 1972).
+\end{itemize}
+
+The tables shall reside on local disk in known locations (i.e., there
+is no need that they are downloaded from the internet and parsed by
+PSLib).  The format of these files shall be simple, for speed in
+reading: Each line shall contain the MJD, $x_p$ (in arcseconds), $y_p$
+(in arcseconds) and $\Delta$UT (in seconds) separated by whitespace;
+blank lines and lines commencing with the comment character (the hash
+symbol, \code{#}) as the first character shall be ignored.  For
+example:
+
+\begin{verbatim}
+# Bulletin A, 9 September 2004.
+# ftp://maia.usno.navy.mil/ser7/ser7.dat
+# MJD       XP(")   YP(")   UT1-UTC(s)
+53258       0.1715  0.4774  -0.45092              
+53259       0.1734  0.4757  -0.45039              
+53260       0.1753  0.4741  -0.45012              
+53261       0.1770  0.4724  -0.45015              
+53262       0.1787  0.4708  -0.45045              
+\end{verbatim}
+
+The location of these files, their priority order, and the ``from''
+and ``to'' dates of applicability will be specified through metadata
+(\S\ref{sec:timeMetadata}).
+
+When a value is required, the tables shall shall be checked in
+priority order to see if the date is within the range of applicability
+for the table.  If a table is found that is applicable, then the
+appropriate value shall be derived from linear interpolation between
+the nearest entries in the table.  If no table is found that is
+applicable, and the required date is later than those covered in the
+tables, a warning shall be generated, and a pre-determined formula
+shall be applied (\S\ref{sec:timeMetadata}).  For dates prior to those
+covered in the tables, the function shall generate a warning and use
+pre-determined values (\S\ref{sec:timeMetadata}).
+
+We define a structure, \code{psTimeTable} to hold a single time table:
+\begin{verbatim}
+typedef struct {
+    const char *filename;		// Filename of time table
+    const psF64 validFrom, validTo;	// MJDs of validity of time table
+    bool loaded;			// Has the table been loaded?
+    psVector *mjd;			// MJD data, type is psF64
+    psVector *dut;			// delta UT = UT1 - UTC data
+    psVector *xp, *yp;			// Polar motion data
+} psTimeTable;
+\end{verbatim}
+
+The tables shall be read in only when required by the user (hence the
+\code{loaded} member); once loaded, the table shall remain in memory
+until the termination of the program.  The corresponding constructor
+shall be:
+\begin{verbatim}
+psTimeTable *psTimeTableAlloc(const char *filename, psF64 validFrom, psF64 validTo);
+\end{verbatim}
+which simply constructs a \code{psTimeTable} with the appropriate
+\code{filename}, \code{validFrom} and \code{validTo}.  Upon
+construction, the \code{loaded} member shall be set to \code{false},
+and the vectors containing the data shall be set to \code{NULL}.
+
+The function \code{psTimeTableLoad} shall load a specified time
+\code{table}, returning \code{true} for success, and \code{false} if
+the table failed to load.  If the \code{table} has already been
+loaded, then it shall be re-loaded.
+\begin{verbatim}
+bool psTimeTableLoad(psTimeTable *table);
+\end{verbatim}
+
+Given a time \code{table} and a Modified Julian Date, \code{mjd}, at
+which to interpolate values, \code{psTimeTableInterpolate} shall
+calculate the appropriate UT1-UTC (\code{dut}; if non-\code{NULL}),
+and polar motion (\code{xp,yp}; if non-\code{NULL}) by interpolation
+on the table.  If the \code{mjd} is outside the range of the table or
+the interpolation was for some other reason unsuccessful, then the
+function shall return \code{false}; otherwise the function shall set
+those parameters which are non-\code{NULL} (\code{dut,xp,yp}) and
+return \code{true}.  If the requested \code{mjd} lies in the range of
+the \code{table}, but the \code{table} has not been \code{loaded},
+then the function shall call \code{psTimeTableLoad}.
+\begin{verbatim}
+bool psTimeTableInterpolate(const psTimeTable *table, double *xp,
+                            double *yp, double *dut, psF64 mjd);
+\end{verbatim}
+
+\paragraph{Time Metadata}
+\label{sec:timeMetadata}
+
+The following metadata keys will be used in time calculations:
+
+\begin{tabular}{l|l} \hline
+Metadata key & Purpose \\ \hline
+psLib.time.tables.files & Time table file names (space-delimited)                          \\
+psLib.time.tables.from  & Time tables are valid from these MJDs (vector)                   \\
+psLib.time.tables.to    & Time tables are valid to these MJDs (vector)                     \\
+psLib.time.before.xp    & Value of XP for before the earliest MJD                          \\
+psLib.time.before.yp    & Value of YP for before the earliest MJD                          \\
+psLib.time.before.dut   & Value of UT1-UTC for before the earliest MJD                     \\
+pslib.time.predict.xp   & A vector containing the $x_p$ prediction formula coefficients    \\
+pslib.time.predict.yp   & A vector containing the $y_p$ prediction formula coefficients    \\
+pslib.time.predict.mjd  & A value containing the MJD offset for temporary variables        \\
+pslib.time.predict.dut  & A vector containing the UT1-UTC prediction formula coefficients  \\
+\hline
+\end{tabular}
+
+These metadata keys shall reside in a configuration file
+(\S\ref{sec:configspec}), \code{psTime.config}, which shall be loaded
+into a \code{psMetadata} structure private to \code{psTime}, as part
+of \code{psLibInit}.  An example of \code{psTime.config} follows:
+
+\begin{verbatim}
+# This configuration file specifies values required for time calculations by psLib.
+psLib.time.tables.n     U8      2                                               # Number of time tables
+psLib.time.tables.files STR     bulletinA_09Sep2004.dat eopc01_1900_2004.40.dat # These are the file names
+@psLib.time.tables.from F64     53258.0, 15020.0                                # Valid from these MJDs
+@psLib.time.tables.to   F64     53622.0, 53258.0                                # Valid to these MJDs
+psLib.time.before.xp    F64     0.0                     # Value of XP for before the earliest MJD
+psLib.time.before.yp    F64     0.0                     # Value of YP for before the earliest MJD
+psLib.time.before.dut   F64     0.0                     # Value of UT1-UTC for before the earliest MJD
+							
+# Now follows formulae for predicting ahead of the most recent available table entry.
+# xp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# yp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# A = 2*pi*(MJD - pslib.time.predict.mjd)/365.25
+# C = 2*pi*(MJD - pslib.time.predict.mjd)/435.0
+# dut = ut1-utc = [0] + [1]*(MJD - [2]) - (UT2-UT1)
+# ut2-ut1 = 0.022 sin(2*pi*T) - 0.012 cos(2*pi*T) - 0.006 sin(4*pi*T) + 0.007 cos(4*pi*T)
+# T = 2000.0 + (MJD - 51544.03)/365.2422
+@psLib.time.predict.xp  F64     0.0569, 0.0555, -0.0200, 0.0513, 0.1483
+@psLib.time.predict.yp  F64     0.3498, -0.0176, -0.0498, 0.1483, -0.0513
+psLib.time.predict.mjd  F64     53257.0
+@psLib.time.predict.dut F64     -0.4944, -0.00023, 53262.0
+\end{verbatim}
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
