Changeset 309
- Timestamp:
- Mar 26, 2004, 4:11:28 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/doc/pslib/psLibSDRS.tex (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/doc/pslib/psLibSDRS.tex
r300 r309 1 %%% $Id: psLibSDRS.tex,v 1.1 1 2004-03-24 03:42:51 price Exp $1 %%% $Id: psLibSDRS.tex,v 1.12 2004-03-27 02:11:28 eugene Exp $ 2 2 \documentclass[panstarrs]{panstarrs} 3 3 %\documentclass[panstarrs]{panstarrs} … … 708 708 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 709 709 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 716 void 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 722 void 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 728 char *psStringCopy(const char *str ///< string to copy 729 ); 730 731 /// Allocates nChar and returns a copy of the string or segment 732 char *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}, 738 and then call \code{abort}. 739 \code{psError} shall call \code{psMsgLog} with a level of \code{PS_LOG_ERROR}, 740 and then return. 741 In 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} 711 751 712 752 We require general data containers, so that associated values (e.g.\ … … 719 759 \end{itemize} 720 760 721 \subsection{The Pan-STARRS \texttt{psDlist} doubly-linked list type} 761 \subsection{Simple Array types} 762 763 \subsubsection{Arrays of Simple Types} 764 765 Any \PS{} datatype \code{psType} may be associated with an array type 766 \code{psTypeArray}: 767 \begin{verbatim} 768 typedef struct { 769 int size; 770 int n; 771 psType *arr; 772 } psTypeArray; 773 \end{verbatim} 774 with associated constructors and a destructor: 775 \begin{verbatim} 776 psTypeArray *psTypeAlloc(int n, int size); 777 psTypeArray *psTypeRealloc(psTypeArray *arr, int n); 778 void psTypeFree(psTypeArray *arr); 779 \end{verbatim} 780 781 The argument \code{n} is the dimension of the array; \code{size} 782 is the number of elements allocated ($s \ge n$). 783 784 This 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 788 use in a header file); the latter generates the code for the three 789 functions \code{psType(Alloc|Realloc|Free)} (and should thus appear in 790 exactly one source file for a given type). 791 792 The \code{psType} should be a single word (e.g. \code{psXY}); in particular, 793 there is no requirement to support a pointer type (\eg{} \code{psXY *}); 794 see next section. 795 796 \subsubsection{Arrays of Pointer Types} 797 798 The data type created with \code{PS_CREATE_ARRAY_TYPE} (\code{psType}) 799 contains an array of \code{psType}s not 800 pointers to \code{psType}s; this means that the individual elements are 801 not allocated using \code{psTypeAlloc}, are not correctly initialized, 802 and shouldn't be individually deleted with \code{psTypeFree}; 803 804 If 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 807 create types \code{typedef psType *psTypePtr} and \code{psTypePtrArray}: 808 \begin{verbatim} 809 typedef struct { 810 int size; 811 int n; 812 psTypePtr *arr; 813 } psTypePtrArray; 814 \end{verbatim} 815 with associated constructors and a destructor: 816 \begin{verbatim} 817 psTypePtrArray *psTypePtrAlloc(int n, int size); 818 psTypePtrArray *psTypePtrRealloc(psTypePtrArray *arr, int n); 819 void psTypePtrArrayFree(psTypePtrArray *arr); 820 \end{verbatim} 821 822 These constructors create arrays of \code{psType *} and call 823 \code{psTypeAlloc} and \code{psTypeFree} to allocate and free the 824 elements. As for the simple arrays, The former defines the typedef and 825 declares the prototypes (and is thus suitable for use in a header 826 file) and the latter generates the code for the three functions 827 \code{psType(Alloc|Realloc|Free)} (and should thus appear in exactly one 828 source file for a given type). 829 830 The objects pointed to by these types have had their \code{refCounter}s 831 incremented (see \ref{secMemRefcounter}); to remove an element from the array you 832 need 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 842 Arrays of \code{void *} are different, as they need an explicitly-specified 843 destructor. 844 845 We require a type \code{psVoidPtrArray} that behaves in all respects 846 as if it had been created with: 847 \begin{verbatim} 848 typedef void *psVoidPtr; 849 PS_DECLARE_ARRAY_TYPE(psVoidPtr); 850 PS_CREATE_ARRAY_TYPE(psVoidPtr); 851 \end{verbatim} 852 except that its destructor is specified as: 853 \begin{verbatim} 854 void psVoidPtrArrayFree(psVoidPtrArray *arr, // array to destroy 855 void (*elemFree)(void *)); // destructor for array data 856 \end{verbatim} 857 858 The routine \code{psVoidPtrArrayFree} assumes that all pointers 859 had their reference counters incremented 860 when they were inserted onto the array.\footnote{% 861 \eg{} \code{va->arr[i] = psMemIncrRefCounter(ptr);}} 862 863 If \code{psVoidPtrArrayFree}'s argument \code{elemFree} is NULL, the 864 list 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 869 The following is a complete C program that illustrates the use of 870 \code{array}s. 871 \begin{verbatim} 872 #include "psLib.h" 873 874 typedef struct { 875 int x, y; 876 } psXY; 877 878 psXY *psXYAlloc(void) 879 { 880 return psAlloc(sizeof(psXY)); 881 } 882 883 void psXYFree(psXY *xy) 884 { 885 psFree(xy); 886 } 887 888 PS_DECLARE_ARRAY_TYPE(psXY); 889 PS_CREATE_ARRAY_TYPE(psXY); 890 891 PS_DECLARE_ARRAY_PTR_TYPE(psXY); 892 PS_CREATE_ARRAY_PTR_TYPE(psXY); 893 894 int 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} 722 927 \hlabel{psDlist} 723 928 … … 843 1048 \code{psDlist}). 844 1049 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 type850 \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)} and870 \code{PS_CREATE_ARRAY_TYPE(psType)}. The former defines the871 \code{typedef} and declares the prototypes (and is thus suitable for872 use in a header file); the latter generates the code for the three873 functions \code{psType(Alloc|Realloc|Free)} (and should thus appear in874 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 not884 pointers to \code{psType}s; this means that the individual elements are885 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 macros889 \code{PS_DECLARE_ARRAY_PTR_TYPE(psType)} and890 \code{PS_CREATE_ARRAY_PTR_TYPE(psType)}. These891 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 call907 \code{psTypeAlloc} and \code{psTypeFree} to allocate and free the908 elements. As for the simple arrays, The former defines the typedef and909 declares the prototypes (and is thus suitable for use in a header910 file) and the latter generates the code for the three functions911 \code{psType(Alloc|Realloc|Free)} (and should thus appear in exactly one912 source file for a given type).913 914 The objects pointed to by these types have had their \code{refCounter}s915 incremented (see \ref{secMemRefcounter}); to remove an element from the array you916 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-specified927 destructor.928 929 We require a type \code{psVoidPtrArray} that behaves in all respects930 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 destroy939 void (*elemFree)(void *)); // destructor for array data940 \end{verbatim}941 942 The routine \code{psVoidPtrArrayFree} assumes that all pointers943 had their reference counters incremented944 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, the948 list should be deleted, but not the elements on it (although their949 \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 of954 \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 1010 1050 \subsection{Hash Tables} 1011 1051 \hlabel{psHash} … … 1069 1109 key from the table, and returns the \code{data}; if the key's invalid it returns NULL. 1070 1110 1071 \subsection{Miscellaneous Utilities}1072 1073 \begin{verbatim}1074 #define PS_STRING(S) #S // converts argument S to string1075 1076 /// Prints an error message and aborts1077 void psAbort(const char *name, ///< Category of code that caused the abort1078 const char *fmt, ///< Format1079 ... ///< Extra arguments to use format1080 );1081 1082 /// Prints an error message and doesn't abort1083 void psError(const char *name, ///< Category of code that caused the abort1084 const char *fmt, ///< Format1085 ... ///< Extra arguments to use format1086 );1087 1088 /// Allocates and returns a copy of a string1089 char *psStringCopy(const char *str ///< string to copy1090 );1091 1092 /// Allocates nChar and returns a copy of the string or segment1093 char *psStringNCopy(const char *str, ///< string to copy1094 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 for1103 \code{name} is \code{__func__}.1104 1105 \code{psStringCopy} shall allocate and return a copy of the input string.1106 1107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%1108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%1109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%1110 1111 1111 \section{Data manipulation} 1112 1112 1113 We require general data manipulation functions, which will act upon 1114 data (in particular, arrays/vectors). We require the following capabilities: 1113 There are a number of data concepts which can be naturally represented 1114 in C as structures. We require a variety of basic data manipulation 1115 functions which will act upon data (in particular, arrays/vectors). 1116 We require the following capabilities: 1115 1117 \begin{itemize} 1116 1118 \item Bit masks; … … 1186 1188 ); 1187 1189 \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 and1194 images, e.g.\ dividing one image by another, subtracting a vector1195 from an image, etc. Both binary operations and unary operations are1196 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 input1204 char *operator, ///< operator1205 void *in2 ///< second input1206 );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, ///< input1215 char *operator, ///< operator1216 );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} and1221 \code{psImage} and \code{psScalar}). It is expected that the1222 implementation of these functions will employ pre-processor macros to1223 perform the onerous task of creating the loops.1224 1225 It is desirable to use the same functions for both vectors and1226 images, so inputs are \code{void*}; this necessitates that vectors1227 and images each have a type element at a pre-determined and constant1228 location in the \code{struct}. It is further desirable to allow1229 scalar values to be used within these functions, which requires the1230 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 description1242 ... ///< value (or values) of specified types1243 );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 information1250 union {1251 int i; ///< integer value entry1252 float f; ///< float value entry1253 double d; ///< double value entry1254 complex float c; ///< complex value entry1255 } val;1256 } p_psScalar;1257 \end{verbatim}1258 1259 This allows one to write the following to take the sine of the square1260 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.1269 1190 1270 1191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% … … 1546 1467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1547 1468 1548 \subsection{ General functions}1469 \subsection{Analytical functions} 1549 1470 1550 1471 We require two types of general functions which will be used in fitting: … … 1637 1558 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1638 1559 1639 \subsection{Minimi sation and fitting routines}1560 \subsection{Minimization and fitting routines} 1640 1561 1641 1562 We require a general minimisation routine, a routine that will … … 1678 1599 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1679 1600 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} 1702 1602 1703 1603 The most important data product produced by the telescope is an image. … … 2118 2018 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2119 2019 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 2022 We will need to be able to perform various operations on vectors and 2023 images, e.g.\ dividing one image by another, subtracting a vector 2024 from an image, etc. Both binary operations and unary operations are 2025 required. 2026 2027 \begin{verbatim} 2028 /** Perform a binary operation on two data items (psImage, psVector, psScalar). 2029 */ 2030 psType * 2031 psBinaryOp (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 */ 2041 psType * 2042 psUnaryOp (void *out, ///< destination (may be NULL) 2043 void *in, ///< input 2044 char *operator, ///< operator 2045 ); 2046 \end{verbatim} 2047 2048 Note that these functions should return the appropriate type (i.e., 2049 the \code{psType} return type refers to \code{psVector} and 2050 \code{psImage} and \code{psScalar}). It is expected that the 2051 implementation of these functions will employ pre-processor macros to 2052 perform the onerous task of creating the loops. 2053 2054 It is desirable to use the same functions for both vectors and 2055 images, so inputs are \code{void*}; this necessitates that vectors 2056 and images each have a type element at a pre-determined and constant 2057 location in the \code{struct}. It is further desirable to allow 2058 scalar values to be used within these functions, which requires the 2059 following additions: 2060 2061 \begin{verbatim} 2062 /** create a psType-ed structure from a constant value. */ 2063 p_ps_Scalar * 2064 psScalar (double value); 2065 \end{verbatim} 2066 2067 \begin{verbatim} 2068 /** create a psType-ed structure from a specified type */ 2069 p_ps_Scalar * 2070 psScalarType (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. */ 2077 typedef 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 2088 This allows one to write the following to take the sine of the square 2089 of all pixels in an image: 2090 \begin{verbatim} 2091 psImage A,B; 2092 2093 B = psBinaryOp (NULL, A, "^", psScalar(2)); 2094 (void) psUnaryOp(B, B, "sin"); 2095 \end{verbatim} 2096 2097 Note that the \code{psUnaryOp} is performed on \code{B} in-place. 2098 2099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2100 2101 \section{Astronomy-Specific Functions} 2102 2103 Some basic, relatively simple astronomy-specific functions are 2104 required which will serve as the foundation for building the Phase $N$ 2105 modules. These functions are not expected to cover every forseeable 2106 function, but will serve as the building blocks of more complicated 2107 processing functions. 2108 2109 We require functions covering each of the following areas: 2163 2110 \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. 2169 2118 \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. 2119 These 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 2131 Both detector and sky positions will be used extensively in the IPP. 2132 Since these both contain two coordinates with their associated errors, 2133 we bundle these into a single generic structure, \code{psCoord}, 2134 containing \code{union}s to handle the semantic differences. 2135 2136 \begin{verbatim} 2137 /** A point in 2-D space, with errors. 2138 */ 2139 typedef 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 2157 We specify two types of transforms between coordinate systems. The 2158 first consists simply of two 2D polynomials to transform both 2159 components; this will be used to apply the coordinate transformations 2160 between Cells, Chips and the Focal Plane. The second consists of two 2161 4D polynomials; this will be used to apply position-, colour- and 2162 magnitude-dependent distortions between the Focal Plane and the 2163 Tangent 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. 2236 2168 */ 2237 2169 typedef 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. 2266 2178 */ 2267 2179 typedef 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 2185 We require corresponding functions to apply the transformations: 2186 2187 \begin{verbatim} 2188 /** apply the coordinate transformation to the given coordinate */ 2189 psCoord *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 */ 2197 psCoord *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 2208 We require a function to calculate the offset between two positions on 2209 the 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 */ 2499 2213 psCoord * 2500 ps CoordSkyToCell(psCoord *out, //!< Coordinates to return, or NULL2501 psCell *cell, //!< Cell to return2502 const psFPA *fpa //!< FPA description2503 );2504 \end{verbatim} 2505 2506 \begin{verbatim} 2507 /** Convert cell and cell coordinate to (RA,Dec)*/2214 psGetOffset(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 */ 2508 2222 psCoord * 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 */ 2223 psApplyOffset(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 2232 We require the ability to calculate the position of major Solar System 2233 objects, as well as Lunar phase. 2234 2235 \begin{verbatim} 2236 /** Get Sun Position */ 2517 2237 psCoord * 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 */ 2238 psGetSunPos(float mjd //!< MJD to get position for 2239 ); 2240 \end{verbatim} 2241 2242 \begin{verbatim} 2243 /** Get Moon position */ 2526 2244 psCoord * 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 */ 2245 psGetMoonPos(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 */ 2253 float 2254 psGetMoonPhase(float mjd //!< MJD to get phase for 2255 ); 2256 \end{verbatim} 2257 2258 \begin{verbatim} 2259 /** Get Planet positions */ 2535 2260 psCoord * 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 */ 2261 psGetSolarSystemPos(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 2268 We need to be able to convert between ICRS, Galactic and Ecliptic 2269 coordinates. 2270 2271 \begin{verbatim} 2272 /** Convert ICRS to Ecliptic */ 2544 2273 psCoord * 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 */ 2274 psCoordinatesItoE(const psCoord *restrict coordinates //!< ICRS coordinates to convert 2275 ); 2276 \end{verbatim} 2277 2278 \begin{verbatim} 2279 /** Convert Ecliptic to ICRS */ 2553 2280 psCoord * 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 */ 2281 psCoordinatesEtoI(const psCoord *restrict coordinates //!< Ecliptic coordinates to convert 2282 ); 2283 \end{verbatim} 2284 2285 \begin{verbatim} 2286 /** Convert ICRS to Galactic */ 2562 2287 psCoord * 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 */ 2288 psCoordinatesItoG(const psCoord *restrict coordinates //!< ICRS coordinates to convert 2289 ); 2290 \end{verbatim} 2291 2292 \begin{verbatim} 2293 /** Convert Galactic to ICRS */ 2571 2294 psCoord * 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.]} 2295 psCoordinatesGtoI(const psCoord *restrict coordinates //!< Galactic coordinates to convert 2296 ); 2297 \end{verbatim} 2298 2651 2299 2652 2300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% … … 2866 2514 \end{verbatim} 2867 2515 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 2520 Some brief review of terminology would be useful so that previous 2521 definitions do not influence the understanding of this document. 2522 2523 A ``readout'' is a read of the detector. 2524 2525 A ``cell'' is defined as the smallest element of the detector readout; 2526 usually associated with an amplifier. Correspondingly, each cell has 2527 its own overscan region. There may be multiple readouts in a cell if 2528 the cell was used to provide fast guiding. 2529 2530 A ``chip'' is defined as a contiguous piece of silicon, and consists 2531 of a group of cells. 2532 2533 A ``focal plane'' is defined as a mosaic of chips, and consists of a 2534 group of chips. 2535 2536 For example, take a mosaic camera consisting of eight $2k\times 4k$ 2537 CCDs, each of which is read out through two amplifiers. Then there 2538 would be sixteen cells in total, each of which is presumably $2k\times 2539 2k$. There would be eight chips, each consisting of two cells, and 2540 the focal plane consists of these eight chips. 2541 2542 As another example, consider an observation by PS1. The focal plane 2543 would consist of 60 chips, each of which consist of 64 cells (or less; 2544 a few cells may be dead). Some cells (those containing guide stars 2545 for the orthogonal transfer) will contain multiple readouts. 2546 2547 \subsubsection{A Readout} 2548 2549 A readout is the result of a single read of a cell (or a portion 2550 thereof). It contains a pointer to the pixel data, a separate pointer 2551 to the overscan pixels, and additional pointers to the objects found 2552 in the readout, and the readout metadata. It also contains the offset 2553 from the lower-left corner of the chip, in the case that the CCD was 2554 windowed. 2555 2556 \begin{verbatim} 2557 /** a Readout: a collection of pixels */ 2558 typedef 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 2570 A cell consists of one or more readouts (usually only one except in the 2571 case that the cell has been used for fast guiding). It also contains 2572 a pointer to the cell metadata, and a pointer to its parent chip. On 2573 the astrometry side, it also contains coordinate transforms from the 2574 cell to the chip and, as a convenience, from the cell to the focal 2575 plane. It is expected that these transforms will consist of two 2576 first-order 2D polynomials, simply specifying a translation, rotation 2577 and magnification; hence they are easily inverted, and there is no 2578 need to add reverse transformations. We also add an additional 2579 transformation, which is intended to provide a ``quick and dirty'' 2580 transform from the cell coordinates to the sky; this transformation 2581 not guaranteed to be as precise as the ``standard'' transformation of 2582 Cell $\rightarrow$ Chip $\rightarrow$ Focal Plane $\rightarrow$ 2583 Tangent Plane $\rightarrow$ Sky, but will be faster. 2584 2585 \begin{verbatim} 2586 /** a Cell: a collection of readouts. 2907 2587 */ 2908 2588 typedef 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 2605 A chip consists of one or more cells (according to the number of 2606 amplifiers on the CCD). It contains a pointer to the chip metadata, 2607 and a pointer to the parent focal plane. For astrometry, it contains 2608 a coordinate transform from the chip to the focal plane. It is 2609 expected that this transforms will consist of two second-order 2D 2610 polynomials; hence we expect that it is prudent to include a reverse 2611 transformation which will be derived from numerically inverting the 2612 forward 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. 2917 2617 */ 2918 2618 typedef 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 2632 A focal plane consists of one or more chips (according to the number 2633 of pieces of contiguous silicon). It contains pointers to the focal 2634 plane metadata and the exposure information. For astrometry, it 2635 contains a transformation from the focal plane to the tangent plane 2636 and the fixed pattern residuals. It is expected that the 2637 transformation will consist of two 4D polynomials (i.e.\ a function of 2638 two coordinates in position, the magnitude of the object, and the 2639 colour of the object) in order to correct for optical distortions and 2640 the effects of the atmosphere; hence we expect that it is prudent to 2641 include a reverse transformation which will be derived from 2642 numerically inverting the forward transformation. Since colours are 2643 involved in the transformation, it is necessary to specify the colour 2644 the transformation is defined for. We also include some values to 2645 characterise the quality of the transformation: the root mean square 2646 deviation for the x and y transformation fits, and the $\chi^2$ for 2647 the 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 */ 2653 typedef 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 2672 We need several quantities from the telescope in order to make a 2673 first guess at the astrometric solution. From these quantities, 2674 further quantities can be derived and stored for later use. 2675 2676 \begin{verbatim} 2677 /** Exposure information from the telescope */ 2678 typedef 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 2705 Each of the above structures needs an appropriate constructor and 2706 destructor. Other than \code{psExposure}, which contains significant 2707 non-pointer types, the constructors should not take any arguments, and 2708 the destructors should only take the structure to be destroyed. 2709 The constructor for \code{psExposure} is specified below. 2710 2711 \begin{verbatim} 2712 /** Constructor */ 2713 psExposure * 2714 psExposureAlloc(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 2731 Astrometry is a basic functionality required for the IPP that will be 2732 used repeatedly, both for low-precision (roughly where is my favourite 2733 object?) and high-precision (what is the proper motion of this star?). 2734 As such, it must be flexible, yet robust. Accordingly, we will wrap 2735 the StarLink Astronomy Libraries (SLALib), which has already been 2736 developed. 2737 2738 \subsubsection{Coordinate frames} 2739 \label{sec:coordinateFrames} 2740 2741 There are five coordinate frames that we need to worry about for the 2742 purposes 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 2751 The following steps are required to convert from the cell coordinates to 2752 the 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) = 2757 h(p,q,m,c)$, where $m$ and $c$ are the magnitude and colour of the 2758 object, respectively; and 2759 \item TP $\longleftrightarrow$ Sky: SLALib transformation using a 2760 transform pre-computed for each pointing. 2761 \end{itemize} 2762 2763 Note that the transformation between the Focal Plane and the Tangent 2764 Plane is a four-dimensional polynomial, in order to account for any 2765 possible dependencies in the astrometry on the stellar magnitude and 2766 colour; the former serves as a check for charge transfer 2767 inefficiencies, while the latter will correct chromatic refraction, 2768 both through the atmosphere and the corrector lenses. 2769 2770 \textbf{[If the magnitude terms serve to check CTI, then shouldn't we 2771 put them in the cell $\leftrightarrow$ chip section?]} 2772 2773 We require structures to contain each of the above transformations as 2774 well as the pixel data. 2775 2776 \subsubsection{SLALib information} 2777 2778 SLALib requires several elements to perform the transformations 2779 between the tangent plane and the sky. Pre-computing these quantities 2780 for each exposure means that subsequent transformations are faster. 2781 For 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 */ 2786 typedef 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 2805 The fixed pattern is a correction to the general astrometric solution 2806 formed by summing the residuals from many observations. The intent is 2807 to correct for higher-order distortions in the camera system on a 2808 coarse grid (larger than individual pixels, but smaller than a single 2809 cell). Hence, in addition to the offsets, we need to specify the size 2810 and scale of the grid in $x$ and $y$, as well as the origin of the 2811 grid. 2812 2813 \begin{verbatim} 2814 /** The fixed pattern residual offsets. These are specified via a coarse grid of x and y offsets. */ 2815 typedef 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 2826 We require functions to return the structure containing given 2827 coordinates. For example, we want the chip that corresponds to the 2828 focal plane coordinates $(p,q) = (-1.234,+5.678)$. These routines 2829 handle the one-to-many problem --- i.e., for one given focal plane 2830 coordinate, there are many chips that this coordinate may be 2831 correspond to; these functions will select the correct one. 2832 2833 2834 \begin{verbatim} 2835 /** returns Chip in FPA which contains the given FPA coordinate */ 2836 psChip * 2837 psChipInFPA (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 */ 2845 psCell * 2846 psCellInChip(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 2852 Usually we will want to go directly from the FPA to the Cell, so we 2853 also specify the following function, which performs the above two 2854 functions in order. 2855 2856 \begin{verbatim} 2857 /** Return the cell in FPA which contains the given FPA coordinates */ 2858 psCell * 2859 psCellInFPA(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 2869 We require functions to convert between the various coordinate frames 2870 (Section~\ref{sec:coordinateFrames}). The heirarchy of the coordinate 2871 frames and the transformations between each are shown in 2872 Figure~\ref{fig:coco}. The functions that employ the transformations 2873 are shown in Figure~\ref{fig:cocoFunc}. In addition to 2874 transformations between each adjoining coordinate frame in the 2875 heirarchy, we also require higher-level functions to convert between 2876 the Cell and Sky coordinate frames; these will simply perform the 2877 intermediate 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 2882 between each by transformations contained in the appropriate 2883 structures.} 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 2893 The function prototypes are: 2894 2895 \begin{verbatim} 2896 /** Convert (RA,Dec) to cell and cell coordinates */ 2952 2897 psCoord * 2953 ps GetOffset(const psCoord *restrict position1, //!< Position 12954 const psCoord *restrict position2, //!< Position 22955 const char *type //!< Type of offset: Linear, Spherical/Arcsec, Spherical/Degreees etc2956 );2957 \end{verbatim} 2958 2959 \begin{verbatim} 2960 /** Apply an offset to a position*/2898 psCoordSkyToCell(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) */ 2961 2906 psCoord * 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 */ 2907 psCoordCellToSky(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 */ 2976 2915 psCoord * 2977 psGetSunPos(float mjd //!< MJD to get position for 2978 ); 2979 \end{verbatim} 2980 2981 \begin{verbatim} 2982 /** Get Moon position */ 2916 psCoordCellToSkyQuick(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 */ 2983 2924 psCoord * 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 */ 2925 psCoordSkyToTP(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 */ 2933 psCoord * 2934 psCoordTPtoFPA(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 */ 2942 psCoord * 2943 psCoordFPAtoChip (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 */ 2951 psCoord * 2952 psCoordChiptoCell (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 */ 2960 psCoord * 2961 psCoordCelltoChip (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 */ 2969 psCoord * 2970 psCoordChiptoFPA (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 */ 2978 psCoord * 2979 psCoordFPAToTP(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) */ 2987 psCoord * 2988 psCoordTPtoSky(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 */ 2996 psCoord * 2997 psCoordCellToFPA(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 3005 We require additional functions to perform general functions which 3006 will be useful for astrometry. Given coordinates on the sky, we 3007 need to get the airmass, the parallactic angle, and an estimate of 3008 the atmospheric refraction. 3009 3010 \begin{verbatim} 3011 /** Get the airmass for a given position and sidereal time */ 2992 3012 float 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 3013 psGetAirmass(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 */ 3021 float 3022 psGetParallactic(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 */ 3029 float 3030 psGetRefraction(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 */ 3039 double 3040 psGetParallaxFactor(const psExposure *exp //!< Exposure details 3041 ); 3042 \end{verbatim} 3038 3043 3039 3044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3040 \subsection{Astronomical objects} 3041 3042 \textbf{[Deferred.]} 3043 3044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3045 3045 3046 \subsection{Photometry} 3046 3047 … … 3113 3114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3114 3115 3116 \subsection{Astronomical objects} 3117 3118 \textbf{[Deferred.]} 3119 3120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3121 3115 3122 \appendix 3116 3123 … … 3129 3136 \input{psAstroGroup.tex} 3130 3137 3138 \section{API Summary: all structures} 3139 \input{psStructures.tex} 3140 3131 3141 \bibliographystyle{plain} \bibliography{panstarrs} 3132 3142
Note:
See TracChangeset
for help on using the changeset viewer.
