IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 30, 2005, 11:14:48 AM (21 years ago)
Author:
eugene
Message:

serious reorg for release 13

File:
1 edited

Legend:

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

    r3537 r3564  
    1 %%% $Id: psLibSDRS.tex,v 1.191 2005-03-29 03:42:21 price Exp $
     1%%% $Id: psLibSDRS.tex,v 1.192 2005-03-30 21:14:48 eugene Exp $
    22\documentclass[panstarrs,spec]{panstarrs}
    33
     
    1111\project{Pan-STARRS Image Processing Pipeline}
    1212\organization{Institute for Astronomy}
    13 \version{12}
     13\version{13}
    1414\docnumber{PSDC-430-007}
    1515
     16% \setcounter{tocdepth}{5} % lowest level to be included in toc
    1617\setlength{\topsep}{-2pt}
    1718 
     
    137138\href{heasarc.gsfc.nasa.gov/docs/software/fitsio}{\tt heasarc.gsfc.nasa.gov/docs/software/fitsio}
    138139
    139 \item \tbd{SLALIB support is likely to be dropped} Many of the
    140 astronomy routines will wrap the StarLink Positional Astronomy
    141 libraries (SLALib):
     140\item the StarLink Positional Astronomy libraries (SLALib) are a
     141  useful reference:
    142142
    143143\href{star-www.rl.ac.uk/star/docs/sun67.htx/sun67.html}{\tt
     
    183183%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    184184
     185\pagebreak
    185186\section{System Utilities}
    186187
     
    11931194%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    11941195
     1196\pagebreak
    11951197\section{Basic Data Types and Collections}
    11961198
     
    18941896%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    18951897
     1898\pagebreak
    18961899\section{Data manipulation}
    18971900
     
    30283031%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    30293032
     3033\subsection{Image Pixel Lists}
     3034
     3035Usually an image mask is the best way to carry information about what
     3036pixels mean what.  However, in the case where the number of pixels in
     3037which we are interested is limited, it is more efficient to simply
     3038carry a list of pixels.  An example of this is in the image
     3039combination code, where we want to perform an operation on a
     3040relatively small fraction of pixels, and it is inefficient to go
     3041through an entire mask image checking each pixel.
     3042
     3043\begin{verbatim}
     3044typedef struct {
     3045    psVector *x;                        // x coordinate
     3046    psVector *y;                        // y coordinate
     3047} psPixels;
     3048\end{verbatim}
     3049
     3050Of course, the size of each of the vectors should match.  In the event
     3051that they do not match, any function which detects the problem shall
     3052generate a warning and use the size of the shorter of the vectors as
     3053the size.  The order in which the pixels are kept is not considered
     3054important.
     3055
     3056\begin{verbatim}
     3057psImage *psPixelsToMask(psImage *out, const psPixels *pixels, const psRegion *region, unsigned int maskVal);
     3058psPixels *psMaskToPixels(psPixels *out, const psImage *mask, unsigned int maskVal);
     3059\end{verbatim}
     3060
     3061\code{psPixelsToMask} shall return an image of type U8 with the
     3062\code{pixels} lying within the specified \code{region} set to the
     3063\code{maskVal}.  The \code{out} image shall be modified if supplied,
     3064or allocated and returned if \code{NULL}.  The size of the output
     3065image shall be \code{region->x1 - region->x0} by \code{region->y1 -
     3066region->y0}, with \code{out->x0 = region->x0} and \code{out->y0 =
     3067region->y0}.  In the event that either of \code{pixels} or
     3068\code{region} are \code{NULL}, the function shall generate an error
     3069and return \code{NULL}.
     3070
     3071\code{psMaskToPixels} shall return a \code{psPixels} consisting of the
     3072coordinates in the \code{mask} that match the \code{maskVal}.  The
     3073\code{out} pixel list shall be modified if supplied, or allocated and
     3074returned if \code{NULL}.  In hte event that \code{mask} is
     3075\code{NULL}, the function shall generate an error and return
     3076\code{NULL}.
     3077
     3078\begin{verbatim}
     3079psPixels *psPixelsConcatenate(psPixels *out, const psPixels *pixels);
     3080\end{verbatim}
     3081
     3082\code{psPixelsConcatenate} shall concatenate \code{pixels} onto
     3083\code{out}.  In the event that \code{out} is \code{NULL}, a new
     3084\code{psPixels} shall be allocated, and the contents of \code{pixels}
     3085simply copied in.  If \code{pixels} is \code{NULL}, the function shall
     3086generate an error and return \code{NULL}.  The function shall take
     3087care to ensure that there are no duplicate pixels in \code{out} (since
     3088the order in which the pixels are stored is not important, the values
     3089may be sorted, allowing the use of a faster algorithm than a linear
     3090scan).
     3091
     3092%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     3093
     3094\subsection{Image Regions}
     3095
     3096In many places, we need to refer to a rectangular area.  We define a
     3097structure to represent a rectangle:
     3098\begin{verbatim}
     3099typedef struct {
     3100  float x0;
     3101  float x1;
     3102  float y0;
     3103  float y1;
     3104} psRegion;
     3105psRegion *psRegionAlloc (float x0, float x1, float y0, float y1);
     3106\end{verbatim}
     3107
     3108\begin{verbatim}
     3109psRegion *psRegionFromString (char *region);
     3110\end{verbatim}
     3111This function converts the IRAF description of a region in the form
     3112\code{[x0:x1,y0:y1]}, used for header entries such as \code{BIASSEC},
     3113into the corresponding \code{psRegion} structure.
     3114
    30303115\subsection{Vector and Image Arithmetic}
    30313116\label{sec:arithmetic}
     
    34433528%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    34443529
     3530\pagebreak
     3531\section{Rich Data Structures and I/O}
     3532
     3533\subsection{Metadata}
     3534\label{sec:metadata}
     3535
     3536\subsubsection{Conceptual Overview}
     3537
     3538Within PSLib, we provide a data structure to carry metadata and
     3539mechanisms to manipulate the metadata.  Metadata is a general concept
     3540that requires some discussion.  In any data analysis task, the
     3541ensemble of all possible data may be divided into two or three
     3542classes: there is the specific data of interest, there is data which
     3543is related or critical but not the primary data of interest, and there
     3544is all of the other data which may or may not be interesting.  For
     3545example, consider a simple 2D image obtained of a galaxy from a CCD
     3546camera on a telescope.  If you want to study the galaxy, the specific
     3547data of interest is the collection of pixels.  There are a variety of
     3548other pieces of data which are closely related and crucial to
     3549understanding the data in those pixels, such as the dimensions of the
     3550image, the coordinate system, the time of the image, the exposure
     3551time, and so forth.  Other data may be known which may be less
     3552critical to understanding the image, but which may be interesting or
     3553desired at a later date.  For example, the observer who took the
     3554image, the filter manufacturer, the humidity at the telescope, etc.
     3555
     3556Formally, all of the related data which describe the principal data of
     3557interest are metadata.  Note that which piece is the metadata and
     3558which is the data may depend on the context.  If you are examining the
     3559pixels in an image, the coordinate and flux of an object may be part
     3560of the metadata.  However, if you are analyzing a collection of
     3561objects extracted from an image, you may consider then pixel data
     3562simply part of the metadata associated with the list of objects. 
     3563
     3564There are various ways to handle metadata vs data within a programming
     3565environment.  In C, it is convenient to use structures to group
     3566associated data together.  One possibility is to define the metadata
     3567as part of the associated data structure.  For example, the image data
     3568structure would have elements for all possible associated measurement.
     3569This approach is both cumbersome (because of the large number metadata
     3570types), impractical (because the full range of necessary metadata is
     3571difficult to know in advance) and inflexible (because any change in
     3572the collection of metadata requires addition of new structure elements
     3573and recompilation). 
     3574
     3575An alternative is to place the metadata in a generic container and use
     3576lookup mechanisms to extract the appropriate metadata when needed.  An
     3577example of this is would be a text-based FITS header for an image read
     3578into a flat text buffer.  In this implementation, metadata lookup
     3579functions could return the current value of, for example, NAXIS1 (the
     3580number of columns of the image) by scanning through the header buffer.
     3581This method has the benefits of flexibility and simplicity of
     3582programming interface, but it has the disadvantage that all metadata
     3583is accessed though this lookup mechanism.  This may make the code less
     3584readable and it may slow down the access. 
     3585
     3586PSLib implements an intermediate solution to this problem.  We specify
     3587a flexible, generic metadata container and access methods.  Data types
     3588which require association with a general collection of metadata should
     3589include an entry of this metadata type.  However, a subset of metadata
     3590concepts which are basic and frequently required may be placed in the
     3591coded structure elements.  This approach allows the code to refer to
     3592the basic metadata concepts as part of the data structure (ie,
     3593\code{image.nx}), but also allows us to provide access to any
     3594arbitrary metadata which may be generated.  As a practical matter, the
     3595choice of which entries are only in the metadata and which are part of
     3596the explicit structure elements is rather subjective.  Any data
     3597elements which are frequently used should be put in the structure;
     3598those which are only infrequently needed should be left in the generic
     3599metadata.
     3600
     3601There are some points of caution which must be noted.  Any
     3602manipulation of the data should be reflected in the metadata where
     3603appropriate.  This is always an issue of concern.  For example,
     3604consider an image of dimensions \code{nx, ny}.  If a function extracts
     3605a subraster, it must change the values of \code{nx, ny} to match the
     3606new dimensions.  What should it do to the corresponding metadata?
     3607Clearly, it should change the corresponding value which defines
     3608\code{nX, nY}.  However, it is not quite so simple: there may be other
     3609metadata values which depend on those values.  These must also be
     3610changed appropriately.  What if the metadata element points to a
     3611copy of the metadata which may be shared by other representations of
     3612the image?  These must be treated differently because the change would
     3613invalidate those other references.  Care must be taken, therefore,
     3614when writing functions which operate on the data to consider all of
     3615the relevant metadata entries which must also be updated.
     3616
     3617A related issue is the definition of metadata names.  Entries in a
     3618structure have the advantage of being hardwired: every instance of
     3619that structure will have the same name for the same entry.  This is
     3620not necessarily the case with a more flexible metadata container.  The
     3621image exposure time is a notorious example in astronomy.  Different
     3622observatories use different header keywords (ie, metadata names) for
     3623the same concept of the exposure time (\code{EXPTIME},
     3624\code{EXPOSURE}, \code{OPENTIME}, \code{INTTIME}, etc).  Any system
     3625which operates on these metadata needs to address the issue of
     3626identifying these names.  This issue seems like an argument for
     3627hardwiring metadata in the structure, but in fact it does not present
     3628such a strong case.  If the metadata are hardwired, some function will
     3629still have to know how to interpret the various names to populate the
     3630structure.  The concept can still be localized with generic metadata
     3631containers by including abstract metadata names within the code which
     3632are tied to the various implementations-specific metadata names.
     3633
     3634\subsubsection{Metadata Representation}
     3635
     3636\begin{figure}
     3637\psfig{file=Metadata,width=6.5in}
     3638\caption{Metadata Structures\label{fig:metadata}}
     3639\end{figure}
     3640
     3641This section addresses the question of how \PS{} metadata should be
     3642represented in memory, not how it should be represented on disk.
     3643
     3644We define an item of metadata with the following structure:
     3645\filbreak
     3646\begin{verbatim}
     3647typedef struct {
     3648    int id;                             ///< unique ID for this item
     3649    char *name;                         ///< Name of item
     3650    psMetadataType type;                ///< type of this item
     3651    psElemType ptype;                   ///< primitive data type
     3652    const union {
     3653        psS32 S32;                      ///< integer data
     3654        psF32 F32;                      ///< floating-point data
     3655        psF64 F64;                      ///< double-precision data
     3656        void *V;                        ///< other type
     3657        psList *list;                   ///< psList entry
     3658        psMetadata *md;                 ///< psMetadata entry
     3659    } data;                             ///< value of metadata
     3660    char *comment;                      ///< optional comment ("", not NULL)
     3661} psMetadataItem;
     3662\end{verbatim}
     3663
     3664The \code{id} is a unique identifier for this item of metadata;
     3665experience shows that such tags are useful.  The entry \code{name}
     3666specifies the name of the metadata item.  The value of the metadata is
     3667given by the union \code{data}, and may be of type \code{psS32},
     3668\code{psF32}, \code{psF64}, or an arbitrary rich structure pointed at
     3669by the \code{void} pointer \code{V}.  A character string comment
     3670associated with this metadata item may be stored in the element
     3671\code{comment}. The \code{type} entry specifies how to interpret the
     3672type of the data being represented, given by the enumerated type
     3673\code{psMetadataType}:
     3674%
     3675\filbreak
     3676\begin{verbatim}
     3677typedef enum {                          ///< type of item.data is:
     3678    PS_META_PRIMITIVE,                  ///< primitive type: use item.ptype
     3679    PS_META_LIST,                       ///< psList; use item.data.list (used for non-unique data)
     3680    PS_META_META,                       ///< psMetadata: use item.data.list
     3681    PS_META_STR,                        ///< string (item.data.V)
     3682    PS_META_MATH,                       ///< psScalar, psVector, psImage (item.data.V)
     3683    PS_META_JPEG,                       ///< JPEG (item.data)
     3684    PS_META_PNG,                        ///< PNG (item.data)
     3685    PS_META_ASTROM,                     ///< astrometric coefficients (item.data)
     3686    PS_META_UNKNOWN,                    ///< other (item.data)
     3687    PS_META_NTYPE                       ///< Number of types; must be last
     3688} psMetadataType;
     3689\end{verbatim}
     3690If the data is a PSLib primitive data value, the primitive data type
     3691is given by the value of \code{ptype}.
     3692
     3693A collection of metadata is represented by the \code{psMetadata} structure:
     3694\begin{verbatim}
     3695typedef struct {
     3696    psList *list;                       ///< list of psMetadataItem
     3697    psHash *table;                      ///< hash table of the same metadata
     3698} psMetadata;
     3699\end{verbatim}
     3700The type \code{psMetadata} is a container class for metadata. Note
     3701that there are in fact \emph{two} representations of the metadata
     3702(each \code{psMetadataItem} appears on both).  The first
     3703representation employs a doubly-linked list that allows the order of
     3704the metadata to be preserved (e.g., if FITS headers are read in a
     3705particular order, they should be written in the same order).  The
     3706second representation employs a hash table which allows fast look-up
     3707given a specific metadata keyword.
     3708
     3709Certain metadata names (such as the FITS keywords \code{COMMENT} and
     3710\code{HISTORY} in a FITS header) may be repeated with different
     3711values.  In such a case, the \code{psMetadata.list} structure contains
     3712the entries in their original sequence with duplicate keys.  The
     3713\code{psMetadata.hash} entries, which are required to have unique
     3714keys, would have a single entry with the keyword of the repeated key,
     3715with the value of \code{psMetadataType} set to \code{PS_META_LIST},
     3716and the \code{psMetadataItem.data} element pointing to a \code{psList}
     3717containing the actual entries.  If \code{psMetadataItemAlloc} is
     3718called with the type set to \code{PS_META_LIST}, such a repeated key
     3719is created.  If the data value passed to \code{psMetadataItemAlloc}
     3720(the quantity in ellipsis) is \code{NULL}, then an empty
     3721\code{psMetadataItem} with the given keyword is created to hold future
     3722entries of that keyword.
     3723
     3724The \code{psMetadataAdd} routine is required to check that all
     3725metadata names are unique unless the type is already qualified as
     3726\code{PS_META_LIST}; in this case the data are added to the
     3727corresponding \code{psMetadataItem.data} list.
     3728
     3729\subsubsection{Metadata APIs}
     3730
     3731The allocator for \code{psMetadataItem} returns a full
     3732\code{psMetadataItem} ready for insertion into the \code{psMetadata}.
     3733The \code{name} entry specifies the name to use for this metadata
     3734item, and may include \code{sprintf}-type formating codes.  The
     3735\code{comment} entry is a fixed string which is used for the comment
     3736associated with this metadata item.  The metadata data and the
     3737arguments to the \code{name} formatting codes are passed, in that
     3738order (metadata pointer first), to \code{psMetadataItemAlloc} as
     3739arguments following the comment string.  The data must be a pointer
     3740for any data types which are stored in the element \code{data.void},
     3741while other data types are passed as numeric values.  The argument
     3742list must be interpreted appropriately by the \code{va_list} operators
     3743in the function.
     3744\begin{verbatim}
     3745psMetadataItem *psMetadataItemAlloc(const char *name, psMetadataType type, const char *comment, ...);
     3746psMetadataItem *psMetadataItemAllocV(const char *name, psMetadataType type, const char *comment, va_list list);
     3747\end{verbatim}
     3748
     3749The constructor for the collection of metadata, \code{psMetadata},
     3750simply returns an empty metadata container (employing the constructors
     3751for the doubly-linked list and hash table).  The destructor needs to
     3752free each of the \code{psMetadataItem}s using \code{psMetadataItemFree}.
     3753\begin{verbatim}
     3754psMetadata *psMetadataAlloc(void);
     3755\end{verbatim}
     3756
     3757Items may be added to the metadata in one of two ways --- firstly, an
     3758item may be added by appending a \code{psMetadataItem} which has
     3759already been created; and secondly by directly providing the data to
     3760be appended.  In both cases, the return value defines the success
     3761(\code{true}) or failure of the operation.  The second function,
     3762\code{psMetadataAdd} takes a pointer or value which is interpreted by
     3763the function using variadic argument interpretation.  The third
     3764version is the \code{va_list} version of the second function.  All
     3765three functions take a parameter, \code{location}, which specifies
     3766where in the list to place the element, following the conventions for
     3767the \code{psList}.  The entry \code{mode} for \code{psMetadataAddItem}
     3768is a bit mask constructed by OR-ing the allowed option flags (eg,
     3769\code{PS_META_REPLACE}) which specifies minor variations on the
     3770behavior.  The \code{format} entry, which specifies both the metadata
     3771type and the optional flags, is constructed by bit-wise OR-ing the
     3772appropriate \code{psMetadataType} and allowed option option flags.
     3773Care should be taken not to leak memory when appending an item for
     3774which the key already exists in the metadata (and is not
     3775\code{PS_META_LIST}).
     3776%
     3777\begin{verbatim}
     3778bool psMetadataAddItem(psMetadata *md, psMetadataItem *item, int location, int mode);
     3779bool psMetadataAdd(psMetadata *md, int location, const char *name, int format, const char *comment, ...);
     3780bool psMetadataAddV(psMetadata *md, int location, const char *name, int format, const char *comment,
     3781                    va_list list);
     3782\end{verbatim}
     3783
     3784The functions above take option flags which modify the behavior when
     3785metadata items are added to the metadata list.  These flags must be
     3786bit-exclusive of those used above for the \code{psMetadataTypes}.  The
     3787flags have the following meanings:
     3788
     3789\code{PS_META_DEFAULT}: This is the zero bit mask, to allow the
     3790default behavior for \code{psMetadataAddItem} above.  If this is OR-ed
     3791with a \code{psMetadataType}, the result is as if no OR-ing took
     3792place.
     3793
     3794\code{PS_META_REPLACE}: If the given metadata item exists in the
     3795metadata list, and is not of type \code{PS_META_LIST} or
     3796\code{PS_META_META} (ie, not a container type), then this entry is
     3797allowed to replace the existing entry.  If this mode bit is not set, a
     3798duplicate (non-container-type) entry is an error.
     3799
     3800\begin{verbatim}
     3801typedef enum {                          ///< option flags for psMetadata functions
     3802    PS_META_DEFAULT,                    ///< default behavior (0x0000) for use in mode above
     3803    PS_META_REPLACE,                    ///< allow entry to be replaced
     3804} psMetadataFlags;
     3805\end{verbatim}
     3806
     3807An example of code to use these metadata APIs to generate the
     3808structure seen in Figure~\ref{fig:metadata} is given below.
     3809
     3810\begin{verbatim}
     3811md = psMetadataAlloc();
     3812
     3813psMetadataAdd(md, PS_LIST_TAIL, "SIMPLE",   PS_META_BOOL, "basic fits",            TRUE);
     3814psMetadataAdd(md, PS_LIST_TAIL, "BLANK",    PS_META_S32,  "invalid pixel data",    -32768);
     3815psMetadataAdd(md, PS_LIST_TAIL, "DATE-OBS", PS_META_STR,  "observing date UT", "   2004-6-16");
     3816psMetadataAdd(md, PS_LIST_TAIL, "COMMENT",  PS_META_LIST, "head of comment block", NULL);
     3817psMetadataAdd(md, PS_LIST_TAIL, "COMMENT",  PS_META_STR,  "",                      "DATA");
     3818psMetadataAdd(md, PS_LIST_TAIL, "COMMENT",  PS_META_STR,  "",                      "PARAMS");
     3819psMetadataAdd(md, PS_LIST_TAIL, "EXPTIME",  PS_META_F32,  "exposure time (sec)",   1.05);
     3820psMetadataAdd(md, PS_LIST_TAIL, "COMMENT",  PS_META_STR,  "",                      "FOO");
     3821
     3822cell = psMetadataAlloc();
     3823psMetadataAdd(cell, PS_LIST_TAIL, "EXTNAME",  PS_META_STR,  "",                    "CCD00");
     3824psMetadataAdd(cell, PS_LIST_TAIL, "BIASNAME", PS_META_STR,  "",                    "BSEC-00");
     3825psMetadataAdd(cell, PS_LIST_TAIL, "CHIP",     PS_META_STR,  "",                    "CHIP.00");
     3826psMetadataAdd(md,   PS_LIST_TAIL, "CELL.00",  PS_META_META, "",                    cell);
     3827
     3828cell = psMetadataAlloc();
     3829psMetadataAdd(cell, PS_LIST_TAIL, "EXTNAME",  PS_META_STR,  "",                    "CCD01");
     3830psMetadataAdd(cell, PS_LIST_TAIL, "BIASNAME", PS_META_STR,  "",                    "BSEC-01");
     3831psMetadataAdd(cell, PS_LIST_TAIL, "CHIP",     PS_META_STR,  "",                    "CHIP.01");
     3832psMetadataAdd(md,   PS_LIST_TAIL, "CELL.01",  PS_META_META, "",                    cell);
     3833\end{verbatim}
     3834
     3835The following code shows how to use the APIs to replace one of these values:
     3836\begin{verbatim}
     3837psMetadataAdd(md, PS_LIST_TAIL, "EXPTIME",  PS_META_F32 | PS_REPLACE,  "new exposure time (sec)",   2.05);
     3838\end{verbatim}
     3839
     3840Items may be removed from the metadata by specifying a key or a
     3841location in the list.  If the value of \code{name} is \code{NULL}, the
     3842value of \code{location} is used.  If the value of \code{name} is not
     3843\code{NULL}, then \code{location} must be set to
     3844\code{PS_LIST_UNKNOWN}.  If the key matches a metadata item, the item
     3845is removed from the metadata and \code{true} is returned; otherwise,
     3846\code{false} is returned.  If the key is not unique, then \emph{all}
     3847items corresponding to the key are removed, and \code{true} is
     3848returned.
     3849%
     3850\begin{verbatim}
     3851bool psMetadataRemove(psMetadata *md, int location, const char *key);
     3852\end{verbatim}
     3853
     3854Items may be found within the metadata by providing a key.  In the
     3855event that the key is non-unique, the first item is returned.
     3856\begin{verbatim}
     3857psMetadataItem *psMetadataLookup(const psMetadata *md, const char *key);
     3858\end{verbatim}
     3859
     3860Several utility functions are provided for simple cases.  These
     3861functions perform the effort of casting the data to the appropriate
     3862type.  The numerical functions shall return 0.0 if their key is not
     3863found.  If the pointer value of \code{status} is not \code{NULL}, it
     3864is set to reflect the success or failure of the lookup.
     3865\begin{verbatim}
     3866void *psMetadataLookupPtr(bool *status, const psMetadata *md, const char *key);
     3867psS32 psMetadataLookupS32(bool *status, const psMetadata *md, const char *key);
     3868psF64 psMetadataLookupF64(bool *status, const psMetadata *md, const char *key);
     3869\end{verbatim}
     3870
     3871Items may be retrieved from the metadata by their entry position.  The
     3872value of which specifies the desired entry in the fashion of
     3873\code{psList}.
     3874\begin{verbatim}
     3875psMetadataItem *psMetadataGet(const psMetadata *md, int location);
     3876\end{verbatim}
     3877
     3878The metadata list component may be iterated over by using a
     3879\code{psListIterator} in a fashion equivalent to the usage for
     3880\code{psList}.  The iterator may be set to a location in the
     3881\code{psMetadata} list, and the user may get the previous or next item
     3882in the list relative to that location.  \code{psMetadataGetNext} has
     3883the ability to match the key using a POSIX regex, e.g., if the user
     3884only wants to iterate through \code{IPP.machines.sky} and doesn't want
     3885to bother with \code{IPP.machines.detector}.  The iterator should
     3886iterate over every item in the metadata list, even those that are
     3887contained in a \code{PS_META_LIST}.  The value \code{iterator}
     3888specifies the iterator to be used.  In setting the iterator, the
     3889position of the iterator is defined by \code{location}, which follows
     3890the conventions of the \code{psList} iterators.
     3891\begin{verbatim}
     3892psListIterator *psMetadataIteratorAlloc(psMetadata *md, int location, bool mutable);
     3893bool psMetadataIteratorSet(psListIterator *iterator, int location);
     3894psMetadataItem *psMetadataGetAndIncrement(psListIterator *iterator, const char *regex);
     3895psMetadataItem *psMetadataGetAndDecrement(psListIterator *iterator, const char *regex);
     3896\end{verbatim}
     3897
     3898Metadata items may be printed to an open file descriptor based on a
     3899provided format.  The format string is an sprintf format statement
     3900with exactly one \% formatting command.  If the metadata item type is
     3901a numeric type, this formatting command must also be numeric, and type
     3902conversion performed to the value to match the format type.  If the
     3903metadata item type is a string, the formatting command must also be
     3904for a string (\%s type of command).  If the metadata type is any other
     3905data type, printing is not allowed.
     3906\begin{verbatim}
     3907bool psMetadataItemPrint(FILE *fd, const char *format, const psMetadataItem *md);
     3908\end{verbatim}
     3909
     3910\subsubsection{Configuration files}
     3911\label{sec:configspec}
     3912
     3913It will be necessary for the \PS{} system, in order to load
     3914pre-defined settings, to parse a configuration file into a
     3915\code{psMetadata} structure.  This shall be performed by the
     3916function \code{psMetadataParseConfig}, as described below.
     3917
     3918\begin{verbatim}
     3919psMetadata *psMetadataParseConfig(psMetadata *md, int *nFail, const char *filename, bool overwrite);
     3920\end{verbatim}
     3921
     3922Given a metadata container, \code{md}, and the name of a configuration
     3923file, \code{filename}, \code{psMetadataParseConfig} shall parse the
     3924configuration file, placing the contained key/type/value/comment quads
     3925into the metadata, and returning a pointer to the metadata structure.
     3926The number of lines that failed to parse is returned in \code{nFail}.
     3927Multiple specifications of a key that haven't been declared (see
     3928below) are overwritten if and only if \code{overwrite} is \code{true}.
     3929If the metadata container is \code{NULL}, it shall be allocated. 
     3930
     3931On error, the function shall return \code{NULL}.
     3932
     3933The configuration file shall consist of plain text with
     3934key/type/value/comment quads on separate lines.  Blank lines,
     3935including those consisting solely of whitespace (both spaces and
     3936tabs), shall be ignored, as shall lines that commence with the comment
     3937character (a hash mark, \code{#}), either immediately at the start of
     3938the line, or preceded by whitespace.  The key/type/value/comment quads
     3939shall all lie on a single line, separated by whitespace.
     3940
     3941The key shall be first, possibly preceded on the line by whitespace
     3942which should not form part of the key.
     3943
     3944Next, to assist the casting of the value, shall be a string
     3945identifying the type of the value, which shall correspond to one of
     3946the simple types supported in \code{psMetadata}:
     3947\code{STRING,BOOL,S32,F32,F64}; \code{STR} may be used to abbreviate
     3948\code{STRING}.
     3949
     3950\tbd{May, in the future, require more types, including U8,S16,C64,
     3951which will also necessitate updating the definition of psMetadata.}
     3952
     3953The value shall follow the type: strings may consist of multiple
     3954words, and shall have all leading and trailing whitespace removed;
     3955booleans shall simply be either \code{T} or \code{F}.
     3956
     3957Following the value may be an optional comment, preceded by a comment
     3958character (a hash mark, \code{#}), which in the case of a string
     3959value, serves to mark the end of the value, and for other types serves
     3960to identify the comment to the reader.  Only one comment character may
     3961be present on any single line (i.e., neither strings nor comments are
     3962permitted to contain the comment character).  The comment may consist
     3963of multiple words, and shall have leading and trailing whitespace
     3964removed.
     3965
     3966One wrinkle is the specification of vectors.  Keys for which the value
     3967is to be parsed as a vector shall be preceded immediately by a
     3968``vector symbol'', which we choose to be the ``at'' sign, \code{@}.
     3969In this case, the type shall be interpreted as the type for the
     3970vector, which may be any of the signed or unsigned integer or floating
     3971point types (\code{U8,U16,U32,U64,S8,S16,S32,S32,S64,F32,F64}) but not
     3972the complex floating point types; and the value shall consist of
     3973multiple numbers, separated either by a comma or whitespace.  These
     3974values shall populate a \code{psVector} of the appropriate type in the
     3975order in which they appear in the configuration file.
     3976
     3977\tbd{May add complex types, likely to be specified with values such as
     3978  1.23+4.56i in the future.}
     3979
     3980An additional hurdle is the specification of keys that may be
     3981non-unique (such as the \code{COMMENT} keyword in a FITS header).
     3982These keys shall be specified in the configuration file as non-unique
     3983by specifying the key at the start of the line (possibly preceded by
     3984whitespace) and specifying the type as a ``multiple symbol'', which we
     3985choose to be an asterisk, \code{*}.  No other data may be provided on
     3986this line, though a comment, preceeded by the comment marker, is
     3987valid.  A warning shall be produced when a key which has not been
     3988specified to be non-unique is repeated; in this case, the former value
     3989shall be overwritten if \code{overwrite} is \code{true}, otherwise the
     3990line shall be ignored and counted as one that could not be parsed.
     3991
     3992If a line does not conform to the rules laid out here, a warning shall
     3993be generated, it shall be ignored and counted as a line that could not
     3994be parsed.  The total number of lines that were not able to be parsed
     3995(including those that were ignored because \code{overwrite} is
     3996\code{false}, and any other parsing problems, but not including blank
     3997lines and comment lines) shall be returned by the function in the
     3998argument \code{nFail}.
     3999
     4000Here are some examples of lines of a valid configuration file:
     4001\filbreak
     4002\begin{verbatim}
     4003Double     F64     1.23456789      # This is a comment
     4004Float    F32 0.98765 # This is a comment too
     4005String  STR This is the string that forms the value #comment
     4006
     4007 # This is a comment line and is to be ignored
     4008boolean     BOOL    T # The value of `boolean' is `true'
     4009
     4010@primes U8  2,3 5 7,11,13 17 #   These are prime numbers
     4011
     4012comment MULTI # The rest of this line is ignored, but `comment' is set to be non-unique
     4013comment STR This
     4014comment STR     is
     4015comment STR       a
     4016comment STR        non-unique
     4017comment STR                  key
     4018Float F64 1.23456 # This generates a warning, and, if `overwrite' is `false', is ignored
     4019\end{verbatim}
     4020
     4021Of course, a real configuration file should look much nicer to humans
     4022than the above example, but PSLib must be able to parse such ugly
     4023files.
     4024
     4025We extend \code{psMetadataParseConfig} to allow a modest tree
     4026structure by defining a reserved keyword \code{TYPE}.  Any line in the
     4027config file which starts with the word \code{TYPE} shall be
     4028interpretted as defining a new valid type.  The defined type name
     4029follows the word \code{TYPE}, and is in turn followed by an arbitrary
     4030number of words.  These words are to be interpreted as the names of an
     4031embedded \code{psMetadata} entry, where the values are given on any
     4032line which (following the \code{TYPE} definition) employs the new type
     4033name.  For example, a new type may be defined as:
     4034\begin{verbatim}
     4035TYPE      CELL   EXTNAME   BIASSEC  CHIP
     4036CELL.00   CELL   CCD00     BSEC-00  CHIP.00
     4037CELL.01   CELL   CCD01     BSEC-01  CHIP.00
     4038\end{verbatim}
     4039
     4040When \code{psMetadataParseConfig} encounters the \code{TYPE} line, it
     4041should construct a \code{psMetadata} container and fill it with
     4042\code{psMetadataItems} having the names \code{EXTNAME, BIASSEC, CHIP},
     4043with type \code{PS_META_STR}, but data allocated.  When it next
     4044encounters an entry of type \code{CELL}, it should then use the given
     4045name (e.g., \code{CELL.00}) for the \code{psMetadataItem}, and copy
     4046the \code{psMetadata} data onto the \code{psMetadataItem.data.md}
     4047entry, filling in the values from the rest of the line (\code{CCD00,
     4048BSEC-00, CHIP.00}).  This hierarchical structure is illustrated in
     4049Figure~\ref{fig:metadata}.
     4050
     4051We further extend \code{psMetadataParseConfig} to allow the definition
     4052of a \code{psMetadata} entry using a sequence of successive lines to
     4053define the values of the \code{psMetadataItem} entries.  The initial
     4054line defines the new \code{psMetadata} entry and its name.  The
     4055following lines have the same format as the other metadata config file
     4056entries.  The sequence is terminated with a line with a single word
     4057\code{END}.  For example, a metadata entry may be defined as:
     4058\begin{verbatim}
     4059CELL      METADATA
     4060 EXTNAME   STR   CCD00
     4061 BIASSEC   STR   BSEC-00
     4062 CHIP      STR   CHIP.00
     4063 NCELL     S32   24
     4064END
     4065\end{verbatim}
     4066
     4067A series of test inputs is contained in
     4068\S\ref{sec:configtest}.
     4069
     4070\subsection{XML Functions}
     4071
     4072Within Pan-STARRS, we will use XML documents as a transport mechanism
     4073to carry data between programs and between IPP and other subsystems.
     4074Configuration information may be stored as well as XML documents, in
     4075addition to the text format discussed in the discussion on Metadata.
     4076XML is an extremely variable document format, and it is not currently
     4077the intention of PSLib to provide a complete PSLib version of XML
     4078operations.  Rather, a limited number of operations are defined to
     4079convert specific data structures to an appropriate XML document.  To
     4080maximize the simplicity of the XML APIs, we will use the convention
     4081that a single XML document to be parsed by PSLib shall contain only a
     4082single data structure.  Each of the XML APIs therefore take as input a
     4083reference to a complete XML document and return a PSLib data
     4084structure, or take a PSLib data structure and return a complete XML
     4085document.
     4086
     4087We start by defining a PSLib wrapper type which is a pointer to an XML
     4088document in memory.  We wrap the \code{libxml2} version of an XML
     4089document pointer for now:
     4090\begin{verbatim}
     4091typedef xmlDocPtr psXMLDoc;
     4092void psXMLDocFree(psXMLDoc *doc);
     4093\end{verbatim}
     4094
     4095The next pair of functions convert a \code{psMetadata} data structure
     4096to a complete \code{psXMLDoc} (in memory) and vice versa:
     4097\begin{verbatim}
     4098psXMLDoc *psMetadataToXMLDoc(const psMetadata *metadata);
     4099psMetadata *psXMLDocToMetadata(const psXMLDoc *doc);
     4100\end{verbatim}
     4101
     4102The next pair of functions loads the data in a named file into a
     4103complete \code{psXMLDoc} (in memory) and write out the \code{psXMLDoc}
     4104to a named file:
     4105\begin{verbatim}
     4106psXMLDoc *psXMLParseFile(const char *filename);
     4107int psXMLDocToFile(const psXMLDoc *doc, const char *filename);
     4108\end{verbatim}
     4109
     4110The next pair of functions accepts a block of memory and parses it
     4111into a complete \code{psXMLDoc} (also in memory), and vice versa:
     4112\begin{verbatim}
     4113psXMLDoc *psXMLParseMemory(const char *buffer, const int size);
     4114int psXMLDocToMemory(const psXMLDoc *doc, char *buffer);
     4115\end{verbatim}
     4116
     4117The next pair of functions read from and write to a file descriptor.
     4118The first converts the imcoming data to a complete \code{psXMLDoc}
     4119(also in memory), the second writes the \code{psXMLDoc} to the file
     4120descriptor:
     4121\begin{verbatim}
     4122psXMLDoc *psXMLParseFD(int fd);
     4123int psXMLDocToFD(const psXMLDoc *doc, int fd);
     4124\end{verbatim}
     4125
     4126\subsection{Database Functions}
     4127
     4128Many of the applications that PSLib will be used for will require
     4129access to a simple relational database.  PSLib includes generic
     4130database-independent interface mechanisms as part of its API set.  The
     4131most important aspect of PSLib's database support is to abstract as
     4132much database specific complexity as is feasible.  As almost all RDBMS
     4133provide at least a simple transactional model, commit and rollback
     4134support should be provided.
     4135
     4136Currently, only support for MySQL 4.1.x is required but other backends
     4137may be added as options in the future.  As a particular example which
     4138has implications for the database interaction model, support for
     4139SQLite may be required in the future.  Currently, the choice of
     4140backend database interface may be made as a compile option.  Details
     4141of the specified APIs in the discussion below refer to the relevant
     4142MySQL functions.
     4143
     4144Database errors must be trapped and placed onto the psError stack.
     4145The complete error message should be retrieved with the database's
     4146error function.
     4147
     4148\subsubsection{Managing the Database Connection}
     4149
     4150We specify a database handle which carries the information about the
     4151database connection:
     4152
     4153\begin{verbatim}
     4154    typedef struct {
     4155        MYSQL *mysql;
     4156    } psDB;
     4157\end{verbatim}
     4158
     4159The following collection of functions provides basic database functionality:
     4160
     4161\begin{verbatim}
     4162    // wraps mysql_init() & mysql_real_connect()
     4163    psDB *psDBInit(const char *host, const char *user, const char *passwd, const char *dbname);
     4164
     4165    // wraps mysql_close()
     4166    void psDBCleanup(psDB *dbh);
     4167
     4168    // wraps mysql_create_db()
     4169    bool psDBCreate(psDB *dbh, const char *dbname);
     4170
     4171    // wraps mysql_select_db()
     4172    bool psDBChange(psDB *dbh, const char *dbname);
     4173
     4174    // wraps mysql_drop_db()
     4175    bool psDBDrop(psDB *dbh, const char *dbname);
     4176\end{verbatim}
     4177
     4178For MySQL support, \code{psDBInit()} wraps \code{mysql_init()} and
     4179\code{mysql_real_connect()} in order to initialize a psDB structure and
     4180establish a database connection.  A null pointer should be returned on
     4181failure.
     4182
     4183When implementing support for SQLite, or other DB which is purely
     4184file-based, the \code{host}, \code{user}, and \code{passwd} arguments
     4185would be ignored while \code{dbname} would specify the path to the
     4186SQLite db file.
     4187
     4188\subsubsection{Interacting with Database Tables}
     4189
     4190The functions in this section perform high level interactions with the
     4191database tables.  All of them should behave ``atomically'' with
     4192respect to the state of the database.  Specifically, all interactions
     4193with the database should be done as a part of a transaction that is
     4194rolled-back on failure and committed only after all queries used by
     4195the API have been run.  In general, this API set attempts to treat a
     4196database table as a 2D matrix where columns can be represented by a
     4197\code{psVector} and rows as a \code{psMetadata} type.  A
     4198\code{psMetadata} collection is also used to define the columns of a
     4199table and as part of the query restrictions.
     4200
     4201\begin{verbatim}
     4202    bool psDBCreateTable(psDB *dbh, const char *tableName, psMetadata *md);
     4203\end{verbatim}
     4204
     4205This function generates and executes the SQL needed to create a table
     4206named \code{tableName}, with the column names and datatypes as
     4207described in \code{md}.  Each data item in the \code{psMetadata}
     4208collection represents a single table field.  The name of the field is
     4209given by the name of the \code{psMetadataItem} and the data type is
     4210give by the \code{psMetadataItem.type} and \code{psMetadataItem.ptype}
     4211entries.  A lookup table should be used to convert from PSLib types
     4212into MySQL compatible SQL data types.  For example, a
     4213\code{PS_META_STR} would map to an SQL99 varchar.  If the value of
     4214\code{type} is \code{PS_META_STR} then the \code{psMetadataItem.data}
     4215element is set to a string with the length for the field written as a
     4216text string.  The value of the \code{psMetadataItem.data} element is
     4217unused for the \code{PS_META_PRIMITIVE} types.  Other metadata types
     4218beyond \code{PS_META_STR} and \code{PS_META_PRIMITIVE} are not allowed
     4219in a table definition metadata collection.
     4220
     4221Database indexes can be specified setting the \code{comment} field to
     4222``\code{Primary Key}'' or ``\code{Key}''.  Comment are otherwise
     4223ignored.
     4224
     4225\begin{verbatim}
     4226    bool psDBDropTable(psDB *dbh, const char *tableName);
     4227\end{verbatim}
     4228
     4229This function deletes the specified table.
     4230
     4231\begin{verbatim}
     4232    psArray *psDBSelectColumn(psDB *dbh, const char *tableName, const char *col, const psU64 limit);
     4233    psVector *psDBSelectColumnNum(psDB *dbh, const char *tableName, const char *col, psElemType pType, const psU64 limit);
     4234\end{verbatim}
     4235
     4236These functions generates and executes the SQL needed to select an entire
     4237column from a table or up to \code{limit} rows from it.  If \code{limit} is 0,
     4238the entire range is returned.  The database response is processed and a
     4239\code{psArray} of strings is returned.  The Num version of the function returns
     4240the data in a \code{psVector}, data cast to \code{pType}.  It returns an error
     4241(NULL) if the requested field is not a numerical type.
     4242
     4243\begin{verbatim}
     4244    psArray *psDBSelectRows(psDB *dbh, const char *tableName, psMetadata *where, const psU64 limit);
     4245\end{verbatim}
     4246
     4247This function returns rows from the specified table which match
     4248the restrictions given by \code{where}.  The restrictions are
     4249specified as field / value pairs.  The \code{psMetadata} collection
     4250where must consist of valid database fields, though the database query
     4251checking functions may be used to validate the fields as part of the
     4252query.  If \code{where} is \code{NULL}, then there are no restrictions
     4253on the rows selected.  The selected rows are returned as a
     4254\code{psArray} of \code{psMetadata} values, one per row.
     4255
     4256\begin{verbatim}
     4257    bool psDBInsertOneRow(psDB *dbh, const char *tableName, psMetadata *row);
     4258\end{verbatim}
     4259
     4260Insert the data from \code{row} into \code{tableName}.  It should be noted in
     4261the API reference that if fields are specified in \code{row} that do not exist
     4262in \code{tablename}, the insert will fail.
     4263
     4264\begin{verbatim}
     4265    bool psDBInsertRows(psDB *dbh, const char *tableName, psArray *rowSet);
     4266\end{verbatim}
     4267
     4268Similar to \code{psDBInsertOneRow()}, this function inserts many rows at once
     4269and is atomic for the complete set of rows.
     4270
     4271\begin{verbatim}
     4272    psArray *psDBDumpRows(psDB *dbh, const char *tableName);
     4273\end{verbatim}
     4274
     4275Fetch all rows as an psArray of psMetadata.
     4276
     4277\begin{verbatim}
     4278    psMetadata *psDBDumpCols(psDB *dbh, const char *tableName);
     4279\end{verbatim}
     4280
     4281Fetch all columns, as either a psVector or a psArray depnding on whether or not
     4282the column is numeric, and return them in a psMetadata structure where
     4283psMetadataItem.name contains the column's name.
     4284
     4285\begin{verbatim}
     4286    psS64 psDBUpdateRows(psDB *dbh, const char *tableName, psMetadata *where, psMetadata *values);
     4287\end{verbatim}
     4288
     4289Update the columns contained in \code{values} in the row(s) that have a field
     4290with the value indicated by \code{where} (note that this is only allows very
     4291limited use of SQL99's ``where'' semantics).  The number of rows modified is
     4292returned.  A negative value is return to indicate an error. If there are
     4293multiple psMetadataItems in \code{where} then each item should be considered as
     4294an additional constraint.  e.g.  ``where foo = x and where bar = y''
     4295
     4296\begin{verbatim}
     4297    psS64 psDBDeleteRows(psDB *dbh, const char *tableName, psMetadata *where);
     4298\end{verbatim}
     4299
     4300Delete the rows that are matched by \code{where} using the same semantics for
     4301\code{where} as in psDBUpdateRow().  A negative value is returned to indicate an
     4302error.
     4303
     4304\subsection{FITS I/O Functions}
     4305
     4306We need a variety of I/O functions between the disk and certain of our
     4307PSLib data structures.  We need the ability to access FITS headers,
     4308images and tables (both ASCII and Binary).  We define here the FITS
     4309I/O functions, all of which are currently specified as wrappers to
     4310functions within CFITSIO.  CFITSIO provides a wide range of utilities
     4311which we do not feel are particularly appropriate as part of a generic
     4312I/O library, such as assumptions about names which change the data
     4313interpretation, etc.  We are defining our calls to avoid the hidden
     4314'features'.  The CFITSIO functions which are wrapped should in general
     4315be the most basic versions.
     4316
     4317\begin{verbatim}
     4318typedef struct {
     4319    fitsfile fd;
     4320} psFits;
     4321\end{verbatim}
     4322We begin by defining a datatype to wrap the CFITSIO \code{fitsfile}
     4323structure.  This is necessary to allow repeated access to the data in
     4324a file without multiple open commands (which are expensive).
     4325
     4326\subsubsection{FITS File Manipulations}
     4327
     4328\begin{verbatim}
     4329psFits *psFitsAlloc(const char *filename);
     4330\end{verbatim}
     4331
     4332Opens a FITS file at positions the pointer to the PHU.
     4333
     4334\begin{verbatim}
     4335bool psFitsMoveExtName(psFits *fits, const char *extname);
     4336\end{verbatim}
     4337
     4338Positions the pointer to the beginning of the specified
     4339\code{extname}.  If the \code{extname} does not exist, the function
     4340shall fail. 
     4341
     4342\begin{verbatim}
     4343bool psFitsMoveExtNum(psFits* fits, int extnum, bool relative);
     4344\end{verbatim}
     4345
     4346Moves the pointer to the beginning of the specified HDU number.  If
     4347\code{relative} is TRUE, \code{extnum} represents the number of HDUs
     4348relative to the current HDU.  The PHU is entry number 0, while the
     4349extended data segments start at number 1.
     4350
     4351\begin{verbatim}
     4352int psFitsGetExtNum(psFits* fits);
     4353\end{verbatim}
     4354
     4355Returns the current HDU number (i.e., file position). 
     4356
     4357\begin{verbatim}
     4358int psFitsGetSize(psFits* fits);
     4359\end{verbatim}
     4360
     4361Returns the number of HDUs in the file.
     4362
     4363\begin{verbatim}
     4364psFitsType psFitsGetExtType(psFits* fits);
     4365\end{verbatim}
     4366
     4367Gets the current HDU's type (table or image).
     4368
     4369\subsubsection{FITS Header I/O Functions}
     4370
     4371\begin{verbatim}
     4372psMetadata *psFitsReadHeader(psMetadata *out, const psFits *fits);
     4373\end{verbatim}
     4374Read header data into a \code{psMetadata} structure.  The data is read
     4375from the current HDU pointed at by the \code{psFits *fits} entry.  If
     4376\code{out} is \code{NULL}, a new psMetadata is created.
     4377
     4378\begin{verbatim}
     4379psMetadata *psFitsReadHeaderSet (psFits *fits);
     4380\end{verbatim}
     4381Load a complete set of headers from the \code{psFits} file pointer.
     4382This function loads the headers from all extensions into a
     4383\code{psMetadata} collection, each entry of which is a pointer to a
     4384\code{psMetadata} structure containing the header data.  The metadata
     4385entry names are the \code{EXTNAME} values for each header (with the
     4386value of \code{PHU} for the primary header unit).  At the start of the
     4387operation, the file pointer is rewound to the beginning of the file.
     4388At the end, it is positioned where it started when the function was
     4389called.
     4390
     4391\begin{verbatim}
     4392bool psFitsWriteHeader(psMetadata *output, const psFits *fits);
     4393\end{verbatim}
     4394Write metadata into the header of a FITS image file.  The header is
     4395written at the current HDU.
     4396
     4397\subsubsection{FITS Image I/O Functions}
     4398
     4399\begin{verbatim}
     4400psImage *psFitsReadImage(psImage *output, psFits *fits, psRegion region, int z);
     4401\end{verbatim}
     4402Read an image or subimage from the \code{psFits} file pointer.  This
     4403function is a wrapper to the CFITSIO library function.  The input
     4404parameters allow a full image or a subimage to be read.  The region to
     4405be read is specified by \code{region}.  A negative value for either of
     4406\code{region.x1} or \code{region.y1} specifies the size of the region
     4407to be read counting down from the end of the array. 
     4408
     4409If the native image is a cube, the value of z specifies the requested
     4410slice of the image.  This function must call \code{psError} and return
     4411\code{NULL} if any of the specified parameters are out of range for
     4412the data in the image file, or if the image on disk is zero- or
     4413one-dimensional.  This function need only read images of the native
     4414FITS image types (\code{psU8}, \code{psS16}, \code{psS32},
     4415\code{psF32}, \code{psF64}).  The user is expected to convert the data
     4416type as needed with \code{psImageCopy}.
     4417 
     4418\begin{verbatim}
     4419bool psFitsUpdateImage(psFits *fits, const psImage *input, psRegion region, int z);
     4420\end{verbatim}
     4421\tbd{we have discussed this as the alternate name}
     4422Write an image section to the open \code{psFits} file pointer.  This
     4423operation may write a portion of an image over the existing bytes of
     4424an existing image.  Care must be taken to interpret \code{region},
     4425which specified the output pixels to be written / over-written.  If
     4426the combination of \code{region} and the size of \code{psImage *input}
     4427implies writing pixels outside the existing data area of the image,
     4428the function shall return an error (ie, if \code{region.x0 + image.nx
     4429>= NAXIS1}, \code{region.y0 + image.ny >= NAXIS2}, or \code{z >=
     4430NAXIS3}).  This function will only write images of the native FITS
     4431image types (\code{psU8}, \code{psS16}, \code{psS32}, \code{psF32},
     4432\code{psF64}).  The user is expected to convert the data type as
     4433needed with \code{psImageCopy}.  The return value must be 0 for a
     4434successful operation and 1 for an error.
     4435
     4436\begin{verbatim}
     4437bool psFitsWriteImage(psFits *fits, psMetadata *header, const psImage *input, int depth);
     4438\end{verbatim}
     4439Create a new image based on the dimensions specified for the image and
     4440the requested depth.  The header and image data segments are written
     4441in the file at the current position of the \code{psFits} pointer.
     4442This function will only write images of the native FITS image types
     4443(\code{psU8}, \code{psS16}, \code{psS32}, \code{psF32}, \code{psF64}).
     4444The user is expected to convert the data type as needed with
     4445\code{psImageCopy}.  The return value must be 0 for a successful
     4446operation and 1 for an error.
     4447
     4448\subsubsection{FITS Table I/O Functions}
     4449
     4450\begin{verbatim}
     4451psMetadata *psFitsReadTableRow (psFits *fits, int row);
     4452\end{verbatim}
     4453This function reads a single row of the table in the extension pointed
     4454at by the \code{psFits} file pointer.  The row number to be read is
     4455given by \code{row}.  The result is returned as a \code{psMetadata}
     4456collection with elements of the apporpriate types and keys
     4457corresponding to the table column names.  The function must apply the
     4458needed byte-swapping on the data in the row based on the description
     4459of the table data in the table header.  \tbr{we may need to be more
     4460flexible here: if we call this function repeatedly, it would be more
     4461efficient to pass the corresponding header or keep it somewhere (and
     4462the file pointer location, for that matter).}
     4463
     4464\begin{verbatim}
     4465void *psFitsReadTableRowRaw (int *nBytes, psFits *fits, int row);
     4466\end{verbatim}
     4467This function reads a single row of the table in the extension pointed
     4468at by the \code{psFits} file pointer.  The row number to be read is
     4469given by \code{row}.  The result is returned as collection of
     4470\code{nBytes} bytes allocated by the function.  The function must
     4471apply the needed byte-swapping on the data in the row based on the
     4472description of the table data in the table header.  \tbr{we may need
     4473to be more flexible here: if we call this function repeatedly, it
     4474would be more efficient to pass the corresponding header or keep it
     4475somewhere (and the file pointer location, for that matter).}
     4476
     4477\begin{verbatim}
     4478psArray *psFitsReadTableColumn (psFits *fits, char *colname);
     4479\end{verbatim}
     4480This function reads a single column of the table in the extension
     4481pointed at by the \code{psFits} file pointer.  The column is specified
     4482by the FITS table column key given by \code{row}.  The result is
     4483returned as a \code{psArray}, with the data from one row of the table
     4484column per array element.
     4485
     4486\begin{verbatim}
     4487psVector *psFitsReadTableColumnNum (psFits *fits, char *colname);
     4488\end{verbatim}
     4489This function reads a single column of the table in the extension
     4490pointed at by the \code{psFits} file pointer.  The column is specified
     4491by the FITS table column key given by \code{row} and must be of a
     4492numeric data type.  The result is returned as a \code{psVector} of the
     4493appropriate data type, with the data from one row of the table column
     4494per array element.
     4495
     4496\begin{verbatim}
     4497psArray *psFitsReadTableRaw (int *nBytes, psFits *fits);
     4498\end{verbatim}
     4499This function reads the entire data block from a table into the a
     4500\code{psArray}, with one element of the array per row.  The number of
     4501bytes per row is returned in \code{nBytes}.  The function must apply
     4502the needed byte-swapping on the data in each row based on the
     4503description of the table data in the table header.
     4504
     4505\begin{verbatim}
     4506psArray *psFitsReadTable (psFits *fits);
     4507\end{verbatim}
     4508This function reads the entire data block from a table into the a
     4509\code{psArray}, with one element of the array per row.  Each row is
     4510stored as a \code{psMetadata} collection as described above for
     4511\code{psFitsReadTableRow}.
     4512
     4513\begin{verbatim}
     4514bool psFitsWriteTable(psFits* fits, psMetadata *header, psArray* table);
     4515\end{verbatim}
     4516Accepts a \code{psArray} of \code{psMetadata} and writes it to the
     4517current HDU.  If the current HDU is not a table type, this will fail
     4518and return FALSE.
     4519
     4520\begin{verbatim}
     4521bool psFitsUpdateTable(psFits* fits, psMetadata *header, psMetadata* data, int row);
     4522\end{verbatim}
     4523Writes the \code{psMetadata} data to a FITS table at the specified row
     4524in the current HDU.  If the current HDU is not a table type, this will
     4525fail and return FALSE. 
     4526
     4527\pagebreak
    34454528\section{Astronomy-Specific Functions}
    34464529
     
    34574540\begin{itemize}
    34584541\item Dates and times
    3459 \item Metadata
    34604542\item Detector and sky positions
    3461 \item Astronomy Image
     4543\item Astronomical Image Containers
    34624544\item Astrometry
    34634545\item Photometry
     
    34874569
    34884570typedef enum {
    3489     PS_IERS_A,                      ///< IERS Bulliten A
    3490     PS_IERS_B,                      ///< IERS Bulliten B
    3491 } psTimeBulliten;
     4571    PS_IERS_A,                      ///< IERS Bulletin A
     4572    PS_IERS_B,                      ///< IERS Bulletin B
     4573} psTimeBulletin;
    34924574
    34934575typedef struct {
    34944576    psS64            sec;           ///< seconds, negative values represent dates before 1970
    3495     psU32            nsec;          ///< nanseconds
     4577    psU32            nsec;          ///< nanoseconds
    34964578    bool             leapsecond;    ///< if time falls on a UTC leapsecond
    34974579    psTimeType       type;          ///< type of time
     
    35234605This function may be used to convert between the various \code{psTimeType} time
    35244606representations.  The \code{time} is modified and returned.  Conversion between
    3525 all of the \emph{SI} length second systems should be implimented as first
     4607all of the \emph{SI} length second systems should be implimented by first
    35264608converting to TAI and then to the destination system.  UT1 is a special case
    35274609for conversion as it uses variable length secounds.  Conversation to UT1, via
    35284610TAI, is allowed but conversion \emph{from} UT1 is currently forbidden.
    35294611
    3530 To convert to Local Mean Sidereal Time, it is necessary to provide the local
    3531 longitude (specified in radians, positive East of Greenwich) as well:
     4612The following function converts to Local Mean Sidereal Time.  It is
     4613necessary to provide the local longitude (specified in radians,
     4614positive East of Greenwich) as well:
    35324615
    35334616\begin{verbatim}
     
    35354618\end{verbatim}
    35364619
    3537 The function may accept any of the \code{psTimeType} types with \emph{SI}
    3538 length seconds.  The \code{time} is modified and returned.  Note that this
    3539 function must supply the value $UT1-UTC$, which is available externally (see
    3540 \code{psTimeGetUT1Delta()}) and should use the UT1 values interpolated from
    3541 IERS bulliten B.  The following utility function encapsulates the PSLib
    3542 mechanism to extract the value of $UT1-UTC$:
    3543 
    3544 \begin{verbatim}
    3545 double psTimeGetUT1Delta(const psTime *time, psTimeBulliten bulliten);
    3546 psSphere *psTimeGetPoleCoords(const psTime *time, psTimeBulliten bulliten);
    3547 \end{verbatim}
    3548 
    3549 Leap seconds are added to UTC in order to keep it within $0.9s$ of UT1 (which
    3550 is defined relative to the Earth's rotation, and hence is useful for
    3551 astronomical purposes).
     4620The function may accept any of the \code{psTimeType} types with
     4621\emph{SI} length seconds.  The \code{time} is modified and returned.
     4622Note that this function requires the value $UT1-UTC$ (see
     4623\code{psTimeGetUT1Delta()}) and should use the UT1 values interpolated
     4624from IERS bulletin B. 
     4625
     4626The following utility function encapsulates the PSLib mechanism to
     4627extract the value of $UT1-UTC$ from the IERS Time Tables:
     4628
     4629\begin{verbatim}
     4630double psTimeGetUT1Delta(const psTime *time, psTimeBulletin bulletin);
     4631\end{verbatim}
     4632
     4633The following function provides tidal corrections to UT1-UTC, using
     4634the Ray model of Simon et al (REF).
     4635\begin{verbatim}
     4636psTime *psTime_TideUT1Corr(const psTime *time);
     4637\end{verbatim}
     4638
     4639Leap seconds are added to UTC in order to keep it within $0.9s$ of UT1
     4640(which is defined relative to the Earth's rotation, and hence is
     4641useful for astronomical purposes).  The following function calculates
     4642the absolute number of leap seconds different between two times.
    35524643
    35534644\begin{verbatim}
     
    35554646\end{verbatim}
    35564647
    3557 This function calculates the absolute number of leap seconds different between
    3558 two times.
     4648The following function accepts \code{PS_TIME_UTC} objects and
     4649determines if the time is potentaly a leapsecond, returning
     4650\code{TRUE} if so.
    35594651
    35604652\begin{verbatim}
    35614653bool psTimeIsLeapSecond(const psTime *utc);
    35624654\end{verbatim}
    3563 
    3564 This function only accepts \code{PS_TIME_UTC} objects and determines if the
    3565 time is potentaly a leapsecond.
    35664655
    35674656\subsubsection{External Date and Time Formats}
     
    35814670\end{verbatim}
    35824671
    3583 The \code{psTimeToISO()} function will convertion \code{PS_TIME_UTC} objects
    3584 with the \code{leapsecond} flag set to represent the number of seconds as
    3585 ``:60''.
     4672The \code{psTimeToISO()} function converts \code{PS_TIME_UTC} objects
     4673with the \code{leapsecond} flag set to represent the number of seconds
     4674as ``:60''.
    35864675
    35874676\subsubsection{Date and Time Parsing}
     
    36224711\code{psS64} (the type of \code{psTime.sec}).
    36234712
    3624 Note that in both these functions, when handling UTC, that the difference
    3625 between two times is not inclusive of leap seconds.  For example, if we add 30
    3626 seconds to 1998-12-31T23:59:45Z, the result is 1999-01-01T00:00:14Z, since a
    3627 leap second was introduced at 1999-01-01T00:00:00Z.
    3628 
    3629 Time math may only be done on the of \code{psTime} objects of the same type,
    3630 and in the case of UT1, the functions shall internally convert the
    3631 \code{psTime} inputs to TAI before performing the math; this is in order that
    3632 leap seconds are accounted for.
    3633 
    3634 The type of the time returned by \code{psTimeMath} shall be the same as that of
    3635 the input \code{time}.
    3636 
     4713Note that in both these functions the difference between two times is
     4714the elapsed number of seconds, inclusing leap seconds.  For example,
     4715if we add 30 seconds to 1998-12-31T23:59:45Z, the result is
     47161999-01-01T00:00:14Z, since a leap second was introduced at
     47171999-01-01T00:00:00Z.
     4718
     4719Time math may only be done on \code{psTime} objects of the same type,
     4720and except in the case of UT1, the functions shall internally convert
     4721the \code{psTime} inputs to TAI before performing the math; this
     4722ensures that leap seconds are correctly counted.
     4723
     4724The type of the time returned by \code{psTimeMath} shall be the same
     4725as that of the input \code{time}.
    36374726
    36384727\subsubsection{Time Tables}
     
    36454734
    36464735\begin{itemize}
    3647 \item IERS Bulliten A \& B (1 year ago $\rightarrow$ now + $\sim$3 months)
     4736\item IERS Bulletin A \& B (1 year ago $\rightarrow$ now + $\sim$3 months)
    36484737\begin{itemize}
    36494738\item \code{ftp://maia.usno.navy.mil/ser7/finals.daily}
    36504739\end{itemize}
    36514740
    3652 \item IERS Bulliten A \& B (1973-1-2 $\rightarrow$ now + $\sim$1 year)
     4741\item IERS Bulletin A \& B (1973-1-2 $\rightarrow$ now + $\sim$1 year)
    36534742\begin{itemize}
    36544743\item \code{ftp://maia.usno.navy.mil/ser7/finals.all}
     
    36734762format of these files shall be simple, for speed in reading.  Each line shall
    36744763contain the date in MJD and the following values from both the A \& B IERS
    3675 bullitens: $x_p$ (in arcseconds), $y_p$ (in arcseconds) and $\Delta$UT (in
     4764bulletins: $x_p$ (in arcseconds), $y_p$ (in arcseconds) and $\Delta$UT (in
    36764765seconds).  This format must be readable by \code{psLookupTableRead}.  For
    36774766example:
     
    37564845%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    37574846
    3758 \subsection{Regions}
    3759 
    3760 In many places, we need to refer to a rectangular area.  We define a
    3761 structure to represent a rectangle:
    3762 \begin{verbatim}
    3763 typedef struct {
    3764   float x0;
    3765   float x1;
    3766   float y0;
    3767   float y1;
    3768 } psRegion;
    3769 psRegion *psRegionAlloc (float x0, float x1, float y0, float y1);
    3770 \end{verbatim}
    3771 
    3772 \begin{verbatim}
    3773 psRegion *psRegionFromString (char *region);
    3774 \end{verbatim}
    3775 This function converts the IRAF description of a region in the form
    3776 \code{[x0:x1,y0:y1]}, used for header entries such as \code{BIASSEC},
    3777 into the corresponding \code{psRegion} structure.
    3778 
    3779 \subsection{Metadata}
    3780 \label{sec:metadata}
    3781 
    3782 \subsubsection{Conceptual Overview}
    3783 
    3784 Within PSLib, we provide a data structure to carry metadata and
    3785 mechanisms to manipulate the metadata.  Metadata is a general concept
    3786 that requires some discussion.  In any data analysis task, the
    3787 ensemble of all possible data may be divided into two or three
    3788 classes: there is the specific data of interest, there is data which
    3789 is related or critical but not the primary data of interest, and there
    3790 is all of the other data which may or may not be interesting.  For
    3791 example, consider a simple 2D image obtained of a galaxy from a CCD
    3792 camera on a telescope.  If you want to study the galaxy, the specific
    3793 data of interest is the collection of pixels.  There are a variety of
    3794 other pieces of data which are closely related and crucial to
    3795 understanding the data in those pixels, such as the dimensions of the
    3796 image, the coordinate system, the time of the image, the exposure
    3797 time, and so forth.  Other data may be known which may be less
    3798 critical to understanding the image, but which may be interesting or
    3799 desired at a later date.  For example, the observer who took the
    3800 image, the filter manufacturer, the humidity at the telescope, etc.
    3801 
    3802 Formally, all of the related data which describe the principal data of
    3803 interest are metadata.  Note that which piece is the metadata and
    3804 which is the data may depend on the context.  If you are examining the
    3805 pixels in an image, the coordinate and flux of an object may be part
    3806 of the metadata.  However, if you are analyzing a collection of
    3807 objects extracted from an image, you may consider then pixel data
    3808 simply part of the metadata associated with the list of objects. 
    3809 
    3810 There are various ways to handle metadata vs data within a programming
    3811 environment.  In C, it is convenient to use structures to group
    3812 associated data together.  One possibility is to define the metadata
    3813 as part of the associated data structure.  For example, the image data
    3814 structure would have elements for all possible associated measurement.
    3815 This approach is both cumbersome (because of the large number metadata
    3816 types), impractical (because the full range of necessary metadata is
    3817 difficult to know in advance) and inflexible (because any change in
    3818 the collection of metadata requires addition of new structure elements
    3819 and recompilation). 
    3820 
    3821 An alternative is to place the metadata in a generic container and use
    3822 lookup mechanisms to extract the appropriate metadata when needed.  An
    3823 example of this is would be a text-based FITS header for an image read
    3824 into a flat text buffer.  In this implementation, metadata lookup
    3825 functions could return the current value of, for example, NAXIS1 (the
    3826 number of columns of the image) by scanning through the header buffer.
    3827 This method has the benefits of flexibility and simplicity of
    3828 programming interface, but it has the disadvantage that all metadata
    3829 is accessed though this lookup mechanism.  This may make the code less
    3830 readable and it may slow down the access. 
    3831 
    3832 PSLib implements an intermediate solution to this problem.  We specify
    3833 a flexible, generic metadata container and access methods.  Data types
    3834 which require association with a general collection of metadata should
    3835 include an entry of this metadata type.  However, a subset of metadata
    3836 concepts which are basic and frequently required may be placed in the
    3837 coded structure elements.  This approach allows the code to refer to
    3838 the basic metadata concepts as part of the data structure (ie,
    3839 \code{image.nx}), but also allows us to provide access to any
    3840 arbitrary metadata which may be generated.  As a practical matter, the
    3841 choice of which entries are only in the metadata and which are part of
    3842 the explicit structure elements is rather subjective.  Any data
    3843 elements which are frequently used should be put in the structure;
    3844 those which are only infrequently needed should be left in the generic
    3845 metadata.
    3846 
    3847 There are some points of caution which must be noted.  Any
    3848 manipulation of the data should be reflected in the metadata where
    3849 appropriate.  This is always an issue of concern.  For example,
    3850 consider an image of dimensions \code{nx, ny}.  If a function extracts
    3851 a subraster, it must change the values of \code{nx, ny} to match the
    3852 new dimensions.  What should it do to the corresponding metadata?
    3853 Clearly, it should change the corresponding value which defines
    3854 \code{nX, nY}.  However, it is not quite so simple: there may be other
    3855 metadata values which depend on those values.  These must also be
    3856 changed appropriately.  What if the metadata element points to a
    3857 copy of the metadata which may be shared by other representations of
    3858 the image?  These must be treated differently because the change would
    3859 invalidate those other references.  Care must be taken, therefore,
    3860 when writing functions which operate on the data to consider all of
    3861 the relevant metadata entries which must also be updated.
    3862 
    3863 A related issue is the definition of metadata names.  Entries in a
    3864 structure have the advantage of being hardwired: every instance of
    3865 that structure will have the same name for the same entry.  This is
    3866 not necessarily the case with a more flexible metadata container.  The
    3867 image exposure time is a notorious example in astronomy.  Different
    3868 observatories use different header keywords (ie, metadata names) for
    3869 the same concept of the exposure time (\code{EXPTIME},
    3870 \code{EXPOSURE}, \code{OPENTIME}, \code{INTTIME}, etc).  Any system
    3871 which operates on these metadata needs to address the issue of
    3872 identifying these names.  This issue seems like an argument for
    3873 hardwiring metadata in the structure, but in fact it does not present
    3874 such a strong case.  If the metadata are hardwired, some function will
    3875 still have to know how to interpret the various names to populate the
    3876 structure.  The concept can still be localized with generic metadata
    3877 containers by including abstract metadata names within the code which
    3878 are tied to the various implementations-specific metadata names.
    3879 
    3880 \subsubsection{Metadata Representation}
    3881 
    3882 \begin{figure}
    3883 \psfig{file=Metadata,width=6.5in}
    3884 \caption{Metadata Structures\label{fig:metadata}}
    3885 \end{figure}
    3886 
    3887 This section addresses the question of how \PS{} metadata should be
    3888 represented in memory, not how it should be represented on disk.
    3889 
    3890 We define an item of metadata with the following structure:
    3891 \filbreak
    3892 \begin{verbatim}
    3893 typedef struct {
    3894     int id;                             ///< unique ID for this item
    3895     char *name;                         ///< Name of item
    3896     psMetadataType type;                ///< type of this item
    3897     psElemType ptype;                   ///< primitive data type
    3898     const union {
    3899         psS32 S32;                      ///< integer data
    3900         psF32 F32;                      ///< floating-point data
    3901         psF64 F64;                      ///< double-precision data
    3902         void *V;                        ///< other type
    3903         psList *list;                   ///< psList entry
    3904         psMetadata *md;                 ///< psMetadata entry
    3905     } data;                             ///< value of metadata
    3906     char *comment;                      ///< optional comment ("", not NULL)
    3907 } psMetadataItem;
    3908 \end{verbatim}
    3909 
    3910 The \code{id} is a unique identifier for this item of metadata;
    3911 experience shows that such tags are useful.  The entry \code{name}
    3912 specifies the name of the metadata item.  The value of the metadata is
    3913 given by the union \code{data}, and may be of type \code{psS32},
    3914 \code{psF32}, \code{psF64}, or an arbitrary rich structure pointed at
    3915 by the \code{void} pointer \code{V}.  A character string comment
    3916 associated with this metadata item may be stored in the element
    3917 \code{comment}. The \code{type} entry specifies how to interpret the
    3918 type of the data being represented, given by the enumerated type
    3919 \code{psMetadataType}:
    3920 %
    3921 \filbreak
    3922 \begin{verbatim}
    3923 typedef enum {                          ///< type of item.data is:
    3924     PS_META_PRIMITIVE,                  ///< primitive type: use item.ptype
    3925     PS_META_LIST,                       ///< psList; use item.data.list (used for non-unique data)
    3926     PS_META_META,                       ///< psMetadata: use item.data.list
    3927     PS_META_STR,                        ///< string (item.data.V)
    3928     PS_META_MATH,                       ///< psScalar, psVector, psImage (item.data.V)
    3929     PS_META_JPEG,                       ///< JPEG (item.data)
    3930     PS_META_PNG,                        ///< PNG (item.data)
    3931     PS_META_ASTROM,                     ///< astrometric coefficients (item.data)
    3932     PS_META_UNKNOWN,                    ///< other (item.data)
    3933     PS_META_NTYPE                       ///< Number of types; must be last
    3934 } psMetadataType;
    3935 \end{verbatim}
    3936 If the data is a PSLib primitive data value, the primitive data type
    3937 is given by the value of \code{ptype}.
    3938 
    3939 A collection of metadata is represented by the \code{psMetadata} structure:
    3940 \begin{verbatim}
    3941 typedef struct {
    3942     psList *list;                       ///< list of psMetadataItem
    3943     psHash *table;                      ///< hash table of the same metadata
    3944 } psMetadata;
    3945 \end{verbatim}
    3946 The type \code{psMetadata} is a container class for metadata. Note
    3947 that there are in fact \emph{two} representations of the metadata
    3948 (each \code{psMetadataItem} appears on both).  The first
    3949 representation employs a doubly-linked list that allows the order of
    3950 the metadata to be preserved (e.g., if FITS headers are read in a
    3951 particular order, they should be written in the same order).  The
    3952 second representation employs a hash table which allows fast look-up
    3953 given a specific metadata keyword.
    3954 
    3955 Certain metadata names (such as the FITS keywords \code{COMMENT} and
    3956 \code{HISTORY} in a FITS header) may be repeated with different
    3957 values.  In such a case, the \code{psMetadata.list} structure contains
    3958 the entries in their original sequence with duplicate keys.  The
    3959 \code{psMetadata.hash} entries, which are required to have unique
    3960 keys, would have a single entry with the keyword of the repeated key,
    3961 with the value of \code{psMetadataType} set to \code{PS_META_LIST},
    3962 and the \code{psMetadataItem.data} element pointing to a \code{psList}
    3963 containing the actual entries.  If \code{psMetadataItemAlloc} is
    3964 called with the type set to \code{PS_META_LIST}, such a repeated key
    3965 is created.  If the data value passed to \code{psMetadataItemAlloc}
    3966 (the quantity in ellipsis) is \code{NULL}, then an empty
    3967 \code{psMetadataItem} with the given keyword is created to hold future
    3968 entries of that keyword.
    3969 
    3970 The \code{psMetadataAdd} routine is required to check that all
    3971 metadata names are unique unless the type is already qualified as
    3972 \code{PS_META_LIST}; in this case the data are added to the
    3973 corresponding \code{psMetadataItem.data} list.
    3974 
    3975 \subsubsection{Metadata APIs}
    3976 
    3977 The allocator for \code{psMetadataItem} returns a full
    3978 \code{psMetadataItem} ready for insertion into the \code{psMetadata}.
    3979 The \code{name} entry specifies the name to use for this metadata
    3980 item, and may include \code{sprintf}-type formating codes.  The
    3981 \code{comment} entry is a fixed string which is used for the comment
    3982 associated with this metadata item.  The metadata data and the
    3983 arguments to the \code{name} formatting codes are passed, in that
    3984 order (metadata pointer first), to \code{psMetadataItemAlloc} as
    3985 arguments following the comment string.  The data must be a pointer
    3986 for any data types which are stored in the element \code{data.void},
    3987 while other data types are passed as numeric values.  The argument
    3988 list must be interpreted appropriately by the \code{va_list} operators
    3989 in the function.
    3990 \begin{verbatim}
    3991 psMetadataItem *psMetadataItemAlloc(const char *name, psMetadataType type, const char *comment, ...);
    3992 psMetadataItem *psMetadataItemAllocV(const char *name, psMetadataType type, const char *comment, va_list list);
    3993 \end{verbatim}
    3994 
    3995 The constructor for the collection of metadata, \code{psMetadata},
    3996 simply returns an empty metadata container (employing the constructors
    3997 for the doubly-linked list and hash table).  The destructor needs to
    3998 free each of the \code{psMetadataItem}s using \code{psMetadataItemFree}.
    3999 \begin{verbatim}
    4000 psMetadata *psMetadataAlloc(void);
    4001 \end{verbatim}
    4002 
    4003 Items may be added to the metadata in one of two ways --- firstly, an
    4004 item may be added by appending a \code{psMetadataItem} which has
    4005 already been created; and secondly by directly providing the data to
    4006 be appended.  In both cases, the return value defines the success
    4007 (\code{true}) or failure of the operation.  The second function,
    4008 \code{psMetadataAdd} takes a pointer or value which is interpreted by
    4009 the function using variadic argument interpretation.  The third
    4010 version is the \code{va_list} version of the second function.  All
    4011 three functions take a parameter, \code{location}, which specifies
    4012 where in the list to place the element, following the conventions for
    4013 the \code{psList}.  The entry \code{mode} for \code{psMetadataAddItem}
    4014 is a bit mask constructed by OR-ing the allowed option flags (eg,
    4015 \code{PS_META_REPLACE}) which specifies minor variations on the
    4016 behavior.  The \code{format} entry, which specifies both the metadata
    4017 type and the optional flags, is constructed by bit-wise OR-ing the
    4018 appropriate \code{psMetadataType} and allowed option option flags.
    4019 Care should be taken not to leak memory when appending an item for
    4020 which the key already exists in the metadata (and is not
    4021 \code{PS_META_LIST}).
    4022 %
    4023 \begin{verbatim}
    4024 bool psMetadataAddItem(psMetadata *md, psMetadataItem *item, int location, int mode);
    4025 bool psMetadataAdd(psMetadata *md, int location, const char *name, int format, const char *comment, ...);
    4026 bool psMetadataAddV(psMetadata *md, int location, const char *name, int format, const char *comment,
    4027                     va_list list);
    4028 \end{verbatim}
    4029 
    4030 The functions above take option flags which modify the behavior when
    4031 metadata items are added to the metadata list.  These flags must be
    4032 bit-exclusive of those used above for the \code{psMetadataTypes}.  The
    4033 flags have the following meanings:
    4034 
    4035 \code{PS_META_DEFAULT}: This is the zero bit mask, to allow the
    4036 default behavior for \code{psMetadataAddItem} above.  If this is OR-ed
    4037 with a \code{psMetadataType}, the result is as if no OR-ing took
    4038 place.
    4039 
    4040 \code{PS_META_REPLACE}: If the given metadata item exists in the
    4041 metadata list, and is not of type \code{PS_META_LIST} or
    4042 \code{PS_META_META} (ie, not a container type), then this entry is
    4043 allowed to replace the existing entry.  If this mode bit is not set, a
    4044 duplicate (non-container-type) entry is an error.
    4045 
    4046 \begin{verbatim}
    4047 typedef enum {                          ///< option flags for psMetadata functions
    4048     PS_META_DEFAULT,                    ///< default behavior (0x0000) for use in mode above
    4049     PS_META_REPLACE,                    ///< allow entry to be replaced
    4050 } psMetadataFlags;
    4051 \end{verbatim}
    4052 
    4053 An example of code to use these metadata APIs to generate the
    4054 structure seen in Figure~\ref{fig:metadata} is given below.
    4055 
    4056 \begin{verbatim}
    4057 md = psMetadataAlloc();
    4058 
    4059 psMetadataAdd(md, PS_LIST_TAIL, "SIMPLE",   PS_META_BOOL, "basic fits",            TRUE);
    4060 psMetadataAdd(md, PS_LIST_TAIL, "BLANK",    PS_META_S32,  "invalid pixel data",    -32768);
    4061 psMetadataAdd(md, PS_LIST_TAIL, "DATE-OBS", PS_META_STR,  "observing date UT", "   2004-6-16");
    4062 psMetadataAdd(md, PS_LIST_TAIL, "COMMENT",  PS_META_LIST, "head of comment block", NULL);
    4063 psMetadataAdd(md, PS_LIST_TAIL, "COMMENT",  PS_META_STR,  "",                      "DATA");
    4064 psMetadataAdd(md, PS_LIST_TAIL, "COMMENT",  PS_META_STR,  "",                      "PARAMS");
    4065 psMetadataAdd(md, PS_LIST_TAIL, "EXPTIME",  PS_META_F32,  "exposure time (sec)",   1.05);
    4066 psMetadataAdd(md, PS_LIST_TAIL, "COMMENT",  PS_META_STR,  "",                      "FOO");
    4067 
    4068 cell = psMetadataAlloc();
    4069 psMetadataAdd(cell, PS_LIST_TAIL, "EXTNAME",  PS_META_STR,  "",                    "CCD00");
    4070 psMetadataAdd(cell, PS_LIST_TAIL, "BIASNAME", PS_META_STR,  "",                    "BSEC-00");
    4071 psMetadataAdd(cell, PS_LIST_TAIL, "CHIP",     PS_META_STR,  "",                    "CHIP.00");
    4072 psMetadataAdd(md,   PS_LIST_TAIL, "CELL.00",  PS_META_META, "",                    cell);
    4073 
    4074 cell = psMetadataAlloc();
    4075 psMetadataAdd(cell, PS_LIST_TAIL, "EXTNAME",  PS_META_STR,  "",                    "CCD01");
    4076 psMetadataAdd(cell, PS_LIST_TAIL, "BIASNAME", PS_META_STR,  "",                    "BSEC-01");
    4077 psMetadataAdd(cell, PS_LIST_TAIL, "CHIP",     PS_META_STR,  "",                    "CHIP.01");
    4078 psMetadataAdd(md,   PS_LIST_TAIL, "CELL.01",  PS_META_META, "",                    cell);
    4079 \end{verbatim}
    4080 
    4081 The following code shows how to use the APIs to replace one of these values:
    4082 \begin{verbatim}
    4083 psMetadataAdd(md, PS_LIST_TAIL, "EXPTIME",  PS_META_F32 | PS_REPLACE,  "new exposure time (sec)",   2.05);
    4084 \end{verbatim}
    4085 
    4086 Items may be removed from the metadata by specifying a key or a
    4087 location in the list.  If the value of \code{name} is \code{NULL}, the
    4088 value of \code{location} is used.  If the value of \code{name} is not
    4089 \code{NULL}, then \code{location} must be set to
    4090 \code{PS_LIST_UNKNOWN}.  If the key matches a metadata item, the item
    4091 is removed from the metadata and \code{true} is returned; otherwise,
    4092 \code{false} is returned.  If the key is not unique, then \emph{all}
    4093 items corresponding to the key are removed, and \code{true} is
    4094 returned.
    4095 %
    4096 \begin{verbatim}
    4097 bool psMetadataRemove(psMetadata *md, int location, const char *key);
    4098 \end{verbatim}
    4099 
    4100 Items may be found within the metadata by providing a key.  In the
    4101 event that the key is non-unique, the first item is returned.
    4102 \begin{verbatim}
    4103 psMetadataItem *psMetadataLookup(const psMetadata *md, const char *key);
    4104 \end{verbatim}
    4105 
    4106 Several utility functions are provided for simple cases.  These
    4107 functions perform the effort of casting the data to the appropriate
    4108 type.  The numerical functions shall return 0.0 if their key is not
    4109 found.  If the pointer value of \code{status} is not \code{NULL}, it
    4110 is set to reflect the success or failure of the lookup.
    4111 \begin{verbatim}
    4112 void *psMetadataLookupPtr(bool *status, const psMetadata *md, const char *key);
    4113 psS32 psMetadataLookupS32(bool *status, const psMetadata *md, const char *key);
    4114 psF64 psMetadataLookupF64(bool *status, const psMetadata *md, const char *key);
    4115 \end{verbatim}
    4116 
    4117 Items may be retrieved from the metadata by their entry position.  The
    4118 value of which specifies the desired entry in the fashion of
    4119 \code{psList}.
    4120 \begin{verbatim}
    4121 psMetadataItem *psMetadataGet(const psMetadata *md, int location);
    4122 \end{verbatim}
    4123 
    4124 The metadata list component may be iterated over by using a
    4125 \code{psListIterator} in a fashion equivalent to the usage for
    4126 \code{psList}.  The iterator may be set to a location in the
    4127 \code{psMetadata} list, and the user may get the previous or next item
    4128 in the list relative to that location.  \code{psMetadataGetNext} has
    4129 the ability to match the key using a POSIX regex, e.g., if the user
    4130 only wants to iterate through \code{IPP.machines.sky} and doesn't want
    4131 to bother with \code{IPP.machines.detector}.  The iterator should
    4132 iterate over every item in the metadata list, even those that are
    4133 contained in a \code{PS_META_LIST}.  The value \code{iterator}
    4134 specifies the iterator to be used.  In setting the iterator, the
    4135 position of the iterator is defined by \code{location}, which follows
    4136 the conventions of the \code{psList} iterators.
    4137 \begin{verbatim}
    4138 psListIterator *psMetadataIteratorAlloc(psMetadata *md, int location, bool mutable);
    4139 bool psMetadataIteratorSet(psListIterator *iterator, int location);
    4140 psMetadataItem *psMetadataGetAndIncrement(psListIterator *iterator, const char *regex);
    4141 psMetadataItem *psMetadataGetAndDecrement(psListIterator *iterator, const char *regex);
    4142 \end{verbatim}
    4143 
    4144 Metadata items may be printed to an open file descriptor based on a
    4145 provided format.  The format string is an sprintf format statement
    4146 with exactly one \% formatting command.  If the metadata item type is
    4147 a numeric type, this formatting command must also be numeric, and type
    4148 conversion performed to the value to match the format type.  If the
    4149 metadata item type is a string, the formatting command must also be
    4150 for a string (\%s type of command).  If the metadata type is any other
    4151 data type, printing is not allowed.
    4152 \begin{verbatim}
    4153 bool psMetadataItemPrint(FILE *fd, const char *format, const psMetadataItem *md);
    4154 \end{verbatim}
    4155 
    4156 \subsubsection{Configuration files}
    4157 \label{sec:configspec}
    4158 
    4159 It will be necessary for the \PS{} system, in order to load
    4160 pre-defined settings, to parse a configuration file into a
    4161 \code{psMetadata} structure.  This shall be performed by the
    4162 function \code{psMetadataParseConfig}, as described below.
    4163 
    4164 \begin{verbatim}
    4165 psMetadata *psMetadataParseConfig(psMetadata *md, int *nFail, const char *filename, bool overwrite);
    4166 \end{verbatim}
    4167 
    4168 Given a metadata container, \code{md}, and the name of a configuration
    4169 file, \code{filename}, \code{psMetadataParseConfig} shall parse the
    4170 configuration file, placing the contained key/type/value/comment quads
    4171 into the metadata, and returning a pointer to the metadata structure.
    4172 The number of lines that failed to parse is returned in \code{nFail}.
    4173 Multiple specifications of a key that haven't been declared (see
    4174 below) are overwritten if and only if \code{overwrite} is \code{true}.
    4175 If the metadata container is \code{NULL}, it shall be allocated. 
    4176 
    4177 On error, the function shall return \code{NULL}.
    4178 
    4179 The configuration file shall consist of plain text with
    4180 key/type/value/comment quads on separate lines.  Blank lines,
    4181 including those consisting solely of whitespace (both spaces and
    4182 tabs), shall be ignored, as shall lines that commence with the comment
    4183 character (a hash mark, \code{#}), either immediately at the start of
    4184 the line, or preceded by whitespace.  The key/type/value/comment quads
    4185 shall all lie on a single line, separated by whitespace.
    4186 
    4187 The key shall be first, possibly preceded on the line by whitespace
    4188 which should not form part of the key.
    4189 
    4190 Next, to assist the casting of the value, shall be a string
    4191 identifying the type of the value, which shall correspond to one of
    4192 the simple types supported in \code{psMetadata}:
    4193 \code{STRING,BOOL,S32,F32,F64}; \code{STR} may be used to abbreviate
    4194 \code{STRING}.
    4195 
    4196 \tbd{May, in the future, require more types, including U8,S16,C64,
    4197 which will also necessitate updating the definition of psMetadata.}
    4198 
    4199 The value shall follow the type: strings may consist of multiple
    4200 words, and shall have all leading and trailing whitespace removed;
    4201 booleans shall simply be either \code{T} or \code{F}.
    4202 
    4203 Following the value may be an optional comment, preceded by a comment
    4204 character (a hash mark, \code{#}), which in the case of a string
    4205 value, serves to mark the end of the value, and for other types serves
    4206 to identify the comment to the reader.  Only one comment character may
    4207 be present on any single line (i.e., neither strings nor comments are
    4208 permitted to contain the comment character).  The comment may consist
    4209 of multiple words, and shall have leading and trailing whitespace
    4210 removed.
    4211 
    4212 One wrinkle is the specification of vectors.  Keys for which the value
    4213 is to be parsed as a vector shall be preceded immediately by a
    4214 ``vector symbol'', which we choose to be the ``at'' sign, \code{@}.
    4215 In this case, the type shall be interpreted as the type for the
    4216 vector, which may be any of the signed or unsigned integer or floating
    4217 point types (\code{U8,U16,U32,U64,S8,S16,S32,S32,S64,F32,F64}) but not
    4218 the complex floating point types; and the value shall consist of
    4219 multiple numbers, separated either by a comma or whitespace.  These
    4220 values shall populate a \code{psVector} of the appropriate type in the
    4221 order in which they appear in the configuration file.
    4222 
    4223 \tbd{May add complex types, likely to be specified with values such as
    4224   1.23+4.56i in the future.}
    4225 
    4226 An additional hurdle is the specification of keys that may be
    4227 non-unique (such as the \code{COMMENT} keyword in a FITS header).
    4228 These keys shall be specified in the configuration file as non-unique
    4229 by specifying the key at the start of the line (possibly preceded by
    4230 whitespace) and specifying the type as a ``multiple symbol'', which we
    4231 choose to be an asterisk, \code{*}.  No other data may be provided on
    4232 this line, though a comment, preceeded by the comment marker, is
    4233 valid.  A warning shall be produced when a key which has not been
    4234 specified to be non-unique is repeated; in this case, the former value
    4235 shall be overwritten if \code{overwrite} is \code{true}, otherwise the
    4236 line shall be ignored and counted as one that could not be parsed.
    4237 
    4238 If a line does not conform to the rules laid out here, a warning shall
    4239 be generated, it shall be ignored and counted as a line that could not
    4240 be parsed.  The total number of lines that were not able to be parsed
    4241 (including those that were ignored because \code{overwrite} is
    4242 \code{false}, and any other parsing problems, but not including blank
    4243 lines and comment lines) shall be returned by the function in the
    4244 argument \code{nFail}.
    4245 
    4246 Here are some examples of lines of a valid configuration file:
    4247 \filbreak
    4248 \begin{verbatim}
    4249 Double     F64     1.23456789      # This is a comment
    4250 Float    F32 0.98765 # This is a comment too
    4251 String  STR This is the string that forms the value #comment
    4252 
    4253  # This is a comment line and is to be ignored
    4254 boolean     BOOL    T # The value of `boolean' is `true'
    4255 
    4256 @primes U8  2,3 5 7,11,13 17 #   These are prime numbers
    4257 
    4258 comment MULTI # The rest of this line is ignored, but `comment' is set to be non-unique
    4259 comment STR This
    4260 comment STR     is
    4261 comment STR       a
    4262 comment STR        non-unique
    4263 comment STR                  key
    4264 Float F64 1.23456 # This generates a warning, and, if `overwrite' is `false', is ignored
    4265 \end{verbatim}
    4266 
    4267 Of course, a real configuration file should look much nicer to humans
    4268 than the above example, but PSLib must be able to parse such ugly
    4269 files.
    4270 
    4271 We extend \code{psMetadataParseConfig} to allow a modest tree
    4272 structure by defining a reserved keyword \code{TYPE}.  Any line in the
    4273 config file which starts with the word \code{TYPE} shall be
    4274 interpretted as defining a new valid type.  The defined type name
    4275 follows the word \code{TYPE}, and is in turn followed by an arbitrary
    4276 number of words.  These words are to be interpreted as the names of an
    4277 embedded \code{psMetadata} entry, where the values are given on any
    4278 line which (following the \code{TYPE} definition) employs the new type
    4279 name.  For example, a new type may be defined as:
    4280 \begin{verbatim}
    4281 TYPE      CELL   EXTNAME   BIASSEC  CHIP
    4282 CELL.00   CELL   CCD00     BSEC-00  CHIP.00
    4283 CELL.01   CELL   CCD01     BSEC-01  CHIP.00
    4284 \end{verbatim}
    4285 
    4286 When \code{psMetadataParseConfig} encounters the \code{TYPE} line, it
    4287 should construct a \code{psMetadata} container and fill it with
    4288 \code{psMetadataItems} having the names \code{EXTNAME, BIASSEC, CHIP},
    4289 with type \code{PS_META_STR}, but data allocated.  When it next
    4290 encounters an entry of type \code{CELL}, it should then use the given
    4291 name (e.g., \code{CELL.00}) for the \code{psMetadataItem}, and copy
    4292 the \code{psMetadata} data onto the \code{psMetadataItem.data.md}
    4293 entry, filling in the values from the rest of the line (\code{CCD00,
    4294 BSEC-00, CHIP.00}).  This hierarchical structure is illustrated in
    4295 Figure~\ref{fig:metadata}.
    4296 
    4297 We further extend \code{psMetadataParseConfig} to allow the definition
    4298 of a \code{psMetadata} entry using a sequence of successive lines to
    4299 define the values of the \code{psMetadataItem} entries.  The initial
    4300 line defines the new \code{psMetadata} entry and its name.  The
    4301 following lines have the same format as the other metadata config file
    4302 entries.  The sequence is terminated with a line with a single word
    4303 \code{END}.  For example, a metadata entry may be defined as:
    4304 \begin{verbatim}
    4305 CELL      METADATA
    4306  EXTNAME   STR   CCD00
    4307  BIASSEC   STR   BSEC-00
    4308  CHIP      STR   CHIP.00
    4309  NCELL     S32   24
    4310 END
    4311 \end{verbatim}
    4312 
    4313 A series of test inputs is contained in
    4314 \S\ref{sec:configtest}.
    4315 
    4316 \subsection{XML Functions}
    4317 
    4318 Within Pan-STARRS, we will use XML documents as a transport mechanism
    4319 to carry data between programs and between IPP and other subsystems.
    4320 Configuration information may be stored as well as XML documents, in
    4321 addition to the text format discussed in the discussion on Metadata.
    4322 XML is an extremely variable document format, and it is not currently
    4323 the intention of PSLib to provide a complete PSLib version of XML
    4324 operations.  Rather, a limited number of operations are defined to
    4325 convert specific data structures to an appropriate XML document.  To
    4326 maximize the simplicity of the XML APIs, we will use the convention
    4327 that a single XML document to be parsed by PSLib shall contain only a
    4328 single data structure.  Each of the XML APIs therefore take as input a
    4329 reference to a complete XML document and return a PSLib data
    4330 structure, or take a PSLib data structure and return a complete XML
    4331 document.
    4332 
    4333 We start by defining a PSLib wrapper type which is a pointer to an XML
    4334 document in memory.  We wrap the \code{libxml2} version of an XML
    4335 document pointer for now:
    4336 \begin{verbatim}
    4337 typedef xmlDocPtr psXMLDoc;
    4338 void psXMLDocFree(psXMLDoc *doc);
    4339 \end{verbatim}
    4340 
    4341 The next pair of functions convert a \code{psMetadata} data structure
    4342 to a complete \code{psXMLDoc} (in memory) and vice versa:
    4343 \begin{verbatim}
    4344 psXMLDoc *psMetadataToXMLDoc(const psMetadata *metadata);
    4345 psMetadata *psXMLDocToMetadata(const psXMLDoc *doc);
    4346 \end{verbatim}
    4347 
    4348 The next pair of functions loads the data in a named file into a
    4349 complete \code{psXMLDoc} (in memory) and write out the \code{psXMLDoc}
    4350 to a named file:
    4351 \begin{verbatim}
    4352 psXMLDoc *psXMLParseFile(const char *filename);
    4353 int psXMLDocToFile(const psXMLDoc *doc, const char *filename);
    4354 \end{verbatim}
    4355 
    4356 The next pair of functions accepts a block of memory and parses it
    4357 into a complete \code{psXMLDoc} (also in memory), and vice versa:
    4358 \begin{verbatim}
    4359 psXMLDoc *psXMLParseMemory(const char *buffer, const int size);
    4360 int psXMLDocToMemory(const psXMLDoc *doc, char *buffer);
    4361 \end{verbatim}
    4362 
    4363 The next pair of functions read from and write to a file descriptor.
    4364 The first converts the imcoming data to a complete \code{psXMLDoc}
    4365 (also in memory), the second writes the \code{psXMLDoc} to the file
    4366 descriptor:
    4367 \begin{verbatim}
    4368 psXMLDoc *psXMLParseFD(int fd);
    4369 int psXMLDocToFD(const psXMLDoc *doc, int fd);
    4370 \end{verbatim}
    4371 
    4372 \subsection{Database Functions}
    4373 
    4374 Many of the applications that PSLib will be used for will require
    4375 access to a simple relational database.  PSLib includes generic
    4376 database-independent interface mechanisms as part of its API set.  The
    4377 most important aspect of PSLib's database support is to abstract as
    4378 much database specific complexity as is feasible.  As almost all RDBMS
    4379 provide at least a simple transactional model, commit and rollback
    4380 support should be provided.
    4381 
    4382 Currently, only support for MySQL 4.1.x is required but other backends
    4383 may be added as options in the future.  As a particular example which
    4384 has implications for the database interaction model, support for
    4385 SQLite may be required in the future.  Currently, the choice of
    4386 backend database interface may be made as a compile option.  Details
    4387 of the specified APIs in the discussion below refer to the relevant
    4388 MySQL functions.
    4389 
    4390 Database errors must be trapped and placed onto the psError stack.
    4391 The complete error message should be retrieved with the database's
    4392 error function.
    4393 
    4394 \subsubsection{Managing the Database Connection}
    4395 
    4396 We specify a database handle which carries the information about the
    4397 database connection:
    4398 
    4399 \begin{verbatim}
    4400     typedef struct {
    4401         MYSQL *mysql;
    4402     } psDB;
    4403 \end{verbatim}
    4404 
    4405 The following collection of functions provides basic database functionality:
    4406 
    4407 \begin{verbatim}
    4408     // wraps mysql_init() & mysql_real_connect()
    4409     psDB *psDBInit(const char *host, const char *user, const char *passwd, const char *dbname);
    4410 
    4411     // wraps mysql_close()
    4412     void psDBCleanup(psDB *dbh);
    4413 
    4414     // wraps mysql_create_db()
    4415     bool psDBCreate(psDB *dbh, const char *dbname);
    4416 
    4417     // wraps mysql_select_db()
    4418     bool psDBChange(psDB *dbh, const char *dbname);
    4419 
    4420     // wraps mysql_drop_db()
    4421     bool psDBDrop(psDB *dbh, const char *dbname);
    4422 \end{verbatim}
    4423 
    4424 For MySQL support, \code{psDBInit()} wraps \code{mysql_init()} and
    4425 \code{mysql_real_connect()} in order to initialize a psDB structure and
    4426 establish a database connection.  A null pointer should be returned on
    4427 failure.
    4428 
    4429 When implementing support for SQLite, or other DB which is purely
    4430 file-based, the \code{host}, \code{user}, and \code{passwd} arguments
    4431 would be ignored while \code{dbname} would specify the path to the
    4432 SQLite db file.
    4433 
    4434 \subsubsection{Interacting with Database Tables}
    4435 
    4436 The functions in this section perform high level interactions with the
    4437 database tables.  All of them should behave ``atomically'' with
    4438 respect to the state of the database.  Specifically, all interactions
    4439 with the database should be done as a part of a transaction that is
    4440 rolled-back on failure and committed only after all queries used by
    4441 the API have been run.  In general, this API set attempts to treat a
    4442 database table as a 2D matrix where columns can be represented by a
    4443 \code{psVector} and rows as a \code{psMetadata} type.  A
    4444 \code{psMetadata} collection is also used to define the columns of a
    4445 table and as part of the query restrictions.
    4446 
    4447 \begin{verbatim}
    4448     bool psDBCreateTable(psDB *dbh, const char *tableName, psMetadata *md);
    4449 \end{verbatim}
    4450 
    4451 This function generates and executes the SQL needed to create a table
    4452 named \code{tableName}, with the column names and datatypes as
    4453 described in \code{md}.  Each data item in the \code{psMetadata}
    4454 collection represents a single table field.  The name of the field is
    4455 given by the name of the \code{psMetadataItem} and the data type is
    4456 give by the \code{psMetadataItem.type} and \code{psMetadataItem.ptype}
    4457 entries.  A lookup table should be used to convert from PSLib types
    4458 into MySQL compatible SQL data types.  For example, a
    4459 \code{PS_META_STR} would map to an SQL99 varchar.  If the value of
    4460 \code{type} is \code{PS_META_STR} then the \code{psMetadataItem.data}
    4461 element is set to a string with the length for the field written as a
    4462 text string.  The value of the \code{psMetadataItem.data} element is
    4463 unused for the \code{PS_META_PRIMITIVE} types.  Other metadata types
    4464 beyond \code{PS_META_STR} and \code{PS_META_PRIMITIVE} are not allowed
    4465 in a table definition metadata collection.
    4466 
    4467 Database indexes can be specified setting the \code{comment} field to
    4468 ``\code{Primary Key}'' or ``\code{Key}''.  Comment are otherwise
    4469 ignored.
    4470 
    4471 \begin{verbatim}
    4472     bool psDBDropTable(psDB *dbh, const char *tableName);
    4473 \end{verbatim}
    4474 
    4475 This function deletes the specified table.
    4476 
    4477 \begin{verbatim}
    4478     psArray *psDBSelectColumn(psDB *dbh, const char *tableName, const char *col, const psU64 limit);
    4479     psVector *psDBSelectColumnNum(psDB *dbh, const char *tableName, const char *col, psElemType pType, const psU64 limit);
    4480 \end{verbatim}
    4481 
    4482 These functions generates and executes the SQL needed to select an entire
    4483 column from a table or up to \code{limit} rows from it.  If \code{limit} is 0,
    4484 the entire range is returned.  The database response is processed and a
    4485 \code{psArray} of strings is returned.  The Num version of the function returns
    4486 the data in a \code{psVector}, data cast to \code{pType}.  It returns an error
    4487 (NULL) if the requested field is not a numerical type.
    4488 
    4489 \begin{verbatim}
    4490     psArray *psDBSelectRows(psDB *dbh, const char *tableName, psMetadata *where, const psU64 limit);
    4491 \end{verbatim}
    4492 
    4493 This function returns rows from the specified table which match
    4494 the restrictions given by \code{where}.  The restrictions are
    4495 specified as field / value pairs.  The \code{psMetadata} collection
    4496 where must consist of valid database fields, though the database query
    4497 checking functions may be used to validate the fields as part of the
    4498 query.  If \code{where} is \code{NULL}, then there are no restrictions
    4499 on the rows selected.  The selected rows are returned as a
    4500 \code{psArray} of \code{psMetadata} values, one per row.
    4501 
    4502 \begin{verbatim}
    4503     bool psDBInsertOneRow(psDB *dbh, const char *tableName, psMetadata *row);
    4504 \end{verbatim}
    4505 
    4506 Insert the data from \code{row} into \code{tableName}.  It should be noted in
    4507 the API reference that if fields are specified in \code{row} that do not exist
    4508 in \code{tablename}, the insert will fail.
    4509 
    4510 \begin{verbatim}
    4511     bool psDBInsertRows(psDB *dbh, const char *tableName, psArray *rowSet);
    4512 \end{verbatim}
    4513 
    4514 Similar to \code{psDBInsertOneRow()}, this function inserts many rows at once
    4515 and is atomic for the complete set of rows.
    4516 
    4517 \begin{verbatim}
    4518     psArray *psDBDumpRows(psDB *dbh, const char *tableName);
    4519 \end{verbatim}
    4520 
    4521 Fetch all rows as an psArray of psMetadata.
    4522 
    4523 \begin{verbatim}
    4524     psMetadata *psDBDumpCols(psDB *dbh, const char *tableName);
    4525 \end{verbatim}
    4526 
    4527 Fetch all columns, as either a psVector or a psArray depnding on whether or not
    4528 the column is numeric, and return them in a psMetadata structure where
    4529 psMetadataItem.name contains the column's name.
    4530 
    4531 \begin{verbatim}
    4532     psS64 psDBUpdateRows(psDB *dbh, const char *tableName, psMetadata *where, psMetadata *values);
    4533 \end{verbatim}
    4534 
    4535 Update the columns contained in \code{values} in the row(s) that have a field
    4536 with the value indicated by \code{where} (note that this is only allows very
    4537 limited use of SQL99's ``where'' semantics).  The number of rows modified is
    4538 returned.  A negative value is return to indicate an error. If there are
    4539 multiple psMetadataItems in \code{where} then each item should be considered as
    4540 an additional constraint.  e.g.  ``where foo = x and where bar = y''
    4541 
    4542 \begin{verbatim}
    4543     psS64 psDBDeleteRows(psDB *dbh, const char *tableName, psMetadata *where);
    4544 \end{verbatim}
    4545 
    4546 Delete the rows that are matched by \code{where} using the same semantics for
    4547 \code{where} as in psDBUpdateRow().  A negative value is returned to indicate an
    4548 error.
    4549 
    4550 \subsection{FITS I/O Functions}
    4551 
    4552 We need a variety of I/O functions between the disk and certain of our
    4553 PSLib data structures.  We need the ability to access FITS headers,
    4554 images and tables (both ASCII and Binary).  We define here the FITS
    4555 I/O functions, all of which are currently specified as wrappers to
    4556 functions within CFITSIO.  CFITSIO provides a wide range of utilities
    4557 which we do not feel are particularly appropriate as part of a generic
    4558 I/O library, such as assumptions about names which change the data
    4559 interpretation, etc.  We are defining our calls to avoid the hidden
    4560 'features'.  The CFITSIO functions which are wrapped should in general
    4561 be the most basic versions.
    4562 
    4563 \begin{verbatim}
    4564 typedef struct {
    4565     fitsfile fd;
    4566 } psFits;
    4567 \end{verbatim}
    4568 We begin by defining a datatype to wrap the CFITSIO \code{fitsfile}
    4569 structure.  This is necessary to allow repeated access to the data in
    4570 a file without multiple open commands (which are expensive).
    4571 
    4572 \subsubsection{FITS File Manipulations}
    4573 
    4574 \begin{verbatim}
    4575 psFits *psFitsAlloc(const char *filename);
    4576 \end{verbatim}
    4577 
    4578 Opens a FITS file at positions the pointer to the PHU.
    4579 
    4580 \begin{verbatim}
    4581 bool psFitsMoveExtName(psFits *fits, const char *extname);
    4582 \end{verbatim}
    4583 
    4584 Positions the pointer to the beginning of the specified
    4585 \code{extname}.  If the \code{extname} does not exist, the function
    4586 shall fail. 
    4587 
    4588 \begin{verbatim}
    4589 bool psFitsMoveExtNum(psFits* fits, int extnum, bool relative);
    4590 \end{verbatim}
    4591 
    4592 Moves the pointer to the beginning of the specified HDU number.  If
    4593 \code{relative} is TRUE, \code{extnum} represents the number of HDUs
    4594 relative to the current HDU.  The PHU is entry number 0, while the
    4595 extended data segments start at number 1.
    4596 
    4597 \begin{verbatim}
    4598 int psFitsGetExtNum(psFits* fits);
    4599 \end{verbatim}
    4600 
    4601 Returns the current HDU number (i.e., file position). 
    4602 
    4603 \begin{verbatim}
    4604 int psFitsGetSize(psFits* fits);
    4605 \end{verbatim}
    4606 
    4607 Returns the number of HDUs in the file.
    4608 
    4609 \begin{verbatim}
    4610 psFitsType psFitsGetExtType(psFits* fits);
    4611 \end{verbatim}
    4612 
    4613 Gets the current HDU's type (table or image).
    4614 
    4615 \subsubsection{FITS Header I/O Functions}
    4616 
    4617 \begin{verbatim}
    4618 psMetadata *psFitsReadHeader(psMetadata *out, const psFits *fits);
    4619 \end{verbatim}
    4620 Read header data into a \code{psMetadata} structure.  The data is read
    4621 from the current HDU pointed at by the \code{psFits *fits} entry.  If
    4622 \code{out} is \code{NULL}, a new psMetadata is created.
    4623 
    4624 \begin{verbatim}
    4625 psMetadata *psFitsReadHeaderSet (psFits *fits);
    4626 \end{verbatim}
    4627 Load a complete set of headers from the \code{psFits} file pointer.
    4628 This function loads the headers from all extensions into a
    4629 \code{psMetadata} collection, each entry of which is a pointer to a
    4630 \code{psMetadata} structure containing the header data.  The metadata
    4631 entry names are the \code{EXTNAME} values for each header (with the
    4632 value of \code{PHU} for the primary header unit).  At the start of the
    4633 operation, the file pointer is rewound to the beginning of the file.
    4634 At the end, it is positioned where it started when the function was
    4635 called.
    4636 
    4637 \begin{verbatim}
    4638 bool psFitsWriteHeader(psMetadata *output, const psFits *fits);
    4639 \end{verbatim}
    4640 Write metadata into the header of a FITS image file.  The header is
    4641 written at the current HDU.
    4642 
    4643 \subsubsection{FITS Image I/O Functions}
    4644 
    4645 \begin{verbatim}
    4646 psImage *psFitsReadImage(psImage *output, psFits *fits, psRegion region, int z);
    4647 \end{verbatim}
    4648 Read an image or subimage from the \code{psFits} file pointer.  This
    4649 function is a wrapper to the CFITSIO library function.  The input
    4650 parameters allow a full image or a subimage to be read.  The region to
    4651 be read is specified by \code{region}.  A negative value for either of
    4652 \code{region.x1} or \code{region.y1} specifies the size of the region
    4653 to be read counting down from the end of the array. 
    4654 
    4655 If the native image is a cube, the value of z specifies the requested
    4656 slice of the image.  This function must call \code{psError} and return
    4657 \code{NULL} if any of the specified parameters are out of range for
    4658 the data in the image file, or if the image on disk is zero- or
    4659 one-dimensional.  This function need only read images of the native
    4660 FITS image types (\code{psU8}, \code{psS16}, \code{psS32},
    4661 \code{psF32}, \code{psF64}).  The user is expected to convert the data
    4662 type as needed with \code{psImageCopy}.
    4663  
    4664 \begin{verbatim}
    4665 bool psFitsUpdateImage(psFits *fits, const psImage *input, psRegion region, int z);
    4666 \end{verbatim}
    4667 \tbd{we have discussed this as the alternate name}
    4668 Write an image section to the open \code{psFits} file pointer.  This
    4669 operation may write a portion of an image over the existing bytes of
    4670 an existing image.  Care must be taken to interpret \code{region},
    4671 which specified the output pixels to be written / over-written.  If
    4672 the combination of \code{region} and the size of \code{psImage *input}
    4673 implies writing pixels outside the existing data area of the image,
    4674 the function shall return an error (ie, if \code{region.x0 + image.nx
    4675 >= NAXIS1}, \code{region.y0 + image.ny >= NAXIS2}, or \code{z >=
    4676 NAXIS3}).  This function will only write images of the native FITS
    4677 image types (\code{psU8}, \code{psS16}, \code{psS32}, \code{psF32},
    4678 \code{psF64}).  The user is expected to convert the data type as
    4679 needed with \code{psImageCopy}.  The return value must be 0 for a
    4680 successful operation and 1 for an error.
    4681 
    4682 \begin{verbatim}
    4683 bool psFitsWriteImage(psFits *fits, psMetadata *header, const psImage *input, int depth);
    4684 \end{verbatim}
    4685 Create a new image based on the dimensions specified for the image and
    4686 the requested depth.  The header and image data segments are written
    4687 in the file at the current position of the \code{psFits} pointer.
    4688 This function will only write images of the native FITS image types
    4689 (\code{psU8}, \code{psS16}, \code{psS32}, \code{psF32}, \code{psF64}).
    4690 The user is expected to convert the data type as needed with
    4691 \code{psImageCopy}.  The return value must be 0 for a successful
    4692 operation and 1 for an error.
    4693 
    4694 \subsubsection{FITS Table I/O Functions}
    4695 
    4696 \begin{verbatim}
    4697 psMetadata *psFitsReadTableRow (psFits *fits, int row);
    4698 \end{verbatim}
    4699 This function reads a single row of the table in the extension pointed
    4700 at by the \code{psFits} file pointer.  The row number to be read is
    4701 given by \code{row}.  The result is returned as a \code{psMetadata}
    4702 collection with elements of the apporpriate types and keys
    4703 corresponding to the table column names.  The function must apply the
    4704 needed byte-swapping on the data in the row based on the description
    4705 of the table data in the table header.  \tbr{we may need to be more
    4706 flexible here: if we call this function repeatedly, it would be more
    4707 efficient to pass the corresponding header or keep it somewhere (and
    4708 the file pointer location, for that matter).}
    4709 
    4710 \begin{verbatim}
    4711 void *psFitsReadTableRowRaw (int *nBytes, psFits *fits, int row);
    4712 \end{verbatim}
    4713 This function reads a single row of the table in the extension pointed
    4714 at by the \code{psFits} file pointer.  The row number to be read is
    4715 given by \code{row}.  The result is returned as collection of
    4716 \code{nBytes} bytes allocated by the function.  The function must
    4717 apply the needed byte-swapping on the data in the row based on the
    4718 description of the table data in the table header.  \tbr{we may need
    4719 to be more flexible here: if we call this function repeatedly, it
    4720 would be more efficient to pass the corresponding header or keep it
    4721 somewhere (and the file pointer location, for that matter).}
    4722 
    4723 \begin{verbatim}
    4724 psArray *psFitsReadTableColumn (psFits *fits, char *colname);
    4725 \end{verbatim}
    4726 This function reads a single column of the table in the extension
    4727 pointed at by the \code{psFits} file pointer.  The column is specified
    4728 by the FITS table column key given by \code{row}.  The result is
    4729 returned as a \code{psArray}, with the data from one row of the table
    4730 column per array element.
    4731 
    4732 \begin{verbatim}
    4733 psVector *psFitsReadTableColumnNum (psFits *fits, char *colname);
    4734 \end{verbatim}
    4735 This function reads a single column of the table in the extension
    4736 pointed at by the \code{psFits} file pointer.  The column is specified
    4737 by the FITS table column key given by \code{row} and must be of a
    4738 numeric data type.  The result is returned as a \code{psVector} of the
    4739 appropriate data type, with the data from one row of the table column
    4740 per array element.
    4741 
    4742 \begin{verbatim}
    4743 psArray *psFitsReadTableRaw (int *nBytes, psFits *fits);
    4744 \end{verbatim}
    4745 This function reads the entire data block from a table into the a
    4746 \code{psArray}, with one element of the array per row.  The number of
    4747 bytes per row is returned in \code{nBytes}.  The function must apply
    4748 the needed byte-swapping on the data in each row based on the
    4749 description of the table data in the table header.
    4750 
    4751 \begin{verbatim}
    4752 psArray *psFitsReadTable (psFits *fits);
    4753 \end{verbatim}
    4754 This function reads the entire data block from a table into the a
    4755 \code{psArray}, with one element of the array per row.  Each row is
    4756 stored as a \code{psMetadata} collection as described above for
    4757 \code{psFitsReadTableRow}.
    4758 
    4759 \begin{verbatim}
    4760 bool psFitsWriteTable(psFits* fits, psMetadata *header, psArray* table);
    4761 \end{verbatim}
    4762 Accepts a \code{psArray} of \code{psMetadata} and writes it to the
    4763 current HDU.  If the current HDU is not a table type, this will fail
    4764 and return FALSE.
    4765 
    4766 \begin{verbatim}
    4767 bool psFitsUpdateTable(psFits* fits, psMetadata *header, psMetadata* data, int row);
    4768 \end{verbatim}
    4769 Writes the \code{psMetadata} data to a FITS table at the specified row
    4770 in the current HDU.  If the current HDU is not a table type, this will
    4771 fail and return FALSE. 
    4772 
    4773 \subsection{Detector and Sky Coordinates}
     4847\subsection{Linear and Spherical Coordinates}
    47744848
    47754849Both detector and sky positions will be used extensively in the IPP.
    47764850The first are linear coordinates which conform to Euclidean geometry
    4777 while the second are angular coordinates for which additional care
    4778 must often be taken.  We put these into two structures, \code{psPlane}
    4779 and \code{psSphere}, respectively.  Partitioning these two will enable
    4780 error-checking.
     4851while the second are angular coordinates which define a position on
     4852the sphere of the sky.  We put these into two structures,
     4853\code{psPlane} and \code{psSphere}, respectively.  Partitioning these
     4854two will enable error-checking.  An alternative representation for
     4855angular positions is the 3-D unit vector.  These are used in
     4856particular as part of spherical rotation calculations.  We define
     4857\code{psCube} to represent such an element.
    47814858%
    47824859\begin{verbatim}
     
    47944871    double dErr;                        ///< Error in Dec
    47954872} psSphere;
     4873
     4874typedef struct {
     4875    double x;                           ///< cos (DEC) cos (RA)
     4876    double y;                           ///< cos (DEC) sin (RA)
     4877    double z;                           ///< sin (DEC)
     4878    double xErr;                        ///< Error in x
     4879    double yErr;                        ///< Error in y
     4880    double zErr;                        ///< Error in z
     4881} psCube;
    47964882\end{verbatim}
    47974883
     
    48184904Constructors for these are straight-forward:
    48194905\begin{verbatim}
    4820 psPlane *psPlaneAlloc(void);
     4906psPlane  *psPlaneAlloc(void);
    48214907psSphere *psSphereAlloc(void);
     4908psCube   *psCubeAlloc(void);
    48224909\end{verbatim}
    48234910Initialization of the structures is not necessary.
     
    49855072\code{NULL}, the function shall generate an error and return
    49865073\code{NULL}.
    4987 
    4988 
    4989 \subsubsection{Celestial Coordinate Conversions}
    4990 
    4991 We need to be able to convert between ICRS, Galactic and Ecliptic
    4992 coordinates, and potentially between arbitrary spherical coordinate
    4993 systems.  All of these basic spherical transformations represent
    4994 rotations of the spherical coordinate reference.  We specify a general
    4995 transformation function which takes a structure,
    4996 \code{psSphereTransform}, defining the transformation between two
    4997 spherical coordinate systems (the structure contains the sines and
    4998 cosines of the angles involved so as to minimize computation time for
    4999 repeated transformations).  We also define a function to generate
    5000 \code{psSphereTransform}, based on the three angles
    5001 describing the location of the pole and the relative equatorial
    5002 rotations of the two systems.  We also specify special functions to
    5003 return the \code{psSphereTransform} for transformations
    5004 between standard coordinate systems.
    5005 
    5006 \begin{verbatim}
    5007 typedef struct {
    5008     double cosDeltaP;                 ///< Cosine of target pole latitude in the source system
    5009     double sinDeltaP;                 ///< Sine of target pole latitude in the source system
    5010     double alphaP;                    ///< Longitude of the target system pole in the source system
    5011     double phiP;                      ///< Longitude of the ascending node in the target system
    5012 } psSphereTransform;
    5013 \end{verbatim}
    5014 
    5015 The constructor is defined as follows:
    5016 \begin{verbatim}
    5017 psSphereTransform *psSphereTransformAlloc(double alphaP, double deltaP, double phiP);
    5018 \end{verbatim}
    5019 where \code{alphaP} and \code{deltaP} define the coordinates in the
    5020 input system of the north pole in the output system and \code{phiP}
    5021 defines the longitude in the input system of the equatorial
    5022 intersection between the two systems (e.g, the first point of Ares).
    5023 The constructor must calculate the sines and cosines above.
    5024 
    5025 Spherical coordinates may be transformed by providing the
    5026 transformation and the coordinate in the input system to
    5027 \code{psSphereTransform}:
    5028 \begin{verbatim}
    5029 psSphere *psSphereTransformApply(psSphere *out,
    5030                                  const psSphereTransform *transform,
    5031                                  const psSphere *coord);
    5032 \end{verbatim}
    5033 
    5034 The following functions simply return the appropriate
    5035 \code{psSphereTransform} to convert between predefined spherical
    5036 coordinate systems (i.e., ICRS, Ecliptic and Galactic).  These are
    5037 constructors as well as the above \code{psSphereTransformAlloc}.
    5038 %
    5039 \begin{verbatim}
    5040 psSphereTransform *psSphereTransformICRSToEcliptic(psTime *time);
    5041 psSphereTransform *psSphereTransformEclipticToICRS(psTime *time);
    5042 psSphereTransform *psSphereTransformICRSToGalactic(void);
    5043 psSphereTransform *psSphereTransformGalacticToICRS(void);
    5044 \end{verbatim}
    5045 
    5046 We also require the ability to precess coordinates from one equinox to
    5047 another.
    5048 
    5049 \begin{verbatim}
    5050 psSphere *psSpherePrecess(psSphere *coords, const psTime *fromTime, const psTime *toTime);
    5051 \end{verbatim}
    5052 
    5053 Given coordinates, \code{coords}, with equinox for \code{fromTime},
    5054 the coordinates are precessed to equinox for \code{toTime}.  The
    5055 \code{coords} are modified in-place.  Equinoxes shall be Julian
    5056 equinoxes (as opposed to Bessellian).
    5057 
    5058 \subsubsection{Projections}
    5059 
    5060 We require functions to convert between spherical and linear
    5061 coordinate systems based on a variety of projections.  The required
    5062 projections include:
    5063 \begin{itemize}
    5064 \item TAN
    5065 \item SIN
    5066 \item AIT
    5067 \item PAR
    5068 \end{itemize}
    5069 
    5070 We specify the following structure \code{psProjection} to define the
    5071 parameters of the projection:
    5072 \begin{verbatim}
    5073 typedef struct {
    5074     double R, D;                         ///< coordinates of projection center
    5075     double Xs, Ys;                       ///< plate-scale in X and Y directions
    5076     psProjectionType type;               ///< projection type
    5077 } psProjection;
    5078 \end{verbatim}
    5079 
    5080 The projection type is defined by the following enumerated type \code{psProjectionType}:
    5081 \begin{verbatim}
    5082 typedef enum {                          ///< type of val is:
    5083     PS_PROJ_TAN,                        ///< Tangent projection
    5084     PS_PROJ_SIN,                        ///< Sine projection
    5085     PS_PROJ_AIT,                        ///< Aitoff projection
    5086     PS_PROJ_PAR,                        ///< Par projection
    5087     PS_PROJ_NTYPE                       ///< Number of types; must be last
    5088 } psProjectionType;
    5089 \end{verbatim}
    5090 
    5091 The constructor is straight-forward:
    5092 \begin{verbatim}
    5093 psProjection *psProjectionAlloc(double R, double D, double Xs, double Ys, psProjectionType type);
    5094 \end{verbatim}
    5095 
    5096 The following functions will project and deproject (respectively)
    5097 spherical coordinates:
    5098 
    5099 \begin{verbatim}
    5100 psPlane  *psProject(const psSphere *coord, const psProjection *projection);
    5101 psSphere *psDeproject(const psPlane *coord, const psProjection *projection);
    5102 \end{verbatim}
    5103 
    5104 \subsubsection{Offsets}
    5105 We require a function to calculate the offset between two positions on
    5106 the sky, as well as a function to apply an offset to a position.  The
    5107 first determines the offset (RA,Dec) on the sky between two positions.
    5108 The second applies the given offset to the coordinate.  Both an offset
    5109 mode and an offset unit may be defined.  The mode may be either
    5110 \code{PS_SPHERICAL}, in which case the specified offset corresponds to
    5111 an offset in angles, or it may be \code{PS_LINEAR}, in which case the
    5112 offset corresponds to a linear offset in a local projection.  The
    5113 offset unit may be in one of \code{PS_ARCSEC}, \code{PS_ARCMIN},
    5114 \code{PS_DEGREE}, and \code{PS_RADIAN}, which specifies the units of
    5115 the offset only.
    5116 
    5117 \begin{verbatim}
    5118 psSphere *psSphereGetOffset(const psSphere *position1,
    5119                             const psSphere *position2,
    5120                             psSphereOffsetMode mode,
    5121                             psSphereOffsetUnit unit);
    5122 
    5123 psSphere *psSphereSetOffset(const psSphere *position,
    5124                             const psSphere *offset,
    5125                             psSphereOffsetMode mode,
    5126                             psSphereOffsetUnit unit);
    5127 
    5128 typedef enum {
    5129     PS_SPHERICAL;                       ///< Offset on a sphere
    5130     PS_LINEAR;                          ///< Linear offset
    5131 } psSphereOffsetMode;
    5132 
    5133 typedef enum {
    5134     PS_ARCSEC;                          ///< Arcseconds
    5135     PS_ARCMIN;                          ///< Arcminutes
    5136     PS_DEGREE;                          ///< Degrees
    5137     PS_RADIAN;                          ///< Radians
    5138 } psSphereOffsetUnit;
    5139 \end{verbatim}
    5140 Note that these should propagate the errors appropriately.
    5141 
    5142 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    5143 
    5144 %%% Astronomical Images and Astrometry
    5145 \include{psLibSDRS_Astrom}
    5146 
    5147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    5148 
    5149 \subsection{Pixel Lists}
    5150 
    5151 Usually an image mask is the best way to carry information about what
    5152 pixels mean what.  However, in the case where the number of pixels in
    5153 which we are interested is limited, it is more efficient to simply
    5154 carry a list of pixels.  An example of this is in the image
    5155 combination code, where we want to perform an operation on a
    5156 relatively small fraction of pixels, and it is inefficient to go
    5157 through an entire mask image checking each pixel.
    5158 
    5159 \begin{verbatim}
    5160 typedef struct {
    5161     psVector *x;                        // x coordinate
    5162     psVector *y;                        // y coordinate
    5163 } psPixels;
    5164 \end{verbatim}
    5165 
    5166 Of course, the size of each of the vectors should match.  In the event
    5167 that they do not match, any function which detects the problem shall
    5168 generate a warning and use the size of the shorter of the vectors as
    5169 the size.  The order in which the pixels are kept is not considered
    5170 important.
    5171 
    5172 \begin{verbatim}
    5173 psImage *psPixelsToMask(psImage *out, const psPixels *pixels, const psRegion *region, unsigned int maskVal);
    5174 psPixels *psMaskToPixels(psPixels *out, const psImage *mask, unsigned int maskVal);
    5175 \end{verbatim}
    5176 
    5177 \code{psPixelsToMask} shall return an image of type U8 with the
    5178 \code{pixels} lying within the specified \code{region} set to the
    5179 \code{maskVal}.  The \code{out} image shall be modified if supplied,
    5180 or allocated and returned if \code{NULL}.  The size of the output
    5181 image shall be \code{region->x1 - region->x0} by \code{region->y1 -
    5182 region->y0}, with \code{out->x0 = region->x0} and \code{out->y0 =
    5183 region->y0}.  In the event that either of \code{pixels} or
    5184 \code{region} are \code{NULL}, the function shall generate an error
    5185 and return \code{NULL}.
    5186 
    5187 \code{psMaskToPixels} shall return a \code{psPixels} consisting of the
    5188 coordinates in the \code{mask} that match the \code{maskVal}.  The
    5189 \code{out} pixel list shall be modified if supplied, or allocated and
    5190 returned if \code{NULL}.  In hte event that \code{mask} is
    5191 \code{NULL}, the function shall generate an error and return
    5192 \code{NULL}.
    5193 
    5194 \begin{verbatim}
    5195 psPixels *psPixelsConcatenate(psPixels *out, const psPixels *pixels);
    5196 \end{verbatim}
    5197 
    5198 \code{psPixelsConcatenate} shall concatenate \code{pixels} onto
    5199 \code{out}.  In the event that \code{out} is \code{NULL}, a new
    5200 \code{psPixels} shall be allocated, and the contents of \code{pixels}
    5201 simply copied in.  If \code{pixels} is \code{NULL}, the function shall
    5202 generate an error and return \code{NULL}.  The function shall take
    5203 care to ensure that there are no duplicate pixels in \code{out} (since
    5204 the order in which the pixels are stored is not important, the values
    5205 may be sorted, allowing the use of a faster algorithm than a linear
    5206 scan).
    52075074
    52085075\begin{verbatim}
     
    52285095and return \code{NULL}.
    52295096
    5230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     5097\subsubsection{Spherical Rotations}
     5098
     5099Spherical rotations represent coordinate transformation in 3-D, as
     5100well as the effects of precession and nutation.  We need spherical
     5101rotatations to convert between ICRS, Galactic and Ecliptic
     5102coordinates, and to determine Alt-Az coordinates for sources.  All of
     5103these basic spherical transformations represent rotations of the
     5104spherical coordinate reference.  We specify a general transformation
     5105function which takes a structure, \code{psSphereRot}, defining the
     5106transformation between two spherical coordinate systems.  The
     5107structure contains the elements of a quaternion to represent the
     5108spherical rotational.  We define two allocators for
     5109\code{psSphereRot}, one which defines the rotation in terms of the
     5110coordinate of the pole and the rotation about that pole.  The other
     5111defines the rotation from the elements of the quaternion.  We also
     5112specify functions to manipulate \code{psSphereRot} in several useful
     5113way.
     5114
     5115\begin{verbatim}
     5116typedef struct {
     5117    double q0;
     5118    double q1;
     5119    double q2;
     5120    double q3;
     5121} psSphereRot;
     5122\end{verbatim}
     5123
     5124The constructor is defined as follows:
     5125\begin{verbatim}
     5126psSphereRot *psSphereRotAlloc(double alphaP, double deltaP, double phiP);
     5127\end{verbatim}
     5128where \code{alphaP} and \code{deltaP} define the coordinates in the
     5129input system of the axis of rotation (the north pole of the output
     5130system), while \code{phiP} defines the rotation about that pole.  This
     5131last angle is also equal to 270\degree - $\phi_a$, where $\phi_a$ is
     5132the longitude in the output system of the ascending node (equatorial
     5133intersection between the two systems, e.g, the first point of Ares).
     5134
     5135The \code{psSphereRot} may also be constructed by supplying the
     5136elements of the quaternion to the following function:
     5137\begin{verbatim}
     5138psSphereRot *psSphereRotQuat(double q0, double q1, double q2, double q3);
     5139\end{verbatim}
     5140This function normalizes the quaternion, so the input elements need
     5141not be normalized.
     5142
     5143Spherical coordinates may be transformed by providing the
     5144transformation and the coordinate in the input system to
     5145\code{psSphereRot}.  The output pointer may be optionally supplied, or
     5146if \code{NULL}, is allocated by the function.
     5147
     5148\begin{verbatim}
     5149psSphere *psSphereRotApply(psSphere *out, const psSphereRot *transform, const psSphere *coord);
     5150\end{verbatim}
     5151
     5152The following function combines two rotations, to produce a single
     5153rotation which is the equivallent of applying the first rotation and
     5154then the second.  The output rotation may be supplied, or will be
     5155allocated if \code{NULL}.
     5156
     5157\begin{verbatim}
     5158psSphereRot *psSphereRotCombine(psSphereRot *out, psSphereRot *rot1, psSphereRot *rot2)
     5159\end{verbatim}
     5160
     5161The following function changes the given rotation to its inverse:
     5162
     5163\begin{verbatim}
     5164psSphereRot *psSphereRotInvert(psSphereRot *rot)
     5165\end{verbatim}
     5166
     5167The 3-vector representation of the angles (\code{psCube}) is needed to
     5168implement these functions, and is useful in other circumstances as
     5169well.  Two utility functions are provided to convert between the
     5170angular and 3-vector representations:
     5171\begin{verbatim}
     5172psSphere *psCubeToSphere(psCube *cube);
     5173psCube *psSphereToCube(psSphere *sphere);
     5174\end{verbatim}
     5175
     5176\subsubsection{Offsets}
     5177We require a function to calculate the offset between two positions on
     5178the sky, as well as a function to apply an offset to a position.  The
     5179first determines the offset (RA,Dec) on the sky between two positions.
     5180The second applies the given offset to the coordinate.  Both an offset
     5181mode and an offset unit may be defined.  The mode may be either
     5182\code{PS_SPHERICAL}, in which case the specified offset corresponds to
     5183an offset in angles, or it may be \code{PS_LINEAR}, in which case the
     5184offset corresponds to a linear offset in a local projection.  The
     5185offset unit may be in one of \code{PS_ARCSEC}, \code{PS_ARCMIN},
     5186\code{PS_DEGREE}, and \code{PS_RADIAN}, which specifies the units of
     5187the offset only.
     5188
     5189\begin{verbatim}
     5190psSphere *psSphereGetOffset(const psSphere *position1,
     5191                            const psSphere *position2,
     5192                            psSphereOffsetMode mode,
     5193                            psSphereOffsetUnit unit);
     5194
     5195psSphere *psSphereSetOffset(const psSphere *position,
     5196                            const psSphere *offset,
     5197                            psSphereOffsetMode mode,
     5198                            psSphereOffsetUnit unit);
     5199
     5200typedef enum {
     5201    PS_SPHERICAL;                       ///< Offset on a sphere
     5202    PS_LINEAR;                          ///< Linear offset
     5203} psSphereOffsetMode;
     5204
     5205typedef enum {
     5206    PS_ARCSEC;                          ///< Arcseconds
     5207    PS_ARCMIN;                          ///< Arcminutes
     5208    PS_DEGREE;                          ///< Degrees
     5209    PS_RADIAN;                          ///< Radians
     5210} psSphereOffsetUnit;
     5211\end{verbatim}
     5212Note that these should propagate the errors appropriately.
     5213
     5214\subsection{Celestial Coordinate Systems}
     5215
     5216The following functions simply return the appropriate
     5217\code{psSphereRot} to convert between predefined spherical
     5218coordinate systems (i.e., ICRS, Ecliptic and Galactic).  These are
     5219constructors as well as the above \code{psSphereRotAlloc}.
     5220%
     5221\begin{verbatim}
     5222psSphereRot *psSphereRotICRSToEcliptic(psTime *time);
     5223psSphereRot *psSphereRotEclipticToICRS(psTime *time);
     5224psSphereRot *psSphereRotICRSToGalactic(void);
     5225psSphereRot *psSphereRotGalacticToICRS(void);
     5226\end{verbatim}
     5227
     5228\subsection{Earth Orientation Calculations}
     5229
     5230One of the critical sets of calculations in astronomy is the sequence
     5231of steps needed to convert between the celestial coordinates of an
     5232object and the observed coordinates of the object.  This problem is
     5233best divided into two major components: transformation between the
     5234celestial sphere and coordinates relative to the surface of the solid
     5235earth, excluding the effects of the atmosphere, and compensation for
     5236the effects of the atmosphere.  In this section, we address the first
     5237of these two transformations: the Earth Orientation Calculations.
     5238
     5239The Earth Orientation Calculations are further subdivided into several
     5240steps, illustrated in Figure~\ref{CoordinateSystems} .  Celestial
     5241coordinates are defined in the International Celestial Reference
     5242System (ICRS), which has the solar barycenter as its reference
     5243position and velocity.  The next coordinate system is the Geocentric
     5244Celestial Reference System (GCRS), which uses the earth barycenter as
     5245a reference.  The transformation between these two includes the
     5246abberation due to the Earth's velocity, the parallax of the object,
     5247which depends on both the Earth's position and the distance to the
     5248object of interest, and the general relativistic correction for the
     5249bending of light as it approaches the Earth.
     5250
     5251The next set of transformations compenstate for the 3-D rotation of
     5252the Earth on various timescales, including the effects of precession,
     5253nutation, and simple solid-body rotation.  These calculations can be
     5254performed using different amounts of information for higher levels of
     5255precision.  Since the Earth's rotation is constantly affected by
     5256stochastic processes (weather, earthquakes, etc), these conversions
     5257are constantly modified by observations reported by authoratative
     5258sources such as the US Naval Observatory.  The target of this
     5259transformation is the International Terrestrial Reference System
     5260(ITRS), which is fixed with respect to the Earth's crust.  This
     5261transformation is subdivided into slow precesion and nutation
     5262(yielding the coordinate system CIP/CEO), followed by the Earth's
     5263rotation (yielding the coordinate system CIP/TEO), and finally
     5264corrections for the short-period motion of the Earth's pole. 
     5265
     5266\subsubsection{Transformation from ICRS to GCRS}
     5267
     5268\tbd{we need a function to construct the direction and speed elements
     5269  given the time}.
     5270
     5271\tbd{supply the velocity as an un-normalized 3 vector?}
     5272
     5273\paragraph{Aberration}
     5274The following function calculates the \code{apparent} position of a
     5275star, given its \code{actual} position and the velocity vector of the
     5276observer, represented as a speed and a direction:
     5277\begin{verbatim}
     5278psAberration(psSphere *apparent, psSphere *actual, psSphere direction, double speed);
     5279\end{verbatim}
     5280The \code{actual} and \code{apparent} positions are represented as
     5281\code{psSphere} entries, as is the \code{direction} of motion.  The
     5282speed in that direction is given in units of the speed of light.
     5283
     5284\paragraph{Gravitational Deflection}
     5285
     5286\paragraph{Parallax}
     5287
     5288\begin{verbatim}
     5289double psEOC_ParallaxFactor(psSphere *coords, psTime *time);
     5290\end{verbatim}
     5291Calculate the parallax factor for the given position and time.
     5292
     5293\subsubsection{Transformation from GCRS to ITRS}
     5294
     5295\paragraph{Precession/Nutation}
     5296
     5297The following routine calculates the components of the rotation
     5298between the CEO and GCRS frames, $X$, $Y$, and $s$, using to the
     5299IAU2000A precession \& nutation model:
     5300%
     5301\begin{verbatim}
     5302psSphere *psEOC_PrecessionModel(double *s, const psTime *time)
     5303\end{verbatim}
     5304%
     5305The input to this function is the desired \code{time}, which may be
     5306represented in any format other than UT1.  This routine must give
     5307results identical to the IERS XYS2000A subroutine within the limits of
     5308machine accuracy.
     5309
     5310The following function provides interpolated corrections to $X$ and
     5311$Y$ from the tables provided by the IERS, just as it does for UT1 and
     5312polar motion. 
     5313
     5314\begin{verbatim}
     5315psSphere *psEOC_GetPolarCorr(const psTime *time, psTimeBulletin bulletin);
     5316\end{verbatim}
     5317
     5318The polar correction is applied to the $X$ and $Y$ elements of the
     5319rotation to provide higher accuracy.  The spherical rotation term is
     5320generated by providing the three elements of the rotation to the
     5321following function:
     5322\begin{verbatim}
     5323psSphereRot *psSphereRot_CEOtoGCRS(double s, const psSphere *pole)
     5324\end{verbatim}
     5325The retulting \code{psSphereRot} may be used to determine the rotation
     5326from CIP/CEO to GCRS.  This function must give results identical to
     5327the IERS BPN2000, within the limits of machine accuracy.
     5328
     5329\paragraph{Earth Rotation}
     5330
     5331The following routine calculates the rotation of the Earth about the CIP:
     5332\begin{verbatim}
     5333psSphereRot *psSphereRot_TEOtoCEO(const psTime *time)
     5334\end{verbatim}
     5335The IERS code to create the comparable rotation is embedded in
     5336T2C2000, with the Earth Rotation Angle calculated by ERA2000.
     5337
     5338\paragraph{Polar Motion}
     5339
     5340The following function provides interpolated values of the polar
     5341motion components, $x_p$ and $y_p$, extracted from the IERS tables. 
     5342\begin{verbatim}
     5343psSphere *psEOC_GetPoleCoords(const psTime *time, psTimeBulletin bulletin);
     5344\end{verbatim}
     5345
     5346The following function provides tidal corrections to the polar motion
     5347components, $x_p$ and $y_p$, using the Ray model of Simon et al (see
     5348ADD).
     5349\begin{verbatim}
     5350psSphere *psEOC_TidePolarCorr(const psTime *time);
     5351\end{verbatim}
     5352
     5353The following function provides the additional corrections due to nutation
     5354terms with periods less than or equal to two days:
     5355\begin{verbatim}
     5356psSphere *psEOC_NutationCorr(psTime *time);
     5357\end{verbatim}
     5358
     5359The following function should generate the \code{psSphereRot} transform from
     5360ITRS to CIP/TEO:
     5361\begin{verbatim}
     5362psSphereRot *psSphereRot_ITRStoTEO(psSphere pole, psTime *time);
     5363\end{verbatim}
     5364The time argument should be used to internally calculate $s'$.
     5365This function should give identical results to the IERS POM2000 subroutine.
     5366
     5367\subsubsection{Earth Orientation Wrappers}
     5368
     5369The following function generates the complete spherical rotation to
     5370account for precession between two times.  If \code{NULL} is provided
     5371for either time, it is assumed to have the reference equinox value of
     5372J2000.
     5373\begin{verbatim}
     5374psSphere *psSpherePrecess(const psTime *fromTime, const psTime *toTime, psPrecessMethod mode);
     5375\end{verbatim}
     5376The mode argument is used to specify the level of detail used in the
     5377calculation.
     5378
     5379\begin{verbatim}
     5380typedef enum {
     5381  PS_PRECESS_ROUGH,
     5382  PS_PRECESS_COMPLETE,
     5383  PS_PRECESS_IAU2000A,
     5384} psPrecessMethod;
     5385\end{verbatim}
     5386
     5387\subsection{Atmospheric Effects}
     5388
     5389\tbd{The ATM effects components should be deferred until we clean up
     5390  the refraction definitions}
     5391
     5392A-priori astrometric transformations between the telescope orientation
     5393(Alt/Az) and the predicted stellar coordinates above the atmosphere
     5394(DEC/HA) requires several pieces of information describing the current
     5395environmental conditions.  These quantities are consistent across an
     5396image, and may vary only slowly with time.  Pre-computing these
     5397quantities for exposures means that subsequent transformations are
     5398faster.  The structure below carries the environmental data of interest.
     5399For historical reasons, this structure is known colloquially as ``the
     5400Grommit''.
     5401
     5402\tbd{this structure needs to be modified to correspond to what we
     5403  actually need to carry around for the atmosphere functions}
     5404
     5405\tbd{provide a single Grommit to carry around all EOC + ATM
     5406  pre-calculated entries and a separate structure for ATM effect?}
     5407
     5408\begin{verbatim}
     5409typedef struct {
     5410    const double latitude;              ///< geodetic latitude (radians)
     5411    const double longitude;             ///< longitude + ... (radians)
     5412    const double height;                ///< height (HM)
     5413    const double abberationMag;         ///< magnitude of diurnal aberration vector
     5414    const double temperature;           ///< ambient temperature (TDK)
     5415    const double pressure;              ///< pressure (PMB)
     5416    const double humidity;              ///< relative humidity (RH)
     5417    const double wavelength;            ///< wavelength (WL)
     5418    const double lapseRate;             ///< lapse rate (TLR)
     5419    const double refractA, refractB;    ///< refraction constants A and B (radians)
     5420    const double siderealTime;          ///< local apparent sidereal time (radians)
     5421} psGrommit;
     5422\end{verbatim}
     5423
     5424The \code{psGrommit} is calculated from telescope information for the
     5425particular exposure, \code{exp}:
     5426\begin{verbatim}
     5427psGrommit *psGrommitAlloc(const psExposure *exp);
     5428\end{verbatim}
     5429
     5430\tbd{these functions probably need to take the ATM structure}
     5431
     5432We require additional functions to perform general functions which
     5433will be useful for astrometry.  Given coordinates on the sky, we
     5434need to get the airmass, the parallactic angle, and an estimate of
     5435the atmospheric refraction.
     5436
     5437\begin{verbatim}
     5438float psGetAirmass(const psSphere *coord, psTime *lst, float height);
     5439\end{verbatim}
     5440which returns the airmass for a given position and local sidereal time
     5441(\code{lst}).
     5442
     5443\begin{verbatim}
     5444float psGetParallactic(const psSphere *coord, double siderealTime);
     5445\end{verbatim}
     5446which returns the parallactic angle for a given position and sidereal time.
     5447
     5448\begin{verbatim}
     5449float psGetRefraction(float colour,            ///< Colour of object
     5450                      psPhotSystem colorPlus,  ///< Colour reference
     5451                      psPhotSystem colorMinus, ///< Colour reference
     5452                      const psExposure *exp);  ///< Telescope pointing information
     5453\end{verbatim}
     5454which provides an estimate of the atmospheric refraction, along the parallactic angle.
     5455
     5456%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     5457
     5458\subsection{Fixed Pattern}
     5459
     5460The fixed pattern is a correction to the general astrometric solution
     5461formed by summing the residuals from many observations.  The intent is
     5462to correct for higher-order distortions in the camera system on a
     5463coarse grid (larger than individual pixels, but smaller than a single
     5464cell).  Hence, in addition to the offsets, we need to specify the size
     5465and scale of the grid in $x$ and $y$, as well as the origin of the
     5466grid.
     5467
     5468\begin{verbatim}
     5469typedef struct {
     5470    int nX, nY;                         ///< Number of elements in x and y
     5471    double x0, y0;                      ///< Position of 0,0 corner on focal plane
     5472    double xScale, yScale;              ///< Scale of the grid
     5473    double **x, **y;                    ///< The grid of offsets in x and y
     5474} psFixedPattern;
     5475\end{verbatim}
     5476
     5477The constructor for \code{psFixedPattern} shall be:
     5478\begin{verbatim}
     5479psFixedPattern *psFixedPatternAlloc(double x0,        double y0,
     5480                                    double xScale,    double yScale,
     5481                                    const psImage *x, const psImage *y);
     5482\end{verbatim}
     5483Here, \code{x0}, \code{y0}, \code{xScale} and \code{yScale} have the
     5484same meaning as in the \code{psFixedPattern} structure.  Note that the
     5485values of the fixed pattern offsets are specified as images, the
     5486values from which need to be copied into the \code{double **x} and
     5487\code{double **y} of \code{psFixedPattern}, and that the number of
     5488elements may be derived from the size of the images.
     5489
     5490%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
     5491
     5492\subsection{Projections}
     5493
     5494We require functions to convert between spherical and linear
     5495coordinate systems based on a variety of projections.  The required
     5496projections include:
     5497\begin{itemize}
     5498\item TAN
     5499\item SIN
     5500\item AIT
     5501\item PAR
     5502\end{itemize}
     5503
     5504We specify the following structure \code{psProjection} to define the
     5505parameters of the projection:
     5506\begin{verbatim}
     5507typedef struct {
     5508    double R, D;                         ///< coordinates of projection center
     5509    double Xs, Ys;                       ///< plate-scale in X and Y directions
     5510    psProjectionType type;               ///< projection type
     5511} psProjection;
     5512\end{verbatim}
     5513
     5514The projection type is defined by the following enumerated type \code{psProjectionType}:
     5515\begin{verbatim}
     5516typedef enum {                          ///< type of val is:
     5517    PS_PROJ_TAN,                        ///< Tangent projection
     5518    PS_PROJ_SIN,                        ///< Sine projection
     5519    PS_PROJ_AIT,                        ///< Aitoff projection
     5520    PS_PROJ_PAR,                        ///< Par projection
     5521    PS_PROJ_NTYPE                       ///< Number of types; must be last
     5522} psProjectionType;
     5523\end{verbatim}
     5524
     5525The constructor is straight-forward:
     5526\begin{verbatim}
     5527psProjection *psProjectionAlloc(double R, double D, double Xs, double Ys, psProjectionType type);
     5528\end{verbatim}
     5529
     5530The following functions will project and deproject (respectively)
     5531spherical coordinates:
     5532
     5533\begin{verbatim}
     5534psPlane  *psProject(const psSphere *coord, const psProjection *projection);
     5535psSphere *psDeproject(const psPlane *coord, const psProjection *projection);
     5536\end{verbatim}
     5537
     5538%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
    52315539
    52325540\subsection{Photometry}
     
    52985606M_{\rm pM} - pA, M_{\rm sP} - M_{\rm sM} - sA)$.
    52995607
    5300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     5608%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     5609
     5610%%% Astronomical Images and Astrometry
     5611\include{psLibSDRS_Astrom}
    53015612
    53025613\subsection{Astronomical objects}
     
    53295640\appendix
    53305641
     5642\pagebreak
    53315643\section{Configuration File Test Inputs}
    53325644\label{sec:configtest}
Note: See TracChangeset for help on using the changeset viewer.