Changeset 3564 for trunk/doc/pslib/psLibSDRS.tex
- Timestamp:
- Mar 30, 2005, 11:14:48 AM (21 years ago)
- File:
-
- 1 edited
-
trunk/doc/pslib/psLibSDRS.tex (modified) (24 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/doc/pslib/psLibSDRS.tex
r3537 r3564 1 %%% $Id: psLibSDRS.tex,v 1.19 1 2005-03-29 03:42:21 price Exp $1 %%% $Id: psLibSDRS.tex,v 1.192 2005-03-30 21:14:48 eugene Exp $ 2 2 \documentclass[panstarrs,spec]{panstarrs} 3 3 … … 11 11 \project{Pan-STARRS Image Processing Pipeline} 12 12 \organization{Institute for Astronomy} 13 \version{1 2}13 \version{13} 14 14 \docnumber{PSDC-430-007} 15 15 16 % \setcounter{tocdepth}{5} % lowest level to be included in toc 16 17 \setlength{\topsep}{-2pt} 17 18 … … 137 138 \href{heasarc.gsfc.nasa.gov/docs/software/fitsio}{\tt heasarc.gsfc.nasa.gov/docs/software/fitsio} 138 139 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: 142 142 143 143 \href{star-www.rl.ac.uk/star/docs/sun67.htx/sun67.html}{\tt … … 183 183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 184 184 185 \pagebreak 185 186 \section{System Utilities} 186 187 … … 1193 1194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1194 1195 1196 \pagebreak 1195 1197 \section{Basic Data Types and Collections} 1196 1198 … … 1894 1896 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1895 1897 1898 \pagebreak 1896 1899 \section{Data manipulation} 1897 1900 … … 3028 3031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3029 3032 3033 \subsection{Image Pixel Lists} 3034 3035 Usually an image mask is the best way to carry information about what 3036 pixels mean what. However, in the case where the number of pixels in 3037 which we are interested is limited, it is more efficient to simply 3038 carry a list of pixels. An example of this is in the image 3039 combination code, where we want to perform an operation on a 3040 relatively small fraction of pixels, and it is inefficient to go 3041 through an entire mask image checking each pixel. 3042 3043 \begin{verbatim} 3044 typedef struct { 3045 psVector *x; // x coordinate 3046 psVector *y; // y coordinate 3047 } psPixels; 3048 \end{verbatim} 3049 3050 Of course, the size of each of the vectors should match. In the event 3051 that they do not match, any function which detects the problem shall 3052 generate a warning and use the size of the shorter of the vectors as 3053 the size. The order in which the pixels are kept is not considered 3054 important. 3055 3056 \begin{verbatim} 3057 psImage *psPixelsToMask(psImage *out, const psPixels *pixels, const psRegion *region, unsigned int maskVal); 3058 psPixels *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, 3064 or allocated and returned if \code{NULL}. The size of the output 3065 image shall be \code{region->x1 - region->x0} by \code{region->y1 - 3066 region->y0}, with \code{out->x0 = region->x0} and \code{out->y0 = 3067 region->y0}. In the event that either of \code{pixels} or 3068 \code{region} are \code{NULL}, the function shall generate an error 3069 and return \code{NULL}. 3070 3071 \code{psMaskToPixels} shall return a \code{psPixels} consisting of the 3072 coordinates in the \code{mask} that match the \code{maskVal}. The 3073 \code{out} pixel list shall be modified if supplied, or allocated and 3074 returned 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} 3079 psPixels *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} 3085 simply copied in. If \code{pixels} is \code{NULL}, the function shall 3086 generate an error and return \code{NULL}. The function shall take 3087 care to ensure that there are no duplicate pixels in \code{out} (since 3088 the order in which the pixels are stored is not important, the values 3089 may be sorted, allowing the use of a faster algorithm than a linear 3090 scan). 3091 3092 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3093 3094 \subsection{Image Regions} 3095 3096 In many places, we need to refer to a rectangular area. We define a 3097 structure to represent a rectangle: 3098 \begin{verbatim} 3099 typedef struct { 3100 float x0; 3101 float x1; 3102 float y0; 3103 float y1; 3104 } psRegion; 3105 psRegion *psRegionAlloc (float x0, float x1, float y0, float y1); 3106 \end{verbatim} 3107 3108 \begin{verbatim} 3109 psRegion *psRegionFromString (char *region); 3110 \end{verbatim} 3111 This 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}, 3113 into the corresponding \code{psRegion} structure. 3114 3030 3115 \subsection{Vector and Image Arithmetic} 3031 3116 \label{sec:arithmetic} … … 3443 3528 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3444 3529 3530 \pagebreak 3531 \section{Rich Data Structures and I/O} 3532 3533 \subsection{Metadata} 3534 \label{sec:metadata} 3535 3536 \subsubsection{Conceptual Overview} 3537 3538 Within PSLib, we provide a data structure to carry metadata and 3539 mechanisms to manipulate the metadata. Metadata is a general concept 3540 that requires some discussion. In any data analysis task, the 3541 ensemble of all possible data may be divided into two or three 3542 classes: there is the specific data of interest, there is data which 3543 is related or critical but not the primary data of interest, and there 3544 is all of the other data which may or may not be interesting. For 3545 example, consider a simple 2D image obtained of a galaxy from a CCD 3546 camera on a telescope. If you want to study the galaxy, the specific 3547 data of interest is the collection of pixels. There are a variety of 3548 other pieces of data which are closely related and crucial to 3549 understanding the data in those pixels, such as the dimensions of the 3550 image, the coordinate system, the time of the image, the exposure 3551 time, and so forth. Other data may be known which may be less 3552 critical to understanding the image, but which may be interesting or 3553 desired at a later date. For example, the observer who took the 3554 image, the filter manufacturer, the humidity at the telescope, etc. 3555 3556 Formally, all of the related data which describe the principal data of 3557 interest are metadata. Note that which piece is the metadata and 3558 which is the data may depend on the context. If you are examining the 3559 pixels in an image, the coordinate and flux of an object may be part 3560 of the metadata. However, if you are analyzing a collection of 3561 objects extracted from an image, you may consider then pixel data 3562 simply part of the metadata associated with the list of objects. 3563 3564 There are various ways to handle metadata vs data within a programming 3565 environment. In C, it is convenient to use structures to group 3566 associated data together. One possibility is to define the metadata 3567 as part of the associated data structure. For example, the image data 3568 structure would have elements for all possible associated measurement. 3569 This approach is both cumbersome (because of the large number metadata 3570 types), impractical (because the full range of necessary metadata is 3571 difficult to know in advance) and inflexible (because any change in 3572 the collection of metadata requires addition of new structure elements 3573 and recompilation). 3574 3575 An alternative is to place the metadata in a generic container and use 3576 lookup mechanisms to extract the appropriate metadata when needed. An 3577 example of this is would be a text-based FITS header for an image read 3578 into a flat text buffer. In this implementation, metadata lookup 3579 functions could return the current value of, for example, NAXIS1 (the 3580 number of columns of the image) by scanning through the header buffer. 3581 This method has the benefits of flexibility and simplicity of 3582 programming interface, but it has the disadvantage that all metadata 3583 is accessed though this lookup mechanism. This may make the code less 3584 readable and it may slow down the access. 3585 3586 PSLib implements an intermediate solution to this problem. We specify 3587 a flexible, generic metadata container and access methods. Data types 3588 which require association with a general collection of metadata should 3589 include an entry of this metadata type. However, a subset of metadata 3590 concepts which are basic and frequently required may be placed in the 3591 coded structure elements. This approach allows the code to refer to 3592 the basic metadata concepts as part of the data structure (ie, 3593 \code{image.nx}), but also allows us to provide access to any 3594 arbitrary metadata which may be generated. As a practical matter, the 3595 choice of which entries are only in the metadata and which are part of 3596 the explicit structure elements is rather subjective. Any data 3597 elements which are frequently used should be put in the structure; 3598 those which are only infrequently needed should be left in the generic 3599 metadata. 3600 3601 There are some points of caution which must be noted. Any 3602 manipulation of the data should be reflected in the metadata where 3603 appropriate. This is always an issue of concern. For example, 3604 consider an image of dimensions \code{nx, ny}. If a function extracts 3605 a subraster, it must change the values of \code{nx, ny} to match the 3606 new dimensions. What should it do to the corresponding metadata? 3607 Clearly, it should change the corresponding value which defines 3608 \code{nX, nY}. However, it is not quite so simple: there may be other 3609 metadata values which depend on those values. These must also be 3610 changed appropriately. What if the metadata element points to a 3611 copy of the metadata which may be shared by other representations of 3612 the image? These must be treated differently because the change would 3613 invalidate those other references. Care must be taken, therefore, 3614 when writing functions which operate on the data to consider all of 3615 the relevant metadata entries which must also be updated. 3616 3617 A related issue is the definition of metadata names. Entries in a 3618 structure have the advantage of being hardwired: every instance of 3619 that structure will have the same name for the same entry. This is 3620 not necessarily the case with a more flexible metadata container. The 3621 image exposure time is a notorious example in astronomy. Different 3622 observatories use different header keywords (ie, metadata names) for 3623 the same concept of the exposure time (\code{EXPTIME}, 3624 \code{EXPOSURE}, \code{OPENTIME}, \code{INTTIME}, etc). Any system 3625 which operates on these metadata needs to address the issue of 3626 identifying these names. This issue seems like an argument for 3627 hardwiring metadata in the structure, but in fact it does not present 3628 such a strong case. If the metadata are hardwired, some function will 3629 still have to know how to interpret the various names to populate the 3630 structure. The concept can still be localized with generic metadata 3631 containers by including abstract metadata names within the code which 3632 are 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 3641 This section addresses the question of how \PS{} metadata should be 3642 represented in memory, not how it should be represented on disk. 3643 3644 We define an item of metadata with the following structure: 3645 \filbreak 3646 \begin{verbatim} 3647 typedef 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 3664 The \code{id} is a unique identifier for this item of metadata; 3665 experience shows that such tags are useful. The entry \code{name} 3666 specifies the name of the metadata item. The value of the metadata is 3667 given by the union \code{data}, and may be of type \code{psS32}, 3668 \code{psF32}, \code{psF64}, or an arbitrary rich structure pointed at 3669 by the \code{void} pointer \code{V}. A character string comment 3670 associated with this metadata item may be stored in the element 3671 \code{comment}. The \code{type} entry specifies how to interpret the 3672 type of the data being represented, given by the enumerated type 3673 \code{psMetadataType}: 3674 % 3675 \filbreak 3676 \begin{verbatim} 3677 typedef 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} 3690 If the data is a PSLib primitive data value, the primitive data type 3691 is given by the value of \code{ptype}. 3692 3693 A collection of metadata is represented by the \code{psMetadata} structure: 3694 \begin{verbatim} 3695 typedef struct { 3696 psList *list; ///< list of psMetadataItem 3697 psHash *table; ///< hash table of the same metadata 3698 } psMetadata; 3699 \end{verbatim} 3700 The type \code{psMetadata} is a container class for metadata. Note 3701 that there are in fact \emph{two} representations of the metadata 3702 (each \code{psMetadataItem} appears on both). The first 3703 representation employs a doubly-linked list that allows the order of 3704 the metadata to be preserved (e.g., if FITS headers are read in a 3705 particular order, they should be written in the same order). The 3706 second representation employs a hash table which allows fast look-up 3707 given a specific metadata keyword. 3708 3709 Certain metadata names (such as the FITS keywords \code{COMMENT} and 3710 \code{HISTORY} in a FITS header) may be repeated with different 3711 values. In such a case, the \code{psMetadata.list} structure contains 3712 the entries in their original sequence with duplicate keys. The 3713 \code{psMetadata.hash} entries, which are required to have unique 3714 keys, would have a single entry with the keyword of the repeated key, 3715 with the value of \code{psMetadataType} set to \code{PS_META_LIST}, 3716 and the \code{psMetadataItem.data} element pointing to a \code{psList} 3717 containing the actual entries. If \code{psMetadataItemAlloc} is 3718 called with the type set to \code{PS_META_LIST}, such a repeated key 3719 is 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 3722 entries of that keyword. 3723 3724 The \code{psMetadataAdd} routine is required to check that all 3725 metadata names are unique unless the type is already qualified as 3726 \code{PS_META_LIST}; in this case the data are added to the 3727 corresponding \code{psMetadataItem.data} list. 3728 3729 \subsubsection{Metadata APIs} 3730 3731 The allocator for \code{psMetadataItem} returns a full 3732 \code{psMetadataItem} ready for insertion into the \code{psMetadata}. 3733 The \code{name} entry specifies the name to use for this metadata 3734 item, and may include \code{sprintf}-type formating codes. The 3735 \code{comment} entry is a fixed string which is used for the comment 3736 associated with this metadata item. The metadata data and the 3737 arguments to the \code{name} formatting codes are passed, in that 3738 order (metadata pointer first), to \code{psMetadataItemAlloc} as 3739 arguments following the comment string. The data must be a pointer 3740 for any data types which are stored in the element \code{data.void}, 3741 while other data types are passed as numeric values. The argument 3742 list must be interpreted appropriately by the \code{va_list} operators 3743 in the function. 3744 \begin{verbatim} 3745 psMetadataItem *psMetadataItemAlloc(const char *name, psMetadataType type, const char *comment, ...); 3746 psMetadataItem *psMetadataItemAllocV(const char *name, psMetadataType type, const char *comment, va_list list); 3747 \end{verbatim} 3748 3749 The constructor for the collection of metadata, \code{psMetadata}, 3750 simply returns an empty metadata container (employing the constructors 3751 for the doubly-linked list and hash table). The destructor needs to 3752 free each of the \code{psMetadataItem}s using \code{psMetadataItemFree}. 3753 \begin{verbatim} 3754 psMetadata *psMetadataAlloc(void); 3755 \end{verbatim} 3756 3757 Items may be added to the metadata in one of two ways --- firstly, an 3758 item may be added by appending a \code{psMetadataItem} which has 3759 already been created; and secondly by directly providing the data to 3760 be 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 3763 the function using variadic argument interpretation. The third 3764 version is the \code{va_list} version of the second function. All 3765 three functions take a parameter, \code{location}, which specifies 3766 where in the list to place the element, following the conventions for 3767 the \code{psList}. The entry \code{mode} for \code{psMetadataAddItem} 3768 is a bit mask constructed by OR-ing the allowed option flags (eg, 3769 \code{PS_META_REPLACE}) which specifies minor variations on the 3770 behavior. The \code{format} entry, which specifies both the metadata 3771 type and the optional flags, is constructed by bit-wise OR-ing the 3772 appropriate \code{psMetadataType} and allowed option option flags. 3773 Care should be taken not to leak memory when appending an item for 3774 which the key already exists in the metadata (and is not 3775 \code{PS_META_LIST}). 3776 % 3777 \begin{verbatim} 3778 bool psMetadataAddItem(psMetadata *md, psMetadataItem *item, int location, int mode); 3779 bool psMetadataAdd(psMetadata *md, int location, const char *name, int format, const char *comment, ...); 3780 bool psMetadataAddV(psMetadata *md, int location, const char *name, int format, const char *comment, 3781 va_list list); 3782 \end{verbatim} 3783 3784 The functions above take option flags which modify the behavior when 3785 metadata items are added to the metadata list. These flags must be 3786 bit-exclusive of those used above for the \code{psMetadataTypes}. The 3787 flags have the following meanings: 3788 3789 \code{PS_META_DEFAULT}: This is the zero bit mask, to allow the 3790 default behavior for \code{psMetadataAddItem} above. If this is OR-ed 3791 with a \code{psMetadataType}, the result is as if no OR-ing took 3792 place. 3793 3794 \code{PS_META_REPLACE}: If the given metadata item exists in the 3795 metadata 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 3797 allowed to replace the existing entry. If this mode bit is not set, a 3798 duplicate (non-container-type) entry is an error. 3799 3800 \begin{verbatim} 3801 typedef 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 3807 An example of code to use these metadata APIs to generate the 3808 structure seen in Figure~\ref{fig:metadata} is given below. 3809 3810 \begin{verbatim} 3811 md = psMetadataAlloc(); 3812 3813 psMetadataAdd(md, PS_LIST_TAIL, "SIMPLE", PS_META_BOOL, "basic fits", TRUE); 3814 psMetadataAdd(md, PS_LIST_TAIL, "BLANK", PS_META_S32, "invalid pixel data", -32768); 3815 psMetadataAdd(md, PS_LIST_TAIL, "DATE-OBS", PS_META_STR, "observing date UT", " 2004-6-16"); 3816 psMetadataAdd(md, PS_LIST_TAIL, "COMMENT", PS_META_LIST, "head of comment block", NULL); 3817 psMetadataAdd(md, PS_LIST_TAIL, "COMMENT", PS_META_STR, "", "DATA"); 3818 psMetadataAdd(md, PS_LIST_TAIL, "COMMENT", PS_META_STR, "", "PARAMS"); 3819 psMetadataAdd(md, PS_LIST_TAIL, "EXPTIME", PS_META_F32, "exposure time (sec)", 1.05); 3820 psMetadataAdd(md, PS_LIST_TAIL, "COMMENT", PS_META_STR, "", "FOO"); 3821 3822 cell = psMetadataAlloc(); 3823 psMetadataAdd(cell, PS_LIST_TAIL, "EXTNAME", PS_META_STR, "", "CCD00"); 3824 psMetadataAdd(cell, PS_LIST_TAIL, "BIASNAME", PS_META_STR, "", "BSEC-00"); 3825 psMetadataAdd(cell, PS_LIST_TAIL, "CHIP", PS_META_STR, "", "CHIP.00"); 3826 psMetadataAdd(md, PS_LIST_TAIL, "CELL.00", PS_META_META, "", cell); 3827 3828 cell = psMetadataAlloc(); 3829 psMetadataAdd(cell, PS_LIST_TAIL, "EXTNAME", PS_META_STR, "", "CCD01"); 3830 psMetadataAdd(cell, PS_LIST_TAIL, "BIASNAME", PS_META_STR, "", "BSEC-01"); 3831 psMetadataAdd(cell, PS_LIST_TAIL, "CHIP", PS_META_STR, "", "CHIP.01"); 3832 psMetadataAdd(md, PS_LIST_TAIL, "CELL.01", PS_META_META, "", cell); 3833 \end{verbatim} 3834 3835 The following code shows how to use the APIs to replace one of these values: 3836 \begin{verbatim} 3837 psMetadataAdd(md, PS_LIST_TAIL, "EXPTIME", PS_META_F32 | PS_REPLACE, "new exposure time (sec)", 2.05); 3838 \end{verbatim} 3839 3840 Items may be removed from the metadata by specifying a key or a 3841 location in the list. If the value of \code{name} is \code{NULL}, the 3842 value 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 3845 is removed from the metadata and \code{true} is returned; otherwise, 3846 \code{false} is returned. If the key is not unique, then \emph{all} 3847 items corresponding to the key are removed, and \code{true} is 3848 returned. 3849 % 3850 \begin{verbatim} 3851 bool psMetadataRemove(psMetadata *md, int location, const char *key); 3852 \end{verbatim} 3853 3854 Items may be found within the metadata by providing a key. In the 3855 event that the key is non-unique, the first item is returned. 3856 \begin{verbatim} 3857 psMetadataItem *psMetadataLookup(const psMetadata *md, const char *key); 3858 \end{verbatim} 3859 3860 Several utility functions are provided for simple cases. These 3861 functions perform the effort of casting the data to the appropriate 3862 type. The numerical functions shall return 0.0 if their key is not 3863 found. If the pointer value of \code{status} is not \code{NULL}, it 3864 is set to reflect the success or failure of the lookup. 3865 \begin{verbatim} 3866 void *psMetadataLookupPtr(bool *status, const psMetadata *md, const char *key); 3867 psS32 psMetadataLookupS32(bool *status, const psMetadata *md, const char *key); 3868 psF64 psMetadataLookupF64(bool *status, const psMetadata *md, const char *key); 3869 \end{verbatim} 3870 3871 Items may be retrieved from the metadata by their entry position. The 3872 value of which specifies the desired entry in the fashion of 3873 \code{psList}. 3874 \begin{verbatim} 3875 psMetadataItem *psMetadataGet(const psMetadata *md, int location); 3876 \end{verbatim} 3877 3878 The 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 3882 in the list relative to that location. \code{psMetadataGetNext} has 3883 the ability to match the key using a POSIX regex, e.g., if the user 3884 only wants to iterate through \code{IPP.machines.sky} and doesn't want 3885 to bother with \code{IPP.machines.detector}. The iterator should 3886 iterate over every item in the metadata list, even those that are 3887 contained in a \code{PS_META_LIST}. The value \code{iterator} 3888 specifies the iterator to be used. In setting the iterator, the 3889 position of the iterator is defined by \code{location}, which follows 3890 the conventions of the \code{psList} iterators. 3891 \begin{verbatim} 3892 psListIterator *psMetadataIteratorAlloc(psMetadata *md, int location, bool mutable); 3893 bool psMetadataIteratorSet(psListIterator *iterator, int location); 3894 psMetadataItem *psMetadataGetAndIncrement(psListIterator *iterator, const char *regex); 3895 psMetadataItem *psMetadataGetAndDecrement(psListIterator *iterator, const char *regex); 3896 \end{verbatim} 3897 3898 Metadata items may be printed to an open file descriptor based on a 3899 provided format. The format string is an sprintf format statement 3900 with exactly one \% formatting command. If the metadata item type is 3901 a numeric type, this formatting command must also be numeric, and type 3902 conversion performed to the value to match the format type. If the 3903 metadata item type is a string, the formatting command must also be 3904 for a string (\%s type of command). If the metadata type is any other 3905 data type, printing is not allowed. 3906 \begin{verbatim} 3907 bool psMetadataItemPrint(FILE *fd, const char *format, const psMetadataItem *md); 3908 \end{verbatim} 3909 3910 \subsubsection{Configuration files} 3911 \label{sec:configspec} 3912 3913 It will be necessary for the \PS{} system, in order to load 3914 pre-defined settings, to parse a configuration file into a 3915 \code{psMetadata} structure. This shall be performed by the 3916 function \code{psMetadataParseConfig}, as described below. 3917 3918 \begin{verbatim} 3919 psMetadata *psMetadataParseConfig(psMetadata *md, int *nFail, const char *filename, bool overwrite); 3920 \end{verbatim} 3921 3922 Given a metadata container, \code{md}, and the name of a configuration 3923 file, \code{filename}, \code{psMetadataParseConfig} shall parse the 3924 configuration file, placing the contained key/type/value/comment quads 3925 into the metadata, and returning a pointer to the metadata structure. 3926 The number of lines that failed to parse is returned in \code{nFail}. 3927 Multiple specifications of a key that haven't been declared (see 3928 below) are overwritten if and only if \code{overwrite} is \code{true}. 3929 If the metadata container is \code{NULL}, it shall be allocated. 3930 3931 On error, the function shall return \code{NULL}. 3932 3933 The configuration file shall consist of plain text with 3934 key/type/value/comment quads on separate lines. Blank lines, 3935 including those consisting solely of whitespace (both spaces and 3936 tabs), shall be ignored, as shall lines that commence with the comment 3937 character (a hash mark, \code{#}), either immediately at the start of 3938 the line, or preceded by whitespace. The key/type/value/comment quads 3939 shall all lie on a single line, separated by whitespace. 3940 3941 The key shall be first, possibly preceded on the line by whitespace 3942 which should not form part of the key. 3943 3944 Next, to assist the casting of the value, shall be a string 3945 identifying the type of the value, which shall correspond to one of 3946 the 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, 3951 which will also necessitate updating the definition of psMetadata.} 3952 3953 The value shall follow the type: strings may consist of multiple 3954 words, and shall have all leading and trailing whitespace removed; 3955 booleans shall simply be either \code{T} or \code{F}. 3956 3957 Following the value may be an optional comment, preceded by a comment 3958 character (a hash mark, \code{#}), which in the case of a string 3959 value, serves to mark the end of the value, and for other types serves 3960 to identify the comment to the reader. Only one comment character may 3961 be present on any single line (i.e., neither strings nor comments are 3962 permitted to contain the comment character). The comment may consist 3963 of multiple words, and shall have leading and trailing whitespace 3964 removed. 3965 3966 One wrinkle is the specification of vectors. Keys for which the value 3967 is to be parsed as a vector shall be preceded immediately by a 3968 ``vector symbol'', which we choose to be the ``at'' sign, \code{@}. 3969 In this case, the type shall be interpreted as the type for the 3970 vector, which may be any of the signed or unsigned integer or floating 3971 point types (\code{U8,U16,U32,U64,S8,S16,S32,S32,S64,F32,F64}) but not 3972 the complex floating point types; and the value shall consist of 3973 multiple numbers, separated either by a comma or whitespace. These 3974 values shall populate a \code{psVector} of the appropriate type in the 3975 order 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 3980 An additional hurdle is the specification of keys that may be 3981 non-unique (such as the \code{COMMENT} keyword in a FITS header). 3982 These keys shall be specified in the configuration file as non-unique 3983 by specifying the key at the start of the line (possibly preceded by 3984 whitespace) and specifying the type as a ``multiple symbol'', which we 3985 choose to be an asterisk, \code{*}. No other data may be provided on 3986 this line, though a comment, preceeded by the comment marker, is 3987 valid. A warning shall be produced when a key which has not been 3988 specified to be non-unique is repeated; in this case, the former value 3989 shall be overwritten if \code{overwrite} is \code{true}, otherwise the 3990 line shall be ignored and counted as one that could not be parsed. 3991 3992 If a line does not conform to the rules laid out here, a warning shall 3993 be generated, it shall be ignored and counted as a line that could not 3994 be 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 3997 lines and comment lines) shall be returned by the function in the 3998 argument \code{nFail}. 3999 4000 Here are some examples of lines of a valid configuration file: 4001 \filbreak 4002 \begin{verbatim} 4003 Double F64 1.23456789 # This is a comment 4004 Float F32 0.98765 # This is a comment too 4005 String STR This is the string that forms the value #comment 4006 4007 # This is a comment line and is to be ignored 4008 boolean BOOL T # The value of `boolean' is `true' 4009 4010 @primes U8 2,3 5 7,11,13 17 # These are prime numbers 4011 4012 comment MULTI # The rest of this line is ignored, but `comment' is set to be non-unique 4013 comment STR This 4014 comment STR is 4015 comment STR a 4016 comment STR non-unique 4017 comment STR key 4018 Float F64 1.23456 # This generates a warning, and, if `overwrite' is `false', is ignored 4019 \end{verbatim} 4020 4021 Of course, a real configuration file should look much nicer to humans 4022 than the above example, but PSLib must be able to parse such ugly 4023 files. 4024 4025 We extend \code{psMetadataParseConfig} to allow a modest tree 4026 structure by defining a reserved keyword \code{TYPE}. Any line in the 4027 config file which starts with the word \code{TYPE} shall be 4028 interpretted as defining a new valid type. The defined type name 4029 follows the word \code{TYPE}, and is in turn followed by an arbitrary 4030 number of words. These words are to be interpreted as the names of an 4031 embedded \code{psMetadata} entry, where the values are given on any 4032 line which (following the \code{TYPE} definition) employs the new type 4033 name. For example, a new type may be defined as: 4034 \begin{verbatim} 4035 TYPE CELL EXTNAME BIASSEC CHIP 4036 CELL.00 CELL CCD00 BSEC-00 CHIP.00 4037 CELL.01 CELL CCD01 BSEC-01 CHIP.00 4038 \end{verbatim} 4039 4040 When \code{psMetadataParseConfig} encounters the \code{TYPE} line, it 4041 should construct a \code{psMetadata} container and fill it with 4042 \code{psMetadataItems} having the names \code{EXTNAME, BIASSEC, CHIP}, 4043 with type \code{PS_META_STR}, but data allocated. When it next 4044 encounters an entry of type \code{CELL}, it should then use the given 4045 name (e.g., \code{CELL.00}) for the \code{psMetadataItem}, and copy 4046 the \code{psMetadata} data onto the \code{psMetadataItem.data.md} 4047 entry, filling in the values from the rest of the line (\code{CCD00, 4048 BSEC-00, CHIP.00}). This hierarchical structure is illustrated in 4049 Figure~\ref{fig:metadata}. 4050 4051 We further extend \code{psMetadataParseConfig} to allow the definition 4052 of a \code{psMetadata} entry using a sequence of successive lines to 4053 define the values of the \code{psMetadataItem} entries. The initial 4054 line defines the new \code{psMetadata} entry and its name. The 4055 following lines have the same format as the other metadata config file 4056 entries. 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} 4059 CELL METADATA 4060 EXTNAME STR CCD00 4061 BIASSEC STR BSEC-00 4062 CHIP STR CHIP.00 4063 NCELL S32 24 4064 END 4065 \end{verbatim} 4066 4067 A series of test inputs is contained in 4068 \S\ref{sec:configtest}. 4069 4070 \subsection{XML Functions} 4071 4072 Within Pan-STARRS, we will use XML documents as a transport mechanism 4073 to carry data between programs and between IPP and other subsystems. 4074 Configuration information may be stored as well as XML documents, in 4075 addition to the text format discussed in the discussion on Metadata. 4076 XML is an extremely variable document format, and it is not currently 4077 the intention of PSLib to provide a complete PSLib version of XML 4078 operations. Rather, a limited number of operations are defined to 4079 convert specific data structures to an appropriate XML document. To 4080 maximize the simplicity of the XML APIs, we will use the convention 4081 that a single XML document to be parsed by PSLib shall contain only a 4082 single data structure. Each of the XML APIs therefore take as input a 4083 reference to a complete XML document and return a PSLib data 4084 structure, or take a PSLib data structure and return a complete XML 4085 document. 4086 4087 We start by defining a PSLib wrapper type which is a pointer to an XML 4088 document in memory. We wrap the \code{libxml2} version of an XML 4089 document pointer for now: 4090 \begin{verbatim} 4091 typedef xmlDocPtr psXMLDoc; 4092 void psXMLDocFree(psXMLDoc *doc); 4093 \end{verbatim} 4094 4095 The next pair of functions convert a \code{psMetadata} data structure 4096 to a complete \code{psXMLDoc} (in memory) and vice versa: 4097 \begin{verbatim} 4098 psXMLDoc *psMetadataToXMLDoc(const psMetadata *metadata); 4099 psMetadata *psXMLDocToMetadata(const psXMLDoc *doc); 4100 \end{verbatim} 4101 4102 The next pair of functions loads the data in a named file into a 4103 complete \code{psXMLDoc} (in memory) and write out the \code{psXMLDoc} 4104 to a named file: 4105 \begin{verbatim} 4106 psXMLDoc *psXMLParseFile(const char *filename); 4107 int psXMLDocToFile(const psXMLDoc *doc, const char *filename); 4108 \end{verbatim} 4109 4110 The next pair of functions accepts a block of memory and parses it 4111 into a complete \code{psXMLDoc} (also in memory), and vice versa: 4112 \begin{verbatim} 4113 psXMLDoc *psXMLParseMemory(const char *buffer, const int size); 4114 int psXMLDocToMemory(const psXMLDoc *doc, char *buffer); 4115 \end{verbatim} 4116 4117 The next pair of functions read from and write to a file descriptor. 4118 The first converts the imcoming data to a complete \code{psXMLDoc} 4119 (also in memory), the second writes the \code{psXMLDoc} to the file 4120 descriptor: 4121 \begin{verbatim} 4122 psXMLDoc *psXMLParseFD(int fd); 4123 int psXMLDocToFD(const psXMLDoc *doc, int fd); 4124 \end{verbatim} 4125 4126 \subsection{Database Functions} 4127 4128 Many of the applications that PSLib will be used for will require 4129 access to a simple relational database. PSLib includes generic 4130 database-independent interface mechanisms as part of its API set. The 4131 most important aspect of PSLib's database support is to abstract as 4132 much database specific complexity as is feasible. As almost all RDBMS 4133 provide at least a simple transactional model, commit and rollback 4134 support should be provided. 4135 4136 Currently, only support for MySQL 4.1.x is required but other backends 4137 may be added as options in the future. As a particular example which 4138 has implications for the database interaction model, support for 4139 SQLite may be required in the future. Currently, the choice of 4140 backend database interface may be made as a compile option. Details 4141 of the specified APIs in the discussion below refer to the relevant 4142 MySQL functions. 4143 4144 Database errors must be trapped and placed onto the psError stack. 4145 The complete error message should be retrieved with the database's 4146 error function. 4147 4148 \subsubsection{Managing the Database Connection} 4149 4150 We specify a database handle which carries the information about the 4151 database connection: 4152 4153 \begin{verbatim} 4154 typedef struct { 4155 MYSQL *mysql; 4156 } psDB; 4157 \end{verbatim} 4158 4159 The 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 4178 For MySQL support, \code{psDBInit()} wraps \code{mysql_init()} and 4179 \code{mysql_real_connect()} in order to initialize a psDB structure and 4180 establish a database connection. A null pointer should be returned on 4181 failure. 4182 4183 When implementing support for SQLite, or other DB which is purely 4184 file-based, the \code{host}, \code{user}, and \code{passwd} arguments 4185 would be ignored while \code{dbname} would specify the path to the 4186 SQLite db file. 4187 4188 \subsubsection{Interacting with Database Tables} 4189 4190 The functions in this section perform high level interactions with the 4191 database tables. All of them should behave ``atomically'' with 4192 respect to the state of the database. Specifically, all interactions 4193 with the database should be done as a part of a transaction that is 4194 rolled-back on failure and committed only after all queries used by 4195 the API have been run. In general, this API set attempts to treat a 4196 database 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 4199 table 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 4205 This function generates and executes the SQL needed to create a table 4206 named \code{tableName}, with the column names and datatypes as 4207 described in \code{md}. Each data item in the \code{psMetadata} 4208 collection represents a single table field. The name of the field is 4209 given by the name of the \code{psMetadataItem} and the data type is 4210 give by the \code{psMetadataItem.type} and \code{psMetadataItem.ptype} 4211 entries. A lookup table should be used to convert from PSLib types 4212 into 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} 4215 element is set to a string with the length for the field written as a 4216 text string. The value of the \code{psMetadataItem.data} element is 4217 unused for the \code{PS_META_PRIMITIVE} types. Other metadata types 4218 beyond \code{PS_META_STR} and \code{PS_META_PRIMITIVE} are not allowed 4219 in a table definition metadata collection. 4220 4221 Database indexes can be specified setting the \code{comment} field to 4222 ``\code{Primary Key}'' or ``\code{Key}''. Comment are otherwise 4223 ignored. 4224 4225 \begin{verbatim} 4226 bool psDBDropTable(psDB *dbh, const char *tableName); 4227 \end{verbatim} 4228 4229 This 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 4236 These functions generates and executes the SQL needed to select an entire 4237 column from a table or up to \code{limit} rows from it. If \code{limit} is 0, 4238 the 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 4240 the 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 4247 This function returns rows from the specified table which match 4248 the restrictions given by \code{where}. The restrictions are 4249 specified as field / value pairs. The \code{psMetadata} collection 4250 where must consist of valid database fields, though the database query 4251 checking functions may be used to validate the fields as part of the 4252 query. If \code{where} is \code{NULL}, then there are no restrictions 4253 on 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 4260 Insert the data from \code{row} into \code{tableName}. It should be noted in 4261 the API reference that if fields are specified in \code{row} that do not exist 4262 in \code{tablename}, the insert will fail. 4263 4264 \begin{verbatim} 4265 bool psDBInsertRows(psDB *dbh, const char *tableName, psArray *rowSet); 4266 \end{verbatim} 4267 4268 Similar to \code{psDBInsertOneRow()}, this function inserts many rows at once 4269 and is atomic for the complete set of rows. 4270 4271 \begin{verbatim} 4272 psArray *psDBDumpRows(psDB *dbh, const char *tableName); 4273 \end{verbatim} 4274 4275 Fetch all rows as an psArray of psMetadata. 4276 4277 \begin{verbatim} 4278 psMetadata *psDBDumpCols(psDB *dbh, const char *tableName); 4279 \end{verbatim} 4280 4281 Fetch all columns, as either a psVector or a psArray depnding on whether or not 4282 the column is numeric, and return them in a psMetadata structure where 4283 psMetadataItem.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 4289 Update the columns contained in \code{values} in the row(s) that have a field 4290 with the value indicated by \code{where} (note that this is only allows very 4291 limited use of SQL99's ``where'' semantics). The number of rows modified is 4292 returned. A negative value is return to indicate an error. If there are 4293 multiple psMetadataItems in \code{where} then each item should be considered as 4294 an 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 4300 Delete 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 4302 error. 4303 4304 \subsection{FITS I/O Functions} 4305 4306 We need a variety of I/O functions between the disk and certain of our 4307 PSLib data structures. We need the ability to access FITS headers, 4308 images and tables (both ASCII and Binary). We define here the FITS 4309 I/O functions, all of which are currently specified as wrappers to 4310 functions within CFITSIO. CFITSIO provides a wide range of utilities 4311 which we do not feel are particularly appropriate as part of a generic 4312 I/O library, such as assumptions about names which change the data 4313 interpretation, etc. We are defining our calls to avoid the hidden 4314 'features'. The CFITSIO functions which are wrapped should in general 4315 be the most basic versions. 4316 4317 \begin{verbatim} 4318 typedef struct { 4319 fitsfile fd; 4320 } psFits; 4321 \end{verbatim} 4322 We begin by defining a datatype to wrap the CFITSIO \code{fitsfile} 4323 structure. This is necessary to allow repeated access to the data in 4324 a file without multiple open commands (which are expensive). 4325 4326 \subsubsection{FITS File Manipulations} 4327 4328 \begin{verbatim} 4329 psFits *psFitsAlloc(const char *filename); 4330 \end{verbatim} 4331 4332 Opens a FITS file at positions the pointer to the PHU. 4333 4334 \begin{verbatim} 4335 bool psFitsMoveExtName(psFits *fits, const char *extname); 4336 \end{verbatim} 4337 4338 Positions the pointer to the beginning of the specified 4339 \code{extname}. If the \code{extname} does not exist, the function 4340 shall fail. 4341 4342 \begin{verbatim} 4343 bool psFitsMoveExtNum(psFits* fits, int extnum, bool relative); 4344 \end{verbatim} 4345 4346 Moves the pointer to the beginning of the specified HDU number. If 4347 \code{relative} is TRUE, \code{extnum} represents the number of HDUs 4348 relative to the current HDU. The PHU is entry number 0, while the 4349 extended data segments start at number 1. 4350 4351 \begin{verbatim} 4352 int psFitsGetExtNum(psFits* fits); 4353 \end{verbatim} 4354 4355 Returns the current HDU number (i.e., file position). 4356 4357 \begin{verbatim} 4358 int psFitsGetSize(psFits* fits); 4359 \end{verbatim} 4360 4361 Returns the number of HDUs in the file. 4362 4363 \begin{verbatim} 4364 psFitsType psFitsGetExtType(psFits* fits); 4365 \end{verbatim} 4366 4367 Gets the current HDU's type (table or image). 4368 4369 \subsubsection{FITS Header I/O Functions} 4370 4371 \begin{verbatim} 4372 psMetadata *psFitsReadHeader(psMetadata *out, const psFits *fits); 4373 \end{verbatim} 4374 Read header data into a \code{psMetadata} structure. The data is read 4375 from 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} 4379 psMetadata *psFitsReadHeaderSet (psFits *fits); 4380 \end{verbatim} 4381 Load a complete set of headers from the \code{psFits} file pointer. 4382 This 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 4385 entry names are the \code{EXTNAME} values for each header (with the 4386 value of \code{PHU} for the primary header unit). At the start of the 4387 operation, the file pointer is rewound to the beginning of the file. 4388 At the end, it is positioned where it started when the function was 4389 called. 4390 4391 \begin{verbatim} 4392 bool psFitsWriteHeader(psMetadata *output, const psFits *fits); 4393 \end{verbatim} 4394 Write metadata into the header of a FITS image file. The header is 4395 written at the current HDU. 4396 4397 \subsubsection{FITS Image I/O Functions} 4398 4399 \begin{verbatim} 4400 psImage *psFitsReadImage(psImage *output, psFits *fits, psRegion region, int z); 4401 \end{verbatim} 4402 Read an image or subimage from the \code{psFits} file pointer. This 4403 function is a wrapper to the CFITSIO library function. The input 4404 parameters allow a full image or a subimage to be read. The region to 4405 be 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 4407 to be read counting down from the end of the array. 4408 4409 If the native image is a cube, the value of z specifies the requested 4410 slice 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 4412 the data in the image file, or if the image on disk is zero- or 4413 one-dimensional. This function need only read images of the native 4414 FITS image types (\code{psU8}, \code{psS16}, \code{psS32}, 4415 \code{psF32}, \code{psF64}). The user is expected to convert the data 4416 type as needed with \code{psImageCopy}. 4417 4418 \begin{verbatim} 4419 bool psFitsUpdateImage(psFits *fits, const psImage *input, psRegion region, int z); 4420 \end{verbatim} 4421 \tbd{we have discussed this as the alternate name} 4422 Write an image section to the open \code{psFits} file pointer. This 4423 operation may write a portion of an image over the existing bytes of 4424 an existing image. Care must be taken to interpret \code{region}, 4425 which specified the output pixels to be written / over-written. If 4426 the combination of \code{region} and the size of \code{psImage *input} 4427 implies writing pixels outside the existing data area of the image, 4428 the function shall return an error (ie, if \code{region.x0 + image.nx 4429 >= NAXIS1}, \code{region.y0 + image.ny >= NAXIS2}, or \code{z >= 4430 NAXIS3}). This function will only write images of the native FITS 4431 image types (\code{psU8}, \code{psS16}, \code{psS32}, \code{psF32}, 4432 \code{psF64}). The user is expected to convert the data type as 4433 needed with \code{psImageCopy}. The return value must be 0 for a 4434 successful operation and 1 for an error. 4435 4436 \begin{verbatim} 4437 bool psFitsWriteImage(psFits *fits, psMetadata *header, const psImage *input, int depth); 4438 \end{verbatim} 4439 Create a new image based on the dimensions specified for the image and 4440 the requested depth. The header and image data segments are written 4441 in the file at the current position of the \code{psFits} pointer. 4442 This function will only write images of the native FITS image types 4443 (\code{psU8}, \code{psS16}, \code{psS32}, \code{psF32}, \code{psF64}). 4444 The user is expected to convert the data type as needed with 4445 \code{psImageCopy}. The return value must be 0 for a successful 4446 operation and 1 for an error. 4447 4448 \subsubsection{FITS Table I/O Functions} 4449 4450 \begin{verbatim} 4451 psMetadata *psFitsReadTableRow (psFits *fits, int row); 4452 \end{verbatim} 4453 This function reads a single row of the table in the extension pointed 4454 at by the \code{psFits} file pointer. The row number to be read is 4455 given by \code{row}. The result is returned as a \code{psMetadata} 4456 collection with elements of the apporpriate types and keys 4457 corresponding to the table column names. The function must apply the 4458 needed byte-swapping on the data in the row based on the description 4459 of the table data in the table header. \tbr{we may need to be more 4460 flexible here: if we call this function repeatedly, it would be more 4461 efficient to pass the corresponding header or keep it somewhere (and 4462 the file pointer location, for that matter).} 4463 4464 \begin{verbatim} 4465 void *psFitsReadTableRowRaw (int *nBytes, psFits *fits, int row); 4466 \end{verbatim} 4467 This function reads a single row of the table in the extension pointed 4468 at by the \code{psFits} file pointer. The row number to be read is 4469 given by \code{row}. The result is returned as collection of 4470 \code{nBytes} bytes allocated by the function. The function must 4471 apply the needed byte-swapping on the data in the row based on the 4472 description of the table data in the table header. \tbr{we may need 4473 to be more flexible here: if we call this function repeatedly, it 4474 would be more efficient to pass the corresponding header or keep it 4475 somewhere (and the file pointer location, for that matter).} 4476 4477 \begin{verbatim} 4478 psArray *psFitsReadTableColumn (psFits *fits, char *colname); 4479 \end{verbatim} 4480 This function reads a single column of the table in the extension 4481 pointed at by the \code{psFits} file pointer. The column is specified 4482 by the FITS table column key given by \code{row}. The result is 4483 returned as a \code{psArray}, with the data from one row of the table 4484 column per array element. 4485 4486 \begin{verbatim} 4487 psVector *psFitsReadTableColumnNum (psFits *fits, char *colname); 4488 \end{verbatim} 4489 This function reads a single column of the table in the extension 4490 pointed at by the \code{psFits} file pointer. The column is specified 4491 by the FITS table column key given by \code{row} and must be of a 4492 numeric data type. The result is returned as a \code{psVector} of the 4493 appropriate data type, with the data from one row of the table column 4494 per array element. 4495 4496 \begin{verbatim} 4497 psArray *psFitsReadTableRaw (int *nBytes, psFits *fits); 4498 \end{verbatim} 4499 This 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 4501 bytes per row is returned in \code{nBytes}. The function must apply 4502 the needed byte-swapping on the data in each row based on the 4503 description of the table data in the table header. 4504 4505 \begin{verbatim} 4506 psArray *psFitsReadTable (psFits *fits); 4507 \end{verbatim} 4508 This 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 4510 stored as a \code{psMetadata} collection as described above for 4511 \code{psFitsReadTableRow}. 4512 4513 \begin{verbatim} 4514 bool psFitsWriteTable(psFits* fits, psMetadata *header, psArray* table); 4515 \end{verbatim} 4516 Accepts a \code{psArray} of \code{psMetadata} and writes it to the 4517 current HDU. If the current HDU is not a table type, this will fail 4518 and return FALSE. 4519 4520 \begin{verbatim} 4521 bool psFitsUpdateTable(psFits* fits, psMetadata *header, psMetadata* data, int row); 4522 \end{verbatim} 4523 Writes the \code{psMetadata} data to a FITS table at the specified row 4524 in the current HDU. If the current HDU is not a table type, this will 4525 fail and return FALSE. 4526 4527 \pagebreak 3445 4528 \section{Astronomy-Specific Functions} 3446 4529 … … 3457 4540 \begin{itemize} 3458 4541 \item Dates and times 3459 \item Metadata3460 4542 \item Detector and sky positions 3461 \item Astronom y Image4543 \item Astronomical Image Containers 3462 4544 \item Astrometry 3463 4545 \item Photometry … … 3487 4569 3488 4570 typedef enum { 3489 PS_IERS_A, ///< IERS Bull iten A3490 PS_IERS_B, ///< IERS Bull iten B3491 } psTimeBull iten;4571 PS_IERS_A, ///< IERS Bulletin A 4572 PS_IERS_B, ///< IERS Bulletin B 4573 } psTimeBulletin; 3492 4574 3493 4575 typedef struct { 3494 4576 psS64 sec; ///< seconds, negative values represent dates before 1970 3495 psU32 nsec; ///< nan seconds4577 psU32 nsec; ///< nanoseconds 3496 4578 bool leapsecond; ///< if time falls on a UTC leapsecond 3497 4579 psTimeType type; ///< type of time … … 3523 4605 This function may be used to convert between the various \code{psTimeType} time 3524 4606 representations. The \code{time} is modified and returned. Conversion between 3525 all of the \emph{SI} length second systems should be implimented asfirst4607 all of the \emph{SI} length second systems should be implimented by first 3526 4608 converting to TAI and then to the destination system. UT1 is a special case 3527 4609 for conversion as it uses variable length secounds. Conversation to UT1, via 3528 4610 TAI, is allowed but conversion \emph{from} UT1 is currently forbidden. 3529 4611 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: 4612 The following function converts to Local Mean Sidereal Time. It is 4613 necessary to provide the local longitude (specified in radians, 4614 positive East of Greenwich) as well: 3532 4615 3533 4616 \begin{verbatim} … … 3535 4618 \end{verbatim} 3536 4619 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). 4620 The function may accept any of the \code{psTimeType} types with 4621 \emph{SI} length seconds. The \code{time} is modified and returned. 4622 Note that this function requires the value $UT1-UTC$ (see 4623 \code{psTimeGetUT1Delta()}) and should use the UT1 values interpolated 4624 from IERS bulletin B. 4625 4626 The following utility function encapsulates the PSLib mechanism to 4627 extract the value of $UT1-UTC$ from the IERS Time Tables: 4628 4629 \begin{verbatim} 4630 double psTimeGetUT1Delta(const psTime *time, psTimeBulletin bulletin); 4631 \end{verbatim} 4632 4633 The following function provides tidal corrections to UT1-UTC, using 4634 the Ray model of Simon et al (REF). 4635 \begin{verbatim} 4636 psTime *psTime_TideUT1Corr(const psTime *time); 4637 \end{verbatim} 4638 4639 Leap 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 4641 useful for astronomical purposes). The following function calculates 4642 the absolute number of leap seconds different between two times. 3552 4643 3553 4644 \begin{verbatim} … … 3555 4646 \end{verbatim} 3556 4647 3557 This function calculates the absolute number of leap seconds different between 3558 two times. 4648 The following function accepts \code{PS_TIME_UTC} objects and 4649 determines if the time is potentaly a leapsecond, returning 4650 \code{TRUE} if so. 3559 4651 3560 4652 \begin{verbatim} 3561 4653 bool psTimeIsLeapSecond(const psTime *utc); 3562 4654 \end{verbatim} 3563 3564 This function only accepts \code{PS_TIME_UTC} objects and determines if the3565 time is potentaly a leapsecond.3566 4655 3567 4656 \subsubsection{External Date and Time Formats} … … 3581 4670 \end{verbatim} 3582 4671 3583 The \code{psTimeToISO()} function will convertion\code{PS_TIME_UTC} objects3584 with the \code{leapsecond} flag set to represent the number of seconds as3585 ``:60''.4672 The \code{psTimeToISO()} function converts \code{PS_TIME_UTC} objects 4673 with the \code{leapsecond} flag set to represent the number of seconds 4674 as ``:60''. 3586 4675 3587 4676 \subsubsection{Date and Time Parsing} … … 3622 4711 \code{psS64} (the type of \code{psTime.sec}). 3623 4712 3624 Note that in both these functions , when handling UTC, that the difference3625 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 that3632 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 4713 Note that in both these functions the difference between two times is 4714 the elapsed number of seconds, inclusing leap seconds. For example, 4715 if we add 30 seconds to 1998-12-31T23:59:45Z, the result is 4716 1999-01-01T00:00:14Z, since a leap second was introduced at 4717 1999-01-01T00:00:00Z. 4718 4719 Time math may only be done on \code{psTime} objects of the same type, 4720 and except in the case of UT1, the functions shall internally convert 4721 the \code{psTime} inputs to TAI before performing the math; this 4722 ensures that leap seconds are correctly counted. 4723 4724 The type of the time returned by \code{psTimeMath} shall be the same 4725 as that of the input \code{time}. 3637 4726 3638 4727 \subsubsection{Time Tables} … … 3645 4734 3646 4735 \begin{itemize} 3647 \item IERS Bull iten A \& B (1 year ago $\rightarrow$ now + $\sim$3 months)4736 \item IERS Bulletin A \& B (1 year ago $\rightarrow$ now + $\sim$3 months) 3648 4737 \begin{itemize} 3649 4738 \item \code{ftp://maia.usno.navy.mil/ser7/finals.daily} 3650 4739 \end{itemize} 3651 4740 3652 \item IERS Bull iten A \& B (1973-1-2 $\rightarrow$ now + $\sim$1 year)4741 \item IERS Bulletin A \& B (1973-1-2 $\rightarrow$ now + $\sim$1 year) 3653 4742 \begin{itemize} 3654 4743 \item \code{ftp://maia.usno.navy.mil/ser7/finals.all} … … 3673 4762 format of these files shall be simple, for speed in reading. Each line shall 3674 4763 contain the date in MJD and the following values from both the A \& B IERS 3675 bull itens: $x_p$ (in arcseconds), $y_p$ (in arcseconds) and $\Delta$UT (in4764 bulletins: $x_p$ (in arcseconds), $y_p$ (in arcseconds) and $\Delta$UT (in 3676 4765 seconds). This format must be readable by \code{psLookupTableRead}. For 3677 4766 example: … … 3756 4845 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3757 4846 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} 4774 4848 4775 4849 Both detector and sky positions will be used extensively in the IPP. 4776 4850 The 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. 4851 while the second are angular coordinates which define a position on 4852 the sphere of the sky. We put these into two structures, 4853 \code{psPlane} and \code{psSphere}, respectively. Partitioning these 4854 two will enable error-checking. An alternative representation for 4855 angular positions is the 3-D unit vector. These are used in 4856 particular as part of spherical rotation calculations. We define 4857 \code{psCube} to represent such an element. 4781 4858 % 4782 4859 \begin{verbatim} … … 4794 4871 double dErr; ///< Error in Dec 4795 4872 } psSphere; 4873 4874 typedef 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; 4796 4882 \end{verbatim} 4797 4883 … … 4818 4904 Constructors for these are straight-forward: 4819 4905 \begin{verbatim} 4820 psPlane *psPlaneAlloc(void);4906 psPlane *psPlaneAlloc(void); 4821 4907 psSphere *psSphereAlloc(void); 4908 psCube *psCubeAlloc(void); 4822 4909 \end{verbatim} 4823 4910 Initialization of the structures is not necessary. … … 4985 5072 \code{NULL}, the function shall generate an error and return 4986 5073 \code{NULL}. 4987 4988 4989 \subsubsection{Celestial Coordinate Conversions}4990 4991 We need to be able to convert between ICRS, Galactic and Ecliptic4992 coordinates, and potentially between arbitrary spherical coordinate4993 systems. All of these basic spherical transformations represent4994 rotations of the spherical coordinate reference. We specify a general4995 transformation function which takes a structure,4996 \code{psSphereTransform}, defining the transformation between two4997 spherical coordinate systems (the structure contains the sines and4998 cosines of the angles involved so as to minimize computation time for4999 repeated transformations). We also define a function to generate5000 \code{psSphereTransform}, based on the three angles5001 describing the location of the pole and the relative equatorial5002 rotations of the two systems. We also specify special functions to5003 return the \code{psSphereTransform} for transformations5004 between standard coordinate systems.5005 5006 \begin{verbatim}5007 typedef struct {5008 double cosDeltaP; ///< Cosine of target pole latitude in the source system5009 double sinDeltaP; ///< Sine of target pole latitude in the source system5010 double alphaP; ///< Longitude of the target system pole in the source system5011 double phiP; ///< Longitude of the ascending node in the target system5012 } 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 the5020 input system of the north pole in the output system and \code{phiP}5021 defines the longitude in the input system of the equatorial5022 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 the5026 transformation and the coordinate in the input system to5027 \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 appropriate5035 \code{psSphereTransform} to convert between predefined spherical5036 coordinate systems (i.e., ICRS, Ecliptic and Galactic). These are5037 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 to5047 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}. The5055 \code{coords} are modified in-place. Equinoxes shall be Julian5056 equinoxes (as opposed to Bessellian).5057 5058 \subsubsection{Projections}5059 5060 We require functions to convert between spherical and linear5061 coordinate systems based on a variety of projections. The required5062 projections include:5063 \begin{itemize}5064 \item TAN5065 \item SIN5066 \item AIT5067 \item PAR5068 \end{itemize}5069 5070 We specify the following structure \code{psProjection} to define the5071 parameters of the projection:5072 \begin{verbatim}5073 typedef struct {5074 double R, D; ///< coordinates of projection center5075 double Xs, Ys; ///< plate-scale in X and Y directions5076 psProjectionType type; ///< projection type5077 } 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 projection5084 PS_PROJ_SIN, ///< Sine projection5085 PS_PROJ_AIT, ///< Aitoff projection5086 PS_PROJ_PAR, ///< Par projection5087 PS_PROJ_NTYPE ///< Number of types; must be last5088 } 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 on5106 the sky, as well as a function to apply an offset to a position. The5107 first determines the offset (RA,Dec) on the sky between two positions.5108 The second applies the given offset to the coordinate. Both an offset5109 mode and an offset unit may be defined. The mode may be either5110 \code{PS_SPHERICAL}, in which case the specified offset corresponds to5111 an offset in angles, or it may be \code{PS_LINEAR}, in which case the5112 offset corresponds to a linear offset in a local projection. The5113 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 of5115 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 sphere5130 PS_LINEAR; ///< Linear offset5131 } psSphereOffsetMode;5132 5133 typedef enum {5134 PS_ARCSEC; ///< Arcseconds5135 PS_ARCMIN; ///< Arcminutes5136 PS_DEGREE; ///< Degrees5137 PS_RADIAN; ///< Radians5138 } psSphereOffsetUnit;5139 \end{verbatim}5140 Note that these should propagate the errors appropriately.5141 5142 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5143 5144 %%% Astronomical Images and Astrometry5145 \include{psLibSDRS_Astrom}5146 5147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5148 5149 \subsection{Pixel Lists}5150 5151 Usually an image mask is the best way to carry information about what5152 pixels mean what. However, in the case where the number of pixels in5153 which we are interested is limited, it is more efficient to simply5154 carry a list of pixels. An example of this is in the image5155 combination code, where we want to perform an operation on a5156 relatively small fraction of pixels, and it is inefficient to go5157 through an entire mask image checking each pixel.5158 5159 \begin{verbatim}5160 typedef struct {5161 psVector *x; // x coordinate5162 psVector *y; // y coordinate5163 } psPixels;5164 \end{verbatim}5165 5166 Of course, the size of each of the vectors should match. In the event5167 that they do not match, any function which detects the problem shall5168 generate a warning and use the size of the shorter of the vectors as5169 the size. The order in which the pixels are kept is not considered5170 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 the5178 \code{pixels} lying within the specified \code{region} set to the5179 \code{maskVal}. The \code{out} image shall be modified if supplied,5180 or allocated and returned if \code{NULL}. The size of the output5181 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} or5184 \code{region} are \code{NULL}, the function shall generate an error5185 and return \code{NULL}.5186 5187 \code{psMaskToPixels} shall return a \code{psPixels} consisting of the5188 coordinates in the \code{mask} that match the \code{maskVal}. The5189 \code{out} pixel list shall be modified if supplied, or allocated and5190 returned if \code{NULL}. In hte event that \code{mask} is5191 \code{NULL}, the function shall generate an error and return5192 \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} onto5199 \code{out}. In the event that \code{out} is \code{NULL}, a new5200 \code{psPixels} shall be allocated, and the contents of \code{pixels}5201 simply copied in. If \code{pixels} is \code{NULL}, the function shall5202 generate an error and return \code{NULL}. The function shall take5203 care to ensure that there are no duplicate pixels in \code{out} (since5204 the order in which the pixels are stored is not important, the values5205 may be sorted, allowing the use of a faster algorithm than a linear5206 scan).5207 5074 5208 5075 \begin{verbatim} … … 5228 5095 and return \code{NULL}. 5229 5096 5230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5097 \subsubsection{Spherical Rotations} 5098 5099 Spherical rotations represent coordinate transformation in 3-D, as 5100 well as the effects of precession and nutation. We need spherical 5101 rotatations to convert between ICRS, Galactic and Ecliptic 5102 coordinates, and to determine Alt-Az coordinates for sources. All of 5103 these basic spherical transformations represent rotations of the 5104 spherical coordinate reference. We specify a general transformation 5105 function which takes a structure, \code{psSphereRot}, defining the 5106 transformation between two spherical coordinate systems. The 5107 structure contains the elements of a quaternion to represent the 5108 spherical rotational. We define two allocators for 5109 \code{psSphereRot}, one which defines the rotation in terms of the 5110 coordinate of the pole and the rotation about that pole. The other 5111 defines the rotation from the elements of the quaternion. We also 5112 specify functions to manipulate \code{psSphereRot} in several useful 5113 way. 5114 5115 \begin{verbatim} 5116 typedef struct { 5117 double q0; 5118 double q1; 5119 double q2; 5120 double q3; 5121 } psSphereRot; 5122 \end{verbatim} 5123 5124 The constructor is defined as follows: 5125 \begin{verbatim} 5126 psSphereRot *psSphereRotAlloc(double alphaP, double deltaP, double phiP); 5127 \end{verbatim} 5128 where \code{alphaP} and \code{deltaP} define the coordinates in the 5129 input system of the axis of rotation (the north pole of the output 5130 system), while \code{phiP} defines the rotation about that pole. This 5131 last angle is also equal to 270\degree - $\phi_a$, where $\phi_a$ is 5132 the longitude in the output system of the ascending node (equatorial 5133 intersection between the two systems, e.g, the first point of Ares). 5134 5135 The \code{psSphereRot} may also be constructed by supplying the 5136 elements of the quaternion to the following function: 5137 \begin{verbatim} 5138 psSphereRot *psSphereRotQuat(double q0, double q1, double q2, double q3); 5139 \end{verbatim} 5140 This function normalizes the quaternion, so the input elements need 5141 not be normalized. 5142 5143 Spherical coordinates may be transformed by providing the 5144 transformation and the coordinate in the input system to 5145 \code{psSphereRot}. The output pointer may be optionally supplied, or 5146 if \code{NULL}, is allocated by the function. 5147 5148 \begin{verbatim} 5149 psSphere *psSphereRotApply(psSphere *out, const psSphereRot *transform, const psSphere *coord); 5150 \end{verbatim} 5151 5152 The following function combines two rotations, to produce a single 5153 rotation which is the equivallent of applying the first rotation and 5154 then the second. The output rotation may be supplied, or will be 5155 allocated if \code{NULL}. 5156 5157 \begin{verbatim} 5158 psSphereRot *psSphereRotCombine(psSphereRot *out, psSphereRot *rot1, psSphereRot *rot2) 5159 \end{verbatim} 5160 5161 The following function changes the given rotation to its inverse: 5162 5163 \begin{verbatim} 5164 psSphereRot *psSphereRotInvert(psSphereRot *rot) 5165 \end{verbatim} 5166 5167 The 3-vector representation of the angles (\code{psCube}) is needed to 5168 implement these functions, and is useful in other circumstances as 5169 well. Two utility functions are provided to convert between the 5170 angular and 3-vector representations: 5171 \begin{verbatim} 5172 psSphere *psCubeToSphere(psCube *cube); 5173 psCube *psSphereToCube(psSphere *sphere); 5174 \end{verbatim} 5175 5176 \subsubsection{Offsets} 5177 We require a function to calculate the offset between two positions on 5178 the sky, as well as a function to apply an offset to a position. The 5179 first determines the offset (RA,Dec) on the sky between two positions. 5180 The second applies the given offset to the coordinate. Both an offset 5181 mode and an offset unit may be defined. The mode may be either 5182 \code{PS_SPHERICAL}, in which case the specified offset corresponds to 5183 an offset in angles, or it may be \code{PS_LINEAR}, in which case the 5184 offset corresponds to a linear offset in a local projection. The 5185 offset 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 5187 the offset only. 5188 5189 \begin{verbatim} 5190 psSphere *psSphereGetOffset(const psSphere *position1, 5191 const psSphere *position2, 5192 psSphereOffsetMode mode, 5193 psSphereOffsetUnit unit); 5194 5195 psSphere *psSphereSetOffset(const psSphere *position, 5196 const psSphere *offset, 5197 psSphereOffsetMode mode, 5198 psSphereOffsetUnit unit); 5199 5200 typedef enum { 5201 PS_SPHERICAL; ///< Offset on a sphere 5202 PS_LINEAR; ///< Linear offset 5203 } psSphereOffsetMode; 5204 5205 typedef enum { 5206 PS_ARCSEC; ///< Arcseconds 5207 PS_ARCMIN; ///< Arcminutes 5208 PS_DEGREE; ///< Degrees 5209 PS_RADIAN; ///< Radians 5210 } psSphereOffsetUnit; 5211 \end{verbatim} 5212 Note that these should propagate the errors appropriately. 5213 5214 \subsection{Celestial Coordinate Systems} 5215 5216 The following functions simply return the appropriate 5217 \code{psSphereRot} to convert between predefined spherical 5218 coordinate systems (i.e., ICRS, Ecliptic and Galactic). These are 5219 constructors as well as the above \code{psSphereRotAlloc}. 5220 % 5221 \begin{verbatim} 5222 psSphereRot *psSphereRotICRSToEcliptic(psTime *time); 5223 psSphereRot *psSphereRotEclipticToICRS(psTime *time); 5224 psSphereRot *psSphereRotICRSToGalactic(void); 5225 psSphereRot *psSphereRotGalacticToICRS(void); 5226 \end{verbatim} 5227 5228 \subsection{Earth Orientation Calculations} 5229 5230 One of the critical sets of calculations in astronomy is the sequence 5231 of steps needed to convert between the celestial coordinates of an 5232 object and the observed coordinates of the object. This problem is 5233 best divided into two major components: transformation between the 5234 celestial sphere and coordinates relative to the surface of the solid 5235 earth, excluding the effects of the atmosphere, and compensation for 5236 the effects of the atmosphere. In this section, we address the first 5237 of these two transformations: the Earth Orientation Calculations. 5238 5239 The Earth Orientation Calculations are further subdivided into several 5240 steps, illustrated in Figure~\ref{CoordinateSystems} . Celestial 5241 coordinates are defined in the International Celestial Reference 5242 System (ICRS), which has the solar barycenter as its reference 5243 position and velocity. The next coordinate system is the Geocentric 5244 Celestial Reference System (GCRS), which uses the earth barycenter as 5245 a reference. The transformation between these two includes the 5246 abberation due to the Earth's velocity, the parallax of the object, 5247 which depends on both the Earth's position and the distance to the 5248 object of interest, and the general relativistic correction for the 5249 bending of light as it approaches the Earth. 5250 5251 The next set of transformations compenstate for the 3-D rotation of 5252 the Earth on various timescales, including the effects of precession, 5253 nutation, and simple solid-body rotation. These calculations can be 5254 performed using different amounts of information for higher levels of 5255 precision. Since the Earth's rotation is constantly affected by 5256 stochastic processes (weather, earthquakes, etc), these conversions 5257 are constantly modified by observations reported by authoratative 5258 sources such as the US Naval Observatory. The target of this 5259 transformation is the International Terrestrial Reference System 5260 (ITRS), which is fixed with respect to the Earth's crust. This 5261 transformation is subdivided into slow precesion and nutation 5262 (yielding the coordinate system CIP/CEO), followed by the Earth's 5263 rotation (yielding the coordinate system CIP/TEO), and finally 5264 corrections 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} 5274 The following function calculates the \code{apparent} position of a 5275 star, given its \code{actual} position and the velocity vector of the 5276 observer, represented as a speed and a direction: 5277 \begin{verbatim} 5278 psAberration(psSphere *apparent, psSphere *actual, psSphere direction, double speed); 5279 \end{verbatim} 5280 The \code{actual} and \code{apparent} positions are represented as 5281 \code{psSphere} entries, as is the \code{direction} of motion. The 5282 speed 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} 5289 double psEOC_ParallaxFactor(psSphere *coords, psTime *time); 5290 \end{verbatim} 5291 Calculate the parallax factor for the given position and time. 5292 5293 \subsubsection{Transformation from GCRS to ITRS} 5294 5295 \paragraph{Precession/Nutation} 5296 5297 The following routine calculates the components of the rotation 5298 between the CEO and GCRS frames, $X$, $Y$, and $s$, using to the 5299 IAU2000A precession \& nutation model: 5300 % 5301 \begin{verbatim} 5302 psSphere *psEOC_PrecessionModel(double *s, const psTime *time) 5303 \end{verbatim} 5304 % 5305 The input to this function is the desired \code{time}, which may be 5306 represented in any format other than UT1. This routine must give 5307 results identical to the IERS XYS2000A subroutine within the limits of 5308 machine accuracy. 5309 5310 The following function provides interpolated corrections to $X$ and 5311 $Y$ from the tables provided by the IERS, just as it does for UT1 and 5312 polar motion. 5313 5314 \begin{verbatim} 5315 psSphere *psEOC_GetPolarCorr(const psTime *time, psTimeBulletin bulletin); 5316 \end{verbatim} 5317 5318 The polar correction is applied to the $X$ and $Y$ elements of the 5319 rotation to provide higher accuracy. The spherical rotation term is 5320 generated by providing the three elements of the rotation to the 5321 following function: 5322 \begin{verbatim} 5323 psSphereRot *psSphereRot_CEOtoGCRS(double s, const psSphere *pole) 5324 \end{verbatim} 5325 The retulting \code{psSphereRot} may be used to determine the rotation 5326 from CIP/CEO to GCRS. This function must give results identical to 5327 the IERS BPN2000, within the limits of machine accuracy. 5328 5329 \paragraph{Earth Rotation} 5330 5331 The following routine calculates the rotation of the Earth about the CIP: 5332 \begin{verbatim} 5333 psSphereRot *psSphereRot_TEOtoCEO(const psTime *time) 5334 \end{verbatim} 5335 The IERS code to create the comparable rotation is embedded in 5336 T2C2000, with the Earth Rotation Angle calculated by ERA2000. 5337 5338 \paragraph{Polar Motion} 5339 5340 The following function provides interpolated values of the polar 5341 motion components, $x_p$ and $y_p$, extracted from the IERS tables. 5342 \begin{verbatim} 5343 psSphere *psEOC_GetPoleCoords(const psTime *time, psTimeBulletin bulletin); 5344 \end{verbatim} 5345 5346 The following function provides tidal corrections to the polar motion 5347 components, $x_p$ and $y_p$, using the Ray model of Simon et al (see 5348 ADD). 5349 \begin{verbatim} 5350 psSphere *psEOC_TidePolarCorr(const psTime *time); 5351 \end{verbatim} 5352 5353 The following function provides the additional corrections due to nutation 5354 terms with periods less than or equal to two days: 5355 \begin{verbatim} 5356 psSphere *psEOC_NutationCorr(psTime *time); 5357 \end{verbatim} 5358 5359 The following function should generate the \code{psSphereRot} transform from 5360 ITRS to CIP/TEO: 5361 \begin{verbatim} 5362 psSphereRot *psSphereRot_ITRStoTEO(psSphere pole, psTime *time); 5363 \end{verbatim} 5364 The time argument should be used to internally calculate $s'$. 5365 This function should give identical results to the IERS POM2000 subroutine. 5366 5367 \subsubsection{Earth Orientation Wrappers} 5368 5369 The following function generates the complete spherical rotation to 5370 account for precession between two times. If \code{NULL} is provided 5371 for either time, it is assumed to have the reference equinox value of 5372 J2000. 5373 \begin{verbatim} 5374 psSphere *psSpherePrecess(const psTime *fromTime, const psTime *toTime, psPrecessMethod mode); 5375 \end{verbatim} 5376 The mode argument is used to specify the level of detail used in the 5377 calculation. 5378 5379 \begin{verbatim} 5380 typedef 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 5392 A-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 5395 environmental conditions. These quantities are consistent across an 5396 image, and may vary only slowly with time. Pre-computing these 5397 quantities for exposures means that subsequent transformations are 5398 faster. The structure below carries the environmental data of interest. 5399 For historical reasons, this structure is known colloquially as ``the 5400 Grommit''. 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} 5409 typedef 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 5424 The \code{psGrommit} is calculated from telescope information for the 5425 particular exposure, \code{exp}: 5426 \begin{verbatim} 5427 psGrommit *psGrommitAlloc(const psExposure *exp); 5428 \end{verbatim} 5429 5430 \tbd{these functions probably need to take the ATM structure} 5431 5432 We require additional functions to perform general functions which 5433 will be useful for astrometry. Given coordinates on the sky, we 5434 need to get the airmass, the parallactic angle, and an estimate of 5435 the atmospheric refraction. 5436 5437 \begin{verbatim} 5438 float psGetAirmass(const psSphere *coord, psTime *lst, float height); 5439 \end{verbatim} 5440 which returns the airmass for a given position and local sidereal time 5441 (\code{lst}). 5442 5443 \begin{verbatim} 5444 float psGetParallactic(const psSphere *coord, double siderealTime); 5445 \end{verbatim} 5446 which returns the parallactic angle for a given position and sidereal time. 5447 5448 \begin{verbatim} 5449 float 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} 5454 which provides an estimate of the atmospheric refraction, along the parallactic angle. 5455 5456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5457 5458 \subsection{Fixed Pattern} 5459 5460 The fixed pattern is a correction to the general astrometric solution 5461 formed by summing the residuals from many observations. The intent is 5462 to correct for higher-order distortions in the camera system on a 5463 coarse grid (larger than individual pixels, but smaller than a single 5464 cell). Hence, in addition to the offsets, we need to specify the size 5465 and scale of the grid in $x$ and $y$, as well as the origin of the 5466 grid. 5467 5468 \begin{verbatim} 5469 typedef 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 5477 The constructor for \code{psFixedPattern} shall be: 5478 \begin{verbatim} 5479 psFixedPattern *psFixedPatternAlloc(double x0, double y0, 5480 double xScale, double yScale, 5481 const psImage *x, const psImage *y); 5482 \end{verbatim} 5483 Here, \code{x0}, \code{y0}, \code{xScale} and \code{yScale} have the 5484 same meaning as in the \code{psFixedPattern} structure. Note that the 5485 values of the fixed pattern offsets are specified as images, the 5486 values from which need to be copied into the \code{double **x} and 5487 \code{double **y} of \code{psFixedPattern}, and that the number of 5488 elements may be derived from the size of the images. 5489 5490 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 5491 5492 \subsection{Projections} 5493 5494 We require functions to convert between spherical and linear 5495 coordinate systems based on a variety of projections. The required 5496 projections include: 5497 \begin{itemize} 5498 \item TAN 5499 \item SIN 5500 \item AIT 5501 \item PAR 5502 \end{itemize} 5503 5504 We specify the following structure \code{psProjection} to define the 5505 parameters of the projection: 5506 \begin{verbatim} 5507 typedef 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 5514 The projection type is defined by the following enumerated type \code{psProjectionType}: 5515 \begin{verbatim} 5516 typedef 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 5525 The constructor is straight-forward: 5526 \begin{verbatim} 5527 psProjection *psProjectionAlloc(double R, double D, double Xs, double Ys, psProjectionType type); 5528 \end{verbatim} 5529 5530 The following functions will project and deproject (respectively) 5531 spherical coordinates: 5532 5533 \begin{verbatim} 5534 psPlane *psProject(const psSphere *coord, const psProjection *projection); 5535 psSphere *psDeproject(const psPlane *coord, const psProjection *projection); 5536 \end{verbatim} 5537 5538 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 5231 5539 5232 5540 \subsection{Photometry} … … 5298 5606 M_{\rm pM} - pA, M_{\rm sP} - M_{\rm sM} - sA)$. 5299 5607 5300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5608 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5609 5610 %%% Astronomical Images and Astrometry 5611 \include{psLibSDRS_Astrom} 5301 5612 5302 5613 \subsection{Astronomical objects} … … 5329 5640 \appendix 5330 5641 5642 \pagebreak 5331 5643 \section{Configuration File Test Inputs} 5332 5644 \label{sec:configtest}
Note:
See TracChangeset
for help on using the changeset viewer.
