IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 309


Ignore:
Timestamp:
Mar 26, 2004, 4:11:28 PM (22 years ago)
Author:
eugene
Message:

major reorganization of sections/subsections
work TBD on transition paragraphs and explanations

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/pslib/psLibSDRS.tex

    r300 r309  
    1 %%% $Id: psLibSDRS.tex,v 1.11 2004-03-24 03:42:51 price Exp $
     1%%% $Id: psLibSDRS.tex,v 1.12 2004-03-27 02:11:28 eugene Exp $
    22\documentclass[panstarrs]{panstarrs}
    33%\documentclass[panstarrs]{panstarrs}
     
    708708%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    709709
    710 \section{Data Containers}
     710\subsection{Miscellaneous Utilities}
     711
     712\begin{verbatim}
     713#define PS_STRING(S) #S                 // converts argument S to string
     714   
     715/// Prints an error message and aborts
     716void psAbort(const char *name,          ///< Category of code that caused the abort
     717             const char *fmt,           ///< Format
     718             ...                        ///< Extra arguments to use format
     719             );
     720
     721/// Prints an error message and doesn't abort
     722void psError(const char *name,          ///< Category of code that caused the abort
     723             const char *fmt,           ///< Format
     724             ...                        ///< Extra arguments to use format
     725    );
     726
     727/// Allocates and returns a copy of a string
     728char *psStringCopy(const char *str      ///< string to copy
     729    );
     730
     731/// Allocates nChar and returns a copy of the string or segment
     732char *psStringNCopy(const char *str,    ///< string to copy
     733                    int nChar           //!< Number of characters (including \0 )
     734    );
     735\end{verbatim}
     736
     737\code{psAbort} shall call \code{psMsgLog} with a level of \code{PS_LOG_ABORT},
     738and then call \code{abort}.
     739\code{psError} shall call \code{psMsgLog} with a level of \code{PS_LOG_ERROR},
     740and then return.
     741In cases of doubt, a good choice for
     742\code{name} is \code{__func__}.
     743
     744\code{psStringCopy} shall allocate and return a copy of the input string.
     745
     746%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     747%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     748%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     749
     750\section{Basic Data Collections}
    711751
    712752We require general data containers, so that associated values (e.g.\
     
    719759\end{itemize}
    720760
    721 \subsection{The Pan-STARRS \texttt{psDlist} doubly-linked list type}
     761\subsection{Simple Array types}
     762
     763\subsubsection{Arrays of Simple Types}
     764
     765Any \PS{} datatype \code{psType} may be associated with an array type
     766\code{psTypeArray}:
     767\begin{verbatim}
     768typedef struct {
     769  int size;
     770  int n;
     771  psType *arr;
     772} psTypeArray;
     773\end{verbatim}
     774with associated constructors and a destructor:
     775\begin{verbatim}
     776psTypeArray *psTypeAlloc(int n, int size);
     777psTypeArray *psTypeRealloc(psTypeArray *arr, int n);
     778void psTypeFree(psTypeArray *arr); 
     779\end{verbatim}
     780
     781The argument \code{n} is the dimension of the array; \code{size}
     782is the number of elements allocated ($s \ge n$).
     783
     784This type and functions may be declared and defined using two macros,
     785\code{PS_DECLARE_ARRAY_TYPE(psType)} and
     786\code{PS_CREATE_ARRAY_TYPE(psType)}.  The former defines the
     787\code{typedef} and declares the prototypes (and is thus suitable for
     788use in a header file); the latter generates the code for the three
     789functions \code{psType(Alloc|Realloc|Free)} (and should thus appear in
     790exactly one source file for a given type).
     791
     792The \code{psType} should be a single word (e.g. \code{psXY}); in particular,
     793there is no requirement to support a pointer type (\eg{} \code{psXY *});
     794see next section.
     795
     796\subsubsection{Arrays of Pointer Types}
     797
     798The data type created with \code{PS_CREATE_ARRAY_TYPE} (\code{psType})
     799contains an array of \code{psType}s not
     800pointers to \code{psType}s; this means that the individual elements are
     801not allocated using \code{psTypeAlloc}, are not correctly initialized,
     802and shouldn't be individually deleted with \code{psTypeFree};
     803
     804If you wish to use arrays of pointers, use the macros
     805\code{PS_DECLARE_ARRAY_PTR_TYPE(psType)} and
     806\code{PS_CREATE_ARRAY_PTR_TYPE(psType)}. These
     807create types \code{typedef psType *psTypePtr} and \code{psTypePtrArray}:
     808\begin{verbatim}
     809typedef struct {
     810  int size;
     811  int n;
     812  psTypePtr *arr;
     813} psTypePtrArray;
     814\end{verbatim}
     815with associated constructors and a destructor:
     816\begin{verbatim}
     817psTypePtrArray *psTypePtrAlloc(int n, int size);
     818psTypePtrArray *psTypePtrRealloc(psTypePtrArray *arr, int n);
     819void psTypePtrArrayFree(psTypePtrArray *arr); 
     820\end{verbatim}
     821
     822These constructors create arrays of \code{psType *} and call
     823\code{psTypeAlloc} and \code{psTypeFree} to allocate and free the
     824elements. As for the simple arrays, The former defines the typedef and
     825declares the prototypes (and is thus suitable for use in a header
     826file) and the latter generates the code for the three functions
     827\code{psType(Alloc|Realloc|Free)} (and should thus appear in exactly one
     828source file for a given type).
     829
     830The objects pointed to by these types have had their \code{refCounter}s
     831incremented (see \ref{secMemRefcounter}); to remove an element from the array you
     832need to say something like:
     833\begin{verbatim}
     834  psTypePtrArray *pt = psTypePtrArrayAlloc(10, 10);
     835  psType *xy = psMemDecrRefCounter(pt->arr[0]);
     836  pt->arr[0] = NULL;
     837\end{verbatim}
     838
     839\subsubsection{Arrays of \texttt{void *}}
     840\hlabel{secArrayVoidPtr}
     841
     842Arrays of \code{void *} are different, as they need an explicitly-specified
     843destructor.
     844
     845We require a type \code{psVoidPtrArray} that behaves in all respects
     846as if it had been created with:
     847\begin{verbatim}
     848typedef void *psVoidPtr;
     849PS_DECLARE_ARRAY_TYPE(psVoidPtr);
     850PS_CREATE_ARRAY_TYPE(psVoidPtr);
     851\end{verbatim}
     852except that its destructor is specified as:
     853\begin{verbatim}
     854void psVoidPtrArrayFree(psVoidPtrArray *arr,      // array to destroy
     855                       void (*elemFree)(void *)); // destructor for array data
     856\end{verbatim}
     857
     858The routine \code{psVoidPtrArrayFree} assumes that all pointers
     859had their reference counters incremented
     860when they were inserted onto the array.\footnote{%
     861  \eg{} \code{va->arr[i] = psMemIncrRefCounter(ptr);}}
     862
     863If \code{psVoidPtrArrayFree}'s argument \code{elemFree} is NULL, the
     864list should be deleted, but not the elements on it (although their
     865\code{refcounter}'s should be decremented).
     866
     867\subsubsection{Examples of Array Types}
     868
     869The following is a complete C program that illustrates the use of
     870\code{array}s.
     871\begin{verbatim}
     872#include "psLib.h"
     873
     874typedef struct {
     875    int x, y;
     876} psXY;
     877
     878psXY *psXYAlloc(void)
     879{
     880    return psAlloc(sizeof(psXY));
     881}
     882
     883void psXYFree(psXY *xy)
     884{
     885    psFree(xy);
     886}
     887
     888PS_DECLARE_ARRAY_TYPE(psXY);
     889PS_CREATE_ARRAY_TYPE(psXY);
     890
     891PS_DECLARE_ARRAY_PTR_TYPE(psXY);
     892PS_CREATE_ARRAY_PTR_TYPE(psXY);
     893
     894int main(void)
     895{
     896    psXYArray *t = psXYArrayAlloc(10, 15);
     897    psXYPtrArray *pt = psXYPtrArrayAlloc(10, 10);
     898
     899    for (int i = 0; i < t->n; i++) {
     900        t->arr[i].x = i;
     901        pt->arr[i]->y = 10*i;
     902    }
     903
     904    t = psXYArrayRealloc(t, 5);
     905    t = psXYArrayRealloc(t, 8);
     906
     907    for (int i = 0; i < t->n; i++) {
     908        printf("%d %d  ", t->arr[i].x, pt->arr[i]->y);
     909    }
     910    printf("\n");
     911   
     912    psXYArrayFree(t);
     913
     914    psXY *xy = psMemDecrRefCounter(pt->arr[0]);
     915    pt->arr[0] = NULL;
     916    psXYFree(xy);   
     917   
     918    psXYPtrArrayFree(pt);
     919
     920    psMemCheckLeaks(0, NULL, stderr);
     921
     922    return 0;
     923}
     924\end{verbatim}
     925
     926\subsection{Doubly-linked lists}
    722927\hlabel{psDlist}
    723928
     
    8431048\code{psDlist}).
    8441049
    845 \subsection{The \PS{} Array types}
    846 
    847 \subsubsection{Arrays of Simple Types}
    848 
    849 Any \PS{} datatype \code{psType} may be associated with an array type
    850 \code{psTypeArray}:
    851 \begin{verbatim}
    852 typedef struct {
    853   int size;
    854   int n;
    855   psType *arr;
    856 } psTypeArray;
    857 \end{verbatim}
    858 with associated constructors and a destructor:
    859 \begin{verbatim}
    860 psTypeArray *psTypeAlloc(int n, int size);
    861 psTypeArray *psTypeRealloc(psTypeArray *arr, int n);
    862 void psTypeFree(psTypeArray *arr); 
    863 \end{verbatim}
    864 
    865 The argument \code{n} is the dimension of the array; \code{size}
    866 is the number of elements allocated ($s \ge n$).
    867 
    868 This type and functions may be declared and defined using two macros,
    869 \code{PS_DECLARE_ARRAY_TYPE(psType)} and
    870 \code{PS_CREATE_ARRAY_TYPE(psType)}.  The former defines the
    871 \code{typedef} and declares the prototypes (and is thus suitable for
    872 use in a header file); the latter generates the code for the three
    873 functions \code{psType(Alloc|Realloc|Free)} (and should thus appear in
    874 exactly one source file for a given type).
    875 
    876 The \code{psType} should be a single word (e.g. \code{psXY}); in particular,
    877 there is no requirement to support a pointer type (\eg{} \code{psXY *});
    878 see next section.
    879 
    880 \subsubsection{Arrays of Pointer Types}
    881 
    882 The data type created with \code{PS_CREATE_ARRAY_TYPE} (\code{psType})
    883 contains an array of \code{psType}s not
    884 pointers to \code{psType}s; this means that the individual elements are
    885 not allocated using \code{psTypeAlloc}, are not correctly initialized,
    886 and shouldn't be individually deleted with \code{psTypeFree};
    887 
    888 If you wish to use arrays of pointers, use the macros
    889 \code{PS_DECLARE_ARRAY_PTR_TYPE(psType)} and
    890 \code{PS_CREATE_ARRAY_PTR_TYPE(psType)}. These
    891 create types \code{typedef psType *psTypePtr} and \code{psTypePtrArray}:
    892 \begin{verbatim}
    893 typedef struct {
    894   int size;
    895   int n;
    896   psTypePtr *arr;
    897 } psTypePtrArray;
    898 \end{verbatim}
    899 with associated constructors and a destructor:
    900 \begin{verbatim}
    901 psTypePtrArray *psTypePtrAlloc(int n, int size);
    902 psTypePtrArray *psTypePtrRealloc(psTypePtrArray *arr, int n);
    903 void psTypePtrArrayFree(psTypePtrArray *arr); 
    904 \end{verbatim}
    905 
    906 These constructors create arrays of \code{psType *} and call
    907 \code{psTypeAlloc} and \code{psTypeFree} to allocate and free the
    908 elements. As for the simple arrays, The former defines the typedef and
    909 declares the prototypes (and is thus suitable for use in a header
    910 file) and the latter generates the code for the three functions
    911 \code{psType(Alloc|Realloc|Free)} (and should thus appear in exactly one
    912 source file for a given type).
    913 
    914 The objects pointed to by these types have had their \code{refCounter}s
    915 incremented (see \ref{secMemRefcounter}); to remove an element from the array you
    916 need to say something like:
    917 \begin{verbatim}
    918   psTypePtrArray *pt = psTypePtrArrayAlloc(10, 10);
    919   psType *xy = psMemDecrRefCounter(pt->arr[0]);
    920   pt->arr[0] = NULL;
    921 \end{verbatim}
    922 
    923 \subsubsection{Arrays of \texttt{void *}}
    924 \hlabel{secArrayVoidPtr}
    925 
    926 Arrays of \code{void *} are different, as they need an explicitly-specified
    927 destructor.
    928 
    929 We require a type \code{psVoidPtrArray} that behaves in all respects
    930 as if it had been created with:
    931 \begin{verbatim}
    932 typedef void *psVoidPtr;
    933 PS_DECLARE_ARRAY_TYPE(psVoidPtr);
    934 PS_CREATE_ARRAY_TYPE(psVoidPtr);
    935 \end{verbatim}
    936 except that its destructor is specified as:
    937 \begin{verbatim}
    938 void psVoidPtrArrayFree(psVoidPtrArray *arr,      // array to destroy
    939                        void (*elemFree)(void *)); // destructor for array data
    940 \end{verbatim}
    941 
    942 The routine \code{psVoidPtrArrayFree} assumes that all pointers
    943 had their reference counters incremented
    944 when they were inserted onto the array.\footnote{%
    945   \eg{} \code{va->arr[i] = psMemIncrRefCounter(ptr);}}
    946 
    947 If \code{psVoidPtrArrayFree}'s argument \code{elemFree} is NULL, the
    948 list should be deleted, but not the elements on it (although their
    949 \code{refcounter}'s should be decremented).
    950 
    951 \subsubsection{Examples of Array Types}
    952 
    953 The following is a complete C program that illustrates the use of
    954 \code{array}s.
    955 \begin{verbatim}
    956 #include "psLib.h"
    957 
    958 typedef struct {
    959     int x, y;
    960 } psXY;
    961 
    962 psXY *psXYAlloc(void)
    963 {
    964     return psAlloc(sizeof(psXY));
    965 }
    966 
    967 void psXYFree(psXY *xy)
    968 {
    969     psFree(xy);
    970 }
    971 
    972 PS_DECLARE_ARRAY_TYPE(psXY);
    973 PS_CREATE_ARRAY_TYPE(psXY);
    974 
    975 PS_DECLARE_ARRAY_PTR_TYPE(psXY);
    976 PS_CREATE_ARRAY_PTR_TYPE(psXY);
    977 
    978 int main(void)
    979 {
    980     psXYArray *t = psXYArrayAlloc(10, 15);
    981     psXYPtrArray *pt = psXYPtrArrayAlloc(10, 10);
    982 
    983     for (int i = 0; i < t->n; i++) {
    984         t->arr[i].x = i;
    985         pt->arr[i]->y = 10*i;
    986     }
    987 
    988     t = psXYArrayRealloc(t, 5);
    989     t = psXYArrayRealloc(t, 8);
    990 
    991     for (int i = 0; i < t->n; i++) {
    992         printf("%d %d  ", t->arr[i].x, pt->arr[i]->y);
    993     }
    994     printf("\n");
    995    
    996     psXYArrayFree(t);
    997 
    998     psXY *xy = psMemDecrRefCounter(pt->arr[0]);
    999     pt->arr[0] = NULL;
    1000     psXYFree(xy);   
    1001    
    1002     psXYPtrArrayFree(pt);
    1003 
    1004     psMemCheckLeaks(0, NULL, stderr);
    1005 
    1006     return 0;
    1007 }
    1008 \end{verbatim}
    1009 
    10101050\subsection{Hash Tables}
    10111051\hlabel{psHash}
     
    10691109key from the table, and returns the \code{data}; if the key's invalid it returns NULL.
    10701110
    1071 \subsection{Miscellaneous Utilities}
    1072 
    1073 \begin{verbatim}
    1074 #define PS_STRING(S) #S                 // converts argument S to string
    1075    
    1076 /// Prints an error message and aborts
    1077 void psAbort(const char *name,          ///< Category of code that caused the abort
    1078              const char *fmt,           ///< Format
    1079              ...                        ///< Extra arguments to use format
    1080              );
    1081 
    1082 /// Prints an error message and doesn't abort
    1083 void psError(const char *name,          ///< Category of code that caused the abort
    1084              const char *fmt,           ///< Format
    1085              ...                        ///< Extra arguments to use format
    1086     );
    1087 
    1088 /// Allocates and returns a copy of a string
    1089 char *psStringCopy(const char *str      ///< string to copy
    1090     );
    1091 
    1092 /// Allocates nChar and returns a copy of the string or segment
    1093 char *psStringNCopy(const char *str,    ///< string to copy
    1094                     int nChar           //!< Number of characters (including \0 )
    1095     );
    1096 \end{verbatim}
    1097 
    1098 \code{psAbort} shall call \code{psMsgLog} with a level of \code{PS_LOG_ABORT},
    1099 and then call \code{abort}.
    1100 \code{psError} shall call \code{psMsgLog} with a level of \code{PS_LOG_ERROR},
    1101 and then return.
    1102 In cases of doubt, a good choice for
    1103 \code{name} is \code{__func__}.
    1104 
    1105 \code{psStringCopy} shall allocate and return a copy of the input string.
    1106 
    1107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1110 
    11111111\section{Data manipulation}
    11121112
    1113 We require general data manipulation functions, which will act upon
    1114 data (in particular, arrays/vectors).  We require the following capabilities:
     1113There are a number of data concepts which can be naturally represented
     1114in C as structures.  We require a variety of basic data manipulation
     1115functions which will act upon data (in particular, arrays/vectors).
     1116We require the following capabilities:
    11151117\begin{itemize}
    11161118\item Bit masks;
     
    11861188    );
    11871189\end{verbatim}
    1188 
    1189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1190 
    1191 \subsection{Vector and Image Arithmetic}
    1192 
    1193 We will need to be able to perform various operations on vectors and
    1194 images, e.g.\ dividing one image by another, subtracting a vector
    1195 from an image, etc.  Both binary operations and unary operations are
    1196 required.
    1197 
    1198 \begin{verbatim}
    1199 /** Perform a binary operation on two data items (psImage, psVector, psScalar).
    1200 */
    1201 psType *
    1202 psBinaryOp (void *out,                  ///< destination (may be NULL)
    1203             void *in1,                  ///< first input
    1204             char *operator,             ///< operator
    1205             void *in2                   ///< second input
    1206     );
    1207 \end{verbatim}
    1208 
    1209 \begin{verbatim}
    1210 /** Perform a binary operation on two data items (psImage, psVector, psScalar).
    1211 */
    1212 psType *
    1213 psUnaryOp (void *out,                   ///< destination (may be NULL)
    1214            void *in,                    ///< input
    1215            char *operator,              ///< operator
    1216     );
    1217 \end{verbatim}
    1218 
    1219 Note that these functions should return the appropriate type (i.e.,
    1220 the \code{psType} return type refers to \code{psVector} and
    1221 \code{psImage} and \code{psScalar}).  It is expected that the
    1222 implementation of these functions will employ pre-processor macros to
    1223 perform the onerous task of creating the loops.
    1224 
    1225 It is desirable to use the same functions for both vectors and
    1226 images, so inputs are \code{void*}; this necessitates that vectors
    1227 and images each have a type element at a pre-determined and constant
    1228 location in the \code{struct}.  It is further desirable to allow
    1229 scalar values to be used within these functions, which requires the
    1230 following additions:
    1231 
    1232 \begin{verbatim}
    1233 /** create a psType-ed structure from a constant value. */
    1234 p_ps_Scalar *
    1235 psScalar (double value);
    1236 \end{verbatim}
    1237 
    1238 \begin{verbatim}
    1239 /** create a psType-ed structure from a specified type  */
    1240 p_ps_Scalar *
    1241 psScalarType (char *mode,               ///< type description
    1242               ...                       ///< value (or values) of specified types
    1243 );
    1244 \end{verbatim}
    1245 
    1246 \begin{verbatim}
    1247 /** private structure used to pass constant values into the math operators. */
    1248 typedef struct {
    1249     psType type;                        ///< data type information
    1250     union {                           
    1251         int i;                          ///< integer value entry
    1252         float f;                        ///< float value entry
    1253         double d;                       ///< double value entry
    1254         complex float c;                ///< complex value entry
    1255     } val;
    1256 } p_psScalar;
    1257 \end{verbatim}
    1258 
    1259 This allows one to write the following to take the sine of the square
    1260 of all pixels in an image:
    1261 \begin{verbatim}
    1262 psImage A,B;
    1263 
    1264 B = psBinaryOp (NULL, A, "^", psScalar(2));
    1265 (void) psUnaryOp(B, B, "sin");
    1266 \end{verbatim}
    1267 
    1268 Note that the \code{psUnaryOp} is performed on \code{B} in-place.
    12691190
    12701191%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    15461467%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    15471468
    1548 \subsection{General functions}
     1469\subsection{Analytical functions}
    15491470
    15501471We require two types of general functions which will be used in fitting:
     
    16371558%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    16381559
    1639 \subsection{Minimisation and fitting routines}
     1560\subsection{Minimization and fitting routines}
    16401561
    16411562We require a general minimisation routine, a routine that will
     
    16781599%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    16791600
    1680 \section{Astronomy-Specific Functions}
    1681 
    1682 Some basic, relatively simple astronomy-specific functions are
    1683 required which will serve as the foundation for building the Phase $N$
    1684 modules.  These functions are not expected to cover every forseeable
    1685 function, but will serve as the building blocks of more complicated
    1686 processing functions.
    1687 
    1688 We require functions covering each of the following areas:
    1689 \begin{itemize}
    1690 \item Astrometry;
    1691 \item Dates and times;
    1692 \item Image handling;
    1693 \item Metadata;
    1694 \item Detector and sky positions;
    1695 \item Astronomical objects; and
    1696 \item Photometry.
    1697 \end{itemize}
    1698 These are each dealt with below.
    1699 
    1700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1701 \subsection{Image handling}
     1601\subsection{Simple Images}
    17021602
    17031603The most important data product produced by the telescope is an image.
     
    21182018%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    21192019
    2120 \subsection{Astrometry}
    2121 
    2122 Astrometry is a basic functionality required for the IPP that will be
    2123 used repeatedly, both for low-precision (roughly where is my favourite
    2124 object?) and high-precision (what is the proper motion of this star?).
    2125 As such, it must be flexible, yet robust.  Accordingly, we will wrap
    2126 the StarLink Astronomy Libraries (SLALib), which has already been
    2127 developed.
    2128 
    2129 \subsubsection{Terminology}
    2130 
    2131 Some brief review of terminology would be useful so that previous
    2132 definitions do not influence the understanding of this document.
    2133 
    2134 A ``readout'' is a read of the detector.
    2135 
    2136 A ``cell'' is defined as the smallest element of the detector readout;
    2137 usually associated with an amplifier.  Correspondingly, each cell has
    2138 its own overscan region.  There may be multiple readouts in a cell if
    2139 the cell was used to provide fast guiding.
    2140 
    2141 A ``chip'' is defined as a contiguous piece of silicon, and consists
    2142 of a group of cells.
    2143 
    2144 A ``focal plane'' is defined as a mosaic of chips, and consists of a
    2145 group of chips.
    2146 
    2147 For example, take a mosaic camera consisting of eight $2k\times 4k$
    2148 CCDs, each of which is read out through two amplifiers.  Then there
    2149 would be sixteen cells in total, each of which is presumably $2k\times
    2150 2k$.  There would be eight chips, each consisting of two cells, and
    2151 the focal plane consists of these eight chips.
    2152 
    2153 As another example, consider an observation by PS1.  The focal plane
    2154 would consist of 60 chips, each of which consist of 64 cells (or less;
    2155 a few cells may be dead).  Some cells (those containing guide stars
    2156 for the orthogonal transfer) will contain multiple readouts.
    2157 
    2158 \subsubsection{Coordinate frames}
    2159 \label{sec:coordinateFrames}
    2160 
    2161 There are five coordinate frames that we need to worry about for the
    2162 purposes of astrometry:
     2020\subsection{Vector and Image Arithmetic}
     2021
     2022We will need to be able to perform various operations on vectors and
     2023images, e.g.\ dividing one image by another, subtracting a vector
     2024from an image, etc.  Both binary operations and unary operations are
     2025required.
     2026
     2027\begin{verbatim}
     2028/** Perform a binary operation on two data items (psImage, psVector, psScalar).
     2029*/
     2030psType *
     2031psBinaryOp (void *out,                  ///< destination (may be NULL)
     2032            void *in1,                  ///< first input
     2033            char *operator,             ///< operator
     2034            void *in2                   ///< second input
     2035    );
     2036\end{verbatim}
     2037
     2038\begin{verbatim}
     2039/** Perform a binary operation on two data items (psImage, psVector, psScalar).
     2040*/
     2041psType *
     2042psUnaryOp (void *out,                   ///< destination (may be NULL)
     2043           void *in,                    ///< input
     2044           char *operator,              ///< operator
     2045    );
     2046\end{verbatim}
     2047
     2048Note that these functions should return the appropriate type (i.e.,
     2049the \code{psType} return type refers to \code{psVector} and
     2050\code{psImage} and \code{psScalar}).  It is expected that the
     2051implementation of these functions will employ pre-processor macros to
     2052perform the onerous task of creating the loops.
     2053
     2054It is desirable to use the same functions for both vectors and
     2055images, so inputs are \code{void*}; this necessitates that vectors
     2056and images each have a type element at a pre-determined and constant
     2057location in the \code{struct}.  It is further desirable to allow
     2058scalar values to be used within these functions, which requires the
     2059following additions:
     2060
     2061\begin{verbatim}
     2062/** create a psType-ed structure from a constant value. */
     2063p_ps_Scalar *
     2064psScalar (double value);
     2065\end{verbatim}
     2066
     2067\begin{verbatim}
     2068/** create a psType-ed structure from a specified type  */
     2069p_ps_Scalar *
     2070psScalarType (char *mode,               ///< type description
     2071              ...                       ///< value (or values) of specified types
     2072);
     2073\end{verbatim}
     2074
     2075\begin{verbatim}
     2076/** private structure used to pass constant values into the math operators. */
     2077typedef struct {
     2078    psType type;                        ///< data type information
     2079    union {                           
     2080        int i;                          ///< integer value entry
     2081        float f;                        ///< float value entry
     2082        double d;                       ///< double value entry
     2083        complex float c;                ///< complex value entry
     2084    } val;
     2085} p_psScalar;
     2086\end{verbatim}
     2087
     2088This allows one to write the following to take the sine of the square
     2089of all pixels in an image:
     2090\begin{verbatim}
     2091psImage A,B;
     2092
     2093B = psBinaryOp (NULL, A, "^", psScalar(2));
     2094(void) psUnaryOp(B, B, "sin");
     2095\end{verbatim}
     2096
     2097Note that the \code{psUnaryOp} is performed on \code{B} in-place.
     2098
     2099%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     2100
     2101\section{Astronomy-Specific Functions}
     2102
     2103Some basic, relatively simple astronomy-specific functions are
     2104required which will serve as the foundation for building the Phase $N$
     2105modules.  These functions are not expected to cover every forseeable
     2106function, but will serve as the building blocks of more complicated
     2107processing functions.
     2108
     2109We require functions covering each of the following areas:
    21632110\begin{itemize}
    2164 \item Cell: $(x,y)$ in pixels --- raw coordinates;
    2165 \item Chip: $(X,Y)$ in pixels --- the location on the silicon;
    2166 \item Focal Plane: $(p,q)$ in microns --- the location on the focal plane;
    2167 \item Tangent Plane: $(l,m)$ in arcsec from the telescope boresight; and
    2168 \item Sky: (RA,Dec) --- ICRS.
     2111\item Astrometry;
     2112\item Dates and times;
     2113\item Image handling;
     2114\item Metadata;
     2115\item Detector and sky positions;
     2116\item Astronomical objects; and
     2117\item Photometry.
    21692118\end{itemize}
    2170 
    2171 The following steps are required to convert from the cell coordinates to
    2172 the sky:
    2173 \begin{itemize}
    2174 \item Cell $\longleftrightarrow$ Chip: two 2D polynomials, $(X,Y) = f(x,y)$;
    2175 \item Chip $\longleftrightarrow$ FP: two 2D polynomials, $(p,q) = g(X,Y)$;
    2176 \item FP $\longleftrightarrow$ TP: two 4D polynomials, $(l,m) =
    2177 h(p,q,m,c)$, where $m$ and $c$ are the magnitude and colour of the
    2178 object, respectively; and
    2179 \item TP $\longleftrightarrow$ Sky: SLALib transformation using a
    2180 transform pre-computed for each pointing.
    2181 \end{itemize}
    2182 
    2183 Note that the transformation between the Focal Plane and the Tangent
    2184 Plane is a four-dimensional polynomial, in order to account for any
    2185 possible dependencies in the astrometry on the stellar magnitude and
    2186 colour; the former serves as a check for charge transfer
    2187 inefficiencies, while the latter will correct chromatic refraction,
    2188 both through the atmosphere and the corrector lenses.
    2189 
    2190 \textbf{[If the magnitude terms serve to check CTI, then shouldn't we
    2191 put them in the cell $\leftrightarrow$ chip section?]}
    2192 
    2193 We require structures to contain each of the above transformations as
    2194 well as the pixel data.
    2195 
    2196 \subsubsection{A Readout}
    2197 
    2198 A readout is the result of a single read of a cell (or a portion
    2199 thereof).  It contains a pointer to the pixel data, a separate pointer
    2200 to the overscan pixels, and additional pointers to the objects found
    2201 in the readout, and the readout metadata.  It also contains the offset
    2202 from the lower-left corner of the chip, in the case that the CCD was
    2203 windowed.
    2204 
    2205 \begin{verbatim}
    2206 /** a Readout: a collection of pixels */
    2207 typedef struct {
    2208     int x0, y0;                         //!< Offset from the lower-left corner
    2209     psImage *image;                     ///< imaging area of cell
    2210     psDlist *objects;                   ///< objects derived from cell
    2211     psImage *overscan;                  ///< bias region (subimage) of cell
    2212     psMetaDataSet *md;                  //!< Readout-level metadata
    2213 } psReadout;
    2214 \end{verbatim}   
    2215 
    2216 
    2217 \subsubsection{A Cell}
    2218 
    2219 A cell consists of one or more readouts (usually only one except in the
    2220 case that the cell has been used for fast guiding).  It also contains
    2221 a pointer to the cell metadata, and a pointer to its parent chip.  On
    2222 the astrometry side, it also contains coordinate transforms from the
    2223 cell to the chip and, as a convenience, from the cell to the focal
    2224 plane.  It is expected that these transforms will consist of two
    2225 first-order 2D polynomials, simply specifying a translation, rotation
    2226 and magnification; hence they are easily inverted, and there is no
    2227 need to add reverse transformations.  We also add an additional
    2228 transformation, which is intended to provide a ``quick and dirty''
    2229 transform from the cell coordinates to the sky; this transformation
    2230 not guaranteed to be as precise as the ``standard'' transformation of
    2231 Cell $\rightarrow$ Chip $\rightarrow$ Focal Plane $\rightarrow$
    2232 Tangent Plane $\rightarrow$ Sky, but will be faster.
    2233 
    2234 \begin{verbatim}
    2235 /** a Cell: a collection of readouts.
     2119These are each dealt with below.
     2120
     2121%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     2122
     2123\subsection{Dates and times}
     2124
     2125\textbf{[May be deferred.]}
     2126
     2127%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     2128
     2129\subsection{Detector and sky positions}
     2130
     2131Both detector and sky positions will be used extensively in the IPP.
     2132Since these both contain two coordinates with their associated errors,
     2133we bundle these into a single generic structure, \code{psCoord},
     2134containing \code{union}s to handle the semantic differences.
     2135
     2136\begin{verbatim}
     2137/** A point in 2-D space, with errors.
     2138 */
     2139typedef union {
     2140    struct {
     2141        double x;                       //!< x position
     2142        double y;                       //!< y position
     2143        double xErr;                    //!< Error in x position
     2144        double yErr;                    //!< Error in y position
     2145    } xy;
     2146    struct {
     2147        double r;                       //!< RA
     2148        double d;                       //!< Dec
     2149        double rErr;                    //!< Error in RA
     2150        double dErr;                    //!< Error in Dec
     2151    } rd;
     2152} psCoord;
     2153\end{verbatim}
     2154
     2155\subsubsection{Transformations}
     2156
     2157We specify two types of transforms between coordinate systems.  The
     2158first consists simply of two 2D polynomials to transform both
     2159components; this will be used to apply the coordinate transformations
     2160between Cells, Chips and the Focal Plane.  The second consists of two
     21614D polynomials; this will be used to apply position-, colour- and
     2162magnitude-dependent distortions between the Focal Plane and the
     2163Tangent Plane.
     2164
     2165\begin{verbatim}
     2166/** A polynomial transformation between coordinate frames.  This may be a linear relationship, or may
     2167 *  represent a higher-order transformation.
    22362168 */
    22372169typedef struct {
    2238     int nReadouts;                      ///< number of readouts in this cell realization; each may have its own
    2239                                         ///< image, objects and overscan.
    2240     struct psReadout *readouts;         //!< Readouts from the cell
    2241     psMetaDataSet *md;                  ///< Cell-level metadata
    2242 
    2243     psCoordXform *cellToChip;           ///< Transformations from cell coordinates to chip coordinates
    2244     psCoordXform *cellToFPA;            ///< Transformations from cell coordinates to FPA coordinates
    2245     psCoordXform *cellToSky;            ///< Quick and Dirty transformations from cell coordinates to sky
    2246 
    2247     struct psChip  *parentChip;         ///< chip which contains this cell
    2248 } psCell;
    2249 \end{verbatim}
    2250 
    2251 
    2252 \subsubsection{A Chip}
    2253 
    2254 A chip consists of one or more cells (according to the number of
    2255 amplifiers on the CCD).  It contains a pointer to the chip metadata,
    2256 and a pointer to the parent focal plane.  For astrometry, it contains
    2257 a coordinate transform from the chip to the focal plane.  It is
    2258 expected that this transforms will consist of two second-order 2D
    2259 polynomials; hence we expect that it is prudent to include a reverse
    2260 transformation which will be derived from numerically inverting the
    2261 forward transformation.
    2262 
    2263 \begin{verbatim}
    2264 /** a Chip: a collection of cells.  Not all valid cells in a chip need to be listed in an
    2265  *  instance of psChip.
     2170    psDPolynomial2D *x;
     2171    psDPolynomial2D *y;
     2172} psCoordXform;
     2173\end{verbatim}
     2174
     2175\begin{verbatim}
     2176/** The optical distortion terms.  The lowest two terms are the x and y axis of the target system.  The higher
     2177 *  two terms represent magnitude and color terms.
    22662178 */
    22672179typedef struct {
    2268     int nCells;                         ///< Number of Cells assigned
    2269     psCell *cells;                      ///< Cells in the Chip
    2270 
    2271     psMetaDataSet *md;                  ///< Chip-level metadata
    2272     psCoordXform *chipToFPA;            ///< Transformations from chip coordinates to FPA coordinates
    2273     psCoordXform *FPAtoChip;            //!< Transformations from FPA coordinates to chip
    2274 
    2275     struct psFPA *parentFPA;            ///< FPA which contains this chip
    2276 } psChip;
    2277 \end{verbatim}
    2278 
    2279 \subsubsection{A Focal Plane}
    2280 
    2281 A focal plane consists of one or more chips (according to the number
    2282 of pieces of contiguous silicon).  It contains pointers to the focal
    2283 plane metadata and the exposure information.  For astrometry, it
    2284 contains a transformation from the focal plane to the tangent plane
    2285 and the fixed pattern residuals.  It is expected that the
    2286 transformation will consist of two 4D polynomials (i.e.\ a function of
    2287 two coordinates in position, the magnitude of the object, and the
    2288 colour of the object) in order to correct for optical distortions and
    2289 the effects of the atmosphere; hence we expect that it is prudent to
    2290 include a reverse transformation which will be derived from
    2291 numerically inverting the forward transformation.  Since colours are
    2292 involved in the transformation, it is necessary to specify the colour
    2293 the transformation is defined for.  We also include some values to
    2294 characterise the quality of the transformation: the root mean square
    2295 deviation for the x and y transformation fits, and the $\chi^2$ for
    2296 the transformation fit.
    2297 
    2298 \begin{verbatim}
    2299 /** a Focal plane array: a collection of chips.  Not all chips in a camera need to be listed in an instance of
    2300  *  psFPA.
    2301  */
    2302 typedef struct {
    2303     int nChips;                         ///< Number of Cells assigned
    2304     int nAlloc;                         ///< Number of Cells available
    2305     psChip *chips;                      ///< Chips in the Focal Plane Array
    2306 
    2307     psMetaDataSet *md;                  ///< FPA-level metadata
    2308     psDistortion *TPtoFP;               ///< Transformation term from
    2309     psDistortion *FPtoTP;               ///< Transformation term from
    2310     psFixedPattern *pattern;            //!< Fixed pattern residual offsets
    2311     psExposure *exp;                    ///< information about this exposure
    2312     psPhotSystem colorPlus, colorMinus; ///< Colour reference
    2313     float rmsX, rmsY;                   //!< Dispersion in astrometric solution
    2314     float chi2;                         //!< chi^2 of astrometric solution
    2315 } psFPA;
    2316 \end{verbatim}
    2317 
    2318 
    2319 \subsubsection{SLALib information}
    2320 
    2321 SLALib requires several elements to perform the transformations
    2322 between the tangent plane and the sky.  Pre-computing these quantities
    2323 for each exposure means that subsequent transformations are faster.
    2324 For historical reasons, this structure is known colloquially as
    2325 ``Wallace's Grommit''.
    2326 
    2327 \begin{verbatim}
    2328 /** Information needed (by SLALib) to convert Apparent to Observed Position */
    2329 typedef struct {
    2330     double latitude;                    ///< geodetic latitude (radians)
    2331     double sinLat, cosLat;              ///< sine and cosine of geodetic latitude
    2332     double abberationMag;               ///< magnitude of diurnal aberration vector
    2333     double height;                      ///< height (HM)
    2334     double temperature;                 ///< ambient temperature (TDK)
    2335     double pressure;                    ///< pressure (PMB)
    2336     double humidity;                    ///< relative humidity (RH)
    2337     double wavelength;                  ///< wavelength (WL)
    2338     double lapseRate;                   ///< lapse rate (TLR)
    2339     double refractA, refractB;          ///< refraction constants A and B (radians)
    2340     double longitudeOffset;             ///< longitude + eqn of equinoxes + ``sidereal UT'' (radians)
    2341     double siderealTime;                ///< local apparent sidereal time (radians)
    2342 } psGrommit;
    2343 \end{verbatim}
    2344 
    2345 
    2346 \subsubsection{Exposure information}
    2347 
    2348 We need several quantities from the telescope in order to make a
    2349 first guess at the astrometric solution.  From these quantities,
    2350 further quantities can be derived and stored for later use.
    2351 
    2352 \begin{verbatim}
    2353 /** Exposure information from the telescope */
    2354 typedef struct {
    2355     // Telescope longitude, latitude and height are stored separately, since they don't change with pointing
    2356     double ra, dec;                     //!< Telescope boresight
    2357     double ha;                          //!< Hour angle
    2358     double zd;                          //!< Zenith distance
    2359     double az;                          //!< Azimuth
    2360     double lst;                         //!< Local Sidereal Time
    2361     float mjd;                          //!< MJD of observation
    2362     float rotAngle;                     //!< Rotator position angle
    2363     float temp;                         //!< Air temperature, for estimating refraction
    2364     float pressure;                     //!< Air pressure, for calculating refraction
    2365     float humidity;                     //!< Relative humidity, for calculating refraction
    2366     float exptime;                      //!< Exposure time
    2367     /* Derived quantities */
    2368     float posAngle;                     //!< Position angle
    2369     float parallactic;                  //!< Parallactic angle
    2370     float airmass;                      //!< Airmass, calculated from zenith distance
    2371     float pf;                           //!< Parallactic factor
    2372     char *cameraName;                   ///< name of camera which provided exposure
    2373     char *telescopeName;                ///< name of telescope which provided exposure
    2374     psGrommit *grommit;                 //!< Data needed to convert from the sky to the tangent plane
    2375 } psExposure;
    2376 \end{verbatim}
    2377 
    2378 
    2379 \subsubsection{Fixed Pattern}
    2380 
    2381 The fixed pattern is a correction to the general astrometric solution
    2382 formed by summing the residuals from many observations.  The intent is
    2383 to correct for higher-order distortions in the camera system on a
    2384 coarse grid (larger than individual pixels, but smaller than a single
    2385 cell).  Hence, in addition to the offsets, we need to specify the size
    2386 and scale of the grid in $x$ and $y$, as well as the origin of the
    2387 grid.
    2388 
    2389 \begin{verbatim}
    2390 /** The fixed pattern residual offsets.  These are specified via a coarse grid of x and y offsets. */
    2391 typedef struct {
    2392     int nX, nY;                         //!< Number of elements in x and y
    2393     double x0, y0;                      //!< Position of the lower-left corner of the grid on the focal plane
    2394     double xScale, yScale;              //!< Scale of the grid
    2395     double **x, **y;                    //!< The grid of offsets in x and y
    2396 } psFixedPattern;
    2397 \end{verbatim}
    2398 
    2399 
    2400 \subsubsection{Constructors and Destructors}
    2401 
    2402 Each of the above structures needs an appropriate constructor and
    2403 destructor.  Other than \code{psExposure}, which contains significant
    2404 non-pointer types, the constructors should not take any arguments, and
    2405 the destructors should only take the structure to be destroyed.
    2406 The constructor for \code{psExposure} is specified below.
    2407 
    2408 \begin{verbatim}
    2409 /** Constructor */
    2410 psExposure *
    2411 psExposureAlloc(double ra, double dec,  //!< Telescope boresight
    2412                 double ha,              //!< Hour angle
    2413                 double zd,              //!< Zenith distance
    2414                 double az,              //!< Azimuth
    2415                 double lst,             //!< Local Sidereal Time
    2416                 float mjd,              //!< MJD
    2417                 float rotAngle,         //!< Rotator position angle
    2418                 float temp,             //!< Temperature
    2419                 float pressure,         //!< Pressure
    2420                 float humidity,         //!< Relative humidity
    2421                 float exptime           //!< Exposure time
    2422                 );
    2423 \end{verbatim}
    2424 
    2425 
    2426 \subsubsection{Finding}
    2427 
    2428 We require functions to return the structure containing given
    2429 coordinates.  For example, we want the chip that corresponds to the
    2430 focal plane coordinates $(p,q) = (-1.234,+5.678)$.  These routines
    2431 handle the one-to-many problem --- i.e., for one given focal plane
    2432 coordinate, there are many chips that this coordinate may be
    2433 correspond to; these functions will select the correct one.
    2434 
    2435 
    2436 \begin{verbatim}
    2437 /** returns Chip in FPA which contains the given FPA coordinate */
    2438 psChip *
    2439 psChipInFPA (psChip *out,               //!< Chip to return, or NULL
    2440              const psFPA *fpa,          ///< FPA description
    2441              const psCoord *coord       ///< coordinate in FPA
    2442              );
    2443 \end{verbatim}
    2444 
    2445 \begin{verbatim}
    2446 /** returns Cell in Chip which contains the given chip coordinate */
    2447 psCell *
    2448 psCellInChip(psCell *out,               //!< Cell to return, or NULL
    2449              const psChip *chip,        ///< chip description
    2450              const psCoord *coord       ///< coordinate in chip
    2451              );
    2452 \end{verbatim}
    2453 
    2454 Usually we will want to go directly from the FPA to the Cell, so we
    2455 also specify the following function, which performs the above two
    2456 functions in order.
    2457 
    2458 \begin{verbatim}
    2459 /** Return the cell in FPA which contains the given FPA coordinates */
    2460 psCell *
    2461 psCellInFPA(psCell *out,                //!< Cell to return, or NULL
    2462             const psFPA *fpa,           //!< FPA description
    2463             const psCoord *coord        //!< Coordinate in FPA
    2464             );
    2465 \end{verbatim}
    2466 
    2467 
    2468 
    2469 \subsubsection{Conversion Functions}
    2470 
    2471 We require functions to convert between the various coordinate frames
    2472 (Section~\ref{sec:coordinateFrames}).  The heirarchy of the coordinate
    2473 frames and the transformations between each are shown in
    2474 Figure~\ref{fig:coco}.  The functions that employ the transformations
    2475 are shown in Figure~\ref{fig:cocoFunc}.  In addition to
    2476 transformations between each adjoining coordinate frame in the
    2477 heirarchy, we also require higher-level functions to convert between
    2478 the Cell and Sky coordinate frames; these will simply perform the
    2479 intermediate steps.
    2480 
    2481 \begin{figure}
    2482 \psfig{file=coordinateFrames.ps,height=7in,angle=-90}
    2483 \caption{The coordinate systems in the \PS{} IPP, and the relation
    2484 between each by transformations contained in the appropriate
    2485 structures.}
    2486 \label{fig:coco}
    2487 \end{figure}
    2488 
    2489 \begin{figure}
    2490 \psfig{file=coordinateConv.ps,height=7in,angle=-90}
    2491 \caption{Conversion between coordinate systems by PSLib.}
    2492 \label{fig:cocoFunc}
    2493 \end{figure}
    2494 
    2495 The function prototypes are:
    2496 
    2497 \begin{verbatim}
    2498 /** Convert (RA,Dec) to cell and cell coordinates */
     2180    psDPolynomial4D *x;
     2181    psDPolynomial4D *y;
     2182} psDistortion;
     2183\end{verbatim}
     2184
     2185We require corresponding functions to apply the transformations:
     2186
     2187\begin{verbatim}
     2188/** apply the coordinate transformation to the given coordinate */
     2189psCoord *psCoordXformApply (psCoord *out, //!< Output coordinates, or NULL
     2190                            const psCoordXform *frame, ///< coordinate transformation
     2191                            const psCoord *coords ///< input coordiate
     2192    );
     2193\end{verbatim}
     2194
     2195\begin{verbatim}
     2196/** apply the optical distortion to the given coordinate, magnitude, color */
     2197psCoord *psDistortionApply (psCoord *out, //!< Output coordinates, or NULL
     2198                            const psdistortion *pattern, ///< optical distortion pattern
     2199                            const psCoord *coords, ///< input coordinate
     2200                            float mag,  ///< magnitude of object
     2201                            float color ///< color of object
     2202    );
     2203\end{verbatim}
     2204
     2205
     2206\subsubsection{Offsets}
     2207
     2208We require a function to calculate the offset between two positions on
     2209the sky, as well as a function to apply an offset to a position.
     2210
     2211\begin{verbatim}
     2212/** Get offset (RA,Dec) on the sky between two positions position1 and position2 may not be identical */
    24992213psCoord *
    2500 psCoordSkyToCell(psCoord *out,          //!< Coordinates to return, or NULL
    2501                  psCell *cell,          //!< Cell to return
    2502                  const psFPA *fpa       //!< FPA description
    2503                  );
    2504 \end{verbatim}
    2505 
    2506 \begin{verbatim}
    2507 /** Convert cell and cell coordinate to (RA,Dec) */
     2214psGetOffset(const psCoord *restrict position1, //!< Position 1
     2215            const psCoord *restrict position2, //!< Position 2
     2216            const char *type            //!< Type of offset: Linear, Spherical/Arcsec, Spherical/Degreees etc
     2217    );
     2218\end{verbatim}
     2219
     2220\begin{verbatim}
     2221/** Apply an offset to a position */
    25082222psCoord *
    2509 psCoordCellToSky(psCoord *out,          //!< Coordinates to return, or NULL
    2510                  const psCell *cell,    //!< Cell to get coordinates for
    2511                  const psCoord *coord   //!< cell coordinates to transform
    2512                  );
    2513 \end{verbatim}
    2514 
    2515 \begin{verbatim}
    2516 /** Quick and dirty cell to (RA,Dec) --- employs cellToSky transformation */
     2223psApplyOffset(const psCoord *restrict position, //!< Position
     2224              const psCoord *restrict offset, //!< Offset
     2225              const char *type          //!< Type of offset: Linear, Spherical/Arcsec, Spherical/Degreees etc
     2226    );
     2227\end{verbatim}
     2228
     2229
     2230\subsubsection{Positions of Major SS Objects}
     2231
     2232We require the ability to calculate the position of major Solar System
     2233objects, as well as Lunar phase.
     2234
     2235\begin{verbatim}
     2236/** Get Sun Position */
    25172237psCoord *
    2518 psCoordCellToSkyQuick(psCoord *out,     //!< Coordinates to return, or NULL
    2519                       const psCell *cell, //!< Cell description
    2520                       const psCoord *coord //!< cell coordinates to transform
    2521                       );
    2522 \end{verbatim}
    2523 
    2524 \begin{verbatim}
    2525 /** Convert (RA,Dec) to tangent plane coords */
     2238psGetSunPos(float mjd                   //!< MJD to get position for
     2239    );
     2240\end{verbatim}
     2241
     2242\begin{verbatim}
     2243/** Get Moon position */
    25262244psCoord *
    2527 psCoordSkyToTP(psCoord *out,            //!< Coordinates to return, or NULL
    2528                const psExposure *exp,   //!< Exposure description
    2529                const psCoord *coord     //!< input Sky coordinate
    2530                );
    2531 \end{verbatim}
    2532 
    2533 \begin{verbatim}
    2534 /** Convert tangent plane coords to focal plane coordinates */
     2245psGetMoonPos(float mjd,                 //!< MJD to get position for
     2246             double latitude,           //!< Latitude for apparent position
     2247             double longitude           //!< Longitude for apparent position
     2248    );
     2249\end{verbatim}
     2250
     2251\begin{verbatim}
     2252/** Get Moon phase */
     2253float
     2254psGetMoonPhase(float mjd                //!< MJD to get phase for
     2255    );
     2256\end{verbatim}
     2257
     2258\begin{verbatim}
     2259/** Get Planet positions */
    25352260psCoord *
    2536 psCoordTPtoFPA(psCoord *out,            //!< Coordinates to return, or NULL
    2537                const psFPA *fpa,        //!< FPA description
    2538                const psCoord *coord     //!< input TP coordinate
    2539                );
    2540 \end{verbatim}
    2541 
    2542 \begin{verbatim}
    2543 /** converts the specified FPA coord to the coord on the given Chip */
     2261psGetSolarSystemPos(const char *solarSystemObject, //!< Named S.S. object
     2262                    float mjd           //!< MJD to get position for
     2263    );
     2264\end{verbatim}
     2265
     2266\subsubsection{Celestial Coordinate Conversions}
     2267
     2268We need to be able to convert between ICRS, Galactic and Ecliptic
     2269coordinates.
     2270
     2271\begin{verbatim}
     2272/** Convert ICRS to Ecliptic */
    25442273psCoord *
    2545 psCoordFPAtoChip (psCoord *out,         //!< Coordinates to return, or NULL
    2546                   const psChip *chip,   ///< Chip of interest
    2547                   const psCoord *coord  ///< input FPA coordinate
    2548                   );
    2549 \end{verbatim}
    2550 
    2551 \begin{verbatim}
    2552 /** converts the specified Chip coord to the coord on the given Cell */
     2274psCoordinatesItoE(const psCoord *restrict coordinates //!< ICRS coordinates to convert
     2275    );
     2276\end{verbatim}
     2277
     2278\begin{verbatim}
     2279/** Convert Ecliptic to ICRS */
    25532280psCoord *
    2554 psCoordChiptoCell (psCoord *out,        //!< Coordinates to return, or NULL
    2555                    const psCell *cell,  ///< Cell of interest
    2556                    const psCoord *coord ///< input Chip coordinate
    2557                    );
    2558 \end{verbatim}
    2559 
    2560 \begin{verbatim}
    2561 /** converts the specified Cell coord to the coord on the parent Chip */
     2281psCoordinatesEtoI(const psCoord *restrict coordinates //!< Ecliptic coordinates to convert
     2282    );
     2283\end{verbatim}
     2284
     2285\begin{verbatim}
     2286/** Convert ICRS to Galactic */
    25622287psCoord *
    2563 psCoordCelltoChip (psCoord *out,        //!< Coordinates to return, or NULL
    2564                    const psCell *cell,  ///< Cell description
    2565                    const psCoord *coord ///< input Cell coordinate
    2566                    );
    2567 \end{verbatim}
    2568 
    2569 \begin{verbatim}
    2570 /** converts the specified Chip coord to the coord on the parent FPA */
     2288psCoordinatesItoG(const psCoord *restrict coordinates //!< ICRS coordinates to convert
     2289    );
     2290\end{verbatim}
     2291
     2292\begin{verbatim}
     2293/** Convert Galactic to ICRS */
    25712294psCoord *
    2572 psCoordChiptoFPA (psCoord *out,         //!< Coordinates to return, or NULL
    2573                   const psChip *chip,   ///< Chip description
    2574                   const psCoord *coord  ///< input Chip coordinate
    2575                   );
    2576 \end{verbatim}
    2577 
    2578 \begin{verbatim}
    2579 /** Convert focal plane coords to tangent plane coordinates */
    2580 psCoord *
    2581 psCoordFPAToTP(psCoord *out,            //!< Coordinates to return, or NULL
    2582                const psFPA *fpa,        //!< FPA description
    2583                const psCoord *coord     //!< input FPA coordinate
    2584                );
    2585 \end{verbatim}
    2586 
    2587 \begin{verbatim}
    2588 /** Convert tangent plane coords to (RA,Dec) */
    2589 psCoord *
    2590 psCoordTPtoSky(psCoord *out,            //!< Coordinates to return, or NULL
    2591                const psExposure *exp,   //!< Exposure description
    2592                const psCoord *coord     //!< input TP coordinate
    2593                );
    2594 \end{verbatim}
    2595 
    2596 \begin{verbatim}
    2597 /** Convert Cell coords to FPA coordinates */
    2598 psCoord *
    2599 psCoordCellToFPA(psCoord *out,          //!< Coordinates to return, or NULL
    2600                  const psCell *cell,    //!< Cell description
    2601                  const psCoord *coord   //!< Input cell coordinates
    2602                  );
    2603 \end{verbatim}
    2604 
    2605 \subsubsection{Additional functions}
    2606 
    2607 We require additional functions to perform general functions which
    2608 will be useful for astrometry.  Given coordinates on the sky, we
    2609 need to get the airmass, the parallactic angle, and an estimate of
    2610 the atmospheric refraction.
    2611 
    2612 \begin{verbatim}
    2613 /** Get the airmass for a given position and sidereal time */
    2614 float
    2615 psGetAirmass(const psCoord *coord,      //!< Position on the sky
    2616              double siderealTime,       //!< Sidereal time
    2617              float height               //!< Height above sea level
    2618              );
    2619 \end{verbatim}
    2620 
    2621 \begin{verbatim}
    2622 /** Get the parallactic angle for a given position and sidereal time */
    2623 float
    2624 psGetParallactic(const psCoord *coord,  //!< Position on the sky
    2625                  double siderealTime    //!< Sidereal time
    2626                  );
    2627 \end{verbatim}
    2628 
    2629 \begin{verbatim}
    2630 /** Estimate atmospheric refraction, along the parallactic */
    2631 float
    2632 psGetRefraction(float colour,           //!< Colour of object
    2633                 psPhotSystem colorPlus, ///< Colour reference
    2634                 psPhotSystem colorMinus, ///< Colour reference
    2635                 const psExposure *exp   //!< Telescope pointing information, for airmass, temp and pressure
    2636                 );
    2637 \end{verbatim}
    2638 
    2639 \begin{verbatim}
    2640 /** Calculate the parallax factor */
    2641 double
    2642 psGetParallaxFactor(const psExposure *exp //!< Exposure details
    2643     );
    2644 \end{verbatim}
    2645 
    2646 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    2647 
    2648 \subsection{Dates and times}
    2649 
    2650 \textbf{[May be deferred.]}
     2295psCoordinatesGtoI(const psCoord *restrict coordinates //!< Galactic coordinates to convert
     2296    );
     2297\end{verbatim}
     2298
    26512299
    26522300%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    28662514\end{verbatim}
    28672515
    2868 \subsection{Detector and sky positions}
    2869 
    2870 Both detector and sky positions will be used extensively in the IPP.
    2871 Since these both contain two coordinates with their associated errors,
    2872 we bundle these into a single generic structure, \code{psCoord},
    2873 containing \code{union}s to handle the semantic differences.
    2874 
    2875 \begin{verbatim}
    2876 /** A point in 2-D space, with errors.
    2877  */
    2878 typedef union {
    2879     struct {
    2880         double x;                       //!< x position
    2881         double y;                       //!< y position
    2882         double xErr;                    //!< Error in x position
    2883         double yErr;                    //!< Error in y position
    2884     } xy;
    2885     struct {
    2886         double r;                       //!< RA
    2887         double d;                       //!< Dec
    2888         double rErr;                    //!< Error in RA
    2889         double dErr;                    //!< Error in Dec
    2890     } rd;
    2891 } psCoord;
    2892 \end{verbatim}
    2893 
    2894 \subsubsection{Transformations}
    2895 
    2896 We specify two types of transforms between coordinate systems.  The
    2897 first consists simply of two 2D polynomials to transform both
    2898 components; this will be used to apply the coordinate transformations
    2899 between Cells, Chips and the Focal Plane.  The second consists of two
    2900 4D polynomials; this will be used to apply position-, colour- and
    2901 magnitude-dependent distortions between the Focal Plane and the
    2902 Tangent Plane.
    2903 
    2904 \begin{verbatim}
    2905 /** A polynomial transformation between coordinate frames.  This may be a linear relationship, or may
    2906  *  represent a higher-order transformation.
     2516\subsection{Astronomy Images}
     2517
     2518\subsubsection{Terminology}
     2519
     2520Some brief review of terminology would be useful so that previous
     2521definitions do not influence the understanding of this document.
     2522
     2523A ``readout'' is a read of the detector.
     2524
     2525A ``cell'' is defined as the smallest element of the detector readout;
     2526usually associated with an amplifier.  Correspondingly, each cell has
     2527its own overscan region.  There may be multiple readouts in a cell if
     2528the cell was used to provide fast guiding.
     2529
     2530A ``chip'' is defined as a contiguous piece of silicon, and consists
     2531of a group of cells.
     2532
     2533A ``focal plane'' is defined as a mosaic of chips, and consists of a
     2534group of chips.
     2535
     2536For example, take a mosaic camera consisting of eight $2k\times 4k$
     2537CCDs, each of which is read out through two amplifiers.  Then there
     2538would be sixteen cells in total, each of which is presumably $2k\times
     25392k$.  There would be eight chips, each consisting of two cells, and
     2540the focal plane consists of these eight chips.
     2541
     2542As another example, consider an observation by PS1.  The focal plane
     2543would consist of 60 chips, each of which consist of 64 cells (or less;
     2544a few cells may be dead).  Some cells (those containing guide stars
     2545for the orthogonal transfer) will contain multiple readouts.
     2546
     2547\subsubsection{A Readout}
     2548
     2549A readout is the result of a single read of a cell (or a portion
     2550thereof).  It contains a pointer to the pixel data, a separate pointer
     2551to the overscan pixels, and additional pointers to the objects found
     2552in the readout, and the readout metadata.  It also contains the offset
     2553from the lower-left corner of the chip, in the case that the CCD was
     2554windowed.
     2555
     2556\begin{verbatim}
     2557/** a Readout: a collection of pixels */
     2558typedef struct {
     2559    int x0, y0;                         //!< Offset from the lower-left corner
     2560    psImage *image;                     ///< imaging area of cell
     2561    psDlist *objects;                   ///< objects derived from cell
     2562    psImage *overscan;                  ///< bias region (subimage) of cell
     2563    psMetaDataSet *md;                  //!< Readout-level metadata
     2564} psReadout;
     2565\end{verbatim}   
     2566
     2567
     2568\subsubsection{A Cell}
     2569
     2570A cell consists of one or more readouts (usually only one except in the
     2571case that the cell has been used for fast guiding).  It also contains
     2572a pointer to the cell metadata, and a pointer to its parent chip.  On
     2573the astrometry side, it also contains coordinate transforms from the
     2574cell to the chip and, as a convenience, from the cell to the focal
     2575plane.  It is expected that these transforms will consist of two
     2576first-order 2D polynomials, simply specifying a translation, rotation
     2577and magnification; hence they are easily inverted, and there is no
     2578need to add reverse transformations.  We also add an additional
     2579transformation, which is intended to provide a ``quick and dirty''
     2580transform from the cell coordinates to the sky; this transformation
     2581not guaranteed to be as precise as the ``standard'' transformation of
     2582Cell $\rightarrow$ Chip $\rightarrow$ Focal Plane $\rightarrow$
     2583Tangent Plane $\rightarrow$ Sky, but will be faster.
     2584
     2585\begin{verbatim}
     2586/** a Cell: a collection of readouts.
    29072587 */
    29082588typedef struct {
    2909     psDPolynomial2D *x;
    2910     psDPolynomial2D *y;
    2911 } psCoordXform;
    2912 \end{verbatim}
    2913 
    2914 \begin{verbatim}
    2915 /** The optical distortion terms.  The lowest two terms are the x and y axis of the target system.  The higher
    2916  *  two terms represent magnitude and color terms.
     2589    int nReadouts;                      ///< number of readouts in this cell realization; each may have its own
     2590                                        ///< image, objects and overscan.
     2591    struct psReadout *readouts;         //!< Readouts from the cell
     2592    psMetaDataSet *md;                  ///< Cell-level metadata
     2593
     2594    psCoordXform *cellToChip;           ///< Transformations from cell coordinates to chip coordinates
     2595    psCoordXform *cellToFPA;            ///< Transformations from cell coordinates to FPA coordinates
     2596    psCoordXform *cellToSky;            ///< Quick and Dirty transformations from cell coordinates to sky
     2597
     2598    struct psChip  *parentChip;         ///< chip which contains this cell
     2599} psCell;
     2600\end{verbatim}
     2601
     2602
     2603\subsubsection{A Chip}
     2604
     2605A chip consists of one or more cells (according to the number of
     2606amplifiers on the CCD).  It contains a pointer to the chip metadata,
     2607and a pointer to the parent focal plane.  For astrometry, it contains
     2608a coordinate transform from the chip to the focal plane.  It is
     2609expected that this transforms will consist of two second-order 2D
     2610polynomials; hence we expect that it is prudent to include a reverse
     2611transformation which will be derived from numerically inverting the
     2612forward transformation.
     2613
     2614\begin{verbatim}
     2615/** a Chip: a collection of cells.  Not all valid cells in a chip need to be listed in an
     2616 *  instance of psChip.
    29172617 */
    29182618typedef struct {
    2919     psDPolynomial4D *x;
    2920     psDPolynomial4D *y;
    2921 } psDistortion;
    2922 \end{verbatim}
    2923 
    2924 We require corresponding functions to apply the transformations:
    2925 
    2926 \begin{verbatim}
    2927 /** apply the coordinate transformation to the given coordinate */
    2928 psCoord *psCoordXformApply (psCoord *out, //!< Output coordinates, or NULL
    2929                             const psCoordXform *frame, ///< coordinate transformation
    2930                             const psCoord *coords ///< input coordiate
    2931     );
    2932 \end{verbatim}
    2933 
    2934 \begin{verbatim}
    2935 /** apply the optical distortion to the given coordinate, magnitude, color */
    2936 psCoord *psDistortionApply (psCoord *out, //!< Output coordinates, or NULL
    2937                             const psdistortion *pattern, ///< optical distortion pattern
    2938                             const psCoord *coords, ///< input coordinate
    2939                             float mag,  ///< magnitude of object
    2940                             float color ///< color of object
    2941     );
    2942 \end{verbatim}
    2943 
    2944 
    2945 \subsubsection{Offsets}
    2946 
    2947 We require a function to calculate the offset between two positions on
    2948 the sky, as well as a function to apply an offset to a position.
    2949 
    2950 \begin{verbatim}
    2951 /** Get offset (RA,Dec) on the sky between two positions position1 and position2 may not be identical */
     2619    int nCells;                         ///< Number of Cells assigned
     2620    psCell *cells;                      ///< Cells in the Chip
     2621
     2622    psMetaDataSet *md;                  ///< Chip-level metadata
     2623    psCoordXform *chipToFPA;            ///< Transformations from chip coordinates to FPA coordinates
     2624    psCoordXform *FPAtoChip;            //!< Transformations from FPA coordinates to chip
     2625
     2626    struct psFPA *parentFPA;            ///< FPA which contains this chip
     2627} psChip;
     2628\end{verbatim}
     2629
     2630\subsubsection{A Focal Plane}
     2631
     2632A focal plane consists of one or more chips (according to the number
     2633of pieces of contiguous silicon).  It contains pointers to the focal
     2634plane metadata and the exposure information.  For astrometry, it
     2635contains a transformation from the focal plane to the tangent plane
     2636and the fixed pattern residuals.  It is expected that the
     2637transformation will consist of two 4D polynomials (i.e.\ a function of
     2638two coordinates in position, the magnitude of the object, and the
     2639colour of the object) in order to correct for optical distortions and
     2640the effects of the atmosphere; hence we expect that it is prudent to
     2641include a reverse transformation which will be derived from
     2642numerically inverting the forward transformation.  Since colours are
     2643involved in the transformation, it is necessary to specify the colour
     2644the transformation is defined for.  We also include some values to
     2645characterise the quality of the transformation: the root mean square
     2646deviation for the x and y transformation fits, and the $\chi^2$ for
     2647the transformation fit.
     2648
     2649\begin{verbatim}
     2650/** a Focal plane array: a collection of chips.  Not all chips in a camera need to be listed in an instance of
     2651 *  psFPA.
     2652 */
     2653typedef struct {
     2654    int nChips;                         ///< Number of Cells assigned
     2655    int nAlloc;                         ///< Number of Cells available
     2656    psChip *chips;                      ///< Chips in the Focal Plane Array
     2657
     2658    psMetaDataSet *md;                  ///< FPA-level metadata
     2659    psDistortion *TPtoFP;               ///< Transformation term from
     2660    psDistortion *FPtoTP;               ///< Transformation term from
     2661    psFixedPattern *pattern;            //!< Fixed pattern residual offsets
     2662    psExposure *exp;                    ///< information about this exposure
     2663    psPhotSystem colorPlus, colorMinus; ///< Colour reference
     2664    float rmsX, rmsY;                   //!< Dispersion in astrometric solution
     2665    float chi2;                         //!< chi^2 of astrometric solution
     2666} psFPA;
     2667\end{verbatim}
     2668
     2669
     2670\subsubsection{Exposure information}
     2671
     2672We need several quantities from the telescope in order to make a
     2673first guess at the astrometric solution.  From these quantities,
     2674further quantities can be derived and stored for later use.
     2675
     2676\begin{verbatim}
     2677/** Exposure information from the telescope */
     2678typedef struct {
     2679    // Telescope longitude, latitude and height are stored separately, since they don't change with pointing
     2680    double ra, dec;                     //!< Telescope boresight
     2681    double ha;                          //!< Hour angle
     2682    double zd;                          //!< Zenith distance
     2683    double az;                          //!< Azimuth
     2684    double lst;                         //!< Local Sidereal Time
     2685    float mjd;                          //!< MJD of observation
     2686    float rotAngle;                     //!< Rotator position angle
     2687    float temp;                         //!< Air temperature, for estimating refraction
     2688    float pressure;                     //!< Air pressure, for calculating refraction
     2689    float humidity;                     //!< Relative humidity, for calculating refraction
     2690    float exptime;                      //!< Exposure time
     2691    /* Derived quantities */
     2692    float posAngle;                     //!< Position angle
     2693    float parallactic;                  //!< Parallactic angle
     2694    float airmass;                      //!< Airmass, calculated from zenith distance
     2695    float pf;                           //!< Parallactic factor
     2696    char *cameraName;                   ///< name of camera which provided exposure
     2697    char *telescopeName;                ///< name of telescope which provided exposure
     2698    psGrommit *grommit;                 //!< Data needed to convert from the sky to the tangent plane
     2699} psExposure;
     2700\end{verbatim}
     2701
     2702
     2703\subsubsection{Constructors and Destructors}
     2704
     2705Each of the above structures needs an appropriate constructor and
     2706destructor.  Other than \code{psExposure}, which contains significant
     2707non-pointer types, the constructors should not take any arguments, and
     2708the destructors should only take the structure to be destroyed.
     2709The constructor for \code{psExposure} is specified below.
     2710
     2711\begin{verbatim}
     2712/** Constructor */
     2713psExposure *
     2714psExposureAlloc(double ra, double dec,  //!< Telescope boresight
     2715                double ha,              //!< Hour angle
     2716                double zd,              //!< Zenith distance
     2717                double az,              //!< Azimuth
     2718                double lst,             //!< Local Sidereal Time
     2719                float mjd,              //!< MJD
     2720                float rotAngle,         //!< Rotator position angle
     2721                float temp,             //!< Temperature
     2722                float pressure,         //!< Pressure
     2723                float humidity,         //!< Relative humidity
     2724                float exptime           //!< Exposure time
     2725                );
     2726\end{verbatim}
     2727
     2728
     2729\subsection{Astrometry}
     2730
     2731Astrometry is a basic functionality required for the IPP that will be
     2732used repeatedly, both for low-precision (roughly where is my favourite
     2733object?) and high-precision (what is the proper motion of this star?).
     2734As such, it must be flexible, yet robust.  Accordingly, we will wrap
     2735the StarLink Astronomy Libraries (SLALib), which has already been
     2736developed.
     2737
     2738\subsubsection{Coordinate frames}
     2739\label{sec:coordinateFrames}
     2740
     2741There are five coordinate frames that we need to worry about for the
     2742purposes of astrometry:
     2743\begin{itemize}
     2744\item Cell: $(x,y)$ in pixels --- raw coordinates;
     2745\item Chip: $(X,Y)$ in pixels --- the location on the silicon;
     2746\item Focal Plane: $(p,q)$ in microns --- the location on the focal plane;
     2747\item Tangent Plane: $(l,m)$ in arcsec from the telescope boresight; and
     2748\item Sky: (RA,Dec) --- ICRS.
     2749\end{itemize}
     2750
     2751The following steps are required to convert from the cell coordinates to
     2752the sky:
     2753\begin{itemize}
     2754\item Cell $\longleftrightarrow$ Chip: two 2D polynomials, $(X,Y) = f(x,y)$;
     2755\item Chip $\longleftrightarrow$ FP: two 2D polynomials, $(p,q) = g(X,Y)$;
     2756\item FP $\longleftrightarrow$ TP: two 4D polynomials, $(l,m) =
     2757h(p,q,m,c)$, where $m$ and $c$ are the magnitude and colour of the
     2758object, respectively; and
     2759\item TP $\longleftrightarrow$ Sky: SLALib transformation using a
     2760transform pre-computed for each pointing.
     2761\end{itemize}
     2762
     2763Note that the transformation between the Focal Plane and the Tangent
     2764Plane is a four-dimensional polynomial, in order to account for any
     2765possible dependencies in the astrometry on the stellar magnitude and
     2766colour; the former serves as a check for charge transfer
     2767inefficiencies, while the latter will correct chromatic refraction,
     2768both through the atmosphere and the corrector lenses.
     2769
     2770\textbf{[If the magnitude terms serve to check CTI, then shouldn't we
     2771put them in the cell $\leftrightarrow$ chip section?]}
     2772
     2773We require structures to contain each of the above transformations as
     2774well as the pixel data.
     2775
     2776\subsubsection{SLALib information}
     2777
     2778SLALib requires several elements to perform the transformations
     2779between the tangent plane and the sky.  Pre-computing these quantities
     2780for each exposure means that subsequent transformations are faster.
     2781For historical reasons, this structure is known colloquially as
     2782``Wallace's Grommit''.
     2783
     2784\begin{verbatim}
     2785/** Information needed (by SLALib) to convert Apparent to Observed Position */
     2786typedef struct {
     2787    double latitude;                    ///< geodetic latitude (radians)
     2788    double sinLat, cosLat;              ///< sine and cosine of geodetic latitude
     2789    double abberationMag;               ///< magnitude of diurnal aberration vector
     2790    double height;                      ///< height (HM)
     2791    double temperature;                 ///< ambient temperature (TDK)
     2792    double pressure;                    ///< pressure (PMB)
     2793    double humidity;                    ///< relative humidity (RH)
     2794    double wavelength;                  ///< wavelength (WL)
     2795    double lapseRate;                   ///< lapse rate (TLR)
     2796    double refractA, refractB;          ///< refraction constants A and B (radians)
     2797    double longitudeOffset;             ///< longitude + eqn of equinoxes + ``sidereal UT'' (radians)
     2798    double siderealTime;                ///< local apparent sidereal time (radians)
     2799} psGrommit;
     2800\end{verbatim}
     2801
     2802
     2803\subsubsection{Fixed Pattern}
     2804
     2805The fixed pattern is a correction to the general astrometric solution
     2806formed by summing the residuals from many observations.  The intent is
     2807to correct for higher-order distortions in the camera system on a
     2808coarse grid (larger than individual pixels, but smaller than a single
     2809cell).  Hence, in addition to the offsets, we need to specify the size
     2810and scale of the grid in $x$ and $y$, as well as the origin of the
     2811grid.
     2812
     2813\begin{verbatim}
     2814/** The fixed pattern residual offsets.  These are specified via a coarse grid of x and y offsets. */
     2815typedef struct {
     2816    int nX, nY;                         //!< Number of elements in x and y
     2817    double x0, y0;                      //!< Position of the lower-left corner of the grid on the focal plane
     2818    double xScale, yScale;              //!< Scale of the grid
     2819    double **x, **y;                    //!< The grid of offsets in x and y
     2820} psFixedPattern;
     2821\end{verbatim}
     2822
     2823
     2824\subsubsection{Finding}
     2825
     2826We require functions to return the structure containing given
     2827coordinates.  For example, we want the chip that corresponds to the
     2828focal plane coordinates $(p,q) = (-1.234,+5.678)$.  These routines
     2829handle the one-to-many problem --- i.e., for one given focal plane
     2830coordinate, there are many chips that this coordinate may be
     2831correspond to; these functions will select the correct one.
     2832
     2833
     2834\begin{verbatim}
     2835/** returns Chip in FPA which contains the given FPA coordinate */
     2836psChip *
     2837psChipInFPA (psChip *out,               //!< Chip to return, or NULL
     2838             const psFPA *fpa,          ///< FPA description
     2839             const psCoord *coord       ///< coordinate in FPA
     2840             );
     2841\end{verbatim}
     2842
     2843\begin{verbatim}
     2844/** returns Cell in Chip which contains the given chip coordinate */
     2845psCell *
     2846psCellInChip(psCell *out,               //!< Cell to return, or NULL
     2847             const psChip *chip,        ///< chip description
     2848             const psCoord *coord       ///< coordinate in chip
     2849             );
     2850\end{verbatim}
     2851
     2852Usually we will want to go directly from the FPA to the Cell, so we
     2853also specify the following function, which performs the above two
     2854functions in order.
     2855
     2856\begin{verbatim}
     2857/** Return the cell in FPA which contains the given FPA coordinates */
     2858psCell *
     2859psCellInFPA(psCell *out,                //!< Cell to return, or NULL
     2860            const psFPA *fpa,           //!< FPA description
     2861            const psCoord *coord        //!< Coordinate in FPA
     2862            );
     2863\end{verbatim}
     2864
     2865
     2866
     2867\subsubsection{Conversion Functions}
     2868
     2869We require functions to convert between the various coordinate frames
     2870(Section~\ref{sec:coordinateFrames}).  The heirarchy of the coordinate
     2871frames and the transformations between each are shown in
     2872Figure~\ref{fig:coco}.  The functions that employ the transformations
     2873are shown in Figure~\ref{fig:cocoFunc}.  In addition to
     2874transformations between each adjoining coordinate frame in the
     2875heirarchy, we also require higher-level functions to convert between
     2876the Cell and Sky coordinate frames; these will simply perform the
     2877intermediate steps.
     2878
     2879\begin{figure}
     2880\psfig{file=coordinateFrames.ps,height=7in,angle=-90}
     2881\caption{The coordinate systems in the \PS{} IPP, and the relation
     2882between each by transformations contained in the appropriate
     2883structures.}
     2884\label{fig:coco}
     2885\end{figure}
     2886
     2887\begin{figure}
     2888\psfig{file=coordinateConv.ps,height=7in,angle=-90}
     2889\caption{Conversion between coordinate systems by PSLib.}
     2890\label{fig:cocoFunc}
     2891\end{figure}
     2892
     2893The function prototypes are:
     2894
     2895\begin{verbatim}
     2896/** Convert (RA,Dec) to cell and cell coordinates */
    29522897psCoord *
    2953 psGetOffset(const psCoord *restrict position1, //!< Position 1
    2954             const psCoord *restrict position2, //!< Position 2
    2955             const char *type            //!< Type of offset: Linear, Spherical/Arcsec, Spherical/Degreees etc
    2956     );
    2957 \end{verbatim}
    2958 
    2959 \begin{verbatim}
    2960 /** Apply an offset to a position */
     2898psCoordSkyToCell(psCoord *out,          //!< Coordinates to return, or NULL
     2899                 psCell *cell,          //!< Cell to return
     2900                 const psFPA *fpa       //!< FPA description
     2901                 );
     2902\end{verbatim}
     2903
     2904\begin{verbatim}
     2905/** Convert cell and cell coordinate to (RA,Dec) */
    29612906psCoord *
    2962 psApplyOffset(const psCoord *restrict position, //!< Position
    2963               const psCoord *restrict offset, //!< Offset
    2964               const char *type          //!< Type of offset: Linear, Spherical/Arcsec, Spherical/Degreees etc
    2965     );
    2966 \end{verbatim}
    2967 
    2968 
    2969 \subsubsection{Positions of Major SS Objects}
    2970 
    2971 We require the ability to calculate the position of major Solar System
    2972 objects, as well as Lunar phase.
    2973 
    2974 \begin{verbatim}
    2975 /** Get Sun Position */
     2907psCoordCellToSky(psCoord *out,          //!< Coordinates to return, or NULL
     2908                 const psCell *cell,    //!< Cell to get coordinates for
     2909                 const psCoord *coord   //!< cell coordinates to transform
     2910                 );
     2911\end{verbatim}
     2912
     2913\begin{verbatim}
     2914/** Quick and dirty cell to (RA,Dec) --- employs cellToSky transformation */
    29762915psCoord *
    2977 psGetSunPos(float mjd                   //!< MJD to get position for
    2978     );
    2979 \end{verbatim}
    2980 
    2981 \begin{verbatim}
    2982 /** Get Moon position */
     2916psCoordCellToSkyQuick(psCoord *out,     //!< Coordinates to return, or NULL
     2917                      const psCell *cell, //!< Cell description
     2918                      const psCoord *coord //!< cell coordinates to transform
     2919                      );
     2920\end{verbatim}
     2921
     2922\begin{verbatim}
     2923/** Convert (RA,Dec) to tangent plane coords */
    29832924psCoord *
    2984 psGetMoonPos(float mjd,                 //!< MJD to get position for
    2985              double latitude,           //!< Latitude for apparent position
    2986              double longitude           //!< Longitude for apparent position
    2987     );
    2988 \end{verbatim}
    2989 
    2990 \begin{verbatim}
    2991 /** Get Moon phase */
     2925psCoordSkyToTP(psCoord *out,            //!< Coordinates to return, or NULL
     2926               const psExposure *exp,   //!< Exposure description
     2927               const psCoord *coord     //!< input Sky coordinate
     2928               );
     2929\end{verbatim}
     2930
     2931\begin{verbatim}
     2932/** Convert tangent plane coords to focal plane coordinates */
     2933psCoord *
     2934psCoordTPtoFPA(psCoord *out,            //!< Coordinates to return, or NULL
     2935               const psFPA *fpa,        //!< FPA description
     2936               const psCoord *coord     //!< input TP coordinate
     2937               );
     2938\end{verbatim}
     2939
     2940\begin{verbatim}
     2941/** converts the specified FPA coord to the coord on the given Chip */
     2942psCoord *
     2943psCoordFPAtoChip (psCoord *out,         //!< Coordinates to return, or NULL
     2944                  const psChip *chip,   ///< Chip of interest
     2945                  const psCoord *coord  ///< input FPA coordinate
     2946                  );
     2947\end{verbatim}
     2948
     2949\begin{verbatim}
     2950/** converts the specified Chip coord to the coord on the given Cell */
     2951psCoord *
     2952psCoordChiptoCell (psCoord *out,        //!< Coordinates to return, or NULL
     2953                   const psCell *cell,  ///< Cell of interest
     2954                   const psCoord *coord ///< input Chip coordinate
     2955                   );
     2956\end{verbatim}
     2957
     2958\begin{verbatim}
     2959/** converts the specified Cell coord to the coord on the parent Chip */
     2960psCoord *
     2961psCoordCelltoChip (psCoord *out,        //!< Coordinates to return, or NULL
     2962                   const psCell *cell,  ///< Cell description
     2963                   const psCoord *coord ///< input Cell coordinate
     2964                   );
     2965\end{verbatim}
     2966
     2967\begin{verbatim}
     2968/** converts the specified Chip coord to the coord on the parent FPA */
     2969psCoord *
     2970psCoordChiptoFPA (psCoord *out,         //!< Coordinates to return, or NULL
     2971                  const psChip *chip,   ///< Chip description
     2972                  const psCoord *coord  ///< input Chip coordinate
     2973                  );
     2974\end{verbatim}
     2975
     2976\begin{verbatim}
     2977/** Convert focal plane coords to tangent plane coordinates */
     2978psCoord *
     2979psCoordFPAToTP(psCoord *out,            //!< Coordinates to return, or NULL
     2980               const psFPA *fpa,        //!< FPA description
     2981               const psCoord *coord     //!< input FPA coordinate
     2982               );
     2983\end{verbatim}
     2984
     2985\begin{verbatim}
     2986/** Convert tangent plane coords to (RA,Dec) */
     2987psCoord *
     2988psCoordTPtoSky(psCoord *out,            //!< Coordinates to return, or NULL
     2989               const psExposure *exp,   //!< Exposure description
     2990               const psCoord *coord     //!< input TP coordinate
     2991               );
     2992\end{verbatim}
     2993
     2994\begin{verbatim}
     2995/** Convert Cell coords to FPA coordinates */
     2996psCoord *
     2997psCoordCellToFPA(psCoord *out,          //!< Coordinates to return, or NULL
     2998                 const psCell *cell,    //!< Cell description
     2999                 const psCoord *coord   //!< Input cell coordinates
     3000                 );
     3001\end{verbatim}
     3002
     3003\subsubsection{Additional functions}
     3004
     3005We require additional functions to perform general functions which
     3006will be useful for astrometry.  Given coordinates on the sky, we
     3007need to get the airmass, the parallactic angle, and an estimate of
     3008the atmospheric refraction.
     3009
     3010\begin{verbatim}
     3011/** Get the airmass for a given position and sidereal time */
    29923012float
    2993 psGetMoonPhase(float mjd                //!< MJD to get phase for
    2994     );
    2995 \end{verbatim}
    2996 
    2997 \begin{verbatim}
    2998 /** Get Planet positions */
    2999 psCoord *
    3000 psGetSolarSystemPos(const char *solarSystemObject, //!< Named S.S. object
    3001                     float mjd           //!< MJD to get position for
    3002     );
    3003 \end{verbatim}
    3004 
    3005 \subsubsection{Celestial Coordinate Conversions}
    3006 
    3007 We need to be able to convert between ICRS, Galactic and Ecliptic
    3008 coordinates.
    3009 
    3010 \begin{verbatim}
    3011 /** Convert ICRS to Ecliptic */
    3012 psCoord *
    3013 psCoordinatesItoE(const psCoord *restrict coordinates //!< ICRS coordinates to convert
    3014     );
    3015 \end{verbatim}
    3016 
    3017 \begin{verbatim}
    3018 /** Convert Ecliptic to ICRS */
    3019 psCoord *
    3020 psCoordinatesEtoI(const psCoord *restrict coordinates //!< Ecliptic coordinates to convert
    3021     );
    3022 \end{verbatim}
    3023 
    3024 \begin{verbatim}
    3025 /** Convert ICRS to Galactic */
    3026 psCoord *
    3027 psCoordinatesItoG(const psCoord *restrict coordinates //!< ICRS coordinates to convert
    3028     );
    3029 \end{verbatim}
    3030 
    3031 \begin{verbatim}
    3032 /** Convert Galactic to ICRS */
    3033 psCoord *
    3034 psCoordinatesGtoI(const psCoord *restrict coordinates //!< Galactic coordinates to convert
    3035     );
    3036 \end{verbatim}
    3037 
     3013psGetAirmass(const psCoord *coord,      //!< Position on the sky
     3014             double siderealTime,       //!< Sidereal time
     3015             float height               //!< Height above sea level
     3016             );
     3017\end{verbatim}
     3018
     3019\begin{verbatim}
     3020/** Get the parallactic angle for a given position and sidereal time */
     3021float
     3022psGetParallactic(const psCoord *coord,  //!< Position on the sky
     3023                 double siderealTime    //!< Sidereal time
     3024                 );
     3025\end{verbatim}
     3026
     3027\begin{verbatim}
     3028/** Estimate atmospheric refraction, along the parallactic */
     3029float
     3030psGetRefraction(float colour,           //!< Colour of object
     3031                psPhotSystem colorPlus, ///< Colour reference
     3032                psPhotSystem colorMinus, ///< Colour reference
     3033                const psExposure *exp   //!< Telescope pointing information, for airmass, temp and pressure
     3034                );
     3035\end{verbatim}
     3036
     3037\begin{verbatim}
     3038/** Calculate the parallax factor */
     3039double
     3040psGetParallaxFactor(const psExposure *exp //!< Exposure details
     3041    );
     3042\end{verbatim}
    30383043
    30393044%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    3040 \subsection{Astronomical objects}
    3041 
    3042 \textbf{[Deferred.]}
    3043 
    3044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     3045
    30453046\subsection{Photometry}
    30463047
     
    31133114%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    31143115
     3116\subsection{Astronomical objects}
     3117
     3118\textbf{[Deferred.]}
     3119
     3120%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     3121
    31153122\appendix
    31163123
     
    31293136\input{psAstroGroup.tex}
    31303137
     3138\section{API Summary: all structures}
     3139\input{psStructures.tex}
     3140
    31313141\bibliographystyle{plain} \bibliography{panstarrs}
    31323142
Note: See TracChangeset for help on using the changeset viewer.