IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 747 for trunk/doc/pslib


Ignore:
Timestamp:
May 19, 2004, 5:41:50 PM (22 years ago)
Author:
eugene
Message:

extensive edits based on MHPCC comments, see ChangeLogSDRS.tex

Location:
trunk/doc/pslib
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/pslib/Makefile

    r681 r747  
    1 # $Id: Makefile,v 1.3 2004-05-14 01:23:03 eugene Exp $
     1# $Id: Makefile,v 1.4 2004-05-20 03:41:49 eugene Exp $
     2
     3PDFLATEX = pdflatex
    24
    35all : psLibDesign.pdf psLibADD.pdf
     
    79        @if [ ! -f $*.aux ]; then \
    810                echo $(PDFLATEX) $*.tex; \
    9                 env TEXINPUTS=$(TEXINPUX).:LaTeX:: $(PDFLATEX) $*.tex; \
    10         fi && env TEXINPUTS=.:LaTeX:: $(PDFLATEX) $*.tex || $(RM) $*.pdf
    11 #
    12 PDFLATEX = pdflatex
    13 #
     11                env TEXINPUTS=.:LaTeX:$(TEXINPUTS): $(PDFLATEX) $*.tex; \
     12        fi && env TEXINPUTS=.:LaTeX:$(TEXINPUTS): $(PDFLATEX) $*.tex || $(RM) $*.pdf
     13
    1414clean :
    1515        $(RM) *.log *.dvi *.aux *.toc *.log *.out *~ core
  • trunk/doc/pslib/psAstroGroup.tex

    r381 r747  
    11\begin{CompactItemize}
    22\item
    3 {\bf ps\-Chip} $\ast$ {\bf ps\-Chip\-In\-FPA} ({\bf ps\-Chip} $\ast$out, const {\bf ps\-FPA} $\ast$fpa, const {\bf ps\-Coord} $\ast$coord)
     3{\bf ps\-Cell} $\ast$ {\bf ps\-Cell\-In\-FPA} ({\bf ps\-Cell} $\ast$out, const {\bf ps\-Plane} $\ast$coord, const {\bf ps\-FPA} $\ast$fpa)
     4\begin{CompactList}\small\item\em Return the cell in FPA which contains the given FPA coordinates.\item\end{CompactList}\item
     5{\bf ps\-Chip} $\ast$ {\bf ps\-Chip\-In\-FPA} ({\bf ps\-Chip} $\ast$out, const {\bf ps\-Plane} $\ast$coord, const {\bf ps\-FPA} $\ast$fpa)
    46\begin{CompactList}\small\item\em returns Chip in FPA which contains the given FPA coordinate\item\end{CompactList}\item
    5 {\bf ps\-Cell} $\ast$ {\bf ps\-Cell\-In\-Chip} ({\bf ps\-Cell} $\ast$out, const {\bf ps\-Chip} $\ast$chip, const {\bf ps\-Coord} $\ast$coord)
     7{\bf ps\-Cell} $\ast$ {\bf ps\-Cell\-In\-Chip} ({\bf ps\-Cell} $\ast$out, const {\bf ps\-Plane} $\ast$coord, const {\bf ps\-Chip} $\ast$chip)
    68\begin{CompactList}\small\item\em returns Cell in Chip which contains the given chip coordinate\item\end{CompactList}\item
    7 {\bf ps\-Cell} $\ast$ {\bf ps\-Cell\-In\-FPA} ({\bf ps\-Cell} $\ast$out, const {\bf ps\-FPA} $\ast$fpa, const {\bf ps\-Coord} $\ast$coord)
    8 \begin{CompactList}\small\item\em Return the cell in FPA which contains the given FPA coordinates.\item\end{CompactList}\item
    9 {\bf ps\-Coord} $\ast$ {\bf ps\-Coord\-Sky\-To\-Cell} ({\bf ps\-Coord} $\ast$out, {\bf ps\-Cell} $\ast$cell, const {\bf ps\-FPA} $\ast$fpa)
     9{\bf ps\-Plane} $\ast$ {\bf ps\-Coord\-Cellto\-Chip} ({\bf ps\-Plane} $\ast$out, const {\bf ps\-Plane} $\ast$in, const {\bf ps\-Cell} $\ast$cell)
     10\begin{CompactList}\small\item\em converts the specified Cell coord to the coord on the parent Chip\item\end{CompactList}\item
     11{\bf ps\-Plane} $\ast$ {\bf ps\-Coord\-Chipto\-FPA} ({\bf ps\-Plane} $\ast$out, const {\bf ps\-Plane} $\ast$in, const {\bf ps\-Chip} $\ast$chip)
     12\begin{CompactList}\small\item\em converts the specified Chip coord to the coord on the parent FPA\item\end{CompactList}\item
     13{\bf ps\-Plane} $\ast$ {\bf ps\-Coord\-FPATo\-TP} ({\bf ps\-Plane} $\ast$out, const {\bf ps\-Plane} $\ast$in, const {\bf ps\-FPA} $\ast$fpa)
     14\begin{CompactList}\small\item\em Convert focal plane coords to tangent plane coordinates.\item\end{CompactList}\item
     15{\bf ps\-Sphere} $\ast$ {\bf ps\-Coord\-TPto\-Sky} ({\bf ps\-Sphere} $\ast$out, const {\bf ps\-Plane} $\ast$in, const {\bf ps\-Grommit} $\ast$grommit)
     16\begin{CompactList}\small\item\em Convert tangent plane coords to (RA,Dec).\item\end{CompactList}\item
     17{\bf ps\-Plane} $\ast$ {\bf ps\-Coord\-Cell\-To\-FPA} ({\bf ps\-Plane} $\ast$out, const {\bf ps\-Plane} $\ast$in, const {\bf ps\-Cell} $\ast$cell)
     18\begin{CompactList}\small\item\em Convert Cell coords to FPA coordinates.\item\end{CompactList}\item
     19{\bf ps\-Sphere} $\ast$ {\bf ps\-Coord\-Cell\-To\-Sky} ({\bf ps\-Sphere} $\ast$out, const {\bf ps\-Plane} $\ast$in, const {\bf ps\-Cell} $\ast$cell)
     20\begin{CompactList}\small\item\em Convert cell and cell coordinate to (RA,Dec).\item\end{CompactList}\item
     21{\bf ps\-Sphere} $\ast$ {\bf ps\-Coord\-Cell\-To\-Sky\-QD} ({\bf ps\-Sphere} $\ast$out, const {\bf ps\-Plane} $\ast$in, const {\bf ps\-Cell} $\ast$cell)
     22\begin{CompactList}\small\item\em Convert cell and cell coordinate to (RA,Dec).\item\end{CompactList}\item
     23{\bf ps\-Plane} $\ast$ {\bf ps\-Coord\-Sky\-To\-TP} ({\bf ps\-Plane} $\ast$out, const {\bf ps\-Sphere} $\ast$in, const {\bf ps\-Grommit} $\ast$grommit)
     24\begin{CompactList}\small\item\em Convert (RA,Dec) to tangent plane coords.\item\end{CompactList}\item
     25{\bf ps\-Plane} $\ast$ {\bf ps\-Coord\-TPto\-FPA} ({\bf ps\-Plane} $\ast$out, const {\bf ps\-Plane} $\ast$in, const {\bf ps\-FPA} $\ast$fpa)
     26\begin{CompactList}\small\item\em Convert tangent plane coords to focal plane coordinates.\item\end{CompactList}\item
     27{\bf ps\-Plane} $\ast$ {\bf ps\-Coord\-FPAto\-Chip} ({\bf ps\-Plane} $\ast$out, const {\bf ps\-Plane} $\ast$in, const {\bf ps\-Chip} $\ast$chip)
     28\begin{CompactList}\small\item\em converts the specified FPA coord to the coord on the given Chip\item\end{CompactList}\item
     29{\bf ps\-Plane} $\ast$ {\bf ps\-Coord\-Chipto\-Cell} ({\bf ps\-Plane} $\ast$out, const {\bf ps\-Plane} $\ast$in, const {\bf ps\-Cell} $\ast$cell)
     30\begin{CompactList}\small\item\em converts the specified Chip coord to the coord on the given Cell\item\end{CompactList}\item
     31{\bf ps\-Plane} $\ast$ {\bf ps\-Coord\-Sky\-To\-Cell} ({\bf ps\-Plane} $\ast$out, const {\bf ps\-Sphere} $\ast$in, const {\bf ps\-Cell} $\ast$cell)
    1032\begin{CompactList}\small\item\em Convert (RA,Dec) to cell and cell coordinates.\item\end{CompactList}\item
    11 {\bf ps\-Coord} $\ast$ {\bf ps\-Coord\-Cell\-To\-Sky} ({\bf ps\-Coord} $\ast$out, const {\bf ps\-Cell} $\ast$cell, const {\bf ps\-Coord} $\ast$coord)
    12 \begin{CompactList}\small\item\em Convert cell and cell coordinate to (RA,Dec).\item\end{CompactList}\item
    13 {\bf ps\-Coord} $\ast$ {\bf ps\-Coord\-Cell\-To\-Sky\-Quick} ({\bf ps\-Coord} $\ast$out, const {\bf ps\-Cell} $\ast$cell, const {\bf ps\-Coord} $\ast$coord)
     33{\bf ps\-Sphere} $\ast$ {\bf ps\-Coord\-Sky\-To\-Cell\-QD} ({\bf ps\-Plane} $\ast$out, const {\bf ps\-Sphere} $\ast$in, const {\bf ps\-Cell} $\ast$cell)
    1434\begin{CompactList}\small\item\em Quick and dirty cell to (RA,Dec) --- employs cell\-To\-Sky transformation.\item\end{CompactList}\item
    15 {\bf ps\-Coord} $\ast$ {\bf ps\-Coord\-Sky\-To\-TP} ({\bf ps\-Coord} $\ast$out, const {\bf ps\-Exposure} $\ast$exp, const {\bf ps\-Coord} $\ast$coord)
    16 \begin{CompactList}\small\item\em Convert (RA,Dec) to tangent plane coords.\item\end{CompactList}\item
    17 {\bf ps\-Coord} $\ast$ {\bf ps\-Coord\-TPto\-FPA} ({\bf ps\-Coord} $\ast$out, const {\bf ps\-FPA} $\ast$fpa, const {\bf ps\-Coord} $\ast$coord)
    18 \begin{CompactList}\small\item\em Convert tangent plane coords to focal plane coordinates.\item\end{CompactList}\item
    19 {\bf ps\-Coord} $\ast$ {\bf ps\-Coord\-FPAto\-Chip} ({\bf ps\-Coord} $\ast$out, const {\bf ps\-Chip} $\ast$chip, const {\bf ps\-Coord} $\ast$coord)
    20 \begin{CompactList}\small\item\em converts the specified FPA coord to the coord on the given Chip\item\end{CompactList}\item
    21 {\bf ps\-Coord} $\ast$ {\bf ps\-Coord\-Chipto\-Cell} ({\bf ps\-Coord} $\ast$out, const {\bf ps\-Cell} $\ast$cell, const {\bf ps\-Coord} $\ast$coord)
    22 \begin{CompactList}\small\item\em converts the specified Chip coord to the coord on the given Cell\item\end{CompactList}\item
    23 {\bf ps\-Coord} $\ast$ {\bf ps\-Coord\-Cellto\-Chip} ({\bf ps\-Coord} $\ast$out, const {\bf ps\-Cell} $\ast$cell, const {\bf ps\-Coord} $\ast$coord)
    24 \begin{CompactList}\small\item\em converts the specified Cell coord to the coord on the parent Chip\item\end{CompactList}\item
    25 {\bf ps\-Coord} $\ast$ {\bf ps\-Coord\-Chipto\-FPA} ({\bf ps\-Coord} $\ast$out, const {\bf ps\-Chip} $\ast$chip, const {\bf ps\-Coord} $\ast$coord)
    26 \begin{CompactList}\small\item\em converts the specified Chip coord to the coord on the parent FPA\item\end{CompactList}\item
    27 {\bf ps\-Coord} $\ast$ {\bf ps\-Coord\-FPATo\-TP} ({\bf ps\-Coord} $\ast$out, const {\bf ps\-FPA} $\ast$fpa, const {\bf ps\-Coord} $\ast$coord)
    28 \begin{CompactList}\small\item\em Convert focal plane coords to tangent plane coordinates.\item\end{CompactList}\item
    29 {\bf ps\-Coord} $\ast$ {\bf ps\-Coord\-TPto\-Sky} ({\bf ps\-Coord} $\ast$out, const {\bf ps\-Exposure} $\ast$exp, const {\bf ps\-Coord} $\ast$coord)
    30 \begin{CompactList}\small\item\em Convert tangent plane coords to (RA,Dec).\item\end{CompactList}\item
    31 {\bf ps\-Coord} $\ast$ {\bf ps\-Coord\-Cell\-To\-FPA} ({\bf ps\-Coord} $\ast$out, const {\bf ps\-Cell} $\ast$cell, const {\bf ps\-Coord} $\ast$coord)
    32 \begin{CompactList}\small\item\em Convert Cell coords to FPA coordinates.\item\end{CompactList}\item
    33 float {\bf ps\-Get\-Airmass} (const {\bf ps\-Coord} $\ast$coord, double sidereal\-Time, float height)
     35float {\bf ps\-Get\-Airmass} (const {\bf ps\-Sphere} $\ast$coord, double sidereal\-Time, float height)
    3436\begin{CompactList}\small\item\em Get the airmass for a given position and sidereal time.\item\end{CompactList}\item
    35 float {\bf ps\-Get\-Parallactic} (const {\bf ps\-Coord} $\ast$coord, double sidereal\-Time)
     37float {\bf ps\-Get\-Parallactic} (const {\bf ps\-Sphere} $\ast$coord, double sidereal\-Time)
    3638\begin{CompactList}\small\item\em Get the parallactic angle for a given position and sidereal time.\item\end{CompactList}\item
    3739float {\bf ps\-Get\-Refraction} (float colour, {\bf ps\-Phot\-System} color\-Plus, {\bf ps\-Phot\-System} color\-Minus, const {\bf ps\-Exposure} $\ast$exp)
    3840\begin{CompactList}\small\item\em Estimate atmospheric refraction, along the parallactic.\item\end{CompactList}\item
    39 {\bf ps\-Coord} $\ast$ {\bf ps\-Get\-Parallax\-Factor} (const {\bf ps\-Exposure} $\ast$exp)
     41{\bf ps\-Sphere} $\ast$ {\bf ps\-Get\-Parallax\-Factor} (const {\bf ps\-Exposure} $\ast$exp)
    4042\begin{CompactList}\small\item\em Calculate the parallax factor.\item\end{CompactList}\item
    4143{\bf ps\-Exposure} $\ast$ {\bf ps\-Exposure\-Alloc} (double ra, double dec, double ha, double zd, double az, double lst, float mjd, float rot\-Angle, float temp, float pressure, float humidity, float exptime)
    4244\begin{CompactList}\small\item\em Constructor.\item\end{CompactList}\item
    4345void {\bf ps\-Exposure\-Free} ({\bf ps\-Exposure} $\ast$restrict my\-Exp)
     46\begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\item
     47{\bf ps\-Grommit} $\ast$ {\bf ps\-Grommit\-Alloc} (const {\bf ps\-Exposure} $\ast$exp)
     48\begin{CompactList}\small\item\em Constructor.\item\end{CompactList}\item
     49void {\bf ps\-Grommit\-Free} ({\bf ps\-Grommit} $\ast$grommit)
    4450\begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\item
    4551double {\bf ps\-Get\-MJD} (void)
     
    4753double {\bf ps\-Get\-Sidereal} (float mjd, float longitude)
    4854\begin{CompactList}\small\item\em Get current sidereal time at longitude.\item\end{CompactList}\item
    49 char $\ast$ {\bf ps\-Time\-To\-ISOTime} (ps\-Time time)
    50 \begin{CompactList}\small\item\em Convert ps\-Time to ISOTime (Human-readable date/time string YYYY/MM/DD,HH:MM:SS.SSS).\item\end{CompactList}\item
    51 double {\bf ps\-Time\-To\-UTC} (ps\-Time time)
    52 \begin{CompactList}\small\item\em Convert ps\-Time to UTC.\item\end{CompactList}\item
    53 double {\bf ps\-Time\-To\-MJD} (ps\-Time time)
    54 \begin{CompactList}\small\item\em Convert ps\-Time to MJD.\item\end{CompactList}\item
    55 double {\bf ps\-Time\-To\-JD} (ps\-Time time)
    56 \begin{CompactList}\small\item\em Convert ps\-Time to JD.\item\end{CompactList}\item
    57 timeval $\ast$ {\bf ps\-Time\-To\-Timeval} (ps\-Time time)
    58 \begin{CompactList}\small\item\em Convert ps\-Time to timeval (struct timeval).\item\end{CompactList}\item
    59 tm $\ast$ {\bf ps\-Time\-To\-Tm} (ps\-Time time)
    60 \begin{CompactList}\small\item\em Convert ps\-Time to broken-down time (struct tm).\item\end{CompactList}\item
    61 ps\-Time $\ast$ {\bf ps\-ISOTime\-To\-Time} (char $\ast$input)
    62 \begin{CompactList}\small\item\em Convert ISOTime (Human-readable date/time string YYYY/MM/DD,HH:MM:SS.SSS) to ps\-Time.\item\end{CompactList}\item
    63 ps\-Time $\ast$ {\bf ps\-UTCTo\-Time} (double input)
    64 \begin{CompactList}\small\item\em Convert UTC to ps\-Time.\item\end{CompactList}\item
    65 ps\-Time $\ast$ {\bf ps\-MJDTo\-Time} (double input)
    66 \begin{CompactList}\small\item\em Convert MJD to ps\-Time.\item\end{CompactList}\item
    67 ps\-Time $\ast$ {\bf ps\-JDTo\-Time} (double input)
    68 \begin{CompactList}\small\item\em Convert JD to ps\-Time.\item\end{CompactList}\item
    69 ps\-Time $\ast$ {\bf ps\-Timeval\-To\-Time} (struct timeval $\ast$input)
    70 \begin{CompactList}\small\item\em Convert timeval to ps\-Time (struct timeval).\item\end{CompactList}\item
    71 ps\-Time $\ast$ {\bf ps\-TMto\-Time} (struct tm $\ast$input)
    72 \begin{CompactList}\small\item\em Convert broken-to ps\-Time down time (struct tm).\item\end{CompactList}\item
    73 {\bf ps\-Image} $\ast$ {\bf ps\-Image\-Alloc} (int nx, int ny, {\bf ps\-Type} type)
     55char $\ast$ {\bf ps\-Time\-To\-ISOTime} ({\bf ps\-Time} time)
     56\begin{CompactList}\small\item\em Convert {\bf ps\-Time} {\rm (p.\,\pageref{structpsTime})} to ISOTime (Human-readable date/time string YYYY/MM/DD,HH:MM:SS.SSS).\item\end{CompactList}\item
     57double {\bf ps\-Time\-To\-UTC} ({\bf ps\-Time} time)
     58\begin{CompactList}\small\item\em Convert {\bf ps\-Time} {\rm (p.\,\pageref{structpsTime})} to UTC.\item\end{CompactList}\item
     59double {\bf ps\-Time\-To\-MJD} ({\bf ps\-Time} time)
     60\begin{CompactList}\small\item\em Convert {\bf ps\-Time} {\rm (p.\,\pageref{structpsTime})} to MJD.\item\end{CompactList}\item
     61double {\bf ps\-Time\-To\-JD} ({\bf ps\-Time} time)
     62\begin{CompactList}\small\item\em Convert {\bf ps\-Time} {\rm (p.\,\pageref{structpsTime})} to JD.\item\end{CompactList}\item
     63timeval $\ast$ {\bf ps\-Time\-To\-Timeval} ({\bf ps\-Time} time)
     64\begin{CompactList}\small\item\em Convert {\bf ps\-Time} {\rm (p.\,\pageref{structpsTime})} to timeval (struct timeval).\item\end{CompactList}\item
     65tm $\ast$ {\bf ps\-Time\-To\-Tm} ({\bf ps\-Time} time)
     66\begin{CompactList}\small\item\em Convert {\bf ps\-Time} {\rm (p.\,\pageref{structpsTime})} to broken-down time (struct tm).\item\end{CompactList}\item
     67float {\bf ps\-Time\-To\-Lunation} ({\bf ps\-Time} time)
     68\begin{CompactList}\small\item\em Convert {\bf ps\-Time} {\rm (p.\,\pageref{structpsTime})} to lunation number.\item\end{CompactList}\item
     69{\bf ps\-Time} $\ast$ {\bf ps\-ISOTime\-To\-Time} (char $\ast$input)
     70\begin{CompactList}\small\item\em Convert ISOTime (Human-readable date/time string YYYY/MM/DD,HH:MM:SS.SSS) to {\bf ps\-Time} {\rm (p.\,\pageref{structpsTime})}.\item\end{CompactList}\item
     71{\bf ps\-Time} $\ast$ {\bf ps\-UTCTo\-Time} (double input)
     72\begin{CompactList}\small\item\em Convert UTC to {\bf ps\-Time} {\rm (p.\,\pageref{structpsTime})}.\item\end{CompactList}\item
     73{\bf ps\-Time} $\ast$ {\bf ps\-MJDTo\-Time} (double input)
     74\begin{CompactList}\small\item\em Convert MJD to {\bf ps\-Time} {\rm (p.\,\pageref{structpsTime})}.\item\end{CompactList}\item
     75{\bf ps\-Time} $\ast$ {\bf ps\-JDTo\-Time} (double input)
     76\begin{CompactList}\small\item\em Convert JD to {\bf ps\-Time} {\rm (p.\,\pageref{structpsTime})}.\item\end{CompactList}\item
     77{\bf ps\-Time} $\ast$ {\bf ps\-Timeval\-To\-Time} (struct timeval $\ast$input)
     78\begin{CompactList}\small\item\em Convert timeval (struct timeval) to {\bf ps\-Time} {\rm (p.\,\pageref{structpsTime})}.\item\end{CompactList}\item
     79{\bf ps\-Time} $\ast$ {\bf ps\-TMTo\-Time} (struct tm $\ast$input)
     80\begin{CompactList}\small\item\em Convert broken-down time (struct tm) to {\bf ps\-Time} {\rm (p.\,\pageref{structpsTime})}.\item\end{CompactList}\item
     81{\bf ps\-Time} $\ast$ {\bf ps\-Lunation\-To\-Time} (float lunation)
     82\begin{CompactList}\small\item\em Convert lunation number to {\bf ps\-Time} {\rm (p.\,\pageref{structpsTime})}.\item\end{CompactList}\item
     83{\bf ps\-Image} $\ast$ {\bf ps\-Image\-Alloc} (int width, int height, {\bf ps\-Elem\-Type} type)
    7484\begin{CompactList}\small\item\em Create an image of the specified size and type.\item\end{CompactList}\item
    75 {\bf ps\-Image} $\ast$ {\bf ps\-Image\-Subset} ({\bf ps\-Image} $\ast$out, const {\bf ps\-Image} $\ast$image, int nx, int ny, int x0, int y0)
     85{\bf ps\-Image} $\ast$ {\bf ps\-Image\-Subset} (const {\bf ps\-Image} $\ast$image, int width, int height, int x0, int y0)
    7686\begin{CompactList}\small\item\em Create a subimage of the specified area.\item\end{CompactList}\item
    7787void {\bf ps\-Image\-Free} ({\bf ps\-Image} $\ast$restrict image)
     
    7989{\bf ps\-Image} $\ast$ {\bf ps\-Image\-Free\-Pixels} ({\bf ps\-Image} $\ast$restrict image)
    8090\begin{CompactList}\small\item\em Destroy the pixels of the specified image.\item\end{CompactList}\item
    81 int {\bf ps\-Image\-Free\-Children} (const {\bf ps\-Image} $\ast$image)
    82 \begin{CompactList}\small\item\em Destroy the children of the specified image. Returns number of children freed.\item\end{CompactList}\item
    83 {\bf ps\-Image} $\ast$ {\bf ps\-Image\-Copy} ({\bf ps\-Image} $\ast$output, const {\bf ps\-Image} $\ast$input)
     91{\bf ps\-Image} $\ast$ {\bf ps\-Image\-Copy} ({\bf ps\-Image} $\ast$output, const {\bf ps\-Image} $\ast$input, {\bf ps\-Elem\-Type} type)
    8492\begin{CompactList}\small\item\em Create a copy of the specified image.\item\end{CompactList}\item
    85 {\bf ps\-Float\-Array} $\ast$ {\bf ps\-Image\-Slice} ({\bf ps\-Float\-Array} $\ast$out, const {\bf ps\-Image} $\ast$input, int x, int y, int nx, int ny, int direction, const {\bf ps\-Stats} $\ast$stats)
     93{\bf ps\-Vector} $\ast$ {\bf ps\-Image\-Slice} ({\bf ps\-Vector} $\ast$out, const {\bf ps\-Image} $\ast$input, int x, int y, int nx, int ny, int direction, const {\bf ps\-Stats} $\ast$stats)
    8694\begin{CompactList}\small\item\em Extract pixels from rectlinear region to a vector.\item\end{CompactList}\item
    87 {\bf ps\-Float\-Array} $\ast$ {\bf ps\-Image\-Cut} ({\bf ps\-Float\-Array} $\ast$out, const {\bf ps\-Image} $\ast$input, float xs, float ys, float xe, float ye, float dw, const {\bf ps\-Stats} $\ast$stats)
     95{\bf ps\-Vector} $\ast$ {\bf ps\-Image\-Cut} ({\bf ps\-Vector} $\ast$out, const {\bf ps\-Image} $\ast$input, float xs, float ys, float xe, float ye, float dw, const {\bf ps\-Stats} $\ast$stats)
    8896\begin{CompactList}\small\item\em Extract pixels along a line to a vector.\item\end{CompactList}\item
    89 {\bf ps\-Float\-Array} $\ast$ {\bf ps\-Image\-Radial\-Cut} ({\bf ps\-Float\-Array} $\ast$out, const {\bf ps\-Image} $\ast$input, float x, float y, float radius, float dr, const {\bf ps\-Stats} $\ast$stats)
     97{\bf ps\-Vector} $\ast$ {\bf ps\-Image\-Radial\-Cut} ({\bf ps\-Vector} $\ast$out, const {\bf ps\-Image} $\ast$input, float x, float y, const {\bf ps\-Vector} $\ast$radii, const {\bf ps\-Stats} $\ast$stats)
    9098\begin{CompactList}\small\item\em Extract radial annulii data to a vector.\item\end{CompactList}\item
    9199{\bf ps\-Image} $\ast$ {\bf ps\-Image\-Rebin} ({\bf ps\-Image} $\ast$out, const {\bf ps\-Image} $\ast$input, float scale, const {\bf ps\-Stats} $\ast$stats)
     
    97105{\bf ps\-Image} $\ast$ {\bf ps\-Image\-Roll} ({\bf ps\-Image} $\ast$out, const {\bf ps\-Image} $\ast$input, int dx, int dy)
    98106\begin{CompactList}\small\item\em Roll image by an integer number of pixels in either direction.\item\end{CompactList}\item
    99 {\bf ps\-Stats} $\ast$ {\bf ps\-Image\-Get\-Stats} (const {\bf ps\-Image} $\ast$input, {\bf ps\-Stats} $\ast$stats)
     107{\bf ps\-Stats} $\ast$ {\bf ps\-Image\-Get\-Stats} ({\bf ps\-Stats} $\ast$stats, const {\bf ps\-Image} $\ast$input)
    100108\begin{CompactList}\small\item\em Determine statistics for image (or subimage).\item\end{CompactList}\item
    101109{\bf ps\-Histogram} $\ast$ {\bf ps\-Image\-Histogram} ({\bf ps\-Histogram} $\ast$hist, const {\bf ps\-Image} $\ast$input)
    102110\begin{CompactList}\small\item\em Construct a histogram from an image (or subimage).\item\end{CompactList}\item
    103 {\bf ps\-Polynomial2D} $\ast$ {\bf ps\-Image\-Fit\-Polynomial} (const {\bf ps\-Image} $\ast$input, {\bf ps\-Polynomial2D} $\ast$coeffs)
     111{\bf ps\-Polynomial2D} $\ast$ {\bf ps\-Image\-Fit\-Polynomial} ({\bf ps\-Polynomial2D} $\ast$coeffs, const {\bf ps\-Image} $\ast$input)
    104112\begin{CompactList}\small\item\em Fit a 2-D polynomial surface to an image.\item\end{CompactList}\item
    105 int {\bf ps\-Image\-Eval\-Polynomial} (const {\bf ps\-Image} $\ast$input, const {\bf ps\-Polynomial2D} $\ast$coeffs)
     113{\bf ps\-Image} $\ast$ {\bf ps\-Image\-Eval\-Polynomial} (const {\bf ps\-Image} $\ast$input, const {\bf ps\-Polynomial2D} $\ast$coeffs)
    106114\begin{CompactList}\small\item\em Evaluate a 2-D polynomial surface to image pixels.\item\end{CompactList}\item
    107115{\bf ps\-Image} $\ast$ {\bf ps\-Image\-Read\-Section} ({\bf ps\-Image} $\ast$output, int x, int y, int nx, int ny, int z, const char $\ast$extname, int extnum, const char $\ast$filename)
     
    109117{\bf ps\-Image} $\ast$ {\bf ps\-Image\-FRead\-Section} ({\bf ps\-Image} $\ast$output, int x, int y, int nx, int ny, int z, const char $\ast$extname, int extnum, FILE $\ast$f)
    110118\begin{CompactList}\small\item\em Read an image or subimage from file descriptor.\item\end{CompactList}\item
    111 {\bf ps\-Image} $\ast$ {\bf ps\-Image\-Write\-Section} ({\bf ps\-Image} $\ast$input, int x, int y, int z, const char $\ast$extname, int extnum, const char $\ast$filename)
     119{\bf ps\-Image} $\ast$ {\bf ps\-Image\-Write\-Section} (const {\bf ps\-Image} $\ast$input, int x, int y, int z, const char $\ast$extname, int extnum, const char $\ast$filename)
    112120\begin{CompactList}\small\item\em Write an image section to named file (which may exist).\item\end{CompactList}\item
    113 {\bf ps\-Image} $\ast$ {\bf ps\-Image\-FWrite\-Section} ({\bf ps\-Image} $\ast$input, int x, int y, int z, const char $\ast$extname, int extnum, FILE $\ast$f)
     121{\bf ps\-Image} $\ast$ {\bf ps\-Image\-FWrite\-Section} (const {\bf ps\-Image} $\ast$input, int x, int y, int z, const char $\ast$extname, int extnum, FILE $\ast$f)
    114122\begin{CompactList}\small\item\em Write an image section to named file (which may exist).\item\end{CompactList}\item
    115 ps\-Metadata $\ast$ {\bf ps\-Image\-Read\-Header} (ps\-Metadata $\ast$output, const char $\ast$extname, int extnum, const char $\ast$filename)
    116 \begin{CompactList}\small\item\em Read only header from image file.\item\end{CompactList}\item
    117 ps\-Metadata $\ast$ {\bf ps\-Image\-FRead\-Header} (ps\-Metadata $\ast$output, const char $\ast$extname, int extnum, FILE $\ast$f)
    118 \begin{CompactList}\small\item\em Read only header from image file descriptor.\item\end{CompactList}\item
    119123int {\bf ps\-Image\-Clip} ({\bf ps\-Image} $\ast$input, float min, float vmin, float max, float vmax)
    120124\begin{CompactList}\small\item\em Clip image values outside of range to given values. Return number of clipped pixels.\item\end{CompactList}\item
     
    123127int {\bf ps\-Image\-Overlay\-Section} ({\bf ps\-Image} $\ast$image, const {\bf ps\-Image} $\ast$overlay, int x0, int y0, const char $\ast$op)
    124128\begin{CompactList}\small\item\em Overlay subregion of image with another image. Return number of pixels replaced.\item\end{CompactList}\item
    125 {\bf ps\-Meta\-Data\-Item} $\ast$ {\bf ps\-Meta\-Data\-Item\-Alloc} (int type\-Flags, const void $\ast$val, const char $\ast$comment, const char $\ast$name,...)
    126 \begin{CompactList}\small\item\em Constructor.\item\end{CompactList}\item
    127 void {\bf ps\-Meta\-Data\-Item\-Free} ({\bf ps\-Meta\-Data\-Item} $\ast$ms)
    128 \begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\item
    129 {\bf ps\-Meta\-Data\-Set} $\ast$ {\bf ps\-Meta\-Data\-Set\-Alloc} (void)
    130 \begin{CompactList}\small\item\em make a new set of metadata\item\end{CompactList}\item
    131 void {\bf ps\-Meta\-Data\-Set\-Free} ({\bf ps\-Meta\-Data\-Set} $\ast$ms)
    132 \begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\item
    133 {\bf ps\-Meta\-Data\-Item} $\ast$ {\bf ps\-Meta\-Data\-Append} ({\bf ps\-Meta\-Data\-Set} $\ast$restrict ms, {\bf ps\-Meta\-Data\-Item} $\ast$restrict item)
    134 \begin{CompactList}\small\item\em Add entry to the end of the metadata set.\item\end{CompactList}\item
    135 {\bf ps\-Meta\-Data\-Item} $\ast$ {\bf ps\-Meta\-Data\-Remove} ({\bf ps\-Meta\-Data\-Set} $\ast$restrict ms, const char $\ast$restrict key)
    136 \begin{CompactList}\small\item\em delete entry from the metadata set\item\end{CompactList}\item
    137 void {\bf ps\-Meta\-Data\-Set\-Iterator} ({\bf ps\-Meta\-Data\-Set} $\ast$ms)
     129{\bf ps\-Metadata\-Item} $\ast$ {\bf ps\-Metadata\-Item\-Alloc} (const char $\ast$name, int format, const char $\ast$comment,...)
     130\begin{CompactList}\small\item\em Constructor.\item\end{CompactList}\item
     131{\bf ps\-Metadata\-Item} $\ast$ {\bf ps\-Metadata\-Item\-Alloc} (const char $\ast$name, int format, const char $\ast$comment, va\_\-list ap)
     132\item
     133void {\bf ps\-Metadata\-Item\-Free} ({\bf ps\-Metadata\-Item} $\ast$ms)
     134\begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\item
     135{\bf ps\-Metadata} $\ast$ {\bf ps\-Metadata\-Alloc} (void)
     136\begin{CompactList}\small\item\em Constructor.\item\end{CompactList}\item
     137void {\bf ps\-Metadata\-Free} ({\bf ps\-Metadata} $\ast$md)
     138\begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\item
     139{\bf ps\-Metadata\-Item} $\ast$ {\bf ps\-Metadata\-Append\-Item} ({\bf ps\-Metadata} $\ast$restrict md, {\bf ps\-Metadata\-Item} $\ast$restrict item)
     140\begin{CompactList}\small\item\em Add item to the end of the metadata.\item\end{CompactList}\item
     141{\bf ps\-Metadata\-Item} $\ast$ {\bf ps\-Metadata\-Append} ({\bf ps\-Metadata} $\ast$restrict md, const char $\ast$name, int format, const char $\ast$comment,...)
     142\begin{CompactList}\small\item\em Add item to the end of the metadata. Combines ps\-Metadata\-Item\-Alloc and ps\-Metadata\-Append\-Item.\item\end{CompactList}\item
     143{\bf ps\-Metadata\-Item} $\ast$ {\bf ps\-Metadata\-Remove} ({\bf ps\-Metadata} $\ast$restrict md, const char $\ast$restrict key)
     144\begin{CompactList}\small\item\em delete item from the metadata\item\end{CompactList}\item
     145void {\bf ps\-Metadata\-Set\-Iterator} ({\bf ps\-Metadata} $\ast$md)
    138146\begin{CompactList}\small\item\em reset the iterator to the start of the list\item\end{CompactList}\item
    139 {\bf ps\-Meta\-Data\-Item} $\ast$ {\bf ps\-Meta\-Data\-Get\-Next} ({\bf ps\-Meta\-Data\-Set} $\ast$restrict ms, const char $\ast$restrict match)
    140 \begin{CompactList}\small\item\em get the next entry in the sequence\item\end{CompactList}\item
    141 {\bf ps\-Meta\-Data\-Item} $\ast$ {\bf ps\-Meta\-Data\-Lookup} (const {\bf ps\-Meta\-Data\-Set} $\ast$restrict ms, const char $\ast$restrict key)
     147{\bf ps\-Metadata\-Item} $\ast$ {\bf ps\-Metadata\-Get\-Next} ({\bf ps\-Metadata} $\ast$restrict md, const char $\ast$restrict match, int which)
     148\begin{CompactList}\small\item\em get the next item in the sequence\item\end{CompactList}\item
     149{\bf ps\-Metadata\-Item} $\ast$ {\bf ps\-Metadata\-Lookup} (const {\bf ps\-Metadata} $\ast$restrict md, const char $\ast$restrict key)
    142150\begin{CompactList}\small\item\em find the metadata with the specified key\item\end{CompactList}\item
    143 void {\bf ps\-Meta\-Data\-Item\-Print} (FILE $\ast$fd, const {\bf ps\-Meta\-Data\-Item} $\ast$restrict ms, const char $\ast$prefix)
     151void {\bf ps\-Metadata\-Item\-Print} (FILE $\ast$fd, const {\bf ps\-Metadata\-Item} $\ast$restrict md, const char $\ast$prefix)
    144152\begin{CompactList}\small\item\em print metadata item to the specified stream\item\end{CompactList}\item
    145 {\bf ps\-Coord} $\ast$ {\bf ps\-Coord\-Xform\-Apply} ({\bf ps\-Coord} $\ast$out, const {\bf ps\-Coord\-Xform} $\ast$frame, const {\bf ps\-Coord} $\ast$coords)
     153{\bf ps\-Metadata} $\ast$ {\bf ps\-Metadata\-Read\-Header} ({\bf ps\-Metadata} $\ast$out, const char $\ast$ext, int extnum, const char $\ast$file)
     154\begin{CompactList}\small\item\em Read only header from image file.\item\end{CompactList}\item
     155{\bf ps\-Metadata} $\ast$ {\bf ps\-Metadata\-FRead\-Header} ({\bf ps\-Metadata} $\ast$out, const char $\ast$ext, int extnum, FILE $\ast$f)
     156\begin{CompactList}\small\item\em Read only header from image file descriptor.\item\end{CompactList}\item
     157{\bf ps\-Plane} $\ast$ {\bf ps\-Plane\-Transform\-Apply} ({\bf ps\-Plane} $\ast$out, const {\bf ps\-Plane\-Transform} $\ast$frame, const {\bf ps\-Plane} $\ast$coords)
    146158\begin{CompactList}\small\item\em apply the coordinate transformation to the given coordinate\item\end{CompactList}\item
    147 {\bf ps\-Coord} $\ast$ {\bf ps\-Distortion\-Apply} ({\bf ps\-Coord} $\ast$out, const psdistortion $\ast$pattern, const {\bf ps\-Coord} $\ast$coords, float mag, float color)
     159{\bf ps\-Plane} $\ast$ {\bf ps\-Plane\-Distort\-Apply} ({\bf ps\-Plane} $\ast$out, const ps\-Plane\-Distortion $\ast$pattern, const {\bf ps\-Plane} $\ast$coords, float mag, float color)
    148160\begin{CompactList}\small\item\em apply the optical distortion to the given coordinate, magnitude, color\item\end{CompactList}\item
    149 {\bf ps\-Coord} $\ast$ {\bf ps\-Get\-Offset} (const {\bf ps\-Coord} $\ast$restrict position1, const {\bf ps\-Coord} $\ast$restrict position2, const char $\ast$type)
     161{\bf ps\-Sphere\-Transform} $\ast$ {\bf ps\-Sphere\-Transform\-Alloc} (double pole1, double pole2, double rotation)
     162\begin{CompactList}\small\item\em Constructor.\item\end{CompactList}\item
     163void {\bf ps\-Sphere\-Transform\-Free} ({\bf ps\-Sphere\-Transform} $\ast$trans)
     164\begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\item
     165{\bf ps\-Sphere} $\ast$ {\bf ps\-Sphere\-Transform\-Apply} (const {\bf ps\-Sphere} $\ast$coord, const {\bf ps\-Sphere\-Transform} $\ast$sys)
     166\begin{CompactList}\small\item\em Apply general spherical transformation.\item\end{CompactList}\item
     167{\bf ps\-Sphere\-Transform} $\ast$ {\bf ps\-Sphere\-Transform\-Ito\-E} (void)
     168\begin{CompactList}\small\item\em Return transformation structure to convert ICRS to Ecliptic.\item\end{CompactList}\item
     169{\bf ps\-Sphere\-Transform} $\ast$ {\bf ps\-Sphere\-Transform\-Eto\-I} (void)
     170\begin{CompactList}\small\item\em Return transformation structure to convert Ecliptic to ICRS.\item\end{CompactList}\item
     171{\bf ps\-Sphere\-Transform} $\ast$ {\bf ps\-Sphere\-Transform\-Ito\-G} (void)
     172\begin{CompactList}\small\item\em Return transformation structure to convert ICRS to Galactic.\item\end{CompactList}\item
     173{\bf ps\-Sphere\-Transform} $\ast$ {\bf ps\-Sphere\-Transform\-Gto\-I} (void)
     174\begin{CompactList}\small\item\em Return transformation structure to convert Galactic to ICRS.\item\end{CompactList}\item
     175{\bf ps\-Plane} $\ast$ {\bf ps\-Coord\-Project} (const {\bf ps\-Sphere} $\ast$coord, const {\bf ps\-Projection} $\ast$projection)
     176\begin{CompactList}\small\item\em Project spherical system onto a plane.\item\end{CompactList}\item
     177{\bf ps\-Sphere} $\ast$ {\bf ps\-Coord\-Deproject} (const {\bf ps\-Plane} $\ast$coord, const {\bf ps\-Projection} $\ast$projection)
     178\begin{CompactList}\small\item\em Deproject plane onto spherical system.\item\end{CompactList}\item
     179{\bf ps\-Sphere} $\ast$ {\bf ps\-Sphere\-Get\-Offset} (const {\bf ps\-Sphere} $\ast$restrict position1, const {\bf ps\-Sphere} $\ast$restrict position2, const char $\ast$type)
    150180\begin{CompactList}\small\item\em Get offset (RA,Dec) on the sky between two positions position1 and position2 may not be identical.\item\end{CompactList}\item
    151 {\bf ps\-Coord} $\ast$ {\bf ps\-Apply\-Offset} (const {\bf ps\-Coord} $\ast$restrict position, const {\bf ps\-Coord} $\ast$restrict offset, const char $\ast$type)
     181{\bf ps\-Sphere} $\ast$ {\bf ps\-Sphere\-Apply\-Offset} (const {\bf ps\-Sphere} $\ast$restrict position, const {\bf ps\-Sphere} $\ast$restrict offset, const char $\ast$type)
    152182\begin{CompactList}\small\item\em Apply an offset to a position.\item\end{CompactList}\item
    153 {\bf ps\-Coord} $\ast$ {\bf ps\-Get\-Sun\-Pos} (float mjd)
     183{\bf ps\-Sphere} $\ast$ {\bf ps\-Sun\-Get\-Pos} ({\bf ps\-Time} time)
    154184\begin{CompactList}\small\item\em Get Sun Position.\item\end{CompactList}\item
    155 {\bf ps\-Coord} $\ast$ {\bf ps\-Get\-Moon\-Pos} (float mjd, double latitude, double longitude)
    156 \begin{CompactList}\small\item\em Get Moon position.\item\end{CompactList}\item
    157 float {\bf ps\-Get\-Moon\-Phase} (float mjd)
     185{\bf ps\-Sphere} $\ast$ {\bf ps\-Sun\-Get\-Rise} ({\bf ps\-Time} $\ast$twi15, {\bf ps\-Time} $\ast$twi18, {\bf ps\-Time} time)
     186\begin{CompactList}\small\item\em Get Sun Rise time.\item\end{CompactList}\item
     187{\bf ps\-Sphere} $\ast$ {\bf ps\-Sun\-Get\-Set} ({\bf ps\-Time} $\ast$twi15, {\bf ps\-Time} $\ast$twi18, {\bf ps\-Time} time)
     188\begin{CompactList}\small\item\em Get Sun Set time.\item\end{CompactList}\item
     189float {\bf ps\-Night\-Length} ({\bf ps\-Time} time)
     190\begin{CompactList}\small\item\em Get Length of closest night.\item\end{CompactList}\item
     191{\bf ps\-Sphere} $\ast$ {\bf ps\-Moon\-Get\-Pos} ({\bf ps\-Time} time)
     192\begin{CompactList}\small\item\em Get Moon Position.\item\end{CompactList}\item
     193{\bf ps\-Sphere} $\ast$ {\bf ps\-Moon\-Get\-Rise} ({\bf ps\-Time} time)
     194\begin{CompactList}\small\item\em Get Moon Rise time.\item\end{CompactList}\item
     195{\bf ps\-Sphere} $\ast$ {\bf ps\-Moon\-Get\-Set} ({\bf ps\-Time} time)
     196\begin{CompactList}\small\item\em Get Moon Set time.\item\end{CompactList}\item
     197float {\bf ps\-Moon\-Get\-Phase} ({\bf ps\-Time} time)
    158198\begin{CompactList}\small\item\em Get Moon phase.\item\end{CompactList}\item
    159 {\bf ps\-Coord} $\ast$ {\bf ps\-Get\-Solar\-System\-Pos} (const char $\ast$solar\-System\-Object, float mjd)
    160 \begin{CompactList}\small\item\em Get Planet positions.\item\end{CompactList}\item
    161 {\bf ps\-Coord} $\ast$ {\bf ps\-Coordinates\-Ito\-E} (const {\bf ps\-Coord} $\ast$restrict coordinates)
    162 \begin{CompactList}\small\item\em Convert ICRS to Ecliptic.\item\end{CompactList}\item
    163 {\bf ps\-Coord} $\ast$ {\bf ps\-Coordinates\-Eto\-I} (const {\bf ps\-Coord} $\ast$restrict coordinates)
    164 \begin{CompactList}\small\item\em Convert Ecliptic to ICRS.\item\end{CompactList}\item
    165 {\bf ps\-Coord} $\ast$ {\bf ps\-Coordinates\-Ito\-G} (const {\bf ps\-Coord} $\ast$restrict coordinates)
    166 \begin{CompactList}\small\item\em Convert ICRS to Galactic.\item\end{CompactList}\item
    167 {\bf ps\-Coord} $\ast$ {\bf ps\-Coordinates\-Gto\-I} (const {\bf ps\-Coord} $\ast$restrict coordinates)
    168 \begin{CompactList}\small\item\em Convert Galactic to ICRS.\item\end{CompactList}\end{CompactItemize}
    169 
     199{\bf ps\-Sphere} $\ast$ {\bf ps\-Planet\-Get\-Pos} (const char $\ast$solar\-System\-Object, {\bf ps\-Time} time)
     200\begin{CompactList}\small\item\em Get Planet positions.\item\end{CompactList}\end{CompactItemize}
  • trunk/doc/pslib/psDataGroup.tex

    r381 r747  
    1111void $\ast$ {\bf ps\-Dlist\-Remove} ({\bf ps\-Dlist} $\ast$list, void $\ast$data, int which)
    1212\begin{CompactList}\small\item\em Remove from a list.\item\end{CompactList}\item
    13 void $\ast$ {\bf ps\-Dlist\-Get} (const {\bf ps\-Dlist} $\ast$list, void $\ast$data, int which)
     13void $\ast$ {\bf ps\-Dlist\-Get} (const {\bf ps\-Dlist} $\ast$list, int which)
    1414\begin{CompactList}\small\item\em Retrieve from a list.\item\end{CompactList}\item
    15 void {\bf ps\-Dlist\-Set\-Iterator} ({\bf ps\-Dlist} $\ast$list, int where)
     15void {\bf ps\-Dlist\-Set\-Iterator} ({\bf ps\-Dlist} $\ast$list, int where, int which)
    1616\begin{CompactList}\small\item\em Set the iterator.\item\end{CompactList}\item
    17 void $\ast$ {\bf ps\-Dlist\-Get\-Next} ({\bf ps\-Dlist} $\ast$list)
     17void $\ast$ {\bf ps\-Dlist\-Get\-Next} ({\bf ps\-Dlist} $\ast$list, int which)
    1818\begin{CompactList}\small\item\em Get next element relative to iter.\item\end{CompactList}\item
    19 void $\ast$ {\bf ps\-Dlist\-Get\-Prev} ({\bf ps\-Dlist} $\ast$list)
     19void $\ast$ {\bf ps\-Dlist\-Get\-Prev} ({\bf ps\-Dlist} $\ast$list, int which)
    2020\begin{CompactList}\small\item\em Get prev element relative to iter.\item\end{CompactList}\item
    21 {\bf ps\-Void\-Ptr\-Array} $\ast$ {\bf ps\-Dlist\-To\-Array} ({\bf ps\-Dlist} $\ast$dlist)
    22 \begin{CompactList}\small\item\em Convert doubly-linked list to an array.\item\end{CompactList}\item
    23 {\bf ps\-Dlist} $\ast$ {\bf ps\-Array\-To\-Dlist} ({\bf ps\-Void\-Ptr\-Array} $\ast$arr)
     21{\bf ps\-Vector} $\ast$ {\bf ps\-Dlist\-To\-Vector} ({\bf ps\-Dlist} $\ast$dlist)
     22\begin{CompactList}\small\item\em Convert doubly-linked list to a vector of (void $\ast$).\item\end{CompactList}\item
     23{\bf ps\-Dlist} $\ast$ {\bf ps\-Array\-To\-Dlist} ({\bf ps\-Vector} $\ast$vector)
    2424\begin{CompactList}\small\item\em Convert array to a doubly-linked list.\item\end{CompactList}\item
     25{\bf ps\-Dlist} $\ast$ {\bf ps\-Dlist\-Sort} ({\bf ps\-Dlist} $\ast$list, int($\ast$compare)(const void $\ast$a, const void $\ast$b))
     26\begin{CompactList}\small\item\em Sort a list.\item\end{CompactList}\item
    2527{\bf ps\-Hash} $\ast$ {\bf ps\-Hash\-Alloc} (void)
    2628\begin{CompactList}\small\item\em Allocate hash buckets in table.\item\end{CompactList}\item
     
    3335void $\ast$ {\bf ps\-Hash\-Remove} ({\bf ps\-Hash} $\ast$table, const char $\ast$key)
    3436\begin{CompactList}\small\item\em Remove key from table.\item\end{CompactList}\item
    35 {\bf ps\-Float\-Array} $\ast$ {\bf ps\-Float\-Array\-Alloc} (int nalloc)
    36 \begin{CompactList}\small\item\em Constructor.\item\end{CompactList}\item
    37 {\bf ps\-Float\-Array} $\ast$ {\bf ps\-Float\-Array\-Realloc} ({\bf ps\-Float\-Array} $\ast$my\-Array, int nalloc)
    38 \begin{CompactList}\small\item\em Reallocator.\item\end{CompactList}\item
    39 void {\bf ps\-Float\-Array\-Free} ({\bf ps\-Float\-Array} $\ast$restrict my\-Array)
    40 \begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\item
    41 {\bf ps\-Complex\-Array} $\ast$ {\bf ps\-Complex\-Array\-Alloc} (int nalloc)
    42 \begin{CompactList}\small\item\em Constructor.\item\end{CompactList}\item
    43 {\bf ps\-Complex\-Array} $\ast$ {\bf ps\-Complex\-Array\-Realloc} ({\bf ps\-Complex\-Array} $\ast$my\-Array, int nalloc)
    44 \begin{CompactList}\small\item\em Reallocator.\item\end{CompactList}\item
    45 void {\bf ps\-Complex\-Array\-Free} ({\bf ps\-Complex\-Array} $\ast$restrict my\-Array)
    46 \begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\item
    47 {\bf ps\-Int\-Array} $\ast$ {\bf ps\-Int\-Array\-Alloc} (int nalloc)
    48 \begin{CompactList}\small\item\em Constructor.\item\end{CompactList}\item
    49 {\bf ps\-Int\-Array} $\ast$ {\bf ps\-Int\-Array\-Realloc} ({\bf ps\-Int\-Array} $\ast$my\-Array, int nalloc)
    50 \begin{CompactList}\small\item\em Reallocator.\item\end{CompactList}\item
    51 void {\bf ps\-Int\-Array\-Free} ({\bf ps\-Int\-Array} $\ast$restrict my\-Array)
    52 \begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\item
    53 {\bf ps\-Double\-Array} $\ast$ {\bf ps\-Double\-Array\-Alloc} (int nalloc)
    54 \begin{CompactList}\small\item\em Constructor.\item\end{CompactList}\item
    55 {\bf ps\-Double\-Array} $\ast$ {\bf ps\-Double\-Array\-Realloc} ({\bf ps\-Double\-Array} $\ast$my\-Array, int nalloc)
    56 \begin{CompactList}\small\item\em Reallocator.\item\end{CompactList}\item
    57 void {\bf ps\-Double\-Array\-Free} ({\bf ps\-Double\-Array} $\ast$restrict my\-Array)
    58 \begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\item
    59 {\bf ps\-Vector\-Array} $\ast$ {\bf ps\-Vector\-Array\-Alloc} (int nalloc)
    60 \begin{CompactList}\small\item\em Constructor.\item\end{CompactList}\item
    61 {\bf ps\-Vector\-Array} $\ast$ {\bf ps\-Vector\-Array\-Realloc} ({\bf ps\-Vector\-Array} $\ast$my\-Array int nalloc)
    62 \begin{CompactList}\small\item\em Reallocator.\item\end{CompactList}\item
    63 void {\bf ps\-Vector\-Array\-Free} ({\bf ps\-Vector\-Array} $\ast$restrict my\-Array)
    64 \begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\item
    65 {\bf ps\-Void\-Ptr\-Array} $\ast$ {\bf ps\-Void\-Ptr\-Array\-Alloc} (int nalloc)
    66 \begin{CompactList}\small\item\em Constructor.\item\end{CompactList}\item
    67 {\bf ps\-Void\-Ptr\-Array} $\ast$ {\bf ps\-Void\-Ptr\-Array\-Realloc} ({\bf ps\-Void\-Ptr\-Array} $\ast$arr, int nalloc)
    68 \begin{CompactList}\small\item\em Reallocate.\item\end{CompactList}\item
    69 void {\bf ps\-Void\-Ptr\-Array\-Free} ({\bf ps\-Void\-Ptr\-Array} $\ast$arr, void($\ast$elem\-Free)(void $\ast$))
    70 \begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\end{CompactItemize}
     37{\bf ps\-Vector} $\ast$ {\bf ps\-Vector\-Alloc} (int nalloc, {\bf ps\-Elem\-Type} type)
     38\begin{CompactList}\small\item\em Create a vector of the specified size and type.\item\end{CompactList}\item
     39{\bf ps\-Vector} $\ast$ {\bf ps\-Vector\-Realloc} (const {\bf ps\-Vector} $\ast$vector, int nalloc)
     40\begin{CompactList}\small\item\em Extend a vector.\item\end{CompactList}\item
     41{\bf ps\-Vector} $\ast$ {\bf ps\-Vector\-Subset} (const {\bf ps\-Vector} $\ast$vector, int start, int end)
     42\begin{CompactList}\small\item\em Create a subvector of the specified range.\item\end{CompactList}\item
     43void {\bf ps\-Vector\-Free} ({\bf ps\-Vector} $\ast$restrict vector, void($\ast$elem\-Free)(void $\ast$))
     44\begin{CompactList}\small\item\em Destroy the specified vector.\item\end{CompactList}\item
     45{\bf ps\-Vector} $\ast$ {\bf ps\-Vector\-Transpose} ({\bf ps\-Vector} $\ast$out, {\bf ps\-Vector} $\ast$my\-Vector)
     46\begin{CompactList}\small\item\em Transpose a vector.\item\end{CompactList}\end{CompactItemize}
  • trunk/doc/pslib/psLibSDRS.tex

    r703 r747  
    1 %%% $Id: psLibSDRS.tex,v 1.45 2004-05-16 04:50:56 eugene Exp $
     1%%% $Id: psLibSDRS.tex,v 1.46 2004-05-20 03:41:49 eugene Exp $
    22\documentclass[panstarrs]{panstarrs}
    33
     
    1717
    1818\setlength{\topsep}{-2pt}
    19 
     19 
    2020\begin{document}
    2121\maketitle
     22\sloppy
    2223
    2324% -- Revision History --
     
    2930DR & 2004 Mar 29 & Draft \\ \hline
    303100 & 2004 Apr 1  & First version, sent to MHPCC \\ \hline
    31 01 & 2004 Apr 23 & Added section on error handling \\ \hline
     3201 & 2004 May 19 & Extensive modifications, see appendix \\ \hline
    3233\RevisionsEnd
    3334
     
    6263well-defined, concise operations which can be coded with only a modest
    6364number of lines.  PSLib is a library of basic functions required by
    64 the IPP, but should include many programming concepts which may be useful
     65the IPP, and it includes many programming concepts which may be useful
    6566for other software projects, especially those which deal with
    6667astronomical data handling tasks.
     
    8081on the functions and data types of the earlier entries. 
    8182
    82 The installed base of code for PSLib consists of header files, the
    83 binary library code, \code{libpslib.a} and the shared-library
    84 equivalent, \code{libpslib.so} (or \code{libpslib.dylib} in the case
    85 of OS/X).  Assuming these components have been installed into the
    86 library and search path, PSLib may be used within a program by
    87 including the line \code{#include <pslib.h>} into the C code and
    88 linking with \code{-lpslib}.
     83The installed code base for PSLib consists of header files, the binary
     84library code, \code{libpslib.a} and the shared-library equivalent,
     85\code{libpslib.so} (or \code{libpslib.dylib} in the case of OS/X).
     86Assuming these components have been installed into the library and
     87search path, PSLib may be used within a program by including the line
     88\code{#include <pslib.h>} into the C code and linking with
     89\code{-lpslib}.
    8990
    9091This document describes the data structures and details the functions
    9192calls. The specified data structures and functions follow the naming
    92 conventions detailed in the IPP Code Conventions (PSDC-430-004).  In
    93 particular, these coding conventions restrict the namespace used by
    94 the library functions by requiring that all globally visible symbols
    95 start with the two letters \code{ps}.  Further namespace organization
    96 is achieved by encouraging functions to be named in the form
    97 psNounVerbPhrase, where Noun is the data type of principle relevance
    98 and VerbPhase describes the operation applied to that data type.  For
    99 example, the function which copies an image (of type \code{psImage})
    100 is called \code{psImageCopy()}.
     93conventions detailed in the IPP Software Requirements Specification
     94(PSDC-430-005).  In particular, these coding conventions restrict the
     95namespace used by the library functions by requiring that all globally
     96visible symbols start with the two letters \code{ps}.  Further
     97namespace organization is achieved by encouraging functions to be
     98named in the form psNounVerbPhrase, where Noun is the data type of
     99principle relevance and VerbPhase describes the operation applied to
     100that data type.  For example, the function which copies an image (of
     101type \code{psImage}) is called \code{psImageCopy()}.
    101102
    102103%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    107108document will be implemented through wrapping external libraries:
    108109\begin{itemize}
    109 \item Many of the matrix functions, some of the polynomial and
    110 minimisation functions functions will wrap the GNU Scientific Library
    111 (GSL; \href{www.gnu.org/software/gsl/}{\tt www.gnu.org/software/gsl});
    112 \item The sort functions will wrap the system \code{qsort} call;
    113 \item Some of the Fourier transform functions will wrap the Fastest Fourier
    114 Transform in the West library (FFTW; \href{www.fftw.org}{\tt www.fftw.org});
    115 \item The FITS functions will wrap the CFITSIO library
    116 (\href{heasarc.gsfc.nasa.gov/docs/software/fitsio/}{\tt
    117 heasarc.gsfc.nasa.gov/docs/software/fitsio/}); and
     110\item Many of the matrix functions, some of the polynomial and some of
     111the minimization functions functions should wrap the GNU Scientific
     112Library (GSL):
     113
     114\href{www.gnu.org/software/gsl/}{\tt www.gnu.org/software/gsl});
     115
     116\item The sort functions should wrap the system \code{qsort} call
     117
     118\item Some of the Fourier transform functions should wrap the Fastest Fourier
     119Transform in the West library (FFTW):
     120
     121\href{www.fftw.org}{\tt www.fftw.org}
     122
     123\item The FITS functions should wrap the CFITSIO library:
     124
     125\href{heasarc.gsfc.nasa.gov/docs/software/fitsio}{\tt heasarc.gsfc.nasa.gov/docs/software/fitsio}
     126
    118127\item Many of the astronomy routines will wrap the StarLink Positional
    119 Astronomy libraries (SLALib;
     128Astronomy libraries (SLALib):
     129
    120130\href{star-www.rl.ac.uk/star/docs/sun67.htx/sun67.html}{\tt
    121 star-www.rl.ac.uk/star/docs/sun67.htx/sun67.html}.
    122 \item \tbd{Some graphics library, possibly the SM library.}
     131star-www.rl.ac.uk/star/docs/sun67.htx/sun67.html}
     132
    123133\end{itemize}
    124134
     
    144154\subsubsection{Introduction}
    145155
    146 The \PS{} software system will need a level of memory management
    147 placed between the operating system (\code{malloc}/\code{free}) and
    148 the high level routines (e.g.\ \code{psMetaDataAlloc}).  This layer is
    149 in addition to the possibility that specific heavily used data types
    150 may need their own special-purpose memory managers.  However, since we
    151 require that all user-level objects be allocated via associated
    152 \code{Alloc/Free} functions, we will easily be able to implement such
    153 functionality without impacting the facilities described here.
     156PSLib needs a level of memory management placed between the operating
     157system (\code{malloc}/\code{free}) and the high level routines (e.g.\
     158\code{psMetadataAlloc}).  This layer is in addition to the possibility
     159that specific heavily used data types may need their own
     160special-purpose memory managers.  However, since we require that all
     161user-level objects be allocated via associated \code{Alloc/Free}
     162functions, we will easily be able to implement such functionality
     163without impacting the facilities described here.
    154164
    155165\subsubsection{Rationale}
     
    162172  We wish to insulate ourselves from the details of the system-provided
    163173  \code{malloc}.  There is no guarantee that the goals of the system
    164   architect align with those of the \PS{} processing
     174  architect align with those of the PSLib or the IPP.
    165175
    166176\item
     
    173183  While it is possible to do this by linking with external libraries
    174184  (e.g.\ \href{gnu.org}{Electric Fence}), it is convenient to do so
    175   within the \PS{} framework.
     185  within the framework provided by PSLib.
    176186
    177187\item
     
    191201\subsubsection{Memory Management}
    192202
    193 In the following sections, we specify the API set, and define the
    194 appropriate data structures, needed by the PSLib memory management
     203In the following sections, we specify the API set and define the
     204appropriate data structures needed by the PSLib memory management
    195205system in order to meet the requirements specified by the desiderata
    196 listed above. 
     206listed above.
    197207
    198208Within the PSLib memory management system, every allocated memory
     
    200210memory segments.  The segment preceeding the user-memory contains data
    201211describing the allocated block, using the \code{psMemBlock} structure.
    202 The first and last elements of this structure \code{void} pointers
     212The first and last elements of this structure are \code{void} pointers
    203213called \code{startblock} and \code{endblock}, which are assigned a
    204214special value, \code{PS_MEM_MAGIC}.  The segment following the
    205215user-memory block consists of a single \code{void} pointer, and is
    206216also assigned the special value of \code{PS_MEM_MAGIC}.  This address
    207 is pointed to by the structure elements \code{endpost}.
    208 
    209 In practice, these bounding memory blocks mean that when a user is
     217is pointed to by the structure element \code{endpost}.
     218
     219In practice, these bounding memory blocks mean that when a user
    210220requests $N$ bytes of memory, the memory management system in fact
    211221allocates \code{N + sizeof(psMemBlock) + sizeof(void)} bytes, starting
    212222at a particular address, \code{ADDR}.  It then fills in the first
    213223\code{sizeof(psMemBlock)} bytes with the data of the \code{psMemBlock}
    214 structure, and the last \code{sizeof(void)} bytes with the
     224structure, and the last \code{sizeof(void)} bytes with
    215225\code{PS_MEM_MAGIC}.  It returns to the user the pointer corresponding
    216226to the address \code{ADDR + sizeof(psMemBlock)}.  If the memory
    217227management system reallocates a block of memory, it must also allocate
    218228the additional space and fill in the boundary values.  If the memory
    219 management system is given a specific pointer for some operation, it is
    220 able to find the corresponding \code{psMemBlock} by simply subtracting
    221 \code{sizeof(psMemBlock)} from the pointer address.
     229management system is given a specific pointer for some operation, it
     230is able to find the corresponding \code{psMemBlock} by simply
     231subtracting \code{sizeof(psMemBlock)} from the pointer address.
    222232
    223233The purpose of the three boundary markers is to catch corruption and
     
    227237is one where the coder mis-counts the range and either fills the data
    228238just before the start of the valid memory or just after the end of the
    229 valid memory.  These actions will (hopefully) alter the boundary-post
     239valid memory.  These actions are likely to alter the boundary-post
    230240values, which can be detected by the memory management system.  In the
    231241second case, hexadecimal dumps of large blocks of memory are easier to
     
    245255    const int lineno;                   ///< set from __LINE__ in e.g. p_psAlloc
    246256    int refCounter;                     ///< how many times pointer is referenced
    247     const void **endpost;               ///< pointer to endpost, initialised to PS_MEM_MAGIC
    248     const void *endblock;              ///< initialised to PS_MEM_MAGIC
     257    const void **endpost;               ///< initialised to PS_MEM_MAGIC
     258    const void *endblock;               ///< initialised to PS_MEM_MAGIC
    249259} psMemBlock;
    250260\end{verbatim}
     
    267277memory.  As discussed below, the basic free function, \code{psFree},
    268278is specified to free the memory block only if the reference counter is
    269 set to 1.  See the discussion of the \code{psDlist} and \code{psHash}
    270 data containers for an example of the usage.  Usage of this feature is
    271 strongly encouraged, but not enforced by the memory management system.
     279set to 1.  See the discussion in section~\ref{sec:free} for an example
     280of the usage.  Usage of this feature is strongly encouraged, but not
     281enforced by the memory management system.
    272282
    273283In order to trace double frees and other memory errors, the memory
     
    276286data are left behind.  If endpost points to the memory location
    277287immediately following the \code{psMemBlock} data, then the memory
    278 block has been freed.  This state shall be enforces by \code{psFree}.
     288block has been freed.  This state must be enforced by \code{psFree}.
    279289
    280290\subsubsection{APIs for Allocating and Freeing}
    281291
    282 PSLib provides the following APIs to create and destroy memory blocks:
     292PSLib must provide the following APIs to create and destroy memory
     293blocks:
    283294%
    284295\begin{verbatim}
     
    291302\code{psRealloc}, and \code{psFree} have identical semantics to the
    292303standard C library functions \code{malloc}, \code{realloc}, and
    293 \code{free}.  In fact, these functions shall be implemented as C
     304\code{free}.  In fact, these functions should be implemented as C
    294305preprocessor macros which call the following private functions:
    295306%
     
    309320
    310321In order to enforce the use of the PSLib versions, the header file
    311 shall take steps to ensure that code calling the functions
     322must take steps to ensure that code calling the functions
    312323\code{malloc}, \code{calloc}, \code{realloc}, or \code{free} will not
    313324compile.  This may be achieved by defining preprocessor macros which
    314 mask these functions with invalid statements (\eg{} \code{#define malloc(S) for}).
    315 In exceptional cases, such as the memory management system itself,
    316 programmers may choose to override this prohibition by defining the
    317 symbol \code{PS_ALLOW_MALLOC}.  Application code will call
    318 \code{p_psAlloc,p_psRealloc,p_psFree} via the macros defined above.
     325mask these functions with invalid statements (\eg{} \code{#define
     326malloc(S) for}).  In exceptional cases, such as the memory management
     327system itself, programmers may choose to override this prohibition by
     328defining the symbol \code{PS_ALLOW_MALLOC}.  Application code will
     329call \code{p_psAlloc}, \code{p_psRealloc}, or \code{p_psFree} via the
     330macros defined above.
    319331 
    320 The functions \code{psAlloc} and \code{psRealloc} shall never return a
     332The functions \code{psAlloc} and \code{psRealloc} must never return a
    321333\code{NULL} pointer. If they are unable to provide the requested
    322 memory they should attempt to obtain the desired memory by calling the
     334memory they must attempt to obtain the desired memory by calling the
    323335routine registered by \code{psMemExhaustedSetCallback} (see
    324336\S\ref{secMemAdvanced}), and if still unsuccessful, call
     
    351363types, specified below.  The callbacks are set using functions with
    352364names of the form \code{psCallbackSet}.  In all cases, the
    353 `\code{Set}' routine takes a pointer to the desired callback
    354 function and returns a pointer to the one that was previously
    355 installed. If the function pointer is \code{NULL}, the default
    356 callback function is reinstalled.  We discuss the use of each of the
    357 four callbacks below.
     365`\code{Set}' routine takes a pointer to the desired callback function
     366and returns a pointer to the one that was previously installed. The
     367defaults for each of these callbacks is \code{NULL}, in which case the
     368corresponding callback is skipped.  If the function pointer passed to
     369the functions above is \code{NULL}, the default behavior is set.  We
     370discuss the use of each of the four callbacks below.
    358371
    359372\subsubsubsection{\tt psMemExhaustedCallback}
     
    396409information.  No return value is accepted, and no specific operations
    397410are expected.  The callback is for informational purposes only.  Where
    398 practical and efficient, the memory manager shall call the routine
     411practical and efficient, the memory manager must call the routine
    399412registered using \code{psMemProblemCallbackSet} whenever a corrupted block
    400413of memory is discovered.  For example, doubly-freed blocks can be
     
    426439typedef long (*psMemFreeCallback)(const psMemBlock *ptr);
    427440psMemFreeCallback psMemFreeCallbackSet(psMemFreeCallback func);
     441long psMemGetId(void);
    428442\end{verbatim}
    429443%
     
    432446\code{psMemAllocateIDSet} accept the desired ID value and return the
    433447old value to the user.  The return values of the handlers installed by
    434 \code{psMemAllocateCallbackSet} and \code{psMemFreeCallbackSet} are used to
    435 increment the values of \code{p_psMemAllocateID} and
     448\code{psMemAllocateCallbackSet} and \code{psMemFreeCallbackSet} are
     449used to increment the values of \code{p_psMemAllocateID} and
    436450\code{p_psMemFreeID} respectively.  For example, a return value of
    437451\code{0} implies that the value is unchanged; if the value is \code{2}
    438452the callback will be called again when the memory ID counter has
    439453increased by two.  This functionality may be useful to check, for
    440 example, every 100th block allocated.  The function, \code{long psMemGetId(void);}
     454example, every 100th block allocated.  The function \code{psMemGetId}
    441455returns the next identification number to be assigned to a memory
    442456block.  This function can be used to guide the choice of ID set with
     
    463477
    464478If the argument \code{array} is non-\code{NULL}, then \code{**array}
    465 is set to an array of \code{psMemBlock *} pointers when the function
     479is set to an array of pointers to \code{psMemBlock} when the function
    466480returns.  These pointers represent the blocks which have been
    467481allocated but not freed.  It is the caller's responsibility to free
     
    479493The return value is the number of corrupted blocks detected. If the
    480494argument \code{abort_on_error} is true, \code{psMemCheckCorruption}
    481 shall call \code{psAbort} as soon as memory corruption is detected.
     495must call \code{psAbort} as soon as memory corruption is detected.
    482496
    483497\subsubsection{Reference Counting}
     
    491505and decrement it when those references are removed.  The memory
    492506management routines respect the use of the \code{refCounter} field:
    493 \code{psFree} will not free a block for which \code{refCounter != 1},
    494 and \code{psAlloc} will initialize the field to 1.  \code{psFree}
    495 must generate an error if \code{refCounter != 1}.  However, they do
    496 not (and cannot practically) enforce the use of the counters; this is
    497 a requirement of external APIs which intend to use the feature.
     507\code{psFree} will not free a block for which \code{refCounter} is not
     5081, and \code{psAlloc} will initialize the field to 1.  \code{psFree}
     509must generate an error if \code{refCounter} is not 1.  However, they
     510do not (and cannot practically) enforce the use of the counters; this
     511is a requirement of external APIs which intend to use the feature.
    498512
    499513Several APIs are provided to manage the reference counters.  These
     
    508522The functions all take a pointer to the start of a user block of
    509523memory.  The first simply returns the value of the reference counter.
    510 The next two functions increment or decrement the reference counter,
    511 returning the pointer which was passed in. These functions must
    512 validate the memory pointer by determining the corresponding
     524If \code{vptr} is \code{NULL}, this function must return a value of
     525NULL.  The next two functions increment or decrement the reference
     526counter, returning the pointer which was passed in. These functions
     527must validate the memory pointer by determining the corresponding
    513528\code{psMemBlock.id} and checking for consistency in the internal
    514 memory block table (the table pointer for \code{psMemBlock.id} should
    515 be in the valid range and should correspond to the address of the
    516 \code{psMemBlock}).  For an example implementation of the
    517 \code{refCounter} facilities, see the discussion of \code{psDlist}
    518 (\S\ref{sec:psDlist}).
     529memory block table (the table pointer for \code{psMemBlock.id} must be
     530in the valid range and must correspond to the address of the
     531\code{psMemBlock}).
    519532
    520533\subsubsection{Relation of Memory Management to Structures}
    521534\label{sec:free}
    522535
    523 In this document, we specify several C \code{struct}s.  It is expected
    524 that instances of, for example, \code{struct psMyType} will be
    525 constructed using \code{psMyTypeAlloc()} calls, and destroyed using
     536Within PSLib and throughout the Pan-STARRS project, we specify a
     537variety of rich data structures.  The IPP Software Requirements
     538Specification states that structures should be defined with
     539corresponding constructors and destructors.  Instances of, for
     540example, \code{psMyType} should be constructed using
     541\code{psMyTypeAlloc()} calls, and destroyed using
    526542\code{psMyTypeFree()} calls.  The allocator will allocate the required
    527543memory with \code{psAlloc} and increment the appropriate
     
    536552
    537553\begin{verbatim}
    538 void psMyTypeFree(psMyType *myType ///< Object to destroy
    539     )
     554void psMyTypeFree(psMyType *myType)
    540555{
    541     /* No operation if object is NULL */
    542     if (myType == NULL) {
     556    /* data is not defined */
     557    if (psMemGetRefCounter(myType) < 1) {
    543558        return;
    544559    }
    545560    /* Only call psFree if reference counter is 1 */
    546561    if (psMemGetRefCounter(myType) == 1) {
     562        psSubFree (myType->sub);
    547563        psFree(myType);
    548564        return;
     
    553569\end{verbatim}
    554570
    555 This allows, for example, the \code{psMyType} to be imported into the
    556 metadata (\S\ref{sec:metadata}) without the user worrying about the
    557 details of the memory allocation/deallocation:
    558 
    559 \begin{verbatim}
    560 void psFooMetadata(psMetadata *md)
    561 {
    562     psFoo *foo = psFooAlloc();
    563     (void) psMetaDataAppend(md, psMetaDataItemAlloc(PS_META_FOO,foo,"Comment","foo.bar"));
    564     (void) psFooFree(foo);
    565 }
    566 \end{verbatim}
    567 
    568 In the above case, \code{foo} is created, stuffed into the metadata,
    569 and then the programmer follows the rule of ``for every \code{alloc},
    570 there is an equal and opposite free'' before the function returns.
    571 However, the metadata needs to carry around the \code{psFoo}, and so
    572 it is important that \code{psFooFree} does not free the memory for
    573 \code{foo}, but only decrements its \code{refCounter}.  Hence, at the
    574 conclusion of the function, the memory pointed to by \code{foo} in the
    575 course of the function remains allocated, and the corresponding
    576 \code{refCounter} is 1 (specifically, the reference in the metadata).
     571Note that the element of \code{myType}, \code{myType.sub} is
     572explicitly freed with its associated destructor.  If this element
     573points to a data block with multiple references, this call would only
     574decrement the counter. 
    577575
    578576\subsection{Tracing and Logging}
     
    604602top-level.  If the user needs to dig deeper into the code, the trace
    605603level should be set lower, and the more detailed messages could be
    606 examined.  In a case of a real, poorly-understood problem with the
     604examined.  In a case of a serious, poorly-understood problem with the
    607605code, the trace threshold would be placed to the bottom and the
    608606lowest-level step-by-step messages would be printed.
    609607
    610 The PSLib tracing facility will provide the above functionality, along
     608The PSLib tracing facility provides the above functionality, along
    611609with the ability to assign different trace levels to messages from
    612 different software components.  Each trace message when placed in the
    613 code is assigned to be part of a specific tracing 'facility', defined
     610different software components.  Each trace message, when placed in the
     611code, is assigned to be part of a specific tracing 'facility', defined
    614612in more detail below.  The trace level for that specific message is
    615613also set when the message is placed.  Each facility may have its trace
     
    664662which returns the trace level of the named facility following the
    665663rules specified above.  A specified trace message (identified by
    666 \code{psTrace}) shall be printed if and only if
     664\code{psTrace}) must be printed if and only if
    667665\code{psTraceGetLevel(facil)} returns a value greater than or equal to
    668666the value of \code{myLevel} for that message.  That is, a larger
     
    670668hence is more verbose.
    671669
    672 PSLib will include a utility function for examining the current
    673 tracing levels of all facilities: \code{void psTracePrintLevels(void);}.
    674 This function will print the hierarchy of trace facilities along with
    675 the current trace level for each facility.  For example, a particular
     670PSLib includes a utility function for examining the current tracing
     671levels of all facilities:
     672%
     673\begin{verbatim}
     674void psTracePrintLevels(void);
     675\end{verbatim}. 
     676%
     677This function prints the hierarchy of trace facilities along with the
     678current trace level for each facility.  For example, a particular
    676679program may have a few facilities defined, along with their trace
    677680levels.  A call to \code{psTracePrintLevels} may produce a listing
     
    706709flat-field image is foo.fits
    707710  doing the divide
    708  got an invalid pixel value (NaN) at 500,20
     711  got an invalid pixel value (NaN) at 500,20
    709712  divide is done
    710713\end{verbatim}
     
    722725%
    723726
    724 The availability of the tracing facility at run-time, shall be decided
     727The availability of the tracing facility at run-time, must be decided
    725728at compilation: If the C pre-processor macro \code{PS_NO_TRACE} is
    726 defined, all trace code shall be replaced by empty space so that none
     729defined, all trace code must be replaced by empty space so that none
    727730of the code is compiled.  This can be implemented via macro front-ends
    728731to private versions of the user APIs.  In addition, a function
     
    733736with \code{psTraceSetDestination}:
    734737\begin{verbatim}
    735 void psTraceSetDestination(FILE *fp     // Open file pointer to write to
    736     );
     738void psTraceSetDestination(FILE *fp);
    737739\end{verbatim}
    738740If the \code{fp} is \code{NULL}, then the trace is sent to standard
    739 output.
     741output, otherwise it is sent to the specified file pointer.
    740742
    741743\subsubsection{Message Logging}
     
    761763\begin{verbatim}
    762764void psLogMsg(char *name, int myLevel, char *fmt, ...);
    763 void psLogVMsg(char *name, int myLevel, char *fmt, va_list ap);
     765void psLogMsgV(char *name, int myLevel, char *fmt, va_list ap);
    764766\end{verbatim}
    765767where \code{name} is a word to describe the source of the message,
     
    767769is a printf-style formatting statement defining the actual message,
    768770and is followed by the arguments to the formatting code.  The second
    769 form, \code{psLogVMsg} is an equivalent command which takes a
     771form, \code{psLogMsgV} is an equivalent command which takes a
    770772\code{va_list} argument.
    771773
     
    777779\end{verbatim}
    778780%
    779 The default level is set to \code{PS_LOG_INFO}. 
    780781
    781782At any time, the program may set the current log level, the level
     
    789790invoked with \code{psLogMsg} is only printed if its value of
    790791\code{myLevel} is less than the current value set by
    791 \code{psLogSetLevel}.
     792\code{psLogSetLevel}.  The default log level is set to
     793\code{PS_LOG_INFO}.
    792794
    793795Log messages are sent to the destination most recently set using:
    794796%
    795797\begin{verbatim}
    796 int psLogSetDestination(int dest);     
    797 \end{verbatim}
    798 %
    799 The only values that are initially defined are \code{PS_LOG_TO_STDERR}
    800 and \code{PS_LOG_TO_STDOUT} to write to \code{stderr} and
    801 \code{stdout} respectively, and \code{PS_LOG_TO_NONE} to turn off
    802 logging.  \tbd{Log to a server via TCP/IP; will possibly set these
    803 values to negative integers and allow psLogSetDestination to take
    804 a positive-integer file descriptor.}.
     798int psLogSetDestination(char *dest);     
     799\end{verbatim}
     800%
     801The destination string consists of a URL in the form
     802\code{protocol:location}.  The \code{protocol} value may be
     803\code{file}, to send the log to a local file named by the value of
     804\code{location}.  Future expansion may allow the logger to send
     805messages to an IP logger, with a protocol to be defined later.  Three
     806other special values are allowed for \code{dest}: \code{stderr} and
     807\code{stdout}, which write to \code{stderr} and \code{stdout}
     808respectively, and \code{none} to turn off logging. 
    805809
    806810The output format is controlled with the function:
     
    826830\code{PS_LOG_ERROR}, \code{PS_LOG_WARN}, and \code{PS_LOG_INFO}
    827831respectively. Other levels are represented numerically (\code{5}
    828 etc.). The other two field, \code{name} and \code{msg} are the
     832etc.). The other two fields, \code{name} and \code{msg}, are the
    829833arguments to \code{psLogMsg}; note that \code{name} has a fixed width
    830834of 15 characters. If \code{msg} doesn't end in a newline, a single
     
    849853\hlabel{errorStack}
    850854
    851 \PS{} errors shall be raised using a function, \code{psError}, with
    852 the caller supplying a component name and error message.  It is
    853 desireable to be able to trace an error through the program so that
    854 the events that led to the error may be quickly and clearly
    855 identified.
    856 
    857 \begin{verbatim}
    858 /// Prints an error message and doesn't abort; returns code
    859 int psError(const char *name,           ///< Category of code that caused the error
    860             psErrorCode code,           ///< class of error (equivalent to errno)
    861             psErrorStatus status,       ///< is this a new error?
    862             const char *fmt,            ///< Format
    863             ...                         ///< Extra arguments to use format
    864     );
    865 
    866 typedef enum {
    867     PS_OLD_ERROR = 0,                   ///< This is an old error, and should append to the error stack
    868     PS_NEW_ERROR = 1,                   ///< This is a new error and should clear the error stack
    869 } psErrorStatus;
     855\PS{} errors must be raised using a function, \code{psError}, with the
     856caller supplying a component name and error message.  It is desireable
     857to be able to trace an error through the program so that the events
     858that led to the error may be quickly and clearly identified.
     859\code{psError} prints an error message and doesn't abort, but instead
     860returns the error code.
     861\begin{verbatim}
     862int psError(const char *name, psErrorCode code, int status, const char *fmt, ...);
    870863\end{verbatim}
    871864
    872865The \code{name} is of the form \code{aaa.bbb.ccc} and identifies the
    873 component raising the error.  The \code{psErrorCode} is an enumerated
    874 type which lists the possible \textit{classes} of errors
     866component raising the error.  The \code{code} is an enumerated type
     867which lists the possible \textit{classes} of errors
    875868(e.g. \code{PS_ERR_IO}) that \PS{} code can generate (see section
    876 \ref{psErrorCodes}). \code{status} specifies whether this is a new
    877 error, or whether this call to \code{psError} is in response to an
    878 error that has already resulted in a call to \code{psError}.  The
     869\ref{psErrorCodes}). The \code{new} argument takes a boolean which, if
     870\code{TRUE} specifies that the error was set initially at this
     871location, and if \code{FALSE} specifies that an error was passed to
     872this location.  Raising new error should clear the error stack.  The
    879873final required argument, \code{fmt}, is a \code{printf}-style format
    880 that is passed to \code{psLogVMsg} with code \code{PS_LOG_ERROR}.
    881 
    882 The result of a call to \code{psError} shall be to push an error onto
    883 a stack; this stack is cleared if \code{psErrorStatus} is true, or by a call
    884 to \code{psErrorClear}.  The errors are defined as the following:
    885 
     874that is passed to \code{psLogMsgV} with code \code{PS_LOG_ERROR}.  The
     875result of a call to \code{psError} must be to push an error onto a
     876stack; this stack is cleared if \code{psErrorStatus} is true, or by a
     877call to \code{psErrorClear}.
     878
     879The errors on the error stack are defined as the following:
    886880\begin{verbatim}
    887881typedef struct {
     
    892886\end{verbatim}
    893887
    894 
    895 The last error reported is available from \code{psLastError}; if no
    896 errors are current, a non-\code{NULL} \code{psErr} shall be returned
    897 with code \code{PS_ERR_NONE}.  Previous errors on the stack shall be
    898 returned by \code{psGetError} (a value of \code{0} passed to
    899 \code{psGetError} is equivalent to a call to \code{psLastError}).
    900 
    901 \begin{verbatim}
    902 const psErr *psErrorGet(int which);     ///< return specified error (or an "error" with code PS_ERR_NONE)
    903 const psErr *psErrorLast(void);         ///< return last error (or an "error" with code PS_ERR_NONE)
    904 \end{verbatim}
    905 
    906 The error stack may be completely cleared:
    907 
    908 \begin{verbatim}
    909 void psErrorClear(void);                ///< Clear the error stack
     888The last error reported is available from \code{psErrorLast}; if no
     889errors are current, a non-\code{NULL} \code{psErr} must be returned
     890with code \code{PS_ERR_NONE}.  Previous errors on the stack must be
     891returned by \code{psErrorGet} (a value of \code{0} passed to
     892\code{psErrorGet} is equivalent to a call to \code{psErrorLast}).
     893The error stack may be completely cleared with \code{psErrorClear}.
     894%
     895\begin{verbatim}
     896const psErr *psErrorGet(int which);
     897const psErr *psErrorLast(void);
     898void psErrorClear(void);
    910899\end{verbatim}
    911900
    912901The entire error stack may be printed to an open file descriptor by
    913 calling \code{psErrorStackPrint} (or \code{psErrorVStackPrint}); if
     902calling \code{psErrorStackPrint} (or \code{psErrorStackPrintV}); if
    914903and only if there are current errors, the printf-style string
    915904\code{fmt} is first printed to the file descriptor \code{fd}. In this
    916 printout, error codes shall be replaced by their string equivalents as
     905printout, error codes must be replaced by their string equivalents as
    917906defined in the next section.  Note that these are also available in
    918907the \code{psErr} structure. The successive lines of the traceback
    919908should be indented by an additional space (see example).
    920 \code{psErrorVStackPrint} shall not invoke \code{va_end}.
    921 
    922 \begin{verbatim}
    923 void psErrorStackPrint(FILE *fd, const char *fmt, ...); ///< print the errorstack to this file descriptor
    924 void psErrorVStackPrint(FILE *fd, const char *fmt, va_list va); ///< print the errorstack to this file
    925                                                                 ///< descriptor
     909\code{psErrorStackPrintV} must not invoke \code{va_end}.
     910%
     911\begin{verbatim}
     912void psErrorStackPrint(FILE *fd, const char *fmt, ...);
     913void psErrorStackPrintV(FILE *fd, const char *fmt, va_list va);
    926914\end{verbatim}
    927915
    928916Any \code{errorCode}s less then or equal to \code{PS_ERR_BASE} (see
    929 next section) shall be taken to be valid values of \code{errno}, and
    930 \code{psErrorStackPrint} shall print the value returned by
     917next section) must be taken to be valid values of \code{errno}, and
     918\code{psErrorStackPrint} must print the value returned by
    931919\code{strerror} if such error codes are encountered.
    932920
    933921The routine \code{psErrorCodeString} returns the string associated
    934922with an error code:
    935 
    936 \begin{verbatim}
    937 const char *psErrorCodeString(psErrorCode code);        ///< return the string associated with an error code.
    938 \end{verbatim}
    939 
     923\begin{verbatim}
     924const char *psErrorCodeString(psErrorCode code);
     925\end{verbatim}
    940926
    941927\subsubsection{Error Codes}
     
    943929
    944930Both error codes for PSLib and error codes for projects that use PSLib
    945 may be registered.  In the former case, the error codes shall be
    946 registered on initialisation, whereas in the latter case, it is
    947 required to explicitly register.
     931may be registered.  In the former case, the error codes must be
     932registered on initialisation, whereas in the latter case, they must be
     933explicitly registered by the programmer.
    948934
    949935\paragraph{Registering error codes}
    950936
    951 An array of error codes may be registered with the PSLib error handler
    952 using a private function:
    953 
    954 \begin{verbatim}
    955 void p_psErrorRegister(const psErrorDescription *errors, ///< register a set of errors
    956                        int nerror                        ///< number of errors
    957     );
    958 \end{verbatim}
    959 
    960 Where the errors are represented internally as follows:
     937PSLib and any project needed to use PSLib must define the necessary
     938error codes and associated message strings.  An array of error codes
     939may be registered with the PSLib error handler using a private
     940function:
     941\begin{verbatim}
     942void psErrorRegisterSet(const psErrorDescription *errors, int nerror);
     943\end{verbatim}
     944where the errors are represented internally as follows:
    961945\begin{verbatim}
    962946typedef struct {
     
    965949} psErrorDescription;
    966950\end{verbatim}
    967 
    968 Projects wishing to employ the PSLib error handler should define
    969 a function,
    970 \begin{verbatim}
    971 void prefixErrorRegister(void);
    972 \end{verbatim}
    973 where \code{prefix} is particular to the project.  For example, PSLib
    974 should have a function,
    975 \begin{verbatim}
    976 void psErrorRegister(void);
    977 \end{verbatim}
    978 In this case (i.e., error codes for PSLib), the function should be
    979 called upon initialisation.  As another example, MOPS should implement
    980 a function,
    981 \begin{verbatim}
    982 void mopsErrorRegister(void);
    983 \end{verbatim}
    984 which would be called explicitly when MOPS utilises PSLib.
    985 
    986 It is left to the external project to produce the appropriate
    987 \code{prefixErrorRegister()}, but they may find helpful the
    988 implementation discussed below for use in PSLib.
    989 
    990 There is a clear need to coordinate the choice of error numbers.  It
    991 is expected that error code ranges for different projects shall be
    992 managed by the Project Office.
     951PSLib internal errors must be registered with the function
     952psErrorRegister, which should be called as part of the program
     953initialization to set up the error codes.  It is left to the external
     954project to produce their own error registration functions which must
     955also be called during initialization. There is a clear need to
     956coordinate the choice of error numbers.  It is expected that error
     957code ranges for different projects must be managed by the Project
     958Office within Pan-STARRS.
    993959
    994960\paragraph{Error Codes for PSLib}
    995961
    996 For ease of maintenance, error codes for PSLib shall be defined by an
     962For ease of maintenance, error codes for PSLib must be defined by an
    997963auxiliary file, conventionally named \file{psErrorCodes.dat}.  The
    998 format of this file shall consist of a number of lines, each of the
     964format of this file must consist of a number of lines, each of the
    999965form:
    1000966\begin{verbatim}
     
    1003969where \code{[ = value]} and the comma are optional, and no spaces are
    1004970significant except in the STRING.  Comments extend from \code{#} to
    1005 the end of the line (except that a \code{\#} shall be replaced by
     971the end of the line (except that a \code{\#} must be replaced by
    1006972\code{#} and not taken to start a comment). For example,
    1007973\begin{verbatim}
     
    1019985The values \code{NONE = 0} and {UNKNOWN} must be present.
    1020986
    1021 A script, called from the Makefiles, shall generate two files,
     987A script, called from the Makefiles, must generate two files,
    1022988\file{psErrorCodes.h} and \file{psErrorCodes.c} from the input file
    1023 \file{psErrorCodes.dat}.  \file{psErrorCodes.h} shall define an
     989\file{psErrorCodes.dat}.  \file{psErrorCodes.h} must define an
    1024990enumerated type \code{psErrorCode} with elements \code{PS_ERR_NAME}
    1025991and values as specified in \file{psErrorCodes.dat}, e.g.
     
    10401006\end{verbatim}
    10411007
    1042 Any \code{errorCode}s less then or equal to \code{PS_ERR_BASE} shall be taken
    1043 to be valid values of \code{errno}.
    1044 
    1045 \file{psErrorCodes.c} shall define the necessary function to register
    1046 the error codes.
    1047 
    1048 \subsubsection{Example}
    1049 
    1050 The following example code:
    1051 
    1052 \begin{verbatim}
    1053 #include "psLib.h"
    1054 
    1055 static int primary(int i)
    1056 {
    1057     if (i != 0) {                       // let's pretend it's an I/O error
    1058         return psError("tst.error.primary", PS_ERR_IO, 1, "Primary error");
    1059     }
    1060 
    1061     return 0;
    1062 }
    1063 
    1064 static int middle(void)
    1065 {
    1066     if (primary(1) != 0) {
    1067         return psError("tst.error.middle", PS_ERR_UNKNOWN, 0, "Secondary error");
    1068     }
    1069 
    1070     return 0;
    1071 }
    1072 
    1073 static int toplevel(void)
    1074 {
    1075     if (middle() != 0) {
    1076         return psError("tst.error", PS_ERR_UNKNOWN, 0, "Toplevel error");
    1077     }
    1078 
    1079     return 0;
    1080 }
    1081 
    1082 int main(void)
    1083 {
    1084     if (toplevel() != 0) {
    1085         psErrorStackPrint(stdout, "Traceback:\n");
    1086 
    1087         if (psErrorLast()->code == PS_ERR_UNKNOWN) {
    1088             fprintf(stderr, "Last error is of unknown type\n");
    1089         }
    1090         if (psErrorGet(2)->code == PS_ERR_IO) {
    1091             fprintf(stderr, "Third oldest error is of type IO\n");
    1092         }
    1093     }
    1094 
    1095     psErrorClear();
    1096     psErrorStackPrint(stdout, "Traceback:\n");
    1097 
    1098     if (psErrorLast()->code == PS_ERR_NONE) {
    1099         fprintf(stderr, "No errors. Hurrah\n");
    1100     }
    1101 
    1102     return 0;
    1103 }
    1104 \end{verbatim}
    1105 
    1106 
    1107 Produces the following output:
    1108 
    1109 \begin{verbatim}
    1110 Traceback:
    1111 tst.error.primary              I/O error                      Primary error
    1112  tst.error.middle              unknown error                  Secondary error
    1113   tst.error                    unknown error                  Toplevel error
    1114 Last error is of unknown type
    1115 Third oldest error is of type IO
    1116 No errors. Hurrah
    1117 \end{verbatim}
     1008Any \code{errorCode}s less then or equal to \code{PS_ERR_BASE} must be
     1009taken to be valid values of \code{errno}.  \file{psErrorCodes.c} must
     1010define the necessary function to register the error codes.
    11181011
    11191012%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    11211014\subsection{Abort}
    11221015
    1123 \code{psAbort}, shall call \code{psMsgLog} with a
     1016\code{psAbort}, must call \code{psMsgLog} with a
    11241017level of \code{PS_LOG_ABORT}, and then call \code{abort}.
    11251018
     
    11441037
    11451038Throughout PSLib, we require a variety of structures which correspond
    1146 to different mathematical data concepts.  For example, we have several
    1147 data structures which correspond to one-dimensional arrays (vectors)
    1148 of different data types (\code{int}, \code{float}, etc).  We also have
    1149 different data structures which correspond to two-dimensional arrays
    1150 (images or matrices), again with different data types for the
    1151 individual elements. 
     1039to different mathematical data concepts.  For example, we have a data
     1040structure which corresponds to one-dimensional arrays (vectors) of
     1041different data types (\code{int}, \code{float}, etc).  We also have a
     1042data structure which corresponds to two-dimensional arrays (images or
     1043matrices), again with different data types for the individual
     1044elements.
    11521045
    11531046A variety of functions perform operations which are equivalent for
     
    11631056operation if $x$ is a vector and $y$ is a matrix.  Nor does it matter
    11641057mathematically that the element data types match; the sum of a float
    1165 and an integer is a well-defined quantity!  One constraint should be
     1058and an integer is a well-defined quantity.  One constraint should be
    11661059noted: the size of the elements in each dimension must match.  For
    11671060example, if $x$ were a vector of 100 elements, but $y$ were a vector
     
    11701063
    11711064Given that some functions should be able to operate equivalently (or
    1172 identically) on a wide range of data types, it seems cumbersome to be
    1173 forced into defining a large number of C functions to handle the
    1174 different data types, just because we have different structures.
    1175 Admittedly, some details of the function would have to vary for
    1176 different data types, but since the basic function is the same, it
    1177 would help both the user and programmer if the same function could be
    1178 used for different data types.  We therefore define a mechanism which
    1179 allows the C functions to accept a generic data type, and determine
    1180 the type of the data on the basis of the data.  The mechanism uses the
    1181 structure \code{psType}.
    1182 
    1183 Each of these equivalent data types is defined by a structure in which
    1184 the first element is always of type \code{psType}.  This element
    1185 defines both the dimensions of the array and the data type of each
    1186 element.  The structure is as follows:
     1065identically) on a wide range of data types, we define a mechanism
     1066which allows the C functions to accept a generic data type, and
     1067determine the type of the data on the basis of the data. 
     1068Supported data types must be defined by a structure in which
     1069the first element is always of type \code{psType}: 
    11871070\begin{verbatim}
    11881071typedef struct {
     
    11931076where \code{psDimen dimen} defines the dimensionality of the data and
    11941077\code{psElemType type} defines the data type of each element.  These
    1195 two variable types are defined as structures:
     1078two variable types are defined as:
    11961079\begin{verbatim}
    11971080typedef enum {
     
    12001083    PS_DIMEN_TRANSV,                    ///< A transposed vector
    12011084    PS_DIMEN_IMAGE,                     ///< An image (matrix)
    1202     PS_DIMEN_OTHER                      ///< Something else that's not supported for arithmetic
     1085    PS_DIMEN_OTHER                      ///< Not supported for arithmetic
    12031086} psDimen;
    12041087\end{verbatim}
     
    12161099    PS_TYPE_F32,                        ///< Floating point
    12171100    PS_TYPE_F64,                        ///< Double-precision floating point
    1218     PS_TYPE_C32,                        ///< Complex numbers consisting of floating point
    1219     PS_TYPE_OTHER,                      ///< Something else that's not supported for arithmetic
     1101    PS_TYPE_C32,                        ///< Complex numbers consisting of floats
     1102    PS_TYPE_OTHER,                      ///< Not supported for arithmetic
    12201103} psElemType;
    12211104\end{verbatim}
     
    12341117    psType type;                        ///< vector data type and dimension
    12351118    const int n;                        ///< size of vector
    1236     const int nalloc;                   ///< data region relative to parent
     1119    const int nalloc;                   ///< allocated data block
    12371120    union {
    1238         psF32 *arr;                     ///< Pointers to floating-point data (default)
    1239         psS8  *arr_S8;                  ///< Pointers to short-integer data
    1240         psS16 *arr_S16;                 ///< Pointers to short-integer data
    1241         psS32 *arr_S32;                 ///< Pointers to integer data
    1242         psS64 *arr_S64;                 ///< Pointers to long-integer data
    1243         psU8  *arr_U18;                 ///< Pointers to unsigned-short-integer data
    1244         psU16 *arr_U16;                 ///< Pointers to unsigned-short-integer data
    1245         psU32 *arr_U32;                 ///< Pointers to unsigned-integer data
    1246         psU64 *arr_U64;                 ///< Pointers to unsigned-long-integer data
    1247         psF32 *arr_F32;                 ///< Pointers to floating-point data
    1248         psF64 *arr_F64;                 ///< Pointers to double-precision data
    1249         psF32 *arr_C32;                 ///< Pointers to complex floating-point data
    1250         void **arr_v;
    1251     } arr;
     1121        psS8  *S8;                      ///< Pointers to short-integer data
     1122        psS16 *S16;                     ///< Pointers to short-integer data
     1123        psS32 *S32;                     ///< Pointers to integer data
     1124        psS64 *S64;                     ///< Pointers to long-integer data
     1125        psU8  *U18;                     ///< Pointers to unsigned-short-integer data
     1126        psU16 *U16;                     ///< Pointers to unsigned-short-integer data
     1127        psU32 *U32;                     ///< Pointers to unsigned-integer data
     1128        psU64 *U64;                     ///< Pointers to unsigned-long-integer data
     1129        psF32 *F32;                     ///< Pointers to floating-point data
     1130        psF64 *F64;                     ///< Pointers to double-precision data
     1131        psF32 *C32;                     ///< Pointers to complex floating-point data
     1132        void **void;
     1133    } data;
    12521134} psVector;
    12531135\end{verbatim}
     
    12561138(the number of elements); \code{nalloc} is the number of elements
    12571139allocated ($nalloc \ge n$).  The allocated memory is available in the
    1258 union \code{arr} which consists of pointers to each of the defined
     1140union \code{data} which consists of pointers to each of the defined
    12591141primitive data types.  Note the parallelism in the names of the types,
    12601142union elements, and the psElemType names.  This parallelism allows us
    12611143to use automatic construction mechanisms effectively.  The data type
    1262 is defined by the first element, \code{psType}.  The
    1263 structure is associated with a constructor and a destructor:
     1144is defined by the first element, \code{psType}.  The structure is
     1145associated with a constructor and a destructor:
    12641146%
    12651147\begin{verbatim}
    12661148psVector *psVectorAlloc(int nalloc, psElemType type);
    12671149psVector *psVectorRealloc(const psVector *vector, int nalloc);
    1268 void psVectorFree(psVector *restrict vector);
     1150void psVectorFree(psVector *restrict vector, void (*elemFree)(void *));
    12691151\end{verbatim}
    12701152%
     
    12771159\code{nalloc} is larger than the current value of \code{psVector.n},
    12781160\code{psVector.n} is left intact.  If the value of \code{myArray} is
    1279 \code{NULL}, then \code{psVectorRealloc} must return an error.
    1280 
    1281 \subsection{Arrays of Pointer Types}
    1282 
    1283 Arrays of pointer types need some additional specification.  We
    1284 require an array of pointers of type \code{void}, with which we can
    1285 carry around a collection of data of an arbitrary type which is more
    1286 complicated than the simple numeric types above.  The structure is as
    1287 follows:
    1288 %
    1289 \begin{verbatim}
    1290 typedef struct {
    1291     psType type;                        ///< Type of data.  Must be first element
    1292     int nAlloc;                         ///< Total number of elements available
    1293     int n;                              ///< Number of elements in use
    1294     void **arr;                         ///< The array data
    1295 } psVoidPtrArray;
    1296 \end{verbatim}
    1297 %
    1298 There is also an equivalent set of constructors and destructor:
    1299 %
    1300 \begin{verbatim}
    1301 psVoidPtrArray *psVoidPtrArrayAlloc(int nAlloc);
    1302 psVoidPtrArray *psVoidPtrArrayRealloc(psVoidPtrArray *myArray, int nAlloc);
    1303 void psVoidPtrArrayFree(psVoidPtrArray *restrict myArray, void (*elemFree)(void *));
    1304 \end{verbatim}
    1305 %
    1306 The only difference with the numeric array types is the addition of a
    1307 destructor function which is passed to \code{psVoidPrtArrayFree}.
    1308 This function, which may be \code{NULL}, is called for each existing
    1309 element of the array before the array itself is freed.  If the
    1310 function is \code{NULL}, the elements are are not freed.
    1311 
    1312 The routine \code{psVoidPtrArrayFree} assumes that all pointers had
    1313 their reference counters incremented when they were inserted onto the
    1314 array.\footnote{\eg{} \code{va->arr[i] = psMemIncrRefCounter(ptr);}}
    1315 If \code{psVoidPtrArrayFree}'s argument \code{elemFree} is NULL, the
    1316 list should be deleted, but not the elements on it (an error should be
    1317 raised if the \code{refCounter} is 1; otherwise their
    1318 \code{refCounter}'s should be decremented) --- this is to account for
    1319 an array of heterogeneous types.
     1161\code{NULL}, then \code{psVectorRealloc} must return an error.  In
     1162\code{psVectorFree}, the function \code{elemFree} is required for
     1163arrays of pointer types; it is the destructor appropriate to the data
     1164pointed to by the pointers.  This function, which may be \code{NULL},
     1165is called for each existing element of the array before the array
     1166itself is freed.  If the function is \code{NULL}, the elements are are
     1167not freed.  This function must not be defined for any data type except
     1168the \code{void} pointer array.
    13201169
    13211170\subsection{Simple Images}
     
    13311180    const int x0, y0;                   ///< data region relative to parent
    13321181    union {
    1333         psF32 **rows;                   ///< Pointers to floating-point data (default)
    1334         psS8  **rows_S8;                ///< Pointers to char data
    1335         psS16 **rows_S16;               ///< Pointers to short-integer data
    1336         psS32 **rows_S32;               ///< Pointers to integer data
    1337         psS64 **rows_S64;               ///< Pointers to long-integer data
    1338         psU8  **rows_U8;                ///< Pointers to unsigned-char data
    1339         psU16 **rows_U16;               ///< Pointers to unsigned-short-integer data
    1340         psU32 **rows_U32;               ///< Pointers to unsigned-integer data
    1341         psU64 **rows_U64;               ///< Pointers to unsigned-long-integer data
    1342         psF32 **rows_F32;               ///< Pointers to floating-point data
    1343         psF64 **rows_F64;               ///< Pointers to double-precision data
    1344         psC32 **rows_C32;               ///< Pointers to complex floating-point data
    1345     } rows;
     1182        psS8  **S8;                     ///< Pointers to char data
     1183        psS16 **S16;                    ///< Pointers to short-integer data
     1184        psS32 **S32;                    ///< Pointers to integer data
     1185        psS64 **S64;                    ///< Pointers to long-integer data
     1186        psU8  **U8;                     ///< Pointers to unsigned-char data
     1187        psU16 **U16;                    ///< Pointers to unsigned-short-integer data
     1188        psU32 **U32;                    ///< Pointers to unsigned-integer data
     1189        psU64 **U64;                    ///< Pointers to unsigned-long-integer data
     1190        psF32 **F32;                    ///< Pointers to floating-point data
     1191        psF64 **F64;                    ///< Pointers to double-precision data
     1192        psC32 **C32;                    ///< Pointers to complex floating-point data
     1193    } data;
    13461194    const struct psImage *parent;       ///< parent, if a subimage
    13471195    int Nchildren;                      ///< number of subimages
    1348     struct psImage **children;          ///< children of this region; array of Nchildren pointers
     1196    struct psImage **children;          ///< children of this region (Nchildren total)
    13491197} psImage;
    13501198\end{verbatim}
     
    13661214(\code{parent}).  Unless this is image is a child of another image
    13671215(represents a subset of the pixels of another image), the image data
    1368 is allocated in a contiguous block.
    1369 
    1370 Create an image of a specified width, height, and data type.  This
    1371 function must allow any of the valid image data types and not restrict
    1372 to the valid FITS BITPIX types.
     1216is allocated in a contiguous block.  We define the following
     1217supporting functions:
     1218
    13731219\begin{verbatim}
    13741220psImage *psImageAlloc (int width, int height, psElemType type);
    13751221\end{verbatim}
    1376 where \code{width} and \code{height} specify the size of the image and
    1377 \code{type} specifies the data type and the image dimensionality
    1378 (which must be 2).
    1379 
     1222Create an image of a specified \code{width}, \code{height}, and data
     1223\code{type}.  This function must allow any of the valid image data
     1224types and not restrict to the valid FITS BITPIX types.  The image
     1225dimensionality must be 2.
     1226
     1227\begin{verbatim}
     1228void psImageFree(psImage *image);
     1229\end{verbatim}
    13801230Free the memory associated with a specific image, including the pixel
    13811231data. Free the children of the image if they exist.
    1382 \begin{verbatim}
    1383 void psImageFree(psImage *image);
    1384 \end{verbatim}
    1385 
    1386 Free only the pixels for a specified image:
    1387 \begin{verbatim}
    1388 psImage *psImageFreePixels(psImage *image);
    1389 \end{verbatim}
    13901232
    13911233\subsection{Doubly-linked lists}
     
    14051247The type \code{psDlist} represents the container of the list.  It has
    14061248a pointer to the first element in the linked list (\code{head}), a
    1407 pointer to the last element in the list (\code{tail}), \tbd{an entry
    1408 for the current cursor location (\code{iter})}, and an entry to define
    1409 the number of elements in the list (\code{n}).
     1249pointer to the last element in the list (\code{tail}), an entry for
     1250the current cursor location (\code{iter}), and an entry to define the
     1251number of elements in the list (\code{n}).
    14101252
    14111253The elements of the list are defined by the type \code{psDlistElem}:
     
    14221264(\code{next}), the previous element in the list (\code{prev}), and a
    14231265\code{void} pointer to whatever data is represented by this list
    1424 element. 
    1425 
    1426 A list may be created with the function
     1266element.    The following supporting functions are required:
     1267
    14271268\begin{verbatim}
    14281269psDlist *psDlistAlloc(void *data);
    14291270\end{verbatim}
    1430 which may take a pointer to a data item, or it may take \code{NULL}.
    1431 The allocator creates both the \code{psDlist} and the first element in
    1432 the list, pointed to by both \code{psDlist.head} and
    1433 \code{psDlist.tail}.  If the data entry is \code{NULL}, then an empty
    1434 list, with both pointers are set to \code{NULL} should be created.
    1435 
    1436 An entry may be added to the list with the function:
     1271Create a list.  This function may take a pointer to a data item, or it
     1272may take \code{NULL}.  The allocator creates both the \code{psDlist}
     1273and the first element in the list, pointed to by both
     1274\code{psDlist.head} and \code{psDlist.tail}.  If the data entry is
     1275\code{NULL}, then an empty list, with both pointers are set to
     1276\code{NULL} should be created.
     1277
    14371278\begin{verbatim}
    14381279psDlist *psDlistAdd(psDlist *list, void *data, int where);
    14391280\end{verbatim}
    1440 which takes a pointer to the list and also returns a pointer to the
    1441 list.  The returned pointer must be used as the value of
    1442 \code{psDlist} may have changed.  The value of \code{where} specifies
    1443 if the specified data item should be placed on the front of the list
    1444 (\code{PS_DLIST_HEAD}), at the end of the list (\code{PS_DLIST_TAIL}),
    1445 to add after (\code{PS_DLIST_NEXT}) or before (\code{PS_DLIST_PREV})
    1446 the current element (specified by the iteration cursor), or an index
    1447 that the new \code{data} should inhabit.
    1448 
    1449 A data item may be retrieved from the list with the function:
     1281Add an entry to the list with this function, which takes a pointer to
     1282the list and also returns a pointer to the list.  The returned pointer
     1283must be used as the value of \code{psDlist} may have changed.  The
     1284value of \code{where} specifies if the specified data item should be
     1285placed on the front of the list (\code{PS_DLIST_HEAD}), at the end of
     1286the list (\code{PS_DLIST_TAIL}), to add after (\code{PS_DLIST_NEXT})
     1287or before (\code{PS_DLIST_PREV}) the current element (specified by the
     1288iteration cursor), or an index that the new \code{data} should
     1289inhabit.
     1290
    14501291\begin{verbatim}
    14511292void *psDlistGet(psDlist *list, int which);
    14521293\end{verbatim}
    1453 The value of \code{which} may be the numerical index or it may be one
    1454 of the special values: \code{PS_DLIST_HEAD}, \code{PS_DLIST_TAIL},
     1294A data item may be retrieved from the list with this function.  The
     1295value of \code{which} may be the numerical index or it may be one of
     1296the special values: \code{PS_DLIST_HEAD}, \code{PS_DLIST_TAIL},
    14551297\code{PS_DLIST_PREV}, and \code{PS_DLIST_NEXT}, all of which are
    14561298defined as negative integers, allowing \code{where} to also be the
    14571299index of one of the data items.
    14581300
    1459 A data item may be removed from the list with the function:
    14601301\begin{verbatim}
    14611302void *psDlistRemove(psDlist *list, void *data, int which);
    14621303\end{verbatim}
    1463 The value of \code{which} may be the numerical index or it may be one
    1464 of the special values: \code{PS_DLIST_HEAD}, \code{PS_DLIST_TAIL},
     1304A data item may be removed from the list with this function.  The
     1305value of \code{which} may be the numerical index or it may be one of
     1306the special values: \code{PS_DLIST_HEAD}, \code{PS_DLIST_TAIL},
    14651307\code{PS_DLIST_PREV}, \code{PS_DLIST_UNKNOWN}, and
    14661308\code{PS_DLIST_NEXT}, all of which are defined as negative integers.
    14671309If the value of \code{which} is \code{PS_DLIST_UNKNOWN}, then the data
    1468 item is identified by matching the pointer value with \code{void *data}.
    1469 
    1470 All data items placed onto lists (\code{psDlistAdd}) shall have their
     1310item is identified by matching the pointer value with \code{void
     1311*data}.
     1312
     1313All data items placed onto lists (\code{psDlistAdd}) must have their
    14711314reference counters (section \ref{secMemRefcounter}) incremented.  When
    1472 elements are removed from a list with \code{psDlistRemove}, they shall
     1315elements are removed from a list with \code{psDlistRemove}, they must
    14731316have their reference counters decremented. The action of retrieving
    1474 data from a list (with \code{psDlistGet}) shall not affect their
     1317data from a list (with \code{psDlistGet}) must not affect their
    14751318reference counter.
    14761319
    1477 A complete list may be freed with the destructor:
    14781320\begin{verbatim}
    14791321void psDlistFree(psDlist *list, void (*elemFree)(void *));
    14801322\end{verbatim}
    1481 If the element destructor (\code{elemFree}) is \code{NULL}, the list
    1482 should be deleted, but not the elements, although their
    1483 \code{refcounter}s should be decremented.
    1484 
    1485 Two functions are available to convert between the \code{psDlist} and
    1486 \code{psVoidPtrArray} containers:
    1487 \begin{verbatim}
    1488 psVoidPtrArray *psDlistToArray(psDlist *dlist);
    1489 psDlist *psArrayToDlist(psVoidPtrArray *arr);
    1490 \end{verbatim}
    1491 These functions do not free the elements or destroy the input
    1492 collection.  Rather, they increment the reference counter for each of
    1493 the elements.
    1494 
    1495 Iteration over all elements of the list using the iteration cursor
    1496 \code{iter} is provided by the functions:
     1323A complete list may be freed with this destructor.  If the element
     1324destructor (\code{elemFree}) is \code{NULL}, the list should be
     1325deleted, but not the elements, although their \code{refcounter}s
     1326should be decremented.
     1327
     1328\begin{verbatim}
     1329psVector *psDlistToVector(psDlist *dlist);
     1330psDlist *psVectorToDlist(psVector *vector);
     1331\end{verbatim}
     1332These two functions are available to convert between the
     1333\code{psDlist} and \code{psVector} containers.  These functions do not
     1334free the elements or destroy the input collection.  Rather, they
     1335increment the reference counter for each of the elements.
     1336
    14971337\begin{verbatim}
    14981338void psDlistSetIterator(psDlist *list, int where, int which);
     
    15001340void *psDlistGetPrev(psDlist *list, int which);
    15011341\end{verbatim}
    1502 The first of these functions uses the value of \code{where} to set the
    1503 iteration cursor for the given list to the beginning
    1504 \code{PS_DLIST_HEAD} or the end \code{PS_DLIST_TAIL} for the iterator
    1505 specified by \code{which}.  The next two functions move the iteration
    1506 cursor forward or backwards, returning the data item from the
    1507 resulting list entry, or returning \code{NULL} at the end of the list.
    1508 Explicit traversal of the list using the \code{psDlistElem}s
    1509 \code{prev} and \code{next} pointers is also supported.
    1510 
     1342Iteration over all elements of the list using the iteration cursor
     1343\code{iter} is provided by these functions.  The first of these
     1344functions uses the value of \code{where} to set the iteration cursor
     1345for the given list to the beginning \code{PS_DLIST_HEAD} or the end
     1346\code{PS_DLIST_TAIL} for the iterator specified by \code{which}.  The
     1347next two functions move the iteration cursor forward or backwards,
     1348returning the data item from the resulting list entry, or returning
     1349\code{NULL} at the end of the list.  Explicit traversal of the list
     1350using the \code{psDlistElem}s \code{prev} and \code{next} pointers is
     1351also supported.
     1352
     1353\begin{verbatim}
     1354psDlist *psDlistSort(psDlist *list, int (*compare)(const void *a, const void *b) );
     1355\end{verbatim}
    15111356A list may be sorted using \code{psDlistSort}, which requires the
    15121357specification of a comparison function to specify how the objects on
    15131358the list should be sorted.  The motivation is primarily to be able to
    15141359iterate on a sorted list of keys from a hash.
    1515 \begin{verbatim}
    1516 psDlist *psDlistSort(psDlist *list, int (*compare)(const void *a, const void *b) );
    1517 \end{verbatim}
    15181360
    15191361\subsection{Hash Tables}
     
    16141456\section{Data manipulation}
    16151457
    1616 There are a number of data concepts which can be naturally represented
    1617 in C as structures.  We require a variety of basic data manipulation
    1618 functions which will act upon data (in particular, arrays/vectors).
    1619 We require the following capabilities:
     1458We require a variety of basic data manipulation functions which will
     1459act upon data (in particular, arrays/vectors).  We require the
     1460following capabilities:
    16201461\begin{itemize}
    16211462\item Bit masks;
     
    16331474\subsection{Bitsets}
    16341475
    1635 Bitsets are required in order to turn options on and off.  We
    1636 require the capability to have a bitset of arbitrary length (i.e.,
    1637 not limited by the length of a \code{long}, say).  The
    1638 \code{psBitset} structure is defined below.  Note that the entry
    1639 \code{bits} is an array of type \code{char} storing the bits as bits
    1640 of each byte in the array, with 8 bits available for each byte in the
    1641 array.  Also note that the constructor is passed the number of
    1642 required bits, which implies that \code{ceil(n / 8)} bytes must be
    1643 allocated.  The bitset structure is define by:
     1476Bitsets are required in order to turn options on and off.  We require
     1477the capability to have a bitset of arbitrary length (i.e., not limited
     1478by the length of a \code{long}, say).  The \code{psBitset} structure
     1479is defined below.  Note that the entry \code{bits} is an array of type
     1480\code{char} storing the bits as bits of each byte in the array, with 8
     1481bits available for each byte in the array.  Also note that the
     1482constructor is passed the number of required bits, which implies that
     1483\code{ceil(n/8)} bytes must be allocated.  The bitset structure is
     1484define by:
    16441485\begin{verbatim}
    16451486typedef struct {
     
    16561497where \code{n} is the requested number of bits.
    16571498
    1658 Four basic operations on bitsets are required:
     1499Several basic operations on bitsets are required:
    16591500\begin{itemize}
    16601501\item Set a bit;
    16611502\item Check if a bit is set; and
    16621503\item \code{OR}, \code{AND} and \code{XOR} two bitsets.
     1504\item \code{NOT} a bitset.
    16631505\end{itemize}
    16641506The corresponding APIs are defined below:
     
    16951537\subsection{Sorting}
    16961538
    1697 We require the ability to sort an array of floating-point values.  The
    1698 following function returns the array, sorted from the smallest (i.e.\
    1699 most negative) value in the first element, and the largest (i.e.\ most
    1700 positive) value in the last element.  The input array, \code{in}, may
    1701 be sorted in-place if it is also specified as the \code{out}
    1702 array. This function is specified for input types \code{psU8, psU16,
    1703 psF32, psF64}.  The input and output vectors must have the same type.
     1539We require the ability to sort a vector.  The following function
     1540returns the vector, sorted from the smallest (i.e.\ most negative)
     1541value in the first element, and the largest (i.e.\ most positive)
     1542value in the last element.  The input vector, \code{in}, may be sorted
     1543in-place if it is also specified as the \code{out} vector. This
     1544function is specified for input types \code{psU8, psU16, psF32,
     1545psF64}.  The input and output vectors must have the same type.
    17041546
    17051547\begin{verbatim}
     
    17071549\end{verbatim}
    17081550
    1709 We also require the ability to sort one array based on another.  For
     1551We also require the ability to sort one vector based on another.  For
    17101552example, we may want to sort both \code{x} and \code{y} by the value
    17111553in \code{x}.  In order to facilitate this, we will have a sort
    1712 function return an array containing the indices for the unsorted list
    1713 in the order appropriate for the sorted array.  The output vector must
     1554function return a vector containing the indices for the unsorted list
     1555in the order appropriate for the sorted vector.  The output vector must
    17141556be of type \code{psU32}.  This function is specified for input types
    17151557\code{psU8, psU16, psF32, psF64}.
     
    17191561\end{verbatim}
    17201562
    1721 The sorted arrays may be accessed in the following manner:
    1722 \begin{verbatim}
    1723 indexArray = psSortIndex(NULL, x);
    1724 for (int i = 0; i < indexArray.n; i++) {
    1725     doMyFunc(x[indexArray.arr.arr_U32[i]], y[indexArray[i].arr.arr_U32]);
     1563The sorted vectors may be accessed in the following manner:
     1564\begin{verbatim}
     1565indexVector = psSortIndex(NULL, x);
     1566for (int i = 0; i < indexVector.n; i++) {
     1567    doMyFunc(x[indexVector.arr.arr_U32[i]], y[indexVector[i].arr.arr_U32]);
    17261568}
    17271569\end{verbatim}
     
    17311573\subsection{Statistics Functions}
    17321574
    1733 \subsubsection{Array Statistics}
    1734 
    1735 We require a very general statistics function, which, given an array
     1575\subsubsection{Vector Statistics}
     1576
     1577We require a very general statistics function, which, given a vector
    17361578of floating-point values, will be able to calculate the following
    17371579statistics:
     
    17481590\item Clipped mean and number of values used to calculate;
    17491591\item Clipped standard deviation; and
    1750 \item Minimum and maximum value in array.
     1592\item Minimum and maximum value in vector.
    17511593\end{itemize}
    17521594
    17531595For definitions of each of these, see the accompanying Algorithms
    17541596Definition Document (ADD), but in general, ``sample'' refers to the
    1755 entire array, ``robust'' refers to fitting the distribution in the
    1756 array with a model, and ``clipped'' refers to clipping the
    1757 distribution.  Each of these shall be available from a single
     1597entire vector, ``robust'' refers to fitting the distribution in the
     1598vector with a model, and ``clipped'' refers to clipping the
     1599distribution.  Each of these must be available from a single
    17581600function:
    17591601
    17601602\begin{verbatim}
    1761 psStats *psArrayStats(const psVector *restrict in,
    1762                       const psVector *restrict mask,
    1763                       unsigned int maskVal,
    1764                       psStats *stats);
     1603psStats *psVectorStats(const psVector *restrict in,
     1604                       const psVector *restrict mask,
     1605                       unsigned int maskVal,
     1606                       psStats *stats);
    17651607\end{verbatim}
    17661608%
     
    17681610in \code{mask}, so that the user may explicitly reject specific
    17691611entries) and a \code{psStats} structure, which will be altered and
    1770 returned.  The input vector may be of type \code{psU8}, \code{psU16},
    1771 \code{psF32}, \code{psF64}; the mask must be of type \code{psU8}.
     1612returned.  The \code{psStats} structure includes several fields which
     1613are used for both input and output: \code{min} and \code{max} may be
     1614used to specify a value range for which the statistics are calculated.
     1615\code{binsize} specifies a choice for the robust statistics histogram
     1616bin size.  If these are to be used, the user should set the
     1617corresponding \code{options} bits \code{PS_STAT_USE_RANGE} or
     1618\code{PS_STAT_USE_BINSIZE}.  \code{clipSigma} specifies the number of
     1619standard deviations for which data should be clipped.  \code{clipIter}
     1620specifies the number of iterations which should be used for clipping.
     1621The defaults for these two numbers is both 3.  Since the sample
     1622statistics scale like $N\log N$, for large numbers of input data
     1623points, it is faster to use the robust statistics.  If the number of
     1624data points is large, \code{psStats} must revert to the robust
     1625calculation even if the user requested sample statistics.  The values
     1626should be returned in the \code{sample} fields, but the bit
     1627\code{PS_STAT_ROBUST_FOR_SAMPLE} in \code{options} must be set in this
     1628case.  The cutoff for this decision must be made on the basis of the
     1629value in \code{sampleLimit},which should have a default of \tbd{3e5}.
     1630Default input field values must be set by the \code{psStats}
     1631constructor.  The input vector may be of type \code{psU8},
     1632\code{psU16}, \code{psF32}, \code{psF64}; the mask must be of type
     1633\code{psU8}.
    17721634
    17731635The \code{psStats} structure is defined with entries for each of the
     
    17821644    double sampleUQ;                    ///< upper quartile of sample
    17831645    double sampleLQ;                    ///< lower quartile of sample
     1646    double sampleLimit;                 ///< Number of datapoints to
    17841647    double robustMean;                  ///< robust mean of data
    1785     int    robustMeanNvalues;           ///< number of measurements used for robust mean
    17861648    double robustMedian;                ///< robust median of data
    1787     int    robustMedianNvalues;         ///< number of measurements used for robust median
    17881649    double robustMode;                  ///< Robust mode of data
    1789     int    robustModeNvalues;           ///< Number of measurements used for robust mode
    17901650    double robustStdev;                 ///< robust standard deviation of data
    17911651    double robustUQ;                    ///< robust upper quartile
    17921652    double robustLQ;                    ///< robust lower quartile
     1653    int    robustN50;                   ///< Number of points UQ-LQ
     1654    int    robustNfit;                  ///< Number of points in Gauss. fit
    17931655    double clippedMean;                 ///< Nsigma clipped mean
    1794     int    clippedMeanNvalues;          ///< number of data points used for clipped mean
    17951656    double clippedStdev;                ///< standard deviation after clipping
     1657    int    clippedNvalues;              ///< number of data points used for clipped mean
    17961658    double clipSigma;                   ///< Nsigma used for clipping; user input
    17971659    int    clipIter;                    ///< Number of clipping iterations; user input
    1798     double min;                         ///< minimum data value in data
    1799     double max;                         ///< maximum data value in data
    1800     int    nValues;                     ///< number of data values in data
     1660    double min;                         ///< minimum data value in data; input range
     1661    double max;                         ///< maximum data value in data; input range
     1662    double binsize;                     ///< binsize for robust fit (input/output)
    18011663    psStatsOptions options;             ///< bitmask of calculated values
    18021664} psStats;
     
    18111673    PS_STAT_SAMPLE_MEDIAN         = 0x000002,
    18121674    PS_STAT_SAMPLE_STDEV          = 0x000004,
    1813     PS_STAT_SAMPLE_UQ             = 0x000008,
    1814     PS_STAT_SAMPLE_LQ             = 0x000010,
    1815     PS_STAT_ROBUST_MEAN           = 0x000020,
    1816     PS_STAT_ROBUST_MEAN_NVALUES   = 0x000040,
    1817     PS_STAT_ROBUST_MEDIAN         = 0x000080,
    1818     PS_STAT_ROBUST_MEDIAN_NVALUES = 0x000100,
    1819     PS_STAT_ROBUST_MODE           = 0x000200,
    1820     PS_STAT_ROBUST_MODE_NVALUES   = 0x000400,
    1821     PS_STAT_ROBUST_STDEV          = 0x000800,
    1822     PS_STAT_ROBUST_UQ             = 0x001000,
    1823     PS_STAT_ROBUST_LQ             = 0x002000,
    1824     PS_STAT_CLIPPED_MEAN          = 0x004000,
    1825     PS_STAT_CLIPPED_MEAN_NVALUES  = 0x008000,
    1826     PS_STAT_CLIPPED_MEAN_NSIGMA   = 0x010000,
    1827     PS_STAT_CLIPPED_STDEV         = 0x020000,
    1828     PS_STAT_MAX                   = 0x040000,     
    1829     PS_STAT_MIN                   = 0x080000,
    1830     PS_STAT_NVALUES               = 0x100000
     1675    PS_STAT_SAMPLE_QUARTILE       = 0x000008,
     1676    PS_STAT_ROBUST_MEAN           = 0x000010,
     1677    PS_STAT_ROBUST_MEDIAN         = 0x000020,
     1678    PS_STAT_ROBUST_MODE           = 0x000040,
     1679    PS_STAT_ROBUST_STDEV          = 0x000080,
     1680    PS_STAT_ROBUST_QUARTILE       = 0x000100,
     1681    PS_STAT_CLIPPED_MEAN          = 0x000200,
     1682    PS_STAT_CLIPPED_STDEV         = 0x000400,
     1683    PS_STAT_MAX                   = 0x000800,     
     1684    PS_STAT_MIN                   = 0x001000,
     1685    PS_STAT_USE_RANGE             = 0x002000,
     1686    PS_STAT_USE_BINSIZE           = 0x004000
     1687    PS_STAT_ROBUST_FOR_SAMPLE     = 0x008000
    18311688} psStatsOptions;                         
    18321689\end{verbatim}
     
    18491706    const psVector *restrict bounds;    ///< Bounds for the bins
    18501707    psVector *nums;                     ///< Number in each of the bins
    1851     int minNum, maxNum;                 ///< Number below the minimum and above the maximum
     1708    int minNum, maxNum;                 ///< Number below minimum / above maximum
    18521709    int uniform;                        ///< Is it a uniform distribution?
    18531710} psHistogram;
     
    18951752\end{verbatim}
    18961753The input vector may be of types \code{psU8, psU16, psF32, psF64}.
     1754
     1755%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     1756
     1757\subsection{Analytical functions}
     1758
     1759\subsubsection{General Polynomials}
     1760
     1761PSLib provides APIs to represent and interact with polynomials in up
     1762to four dimensions, with both floating-point and double-precision
     1763numbers.  In Pan-STARRS processing, the astrometry requirements push
     1764the need for at least four dimensions ($x$,$y$, color and magnitude)
     1765and double-precision (for milli-arcsec precision) versions.  We must
     1766also be able to calculate the errors in the fit coefficients, as well
     1767as be able to turn on and off each coefficient.  This leads us to
     1768define the following polynomial types:
     1769
     1770\begin{verbatim}
     1771/** One-dimensional polynomial */
     1772typedef struct {
     1773    int n;                              ///< Number of terms
     1774    float *restrict coeff;              ///< Coefficients
     1775    float *restrict coeffErr;           ///< Error in coefficients
     1776    char *restrict mask;                ///< Coefficient mask
     1777} psPolynomial1D;
     1778\end{verbatim}
     1779
     1780\begin{verbatim}
     1781/** Two-dimensional polynomial */
     1782typedef struct {
     1783    int nX, nY;                         ///< Number of terms in x and y
     1784    float *restrict *restrict coeff;    ///< Coefficients
     1785    float *restrict *restrict coeffErr; ///< Error in coefficients
     1786    char *restrict *restrict mask;      ///< Coefficients mask
     1787} psPolynomial2D;
     1788\end{verbatim}
     1789
     1790etc., up to four dimensions.  We also define double-precision versions:
     1791
     1792\begin{verbatim}
     1793/** Double-precision one-dimensional polynomial */
     1794typedef struct {
     1795    int n;                              ///< Number of terms
     1796    double *restrict coeff;             ///< Coefficients
     1797    double *restrict coeffErr;          ///< Error in coefficients
     1798    char *restrict mask;                ///< Coefficient mask
     1799} psDPolynomial1D;
     1800\end{verbatim}
     1801
     1802\begin{verbatim}
     1803/** Double-precision two-dimensional polynomial */
     1804typedef struct {
     1805    int nX, nY;                         ///< Number of terms in x and y
     1806    double *restrict *restrict coeff;   ///< Coefficients
     1807    double *restrict *restrict coeffErr; ///< Error in coefficients
     1808    char *restrict *restrict mask;      ///< Coefficients mask
     1809} psDPolynomial2D;
     1810\end{verbatim}
     1811
     1812etc.  In what follows, we only show the version for double-precision
     1813two-dimensionals; the others may be inferred following the standard
     1814naming convention exampled above.
     1815
     1816The constructor and destructor are:
     1817\begin{verbatim}
     1818psDPolynomial2D *psDPolynomial2DAlloc(int nX, int nY);
     1819void psDPolynomial2DFree(psDPolynomial2D *restrict myPoly);
     1820\end{verbatim}
     1821where \code{nX} and \code{nY} are the number of terms in x and y
     1822respectively.  The coefficients and errors are set initially to 0.0.
     1823
     1824To evaluate the polynomials at specific coordinates, we define:
     1825\begin{verbatim}
     1826double psDPolynomial2DEval(double x, double y, const psDPolynomial2D *restrict myPoly);
     1827\end{verbatim}
     1828
     1829\subsubsection{Gaussians}
     1830
     1831Gaussians are used extensively in any data-analysis system, in
     1832particular to represent a real population distribution.  We require
     1833a function to evaluate a Gaussian for a given coordinate and one which
     1834generates a Gaussian deviate; a collection of data points whose
     1835distribution obeys a specified Gaussian. 
     1836
     1837The Gaussian evaluation is provide by:
     1838\begin{verbatim}
     1839float psGaussian(float x, float mean, float sigma, int normal);
     1840\end{verbatim}
     1841which evaluates a Gaussian with the given \code{mean} and \code{sigma}
     1842at the given coordinate \code{x}.  If \code{normal} is true, the
     1843Gaussian is normalized (total integral = 1), otherwise, the Gaussian
     1844is non-normalized (central peak value = 1).  The evaluated Gaussian
     1845is:
     1846
     1847\[ \frac{1}{\sqrt{2\pi\sigma^2}} exp^{-\frac{(x-mean)^2}{2\sigma^2}} \]
     1848
     1849In the case of the non-normalized Gaussian, the leading coefficient is
     1850dropped.
     1851
     1852A vector with a specified Gaussian deviate distribution is provide by:
     1853\begin{verbatim}
     1854psVector *psGaussianDev(float mean, float sigma, int Npts);
     1855\end{verbatim}
     1856which generates a vector (type \code{psF32}) of \code{Npts} elements
     1857whose distribution has the given \code{mean} and \code{sigma}.
     1858
     1859%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     1860
     1861\subsection{Minimization and fitting routines}
     1862
     1863We require a general minimization routine, a routine that will
     1864specifically minimize $\chi^2$ given a list of data with associated
     1865errors, and a function that will analytically determine the best
     1866polynomial fit by minimizing $\chi^2$. 
     1867
     1868Consider a function \code{myFunction} which is a function of a
     1869collection of parameters \code{params} and coordiate vector
     1870\code{coord}, and returns a single floating point value.  We define
     1871\code{psMinimize}, which determines the parameters of
     1872\code{myFunction} which minimize the function for the coordinate
     1873\code{coord}.  The returned vector must be the same length as the
     1874vector argument to the input function.
     1875\begin{verbatim}
     1876float myFunction (psVector *params, psVector *coord);
     1877float myFuncDeriv (psVector *params, psVector *coord);
     1878psVector *psMinimize(psVector *restrict initialGuess,
     1879                     float (*myFunction)(psVector *, psVector *),
     1880                     float (*myFuncDeriv)(psVector *, psVector *),
     1881                     const psVector *restrict coord,
     1882                     const psVector *restrict paramMask);
     1883\end{verbatim}
     1884\code{psMinimize} determines and returns the vector that minimizes the
     1885specified function.  It takes as input a function, \code{myFunction},
     1886an initial guess for the vector that minimizes the function,
     1887\code{initialGuess}, the current coordiate \code{coord}, and an
     1888optional mask for the vector elements (function parameters) to
     1889minimize, \code{paramMask} (all parameters are fit if \code{NULL}).
     1890Note that \code{paramMask} must be of type \code{psU8}, while
     1891\code{params} must be of type \code{psF32}.  The optional function,
     1892\code{myFuncDeriv} returns the derivative of the function.
     1893
     1894\begin{verbatim}
     1895psVector *psMinimizeChi2(psVector *restrict initialGuess,
     1896                         float (*evalModel)(psVector *, psVector *),
     1897                         const psVector *restrict domain,
     1898                         const psVector *restrict data,
     1899                         const psVector *restrict errors,
     1900                         const psVector *restrict paramMask,
     1901                         float *ChiSq);
     1902\end{verbatim}
     1903\code{psMinimizeChi2} fits a model to observations by minimizing
     1904$\chi^2$, returing the best-fit parameters.  The input parameters are
     1905a function that evaluates the model for a specified domain, given the
     1906parameters, \code{evalModel}; a list of observations, (\code{domain},
     1907\code{data}, and \code{errors}); an initial guess at the best-fit
     1908parameters, \code{initialGuess} which is returned with the best-fit
     1909parameters, and an optional mask specifying which parameters are to be
     1910fit, \code{paramMask}, which must be of type \code{psU8}.  All
     1911parameters are fit if this vector is \code{NULL}.
     1912
     1913\begin{verbatim}
     1914psPolynomial1D *psVectorFitPolynomial1D(psPolynomial1D myPoly,
     1915                                     const psVector *restrict x,
     1916                                     const psVector *restrict y,
     1917                                     const psVector *restrict yErr);
     1918\end{verbatim}
     1919\code{psVectorFitPolynomial} returns the polynomial that best fits the
     1920observations.  The input parameters are a polynomial that specifies
     1921the fit order, \code{myPoly}, which will be altered and returned with
     1922the best-fit coefficients; and the observations, \code{x}, \code{y}
     1923and \code{yErr}.  The independent variable list, \code{x} may be
     1924\code{NULL}, in which case the vector index is used.  The dependent
     1925variable error, \code{yErr} may be null, in which case the solution is
     1926determined in the assumption that all data errors are equal.  This
     1927function must be valid for types \code{psU8}, \code{psU16},
     1928\code{psF32}, \code{psF64}.
     1929
     1930%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     1931
     1932\subsection{Image Operations}
     1933
     1934We require a variety of functions to manipulate these image
     1935structures, including creation, destruction, input, output, and
     1936various manipulations of the pixels.  The required functions are
     1937listed below, and fall into several categories.
     1938
     1939\subsubsection{Image Structure Manipulation}
     1940
     1941\begin{verbatim}
     1942psImage *psImageSubset(const psImage *image, int nx, int ny, int x0, int y0);
     1943\end{verbatim}
     1944Define a subimage of the specified area of the given image.  This
     1945function must return an error if the requested subset area lies
     1946outside of the parent image.  The argument \code{image} is the parent
     1947image, \code{nx,ny} specify the dimensions of the desired subraster,
     1948and \code{x0, y0} specify the starting pixel of the subraster.  The
     1949entire subraster must be contained within the raster of the parent
     1950image.  Note that the \code{refCounter} for the parent should be
     1951incremented.  This function must be defined for the following types:
     1952\code{psU8}, \code{psU16}, \code{psS8}, \code{psS16}, \code{psF32},
     1953\code{psF64}, \code{psC32}, \code{psC64}.
     1954
     1955\begin{verbatim}
     1956psImage *psImageCopy(psImage *output, const psImage *input, psElemType type);
     1957\end{verbatim}
     1958Create a copy of the specified image, converting the type in the
     1959process.  If the output target pointer is not NULL, place the result
     1960in the specified structure.  The output image data must be allocated
     1961as a single, contiguous block of memory.  The output image may not be
     1962the input image.  This function must be defined for the following
     1963types: \code{psU8}, \code{psU16}, \code{psS8}, \code{psS16},
     1964\code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
     1965
     1966\subsubsection{Image Pixel Extractions}
     1967
     1968\begin{verbatim}
     1969psVector *psImageSlice(psVector *out, const psImage *input,
     1970                       int x, int y, int nx, int ny,
     1971                       int direction, const psStats *stats);
     1972\end{verbatim}
     1973Extract pixels from rectlinear region to a vector (array of floats).
     1974The output vector contains either \code{nx} or \code{ny} elements,
     1975based on the value of the direction: e.g., if \code{direction} is
     1976\tbd{+x}, there are \code{nx} elements.  The input region is collapsed
     1977in the perpendicular direction, and each element of the output vectors
     1978is derived from the statistics of the pixels at that direction
     1979coordinate.  The statistic used to derive the output vector value is
     1980specified by \code{stats}.  This function must be defined for the
     1981following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
     1982
     1983\begin{verbatim}
     1984psVector *psImageCut(psVector *out, const psImage *input,
     1985                     float xs, float ys, float xe, float ye,
     1986                     float dw, const psStats *stats);
     1987\end{verbatim}
     1988Extract pixels from an image along a line to a vector (array of
     1989floats).  The vector \code{(xs,ys)} - \code{(xe,ye)} forms the basis of
     1990the output vector.  Pixels are considered in a rectangular region of
     1991width \code{dw} about this vector.  The input region is collapsed in
     1992the perpendicular direction, and each element of the output vector
     1993represents pixel-sized boxes, where the value is derived from the
     1994statistics of the pixels interpolated along the perpendicular
     1995direction.  The statistic used to derive the output vector value is
     1996specified by \code{stats}.  This function must be defined for the
     1997following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}
     1998
     1999\begin{verbatim}
     2000psVector *psImageRadialCut(psVector *out, const psImage *input, float x, float y,
     2001                           const psVector *radii, const psStats *stats);
     2002\end{verbatim}
     2003Extract radial annuli data to a vector.  A vector is constructed where
     2004each vector elements is derived from the statistics of the pixels
     2005which land in one of a sequence of annuli.  The annuli are centered on
     2006the image pixel coordinate \code{x,y}, and have width \code{dr}.  The
     2007number of annuli is $radius / dr$.  The statistic used to derive the
     2008output vector value is specified by \code{stats}.  This function must be defined for the
     2009following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
     2010
     2011\subsubsection{Image Geometry Manipulation}
     2012
     2013\begin{verbatim}
     2014psImage *psImageRebin(psImage *out, const psImage *in,
     2015                      float scale, const psStats *stats);
     2016\end{verbatim}
     2017Rebin image to new scale.  A new image is constructed in which the
     2018dimensions are reduced by a factor of \code{scale} $\le 1$ (it is an
     2019error for \code{scale} $> 1$).  The \code{scale} is equal in each
     2020dimension.  The output image is generated from all input image pixels.
     2021Each pixel in the output image is derived from the statistics of the
     2022corresponding set of input image pixels based on the statistics
     2023specified by \code{stats}.  This function must be defined for the
     2024following types: \code{psU8}, \code{psU16}, \code{psS8}, \code{psS16},
     2025\code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
     2026
     2027\begin{verbatim}
     2028psImage *psImageRotate(psImage *out, const psImage *input, float angle);
     2029\end{verbatim}
     2030Rotate the input image by given angle, specified in degrees.  The
     2031output image must contain all of the pixels from the input image in
     2032their new frame.  Pixels in the output image which do not map to input
     2033pixels should be set to \tbd{value}.  The center of rotation is always
     2034the center pixel of the image.  The rotation is specified in the sense
     2035that a positive angle is an anti-clockwise rotation.  This function
     2036must be defined for the following types: \code{psU8}, \code{psU16},
     2037\code{psS8}, \code{psS16}, \code{psF32}, \code{psF64}, \code{psC32},
     2038\code{psC64}.
     2039
     2040\begin{verbatim}
     2041psImage *psImageShift(psImage *out, const psImage *input,
     2042                      float dx, float dy, float exposed);
     2043\end{verbatim}
     2044Shift image by an arbitrary number of pixels (\code{dx,dy}) in either
     2045direction.  If the shift values are fractional, the output pixel
     2046values should interpolate between the input pixel values.  The output
     2047image has the same dimensions as the input image.  Pixels which fall
     2048off the edge of the output image are lost.  Newly exposed pixels are
     2049set to the value given by \code{exposed}.  This function must be
     2050defined for the following types: \code{psU8}, \code{psU16},
     2051\code{psS8}, \code{psS16}, \code{psF32}, \code{psF64}, \code{psC32},
     2052\code{psC64}.
     2053
     2054\begin{verbatim}
     2055psImage *psImageRoll(psImage *out, const psImage *input, int dx, int dy);
     2056\end{verbatim}
     2057Roll image by an integer number of pixels (\code{dx,dy}) in either
     2058direction.  The output image is the same dimensions as the input
     2059image.  Edge pixels wrap to the other side (no values are lost).  This
     2060function must be defined for the following types: \code{psU8},
     2061\code{psU16}, \code{psS8}, \code{psS16}, \code{psF32}, \code{psF64},
     2062\code{psC32}, \code{psC64}.
     2063
     2064\subsubsection{Image Statistical Functions}
     2065
     2066\begin{verbatim}
     2067psStats *psImageGetStats(psStats *stats, const psImage *input);
     2068\end{verbatim}
     2069Determine statistics for image (or subimage).  The statistics to be
     2070determined are specified by \code{stats}.  This function must be
     2071defined for the following types: \code{psU8}, \code{psU16},
     2072\code{psF32}, \code{psF64}.
     2073
     2074\begin{verbatim}
     2075psHistogram *psImageHistogram(psHistogram *hist, const psImage *input);
     2076\end{verbatim}
     2077Construct a histogram from an image (or subimage).  The histogram to
     2078generate is specified by \code{psHistogram hist} (see
     2079section~\ref{sec:histograms}).  This function must be defined for the
     2080following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
     2081
     2082\begin{verbatim}
     2083psPolynomial2D *psImageFitPolynomial(psPolynomial2D *coeffs, const psImage *input);
     2084\end{verbatim}
     2085Fit a 2-D Chebychev polynomial surface to an image.  The input
     2086structure \code{coeffs} contains the desired order and terms of
     2087interest.  This function must be defined for the
     2088following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
     2089
     2090\begin{verbatim}
     2091psImage *psImageEvalPolynomial(psImage *input, const psPolynomial2D *coeffs);
     2092\end{verbatim}
     2093Evaluate a 2-D polynomial surface for the image pixels.  Given the
     2094input polynomial coefficients, set the image pixel values on the basis
     2095of the polynomial function.  This function must be defined for the
     2096following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
     2097
     2098\subsubsection{Image I/O Functions}
     2099
     2100\begin{verbatim}
     2101psImage *psImageReadSection(psImage *output, int x0, int y0, int nx, int ny, int z,
     2102                            const char *extname, int extnum, const char *filename);
     2103\end{verbatim}
     2104Read an image or subimage from a named file.  This function is a
     2105wrapper to the FITS library function.  The input parameters allow a
     2106full image or a subimage to be read.  The starting pixel of the region
     2107is specified by \code{x,y}, while the dimensions of the requested
     2108region are specified by \code{nx,ny}.  A negative value of -1 for
     2109these two parameters specifies the full array of the requested image,
     2110less absolute value of the variable.  If the native image is a cube,
     2111the value of z specifies the requested slice of the image.  The data
     2112is read from the extension specified by extname (matching the EXTNAME
     2113keyword) or by the extnum value (with 0 representing the PHU, 1 the
     2114first extension, etc).  This function must call \code{psError} and
     2115return \code{NULL} if any of the specified parameters are out of range
     2116for the data in the image file, if the specified image file does not
     2117exist, or the image on disk is zero- or one-dimensional.
     2118 
     2119\begin{verbatim}
     2120psImage *psImageFReadSection(psImage *output, int x, int y, int nx, int ny, int z,
     2121                             const char *extname, int extnum, FILE *f);
     2122\end{verbatim}
     2123Read an image or subimage from file descriptor.  The input parameters
     2124and their behavior for this function are identical with those in
     2125\code{psImageReadSection}.
     2126
     2127\begin{verbatim}
     2128psImage *psImageWriteSection(const psImage *input, int x, int y, int z,
     2129                             const char *extname, int extnum, const char *filename);
     2130\end{verbatim}
     2131Write an image section to the named file, which may exist.  This
     2132operation may write a portion of an image over the existing bytes of
     2133an existing image.  If the file does not exist, it should be created.
     2134If the specified extension does not exist, it should be created.  If
     2135an extension is specified and no PHU exists, a basic PHU should be
     2136created.
     2137
     2138\begin{verbatim}
     2139psImage *psImageFWriteSection(const psImage *input, int x, int y, int z,
     2140                              const char *extname, int extnum, FILE *f);
     2141\end{verbatim}
     2142Write an image section to file descriptor as above:
     2143
     2144\subsubsection{Image Pixel Manipulations}
     2145
     2146\begin{verbatim}
     2147int psImageClip(psImage *input, float min, float vmin, float max, float vmax);
     2148\end{verbatim}
     2149Clip image values outside of range to given values.  All pixels with
     2150values \code{< min} are set to the value \code{vmin}. All pixels with
     2151values \code{> max} are set to the value \code{vmax}. Returns the
     2152number of clipped pixels.  This function must be defined for the
     2153following types: \code{psU8}, \code{psU16}, \code{psS8}, \code{psS16},
     2154\code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
     2155
     2156\begin{verbatim}
     2157int psImageClipNaN(psImage *input, float value);
     2158\end{verbatim}
     2159Clip \code{NaN} image pixels to given value.  Pixels with \code{NaN},
     2160\code{+Inf} or \code{-Inf} values are set to the specified value.
     2161Returns the number of clipped pixels.  This function must be defined
     2162for the following types: \code{psU8}, \code{psU16}, \code{psS8},
     2163\code{psS16}, \code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
     2164
     2165\begin{verbatim}
     2166int psImageOverlaySection(psImage *image, const psImage *overlay,
     2167                          int x0, int y0, const char *op);
     2168\end{verbatim}
     2169Overlay subregion of image with another image.  Replace the pixels in
     2170the \code{image} which correspond to the pixels in \code{overlay} with
     2171values derived from the values in \code{image} and \code{overlay}
     2172based on the given operator \code{op}.  Valid operators are \code{=}
     2173(set image value to overlay value), \code{+} (add overlay value to
     2174image value), \code{-} (subtract overlay from image), \code{*}
     2175(multiply overlay times image), \code{/} (divide image by overlay).
     2176This function must be defined for the following types: \code{psU8},
     2177\code{psU16}, \code{psS8}, \code{psS16}, \code{psF32}, \code{psF64},
     2178\code{psC32}, \code{psC64}.
     2179
     2180%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     2181
     2182\subsection{Vector and Image Arithmetic}
     2183\label{sec:arithmetic}
     2184
     2185We will need to be able to perform various operations on vectors and
     2186images, e.g.\ dividing one image by another, subtracting a vector
     2187from an image, etc.  Both binary operations and unary operations are
     2188required.  To avoid the burden of memorizing a ton of APIs, we specify
     2189two generic APIs for the binary and unary operations.
     2190
     2191\begin{verbatim}
     2192psType *psBinaryOp (void *out, void *in1, char *op, void *in2);
     2193psType *psUnaryOp (void *out, void *in, char *op);
     2194\end{verbatim}
     2195These functions determine the type of the operands on the basis of
     2196their \code{psType} elements, which always are the first elements.
     2197Note that these functions return a pointer to the appropriate type for
     2198the operation.  Since the result may is cast to \code{psType}, the
     2199resulting type may be determined by examining the return value.  It is
     2200expected that the implementation of these functions will employ
     2201pre-processor macros to perform the onerous task of creating the
     2202loops.  Also note that \code{psVector} is equivalent to
     2203\code{psVector}.  An attempt to perform an arithmetic operation on
     2204an object of dimension \code{PS_DIMEN_OTHER} should produce an error.
     2205
     2206Binary operations between an image and a vector have a potential
     2207ambiguity --- do the vector elements correspond to the rows or the
     2208columns?  For this reason, we define two vector types: a ``vector''
     2209(\code{PS_DIMEN_VECTOR}), and a ``transposed vector''
     2210(\code{PS_DIMEN_TRANSV}).  We specify that a ``vector'', when involved
     2211in binary operations on an image, acts on the rows, while a
     2212``transposed vector'' in the same context acts on the columns.
     2213Vectors, when created, will be created as ``vectors'', but may be
     2214converted to ``transposed vectors'' using the following function:
     2215\begin{verbatim}
     2216psVector *psVectorTranspose(psVector *out, psVector *myVector);
     2217\end{verbatim}
     2218
     2219It is further desirable to allow scalar values to be used within these
     2220functions, which requires the following additions:
     2221\begin{verbatim}
     2222p_ps_Scalar *psScalar (double value);
     2223p_ps_Scalar *psScalarType (char *mode, ...);
     2224\end{verbatim}
     2225The first creates a psType-ed structure from a constant value, while
     2226the second creates a psType-ed structure for a specified type.  The
     2227structure which carries a scalar value is specified as the following
     2228private type, and is analogous to the \code{psVector} and
     2229\code{psImage} structures:
     2230\begin{verbatim}
     2231typedef struct {
     2232    psType type;                        ///< data type information
     2233    union {                           
     2234        psS32 S32;                      ///< integer value entry
     2235        psF32 F32;                      ///< float value entry
     2236        psF64 F64;                      ///< double value entry
     2237        psC32 C32;                      ///< complex value entry
     2238    } data;
     2239} p_psScalar;
     2240\end{verbatim}
     2241
     2242This allows one to write the following to take the sine of the square
     2243of all pixels in an image:
     2244\begin{verbatim}
     2245psImage A,B;
     2246
     2247B = psBinaryOp (NULL, A, "^", psScalar(2));
     2248(void) psUnaryOp(B, B, "sin");
     2249\end{verbatim}
     2250
     2251Note that the \code{psUnaryOp} is performed on \code{B} in-place.
    18972252
    18982253%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    19452300\end{verbatim}
    19462301
    1947 Matrix arithmetic is supported through \code{psMatrixOp}.  Note that
    1948 \code{psMatrixOp} differs from \code{psBinaryOp} in that
    1949 multiplication with \code{psBinaryOp} acts on corresponding elements,
    1950 while \code{psMatrixOp} performs classical matrix multiplication
    1951 involving row and column operations.  Addition and subtraction by
    1952 \code{psMatrixOp} are identical to that for \code{psBinaryOp} (since
    1953 that is how matrix addition is defined).  Matrix division is not
    1954 defined.  \tbd{why specify addition as an operator? why not only
    1955 define operators which are different for matrices?}.  This function is
     2302Matrix multiplication is supported through \code{psMatrixMultiply}.  This function is
    19562303specified for data types \code{psF32, psF64}.
    1957 
    1958 \begin{verbatim}
    1959 psImage *psMatrixOp(psImage *out, const psImage *in1, const char *op, const psImage *in2);
     2304\begin{verbatim}
     2305psImage *psMatrixMultiply(psImage *out, const psImage *in1, const psImage *in2);
    19602306\end{verbatim}
    19612307
     
    20092355always \code{psC32}.  If the input vector is \code{psF32}, the
    20102356direction must be forward.  Neither the forward or inverse transforms
    2011 shall multiply by $1/N$ (or $1/N^{1/2}$), and so it falls to the
     2357must multiply by $1/N$ (or $1/N^{1/2}$), and so it falls to the
    20122358responsibility of the user to multiply a vector that has been forward-
    20132359and reverse-transformed by $1/N$.
     
    20302376\begin{verbatim}
    20312377psImage *psImageFFT(const psImage *image, int direction);
    2032 psImage *psImagePowerSpectrum(const psImage *image);
    20332378psImage *psImageReal(psImage *out, const psImage *in);
    2034 psImage *psImageReal(psImage *out, const psImage *in);
    2035 psImage *psImageReal(psImage *out, const psImage *in);
     2379psImage *psImageImaginary(psImage *out, const psImage *in);
     2380psImage *psImageComplex(psImage *real, const psImage *imag);
    20362381psImage *psImageConjugate(psImage *out, const psImage *in);
    2037 \end{verbatim}
    2038 
    2039 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    2040 
    2041 \subsection{Analytical functions}
    2042 
    2043 We require two types of general functions which will be used in fitting:
    2044 Gaussians and Polynomials.  The Gaussian is defined as:
    2045 \begin{verbatim}
    2046 float psGaussian(float x, float mean, float stdev);
    2047 \end{verbatim}
    2048 
    2049 which evaluates a non-normalized Gaussian with the given mean and
    2050 sigma at the given coordianate.  Note that this is not a Gaussian
    2051 deviate.  The evaluated Gaussian is:
    2052 
    2053 \[ 1/(\sqrt(2\pi)\sigma) exp(-\frac{(x-mean)^2}{2\sigma^2}) \]
    2054 
    2055 For the polynomial, \PS{} astrometry requirements lead us to specify
    2056 that we must be able to support at least four dimensions, in both
    2057 floating-point (for speed) and double-precision (for milli-arcsec
    2058 precision) versions.  This comes from the need to fit over $x$,$y$,
    2059 color and magnitude simultaneously.  We must also be able to
    2060 calculate the errors in the fit coefficients, as well as be able to
    2061 turn on and off each coefficient.  This leads us to define polynomial
    2062 types:
    2063 
    2064 \begin{verbatim}
    2065 /** One-dimensional polynomial */
    2066 typedef struct {
    2067     int n;                              ///< Number of terms
    2068     float *restrict coeff;              ///< Coefficients
    2069     float *restrict coeffErr;           ///< Error in coefficients
    2070     char *restrict mask;                ///< Coefficient mask
    2071 } psPolynomial1D;
    2072 \end{verbatim}
    2073 
    2074 \begin{verbatim}
    2075 /** Two-dimensional polynomial */
    2076 typedef struct {
    2077     int nX, nY;                         ///< Number of terms in x and y
    2078     float *restrict *restrict coeff;    ///< Coefficients
    2079     float *restrict *restrict coeffErr; ///< Error in coefficients
    2080     char *restrict *restrict mask;      ///< Coefficients mask
    2081 } psPolynomial2D;
    2082 \end{verbatim}
    2083 
    2084 etc., up to four dimensions.  We also define double-precision versions:
    2085 
    2086 \begin{verbatim}
    2087 /** Double-precision one-dimensional polynomial */
    2088 typedef struct {
    2089     int n;                              ///< Number of terms
    2090     double *restrict coeff;             ///< Coefficients
    2091     double *restrict coeffErr;          ///< Error in coefficients
    2092     char *restrict mask;                ///< Coefficient mask
    2093 } psDPolynomial1D;
    2094 \end{verbatim}
    2095 
    2096 \begin{verbatim}
    2097 /** Double-precision two-dimensional polynomial */
    2098 typedef struct {
    2099     int nX, nY;                         ///< Number of terms in x and y
    2100     double *restrict *restrict coeff;   ///< Coefficients
    2101     double *restrict *restrict coeffErr; ///< Error in coefficients
    2102     char *restrict *restrict mask;      ///< Coefficients mask
    2103 } psDPolynomial2D;
    2104 \end{verbatim}
    2105 
    2106 etc.  In what follows, we only show the version for double-precision
    2107 two-dimensionals; the others may be inferred following the standard
    2108 naming convention exampled above.
    2109 
    2110 The constructor and destructor are:
    2111 \begin{verbatim}
    2112 psDPolynomial2D *psDPolynomial2DAlloc(int nX, int nY);
    2113 void psDPolynomial2DFree(psDPolynomial2D *restrict myPoly);
    2114 \end{verbatim}
    2115 where \code{nX} and \code{nY} are the number of terms in x and y
    2116 respectively.
    2117 
    2118 To evaluate the polynomials at specific coordinates, we define:
    2119 \begin{verbatim}
    2120 double psEvalDPolynomial2D(double x, double y, const psDPolynomial2D *restrict myPoly);
    2121 \end{verbatim}
    2122 
    2123 \tbd{Generate a vector of random Gaussian deviates}
    2124 
    2125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    2126 
    2127 \subsection{Minimization and fitting routines}
    2128 
    2129 \tbd{I am concerned the minimization functions defined here are
    2130   missing details - gene}
    2131 
    2132 We require a general minimization routine, a routine that will
    2133 specifically minimize $\chi^2$ given a list of data with associated
    2134 errors, and a function that will analytically determine the best
    2135 polynomial fit by minimizing $\chi^2$. 
    2136 
    2137 First, we define \code{psMinimize}, which returns the vector which
    2138 minimizes the specified function, which is itself a function of a
    2139 single vector.  The returned vector must be the same length as the
    2140 vector argument to the input function. 
    2141 \begin{verbatim}
    2142 psVector *psMinimize(psVector *restrict initialGuess,
    2143                      float (*myFunction)(const psVector *restrict),
    2144                      float (*myFuncDeriv)(const psVector *restrict),
    2145                      const psVector *restrict paramMask);
    2146 \end{verbatim}
    2147 
    2148 \code{psMinimize} determines and returns the vector that minimizes the
    2149 specified function.  It takes as input a function, \code{myFunction},
    2150 an initial guess for the vector that minimizes the function,
    2151 \code{initialGuess}, and an optional mask for the vector elements
    2152 (function parameters) to minimize, \code{paramMask} (all parameters
    2153 are fit if \code{NULL}).  Note that \code{paramMask} must be of type
    2154 \code{psU8}, while \tbd{what are valid types for the function
    2155 parameter lists?}.  The optional function, \code{myFuncDeriv} returns
    2156 the derivative of the function.  \tbd{is this sufficient? clear?}
    2157 
    2158 \begin{verbatim}
    2159 psVector *psMinimizeChi2(psVector *restrict initialGuess,
    2160                          float (*evalModel)(const psVector *restrict, const psVector *restrict),
    2161                          const psVector *restrict domain,
    2162                          const psVector *restrict data,
    2163                          const psVector *restrict errors,
    2164                          const psVector *restrict paramMask);
    2165 \end{verbatim}
    2166 \code{psMinimizeChi2} fits a model to observations by minimizing
    2167 $\chi^2$, returing the best-fit parameters.  The input parameters are
    2168 a function that evaluates the model for a specified domain, given the
    2169 parameters, \code{evalModel}; a list of observations, (\code{domain},
    2170 \code{data}, and \code{errors}); an initial guess at the best-fit
    2171 parameters, \code{initialGuess} which is returned with the best-fit
    2172 parameters \tbd{how? unclear!}, and an optional mask specifying which
    2173 parameters are to be fit, \code{paramMask}, which must be of type
    2174 \code{psU8}.  All parameters are fit if this vector is \code{NULL}.
    2175 
    2176 \begin{verbatim}
    2177 psPolynomial1D *psGetArrayPolynomial(psPolynomial1D myPoly,
    2178                                      const psVector *restrict x,
    2179                                      const psVector *restrict y,
    2180                                      const psVector *restrict yErr);
    2181 \end{verbatim}
    2182 \code{psGetArrayPolynomial} returns the polynomial that best fits the
    2183 observations.  The input parameters are a polynomial that specifies
    2184 the fit order, \code{myPoly}, which will be altered and returned with
    2185 the best-fit coefficients; and the observations, \code{x}, \code{y}
    2186 and \code{yErr}.  The independent variable list, \code{x} may be
    2187 \code{NULL}, in which case the vector index is used.  The dependent
    2188 variable error, \code{yErr} may be null, in which case the solution is
    2189 determined in the assumption that all data errors are equal.
    2190 \tbd{valid types?}
    2191 
    2192 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    2193 
    2194 \subsection{Image Operations}
    2195 
    2196 \subsubsection{Image Structure Manipulation}
    2197 
    2198 We require a variety of functions to manipulate these image
    2199 structures, including creation, destruction, input, output, and
    2200 various manipulations of the pixels.  The required functions are
    2201 listed below, and fall into several categories.
    2202 
    2203 Define a subimage of the specified area of the given image.  This
    2204 function must return an error if the requested subset area lies
    2205 outside of the parent image.
    2206 \begin{verbatim}
    2207 psImage *psImageSubset(const psImage *image, int nx, int ny, int x0, int y0);
    2208 \end{verbatim}
    2209 where \code{image} is the parent image, \code{nx,ny} specify the
    2210 dimensions of the desired subraster, and \code{x0, y0} specify the
    2211 starting pixel of the subraster.  The entire subraster must be
    2212 contained within the raster of the parent image.  Note that the
    2213 \code{refCounter} for the parent should be incremented.  This function
    2214 must be defined for the following types: \code{psU8}, \code{psU16},
    2215 \code{psS8}, \code{psS16}, \code{psF32}, \code{psF64}, \code{psC32},
    2216 \code{psC64}.
    2217 
    2218 Create a copy of the specified image, converting the type in the
    2219 process.  If the output target pointer is not NULL, place the result
    2220 in the specified structure.  The output image data must be allocated
    2221 as a single, contiguous block of memory.  The output image may not be
    2222 the input image.  This function must be defined for the following
    2223 types: \code{psU8}, \code{psU16}, \code{psS8}, \code{psS16},
    2224 \code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
    2225 \begin{verbatim}
    2226 psImage *psImageCopy(psImage *output, const psImage *input, psElemType type);
    2227 \end{verbatim}
    2228 
    2229 \subsubsection{Image Pixel Extractions}
    2230 
    2231 Extract pixels from rectlinear region to a vector (array of floats).
    2232 The output vector contains either \code{nx} or \code{ny} elements,
    2233 based on the value of the direction: e.g., if \code{direction} is
    2234 \tbd{+x}, there are \code{nx} elements.  The input region is collapsed
    2235 in the perpendicular direction, and each element of the output vectors
    2236 is derived from the statistics of the pixels at that direction
    2237 coordinate.  The statistic used to derive the output vector value is
    2238 specified by \code{stats}.  This function must be defined for the
    2239 following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
    2240 \begin{verbatim}
    2241 psVector *psImageSlice(psVector *out, const psImage *input, int x, int y, int nx, int ny,
    2242                            int direction, const psStats *stats);
    2243 \end{verbatim}
    2244 
    2245 Extract pixels from an image along a line to a vector (array of
    2246 floats).  The vector \code{(xs,ys)} - \code{(xe,ye)} forms the basis of
    2247 the output vector.  Pixels are considered in a rectangular region of
    2248 width \code{dw} about this vector.  The input region is collapsed in
    2249 the perpendicular direction, and each element of the output vector
    2250 represents pixel-sized boxes, where the value is derived from the
    2251 statistics of the pixels interpolated along the perpendicular
    2252 direction.  The statistic used to derive the output vector value is
    2253 specified by \code{stats}.  This function must be defined for the
    2254 following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}
    2255 \begin{verbatim}
    2256 psVector *psImageCut(psVector *out, const psImage *input, float xs, float ys, float xe, float ye,
    2257                          float dw, const psStats *stats);
    2258 \end{verbatim}
    2259 
    2260 Extract radial annuli data to a vector.  A vector is constructed where
    2261 each vector elements is derived from the statistics of the pixels
    2262 which land in one of a sequence of annuli.  The annuli are centered on
    2263 the image pixel coordinate \code{x,y}, and have width \code{dr}.  The
    2264 number of annuli is $radius / dr$.  The statistic used to derive the
    2265 output vector value is specified by \code{stats}.  This function must be defined for the
    2266 following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
    2267 \begin{verbatim}
    2268 psVector *psImageRadialCut(psVector *out, const psImage *input, float x, float y,
    2269                                const psVector *radii, const psStats *stats);
    2270 \end{verbatim}
    2271 
    2272 \subsubsection{Image Geometry Manipulation}
    2273 
    2274 Rebin image to new scale.  A new image is constructed in which the
    2275 dimensions are reduced by a factor of \code{scale} $\le 1$ (it is an
    2276 error for \code{scale} $> 1$).  The \code{scale} is equal in each
    2277 dimension.  The output image is generated from all input image pixels.
    2278 Each pixel in the output image is derived from the statistics of the
    2279 corresponding set of input image pixels based on the statistics
    2280 specified by \code{stats}.  This function must be defined for the following
    2281 types: \code{psU8}, \code{psU16}, \code{psS8}, \code{psS16},
    2282 \code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
    2283 \begin{verbatim}
    2284 psImage *psImageRebin(psImage *out, const psImage *input, float scale, const psStats *stats);
    2285 \end{verbatim}
    2286 
    2287 Rotate the input image by given angle, specified in degrees.  The
    2288 output image must contain all of the pixels from the input image in
    2289 their new frame.  Pixels in the output image which do not map to input
    2290 pixels should be set to \tbd{value}.  The center of rotation is always
    2291 the center pixel of the image.  The rotation is specified in the sense
    2292 that a positive angle is an anti-clockwise rotation.    This function must be defined for the following
    2293 types: \code{psU8}, \code{psU16}, \code{psS8}, \code{psS16},
    2294 \code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
    2295 \begin{verbatim}
    2296 psImage *psImageRotate(psImage *out, const psImage *input, float angle);
    2297 \end{verbatim}
    2298 
    2299 Shift image by an arbitrary number of pixels (\code{dx,dy}) in either
    2300 direction.  If the shift values are fractional, the output pixel
    2301 values should interpolate between the input pixel values.  The output
    2302 image has the same dimensions as the input image.  Pixels which fall
    2303 off the edge of the output image are lost.  Newly exposed pixels are
    2304 set to the value given by \code{exposed}.    This function must be defined for the following
    2305 types: \code{psU8}, \code{psU16}, \code{psS8}, \code{psS16},
    2306 \code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
    2307 \begin{verbatim}
    2308 psImage *psImageShift(psImage *out, const psImage *input, float dx, float dy, float exposed);
    2309 \end{verbatim}
    2310 
    2311 Roll image by an integer number of pixels (\code{dx,dy}) in either
    2312 direction.  The output image is the same dimensions as the input
    2313 image.  Edge pixels wrap to the other side (no values are lost).  This function must be defined for the following
    2314 types: \code{psU8}, \code{psU16}, \code{psS8}, \code{psS16},
    2315 \code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
    2316 \begin{verbatim}
    2317 psImage *psImageRoll(psImage *out, const psImage *input, int dx, int dy);
    2318 \end{verbatim}
    2319 
    2320 \subsubsection{Image Statistical Functions}
    2321 
    2322 Determine statistics for image (or subimage).  The statistics to be
    2323 determined are specified by \code{stats}.  This function must be defined for the
    2324 following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
    2325 \begin{verbatim}
    2326 psStats *psImageGetStats(psStats *stats, const psImage *input);
    2327 \end{verbatim}
    2328 
    2329 Construct a histogram from an image (or subimage).  The histogram to
    2330 generate is specified by \code{psHistogram hist} (see
    2331 section~\ref{sec:histograms}).  This function must be defined for the
    2332 following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
    2333 \begin{verbatim}
    2334 psHistogram *psImageHistogram(psHistogram *hist, const psImage *input);
    2335 \end{verbatim}
    2336 
    2337 Fit a 2-D Chebychev polynomial surface to an image.  The input
    2338 structure \code{coeffs} contains the desired order and terms of
    2339 interest.  This function must be defined for the
    2340 following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
    2341 \begin{verbatim}
    2342 psPolynomial2D *psImageFitPolynomial(psPolynomial2D *coeffs, const psImage *input);
    2343 \end{verbatim}
    2344 
    2345 Evaluate a 2-D polynomial surface for the image pixels.  Given the
    2346 input polynomial coefficients, set the image pixel values on the basis
    2347 of the polynomial function.  This function must be defined for the
    2348 following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
    2349 \begin{verbatim}
    2350 psImage *psImageEvalPolynomial(psImage *input, const psPolynomial2D *coeffs);
    2351 \end{verbatim}
    2352 
    2353 \subsubsection{Image I/O Functions}
    2354 
    2355 Read an image or subimage from a named file.  This function is a
    2356 wrapper to the FITS library function.  The input parameters allow a
    2357 full image or a subimage to be read.  The starting pixel of the region
    2358 is specified by \code{x,y}, while the dimensions of the requested
    2359 region are specified by \code{nx,ny}.  A negative value of -1 for
    2360 these two parameters specifies the full array of the requested image,
    2361 less absolute value of the variable.  If the native image is a cube,
    2362 the value of z specifies the requested slice of the image.  The data
    2363 is read from the extension specified by extname (matching the EXTNAME
    2364 keyword) or by the extnum value (with 0 representing the PHU, 1 the
    2365 first extension, etc).  This function must call \code{psError} and
    2366 return \code{NULL} if any of the specified parameters are out of range
    2367 for the data in the image file, if the specified image file does not
    2368 exist, or the image on disk is zero- or one-dimensional.
    2369 \begin{verbatim}
    2370 psImage *psImageReadSection(psImage *output, int x0, int y0, int nx, int ny, int z,
    2371                             const char *extname, int extnum, const char *filename);
    2372 \end{verbatim}
    2373  
    2374 Read an image or subimage from file descriptor.  The input parameters
    2375 and their behavior for this function are identical with those in
    2376 \code{psImageReadSection}.
    2377 \begin{verbatim}
    2378 psImage *psImageFReadSection(psImage *output, int x, int y, int nx, int ny, int z,
    2379                              const char *extname, int extnum, FILE *f);
    2380 \end{verbatim}
    2381 \tbd{The use of \code{FILE*} to carry around the file descriptor is to be reviewed.}
    2382 
    2383 Write an image section to the named file, which may exist.  This
    2384 operation may write a portion of an image over the existing bytes of
    2385 an existing image.  If the file does not exist, it should be created.
    2386 If the specified extension does not exist, it should be created.  If
    2387 an extension is specified and no PHU exists, a basic PHU should be
    2388 created.
    2389 \begin{verbatim}
    2390 psImage *psImageWriteSection(const psImage *input, int x, int y, int z,
    2391                              const char *extname, int extnum, const char *filename);
    2392 \end{verbatim}
    2393 
    2394 Write an image section to file descriptor as above:
    2395 \begin{verbatim}
    2396 psImage *psImageFWriteSection(const psImage *input, int x, int y, int z,
    2397                               const char *extname, int extnum, FILE *f);
    2398 \end{verbatim}
    2399 \tbd{The use of \code{FILE*} to carry around the file descriptor is to be reviewed.}
    2400 
    2401 Read header data from a FITS image file into a \code{psMetaData}
    2402 structure (see section~\ref{sec:metadata}.  The \code{extname} and
    2403 \code{extnum} parameters specify the extension of interest as above.
    2404 If the named extension does not exist, the function should return an
    2405 error.
    2406 \begin{verbatim}
    2407 psMetadata *psImageReadHeader(psMetadata *output, const char *extname, int extnum, const char *filename);
    2408 \end{verbatim}
    2409 
    2410 Read header data from a FITS image file descriptor into a
    2411 \code{psMetaData} structure.
    2412 \begin{verbatim}
    2413 psMetadata *psImageFReadHeader(psMetadata *output, const char *extname, int extnum, FILE *f);
    2414 \end{verbatim}
    2415 
    2416 \subsubsection{Image Pixel Manipulations}
    2417 
    2418 Clip image values outside of range to given values.  All pixels with
    2419 values \code{< min} are set to the value \code{vmin}. All pixels with
    2420 values \code{> max} are set to the value \code{vmax}. Returns the
    2421 number of clipped pixels.  This function must be defined for the
    2422 following types: \code{psU8}, \code{psU16}, \code{psS8}, \code{psS16},
    2423 \code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
    2424 \begin{verbatim}
    2425 int psImageClip(psImage *input, float min, float vmin, float max, float vmax);
    2426 \end{verbatim}
    2427 
    2428 Clip \code{NaN} image pixels to given value.  Pixels with \code{NaN},
    2429 \code{+Inf} or \code{-Inf} values are set to the specified value.
    2430 Returns the number of clipped pixels.  This function must be defined
    2431 for the following types: \code{psU8}, \code{psU16}, \code{psS8},
    2432 \code{psS16}, \code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
    2433 \begin{verbatim}
    2434 int psImageClipNaN(psImage *input, float value);
    2435 \end{verbatim}
    2436 
    2437 Overlay subregion of image with another image.  Replace the pixels in
    2438 the \code{image} which correspond to the pixels in \code{overlay} with
    2439 values derived from the values in \code{image} and \code{overlay}
    2440 based on the given operator \code{op}.  Valid operators are \code{=}
    2441 (set image value to overlay value), \code{+} (add overlay value to
    2442 image value), \code{-} (subtract overlay from image), \code{*}
    2443 (multiply overlay times image), \code{/} (divide image by overlay).
    2444 This function must be defined for the following types: \code{psU8},
    2445 \code{psU16}, \code{psS8}, \code{psS16}, \code{psF32}, \code{psF64},
    2446 \code{psC32}, \code{psC64}.
    2447 \begin{verbatim}
    2448 int psImageOverlaySection(psImage *image, const psImage *overlay, int x0, int y0, const char *op);
    2449 \end{verbatim}
    2450 
    2451 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    2452 
    2453 \subsection{Vector and Image Arithmetic}
    2454 \label{sec:arithmetic}
    2455 
    2456 We will need to be able to perform various operations on vectors and
    2457 images, e.g.\ dividing one image by another, subtracting a vector
    2458 from an image, etc.  Both binary operations and unary operations are
    2459 required.  To avoid the burden of memorizing a ton of APIs, we specify
    2460 two generic APIs for the binary and unary operations.
    2461 
    2462 \begin{verbatim}
    2463 psType *psBinaryOp (void *out, void *in1, char *op, void *in2);
    2464 psType *psUnaryOp (void *out, void *in, char *op);
    2465 \end{verbatim}
    2466 These functions determine the type of the operands on the basis of
    2467 their \code{psType} elements, which always are the first elements.
    2468 Note that these functions return a pointer to the appropriate type for
    2469 the operation.  Since the result may is cast to \code{psType}, the
    2470 resulting type may be determined by examining the return value.  It is
    2471 expected that the implementation of these functions will employ
    2472 pre-processor macros to perform the onerous task of creating the
    2473 loops.  Also note that \code{psVector} is equivalent to
    2474 \code{psVector}.  An attempt to perform an arithmetic operation on
    2475 an object of dimension \code{PS_DIMEN_OTHER} should produce an error.
    2476 
    2477 Binary operations between an image and a vector have a potential
    2478 ambiguity --- do the vector elements correspond to the rows or the
    2479 columns?  For this reason, we define two vector types: a ``vector''
    2480 (\code{PS_DIMEN_VECTOR}), and a ``transposed vector''
    2481 (\code{PS_DIMEN_TRANSV}).  We specify that a ``vector'', when involved
    2482 in binary operations on an image, acts on the rows, while a
    2483 ``transposed vector'' in the same context acts on the columns.
    2484 Vectors, when created, will be created as ``vectors'', but may be
    2485 converted to ``transposed vectors'' using the following function:
    2486 
    2487 \begin{verbatim}
    2488 /** Transpose a vector.  Changes the type to a PS_DIMEN_TRANSV */
    2489 psVector *psVectorTranspose(psVector *out, //!< Output vector, or NULL
    2490                             psVector *myVector //!< Vector to be transposed
    2491     );
    2492 \end{verbatim}
    2493 
    2494 It is further desirable to allow scalar values to be used within these
    2495 functions, which requires the following additions:
    2496 
    2497 \begin{verbatim}
    2498 /** create a psType-ed structure from a constant value. */
    2499 p_ps_Scalar *
    2500 psScalar (double value);
    2501 \end{verbatim}
    2502 
    2503 \begin{verbatim}
    2504 /** create a psType-ed structure from a specified type  */
    2505 p_ps_Scalar *
    2506 psScalarType (char *mode,               ///< type description
    2507               ...                       ///< value (or values) of specified types
    2508 );
    2509 \end{verbatim}
    2510 
    2511 \begin{verbatim}
    2512 /** private structure used to pass constant values into the math operators. */
    2513 typedef struct {
    2514     psType type;                        ///< data type information
    2515     union {                           
    2516         int i;                          ///< integer value entry
    2517         float f;                        ///< float value entry
    2518         double d;                       ///< double value entry
    2519         complex float c;                ///< complex value entry
    2520     } val;
    2521 } p_psScalar;
    2522 \end{verbatim}
    2523 
    2524 This allows one to write the following to take the sine of the square
    2525 of all pixels in an image:
    2526 \begin{verbatim}
    2527 psImage A,B;
    2528 
    2529 B = psBinaryOp (NULL, A, "^", psScalar(2));
    2530 (void) psUnaryOp(B, B, "sin");
    2531 \end{verbatim}
    2532 
    2533 Note that the \code{psUnaryOp} is performed on \code{B} in-place.
     2382psImage *psImagePowerSpectrum(const psImage *in);
     2383\end{verbatim}
    25342384
    25352385%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    25612411\subsection{Dates and times}
    25622412
    2563 \textbf{[May be deferred.]}
     2413We require a collection of functions to manipulate time data.  These
     2414operations primarily consist of conversions between specific time
     2415formats.  PSLib wraps the libTAI structure \code{taia} for use as the
     2416native time format. 
     2417\begin{verbatim}
     2418typedef struct {
     2419  struct taia t;
     2420} psTime;
     2421\end{verbatim}
     2422
     2423Two utility functions provide the current time in two formats, MJD
     2424(modified Julian day) and the Sidereal time. 
     2425
     2426\begin{verbatim}
     2427psTime psGetMJD(void);
     2428psTime psGetSidereal(float mjd, float longitude);
     2429\end{verbatim}
     2430
     2431A collection of functions convert from the native \code{psTime} format
     2432to various external formats.  Note that ISO Time is represented by
     2433YYYY/MM/DD,HH:MM:SS.SSS. 
     2434\begin{verbatim}
     2435char *psTimeToISOTime (psTime time);
     2436double psTimeToUTC (psTime time);
     2437double psTimeToMJD (psTime time);
     2438double psTimeToJD (psTime time);
     2439struct timeval *psTimeToTimeval (psTime time);
     2440struct tm *psTimeToTm (psTime time);
     2441\end{verbatim}
     2442
     2443A matching set of functions convert from the external formats to the
     2444native \code{psTime}:
     2445\begin{verbatim}
     2446psTime *psISOTimeToTime (char *input);
     2447psTime *psUTCToTime (double input);
     2448psTime *psMJDToTime (double input);
     2449psTime *psJDToTime (double input);
     2450psTime *psTimevalToTime (struct timeval *input);
     2451psTime *psTMtoTime (struct tm *input);
     2452\end{verbatim}
    25642453
    25652454%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    26182507readable and it may slow down the access. 
    26192508
    2620 We propose an intermediate solution to this problem.  We specify a
    2621 flexible, generic metadata container and access methods.  Data types
    2622 which require access to a general collection of metadata should
     2509PSLib implements an intermediate solution to this problem.  We specify
     2510a flexible, generic metadata container and access methods.  Data types
     2511which require association with a general collection of metadata should
    26232512include an entry of this metadata type.  However, a subset of metadata
    26242513concepts which are basic and frequently required may be placed in the
    26252514coded structure elements.  This approach allows the code to refer to
    26262515the basic metadata concepts as part of the data structure (ie,
    2627 image.nx), but also allows us to provide access to any arbitrary
    2628 metadata which may be generated.  As a practical matter, the choice of
    2629 which entries are only in the metadata and which are part of the
    2630 explicit structure elements is rather subjective.  Any data elements
    2631 which are frequently used should be put in the structure; those which
    2632 are only infrequently needed should be left in the generic metadata.
     2516\code{image.nx}), but also allows us to provide access to any
     2517arbitrary metadata which may be generated.  As a practical matter, the
     2518choice of which entries are only in the metadata and which are part of
     2519the explicit structure elements is rather subjective.  Any data
     2520elements which are frequently used should be put in the structure;
     2521those which are only infrequently needed should be left in the generic
     2522metadata.
    26332523
    26342524There are some points of caution which must be noted.  Any
    26352525manipulation of the data should be reflected in the metadata where
    26362526appropriate.  This is always an issue of concern.  For example,
    2637 consider an image of dimensions \code{nX, nY}.  If a function extracts
    2638 a subraster, it must change the values of \code{nX, nY} to match the
     2527consider an image of dimensions \code{nx, ny}.  If a function extracts
     2528a subraster, it must change the values of \code{nx, ny} to match the
    26392529new dimensions.  What should it do to the corresponding metadata?
    26402530Clearly, it should change the corresponding value which defines
     
    26442534copy of the metadata which may be shared by other representations of
    26452535the image?  These must be treated differently because the change would
    2646 invalidate those other references. 
     2536invalidate those other references.  Care must be taken, therefore,
     2537when writing functions which operate on the data to consider all of
     2538the relevant metadata entries which must also be updated.
    26472539
    26482540A related issue is the definition of metadata names.  Entries in a
     
    26652557\subsubsection{Metadata Representation}
    26662558
    2667 \tbd{descriptions in this section need to be clarified}
    2668 
    26692559This section addresses the question of how \PS{} metadata should be
    2670 represented in memory. We do not (yet) address how it should be
    2671 represented on disk.
    2672 
    2673 We propose that an item of metadata be represented as a C structure with at least the following
    2674 fields:
    2675 \begin{verbatim}
    2676 /** A struct to define a single item of metadata */
     2560represented in memory, not how it should be represented on disk.
     2561
     2562We define an item of metadata with the following structure:
     2563\begin{verbatim}
    26772564typedef struct {
    26782565    const int id;                       ///< unique ID for this item
     
    26812568    psMetadataFlags flags;              ///< flags associated with this item
    26822569    const union {
    2683         double d;                       ///< double value
    2684         float f;                        ///< floating value
    2685         int i;                          ///< integer value
    2686         void *v;                        ///< other type
    2687     } val;                              ///< value of metadata
     2570        psS32 S32;                      ///< integer value
     2571        psF32 F32;                      ///< floating value
     2572        psF64 F64;                      ///< double value
     2573        void *void;                     ///< other type
     2574    } data;                             ///< value of metadata
    26882575    char *comment;                      ///< optional comment ("", not NULL)
    26892576    psDlist *restrict items;            ///< list of psMetadataItems with the same name
     
    26912578\end{verbatim}
    26922579
    2693 The \code{id} is a unique identifier for this item of metadata; experience
    2694 shows that such tags are useful.
    2695 
    2696 The \code{psMetadataType type} entry specifies the type of the data
    2697 being represented; the possibilities are listed in section \ref{metadataTypes}.
    2698 
    2699 \paragraph{Possible Types of Metadata}
    2700 \label{metadataTypes}
    2701 
    2702 The possible types of metadata are identified by the enumerated type
    2703 \code{psMetadataType} (see also table \ref{tabMetaDataTypes}); the initial defined values are:
    2704 \begin{verbatim}
    2705 /** Possible types of metadata. */
     2580The \code{id} is a unique identifier for this item of metadata;
     2581experience shows that such tags are useful.  The entry \code{name}
     2582specifies the name of the metadata item.  Metadata naming conventions
     2583for the Pan-STARRS IPP are specified in the IPP Software Requirements
     2584Specification (PSDC-430-005).  The value of the metadata is given by
     2585the union \code{data}, and may be of type \code{psS32}, \code{psF32},
     2586\code{psF64}, or an arbitrary rich structure pointed at by the
     2587\code{void} pointer \code{void}.  A character string comment
     2588associated with this metadata item may be stored in the element
     2589\code{comment}. The \code{type} entry specifies the type of the data
     2590being represented, given by the enumerated type \code{psMetadataType}:
     2591\begin{verbatim}
    27062592typedef enum {                          ///< type of val is:
    27072593    PS_META_ITEM_SET = 0,               ///< NULL; metadata is in psMetadataType.items
    2708     PS_META_FLOAT,                      ///< float (.f)
    2709     PS_META_INT,                        ///< int (.i)
    2710     PS_META_STR,                        ///< string (.v)
    2711     PS_META_IMG,                        ///< image (.v)
    2712     PS_META_JPEG,                       ///< JPEG (.v)
    2713     PS_META_PNG,                        ///< PNG (.v)
    2714     PS_META_ASTROM,                     ///< astrometric coefficients (.v)
    2715     PS_META_UNKNOWN,                    ///< other (.v)
     2594    PS_META_S32,                        ///< int (.S32)
     2595    PS_META_F32,                        ///< float (.F32)
     2596    PS_META_F64,                        ///< double (.F64)
     2597    PS_META_STR,                        ///< string (.void)
     2598    PS_META_IMG,                        ///< image (.void)
     2599    PS_META_JPEG,                       ///< JPEG (.void)
     2600    PS_META_PNG,                        ///< PNG (.void)
     2601    PS_META_ASTROM,                     ///< astrometric coefficients (.void)
     2602    PS_META_UNKNOWN,                    ///< other (.void)
    27162603    PS_META_NTYPE                       ///< Number of types; must be last
    27172604} psMetadataType;
    27182605\end{verbatim}
    2719 
    2720 \begin{table}
    2721 \begin{tabular}{llll}
    2722 \textbf{Value} & \textbf{Type} & \textbf{member of union} & \textbf{Comments}\\
    2723 \hline
    2724 \code{PS_META_FLOAT}   & float    & f & value, not pointer, is stored \\
    2725 \code{PS_META_INT}     & int      & i & value, not pointer, is stored \\
    2726 \code{PS_META_STR}     & string   & v & value, not pointer to original, is stored \\
    2727 \code{PS_META_IMG}     & psImage  & v & \\
    2728 \code{PS_META_JPEG}    & JPEG     & v & \\
    2729 \code{PS_META_PNG}     & PNG      & v & \\
    2730 \code{PS_META_ASTROM}  & psAstrom & v & \\
    2731 \code{PS_META_UNKNOWN} & other    & v & \\
    2732 \code{PS_META_NTYPE}   & (none)   &   & The number of types defined
    2733 \end{tabular}
    2734 \begin{caption}{Supported Metadata Types}
    2735 \label{tabMetaDataTypes}
    2736   Possible types of metadata
    2737 \end{caption}
    2738 \end{table}
    2739 
    2740 \subsubsection{Collections of Metadata}
    2741 
    2742 \begin{verbatim}
    2743 /** A set of metadata */
     2606The \code{flags} entry specifies some optional characteristics of the
     2607metadata type, given by the enumerated type \code{psMetadataFlags}:
     2608\begin{verbatim}
     2609typedef enum {
     2610    PS_META_TYPE_MASK =     0xffff,     ///< the type enum must fit in this mask
     2611    PS_META_UNIQUE =       0x10000,     ///< the name must be unique (default)
     2612    PS_META_NON_UNIQUE =   0x20000,     ///< the name may be repeated
     2613} psMetadataFlags;
     2614\end{verbatim}
     2615
     2616A collection of metadata is represented by the \code{psMetadata} structure:
     2617\begin{verbatim}
    27442618typedef struct {
    27452619    psDlist *restrict list;             ///< list of psMetadataItem
     
    27472621} psMetadata;
    27482622\end{verbatim}
    2749 
    27502623The type \code{psMetadata} is a container class for metadata. Note
    27512624that there are in fact \emph{two} representations of the metadata
     
    27562629second representation employs a hash table which allows fast look-up
    27572630given a specific metadata keyword.
     2631
     2632Certain metadata names (such as the FITS keywords \code{COMMENT} and
     2633\code{HISTORY} in a FITS header) may be repeated with different
     2634values.  The \code{psMetadataAppend} routine is required to check that
     2635all metadata names are unique unless the type is qualified as
     2636\code{PS_META_NON_UNIQUE}; in this case a unique integer must be added
     2637to each name specified.
     2638
     2639\subsubsection{Metadata APIs}
     2640
     2641In this section, we explain the metadata APIs more fully.
     2642
     2643The allocator for \code{psMetadataItem} returns a full
     2644\code{psMetadataItem} ready for insertion into the \code{psMetadata}.
     2645The \code{name} entry specifies the name to use for this metadata
     2646item, and may include \code{sprintf}-stype formating codes.  The
     2647\code{format} entry, which specifies both the metadata type and the
     2648optional flags, is constructed by bit-wise or'ing the appropriate type
     2649and flag.  The \code{comment} entry is a fixed string which is used
     2650for the comment associated with this metadata item.  The arguments to
     2651the \code{name} formatting codes and the metadata data itself are
     2652passed to \code{psMetadataItemAlloc} as arguments following the
     2653comment string.  The data must be a pointer for any data types which
     2654are stored in the element \code{data.void}, while other data types are
     2655passed as numeric values.  The argument list must be interpreted
     2656appropriately by the \code{va_list} operators in the function.   
     2657\begin{verbatim}
     2658psMetadataItem *psMetadataItemAlloc(const char *name, int format, const char *comment, ...);
     2659psMetadataItem *psMetadataItemAllocV(const char *name, int format, const char *comment, va_list list);
     2660\end{verbatim}
     2661
     2662The \code{psMetadataItem} destructor is specified below.  Note that
     2663the destructor for \code{psMetadataItem} must call the appropriate
     2664destructor for the \code{val} (recall that it is the duty of the
     2665\code{psMyTypeFree}s to decrement the \code{refCounter} and free the
     2666memory if and only if the \code{refCounter == 1} --- see
     2667\S\ref{sec:free}).
     2668\begin{verbatim}
     2669void psMetadataItemFree(psMetadataItem *item);
     2670\end{verbatim}
     2671
     2672The constructor for the collection of metadata, \code{psMetadata},
     2673simply returns an empty metadata container (employing the constructors
     2674for the doubly-linked list and hash table).  The destructor needs to
     2675free each of the \code{psMetadataItem}s using \code{psMetadataItemFree}.
     2676\begin{verbatim}
     2677psMetadata *psMetadataAlloc(void);
     2678void psMetadataFree(psMetadata *md);
     2679\end{verbatim}
     2680
     2681Items may be added to the metadata in one of two ways --- firstly, an
     2682item may be added by appending a \code{psMetadataItem} which has
     2683already been created; and secondly by directly providing the data to
     2684be appended.  In both cases, the \code{psMetadataItem} that is
     2685appended to the metadata is returned.  The second function,
     2686\code{psMetadataAppend} takes a pointer or value which is interpretted
     2687by the \code{va_list} operators in the function.
     2688%
     2689\begin{verbatim}
     2690psMetadataItem *psMetadataAppendItem(psMetadata *restrict md,
     2691                                     psMetadataItem *restrict item);
     2692psMetadataItem *psMetadataAppend(psMetadata *restrict md, const char *name,
     2693                                 int format, const char *comment, ...);
     2694\end{verbatim}
     2695
     2696Items may be removed from the metadata by specifying a key.  If the
     2697key matches a metadata item, the item is removed from the metadata and
     2698returned; otherwise, \code{NULL} is returned.  If the key is not
     2699unique, then \emph{all} items corresponding to the key are removed,
     2700and the first item is returned.  Care should be taken not to leak
     2701memory when appending an item for which the key already exists in the
     2702metadata (and is not \code{PS_META_NON_UNIQUE}).
     2703%
     2704\begin{verbatim}
     2705psMetadataItem *psMetadataRemove(psMetadata *restrict md, const char *restrict key);
     2706\end{verbatim}
     2707
     2708The metadata may be iterated over by (re-)setting the iterator for the
     2709appropriate \code{psMetadata}, and getting the next item.
     2710\code{psMetadataGetNext} has the ability to match the beginning of a
     2711key, e.g., if the user only wants to iterate through
     2712\code{IPP.machines.sky} and doesn't want to bother with
     2713\code{IPP.machines.detector}.  The iterator should iterate over every
     2714item of metadata --- even those that are non-unique.
     2715\begin{verbatim}
     2716void psMetadataSetIterator(psMetadata *md);
     2717psMetadataItem *psMetadataGetNext(psMetadata *restrict md, const char *restrict match);
     2718\end{verbatim}
     2719
     2720Items may be found within the metadata by providing a key.  In the
     2721event that the key is non-unique, the first item is returned.
     2722\begin{verbatim}
     2723psMetadataItem *psMetadataLookup(const psMetadata *restrict md,
     2724                                 const char *restrict key);
     2725\end{verbatim}
     2726
     2727Metadata items may be printed to an open file descriptor, optionally
     2728pre-pending a specified string.
     2729\begin{verbatim}
     2730void psMetadataItemPrint(FILE *fd, const psMetadataItem *restrict md,
     2731                         const char *prefix);
     2732\end{verbatim}
     2733
     2734\begin{verbatim}
     2735psMetadata *psMetadataReadHeader(psMetadata *output, const char *extname,
     2736                              int extnum, const char *filename);
     2737\end{verbatim}
     2738Read header data from a FITS image file into a \code{psMetadata}
     2739structure (see section~\ref{sec:metadata}.  The \code{extname} and
     2740\code{extnum} parameters specify the extension of interest as above.
     2741If the named extension does not exist, the function should return an
     2742error.
     2743
     2744\begin{verbatim}
     2745psMetadata *psMetadataFReadHeader(psMetadata *output, const char *extname,
     2746                               int extnum, FILE *f);
     2747\end{verbatim}
     2748Read header data from a FITS image file descriptor into a
     2749\code{psMetadata} structure.
     2750
     2751\subsection{Detector and sky positions}
     2752
     2753Both detector and sky positions will be used extensively in the IPP.
     2754The first are linear coordinates which conform to Euclidean geometry
     2755while the second are angular coordinates for which additional care
     2756must often be taken.  We put these into two structures, \code{psPlane}
     2757and \code{psSphere}, respectively.  Partitioning these two will enable
     2758error-checking.
     2759%
     2760\begin{verbatim}
     2761typedef struct {
     2762    double x;                           ///< x position
     2763    double y;                           ///< y position
     2764    double xErr;                        ///< Error in x position
     2765    double yErr;                        ///< Error in y position
     2766} psPlane;
     2767
     2768typedef struct {
     2769    double r;                           ///< RA
     2770    double d;                           ///< Dec
     2771    double rErr;                        ///< Error in RA
     2772    double dErr;                        ///< Error in Dec
     2773} psSphere;
     2774\end{verbatim}
     2775
     2776Three major classes of coordinate transformations are necessary.
     2777First, linear coordinates from one frame must be converted to linear
     2778coordinates in a different frame of references.  Simple transformations
     2779of this type are independent of other quantities of the positions --
     2780they are simply mapping between two linear spaces.  In practice, these
     2781transformations may often be a function of the magnitude or color of
     2782the imaged object.  The second type of conversion is the
     2783transformation of linear coordinates to angular coordinates and
     2784vice-versa.  This conversion depends on the desired projection, and
     2785may represent the real mapping performed by the telescope or may
     2786simply represent a convenient mechanism to display 3D coordinates in
     2787useful forms.  The third conversion of interest is the transformation
     2788of one set of spherical coordinates to another set.  Frequently in
     2789astronomy, these conversions consist only of rotations between the two
     2790spherical coordinates systems, where the coordinates of the pole and
     2791equatorial rotation between the two systems define the
     2792transformation.  Conversions between standard coordinate systems such
     2793as Galactic, Ecliptic, and various epochs of the Celestial coordinates
     2794are represented by these spherical transformations. 
     2795
     2796\subsubsection{Linear Coordinate Transformations}
     2797
     2798We specify two types of transforms between coordinate systems.  The
     2799first consists simply of two 2D polynomials to transform both
     2800components -- the output coordinates depend only on the input
     2801coordinates and no other quantities of objects at those coordinates.
     2802The second consists of two 4D polynomials in which the output
     2803coordinates are also specified to be a function of the magnitude and
     2804color of the object with the given coordinates.  This type of
     2805coordinate transformation is necessary to represent the
     2806(color-dependent) optical distortions caused by the atmosphere and
     2807camera optics, and the possibly effects of charge transfer
     2808inefficiency.  We specify two structures to represent the coefficients
     2809of these transformations:
     2810
     2811\begin{verbatim}
     2812typedef struct {
     2813    psDPolynomial2D *x;
     2814    psDPolynomial2D *y;
     2815} psPlaneTransform;
     2816\end{verbatim}
     2817
     2818The \code{psDPolynomial2D} structures represent polynomials of
     2819arbitrary order as a function of two dimensions.  There is one of
     2820these structures for each of the two output dimensions.  As an
     2821example, consider the simple transformation from one linear coordinate
     2822frame ($x,y$), e.g., on a CCD, to a second frame ($p,q$), e.g., on a
     2823chip. If we have only first order terms in the transformation
     2824\code{psPlaneTransform T}, the new coordinates would be represented by
     2825the terms:
     2826%
     2827\begin{verbatim}
     2828p = T.x->coeff[0][0] + x*T.x->coeff[1][0] + y*T.x->coeff[0][1];
     2829q = T.y->coeff[0][0] + x*T.y->coeff[1][0] + y*T.y->coeff[0][1];
     2830\end{verbatim}
     2831%
     2832where we have excluded the basic cross-term ($x \times y$) by using
     2833the mask: \code{T.x->mask[1][1] = 0; T.y->mask[1][1] = 0;}
     2834
     2835The \code{psPlaneDistortion} represents an optical distortion.  The
     2836lowest two terms are the $x$ and $y$ axis of the target system.  The
     2837higher two terms may represent magnitude and color terms.
     2838\begin{verbatim}
     2839typedef struct {
     2840    psDPolynomial4D *x;
     2841    psDPolynomial4D *y;
     2842} psPlaneDistort;
     2843\end{verbatim}
     2844
     2845Like \code{psPlaneTransform}, \code{psPlaneDistort} contains two
     2846\code{psDPolynomial4D} structures representing polynomials of
     2847arbitrary order as a function of four, rather than two dimensions.
     2848There is one of these structures for each of the two output
     2849dimensions.  In this structure, the highest two dimensions could
     2850represent a magnitude and a color.  As an example, consider the simple
     2851transformation from one linear coordinate frame ($x,y$), e.g., on a
     2852CCD, of an object with magnitude and color ($m,c$) to a second frame
     2853($p,q$), e.g., the focal plane. If we have only first order terms in
     2854the transformation \code{psPlaneTransform T}, the new coordinates
     2855would be represented by the terms:
     2856%
     2857\begin{verbatim}
     2858p = T.x->coeff[0][0][0][0] + x*T.x->coeff[1][0][0][0] + y*T.x->coeff[0][1][0][0]
     2859  + m*T.x->coeff[0][0][1][0] + c*T.x->coeff[0][0][0][1]
     2860q = T.y->coeff[0][0][0][0] + x*T.y->coeff[1][0][0][0] + y*T.y->coeff[0][1][0][0]
     2861  + m*T.y->coeff[0][0][1][0] + c*T.y->coeff[0][0][0][1]
     2862\end{verbatim}
     2863%
     2864where we have again excluded the cross-term ($x \times y$) by using the
     2865mask.
     2866
     2867We require corresponding functions to apply the transformations to a
     2868specified coordinate \code{coords}:
     2869%
     2870\begin{verbatim}
     2871psPlane *psPlaneTransformApply (psPlane *out,
     2872                                const psPlaneTransform *transform,
     2873                                const psPlane *coords);
     2874psPlane *psPlaneDistortApply (psPlane *out,
     2875                              const psPlaneDistort *distort,
     2876                              const psPlane *coords,
     2877                              float term3, float term4);
     2878\end{verbatim}
     2879
     2880\subsubsection{Celestial Coordinate Conversions}
     2881
     2882We need to be able to convert between ICRS, Galactic and Ecliptic
     2883coordinates, and potentially between arbitrary spherical coordinate
     2884systems.  All of these basic spherical transformations represent
     2885rotations of the spherical coordinate reference.  We specify a general
     2886transformation function which takes a structure,
     2887\code{psSphereTransform}, defining the transformation between two
     2888spherical coordinate systems (the structure contains the sines and
     2889cosines of the angles involved so as to minimize computation time for
     2890repeated transformations).  We also define a function to generate
     2891\code{psSphereTransform}, based on the three angles
     2892describing the location of the pole and the relative equatorial
     2893rotations of the two systems.  We also specify special functions to
     2894return the \code{psSphereTransform} for transformations
     2895between standard coordinate systems.
     2896
     2897\begin{verbatim}
     2898typedef struct {
     2899    double sinNPlon;                     ///< sin of North Pole longitude
     2900    double cosNPlon;                     ///< cos of North Pole longitude
     2901    double sinNPlat;                     ///< sin of North Pole lattitude
     2902    double cosNPlat;                     ///< cos of North Pole lattitude
     2903    double sinZP;                        ///< sin of First PT of Ares lon
     2904    double cosZP;                        ///< cos of First PT of Ares lon
     2905} psSphereTransform;
     2906\end{verbatim}
     2907
     2908The constructor and destructor are defined as follows:
     2909\begin{verbatim}
     2910psSphereTransform *psSphereTransformAlloc(double NPlon, double NPlat, double ZP);
     2911void psSphereTransformFree(psSphereTransform *trans);
     2912\end{verbatim}
     2913where \code{NPlon} and \code{NPlat} define the coordinates in the
     2914input system of the north pole in the output system and \code{ZP}
     2915defines the longitude in the input system of the equatorial
     2916intersection between the two systems (e.g, the first point of Ares).
     2917
     2918Spherical coordinates may be transformed by providing the
     2919transformation and the coordinate in the input system to
     2920\code{psSphereTransform}:
     2921\begin{verbatim}
     2922psSphere *psSphereTransformApply(psSphere *out,
     2923                                 const psSphereTransform *transform,
     2924                                 const psSphere *coord);
     2925\end{verbatim}
     2926
     2927The following functions simply return the appropriate
     2928\code{psSphereTransform} to convert between predefined spherical
     2929coordinate systems (i.e., {\bf I}CRS, {\bf E}cliptic and {\bf
     2930G}alactic).
     2931%
     2932\begin{verbatim}
     2933psSphereTransform *psSphereTransformItoE(void);
     2934psSphereTransform *psSphereTransformEtoI(void);
     2935psSphereTransform *psSphereTransformItoG(void);
     2936psSphereTransform *psSphereTransformGtoI(void);
     2937\end{verbatim}
     2938
     2939\subsubsection{Projections}
     2940
     2941We require functions to convert between spherical and linear
     2942coordinate systems based on a variety of projections.  The required
     2943projections include:
     2944\begin{itemize}
     2945\item TAN
     2946\item SIN
     2947\item AIT
     2948\item PAR
     2949\item GLS
     2950\end{itemize}
     2951
     2952We specify the following structure \code{psProjection} to define the
     2953parameters of the projection:
     2954\begin{verbatim}
     2955typedef struct {
     2956    double R, D;                         ///< coordinates of projection center
     2957    double Xs, Ys;                       ///< plate-scale in X and Y directions
     2958    psProjectionType type;               ///< projection type
     2959} psProjection;
     2960\end{verbatim}
     2961
     2962The projection type is defined by the following enumerated type \code{psProjectionType}:
     2963\begin{verbatim}
     2964typedef enum {                          ///< type of val is:
     2965    PS_PROJ_TAN,                        ///< Tangent projection
     2966    PS_PROJ_SIN,                        ///< Sine projection
     2967    PS_PROJ_AIT,                        ///< Aitoff projection
     2968    PS_PROJ_PAR,                        ///< Par projection
     2969    PS_PROJ_GLS,                        ///< GLS projection
     2970    PS_PROJ_NTYPE                       ///< Number of types; must be last
     2971} psProjectionType;
     2972\end{verbatim}
     2973
     2974The following functions will project and deproject (respectively)
     2975spherical coordinates:
     2976
     2977\begin{verbatim}
     2978psPlane  *psProject(const psSphere *coord, const psProjection *projection);
     2979psSphere *psDeproject(const psPlane *coord, const psProjection *projection);
     2980\end{verbatim}
     2981
     2982\subsubsection{Offsets}
     2983We require a function to calculate the offset between two positions on
     2984the sky, as well as a function to apply an offset to a position.  The
     2985first determines the offset (RA,Dec) on the sky between two positions.
     2986The second applies the given offset to the coordinate. The offsets may
     2987be of type: \tbd{Linear, Spherical/Arcsec, Spherical/Degreees, etc.}
     2988
     2989\begin{verbatim}
     2990psSphere *psSphereGetOffset(const psSphere *restrict position1,
     2991                            const psSphere *restrict position2,
     2992                            const char *type);
     2993psSphere *psSphereSetOffset(const psSphere *restrict position,
     2994                            const psSphere *restrict offset,
     2995                            const char *type);
     2996\end{verbatim}
     2997Note that these should propagate the errors appropriately.
     2998
     2999%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     3000
     3001\subsection{Astronomical Images}
     3002
     3003\subsubsection{Overview}
     3004
     3005Above, we have defined a basic container for a single 2D collection of
     3006pixels (\code{psImage}), along with basic operations to manipulate the
     3007image pixels.  For astronomical applications, this data structure is
     3008insufficient for two reasons.  First, it does provide sufficient
     3009additional metadata to describe the data in detail.  Second, astronomy
     3010applications frequent involve multiple, related images.  For
     3011PanSTARRS, and for general astronomical applications, we require a
     3012richer collection of data structures which describe a very general
     3013image concept.  We have defined several layers in the hierarchy which
     3014are necessary to describe the image data which will be produced by the
     3015PanSTARRS Gigapixel cameras as well as other standard astronomical
     3016images. 
     3017
     3018A simple 2D image is a basic data unit for much of astronomical
     3019imaging.  If we consider various optical and IR array cameras, a
     3020single readout of the detector produces a collection of pixels
     3021measurements.  We define our lowest-level astronomical image
     3022structure, \code{psReadout}, to contain the pixels produced by a
     3023single readout of the detector, along with metadata needed to define
     3024that readout: the origin and binning of the image relative to the
     3025original detector pixels explicitly in the structure, and pointers to
     3026the general metadata and derived objects, if any.
     3027
     3028A single detector may produce more than one read which is associated.
     3029For example, infrared detectors frequently produce an image
     3030immediately after the detector is reset followed by an image after the
     3031basic exposure is complete.  Both readouts correspond to the same
     3032pixels, though the binning or rastering may be different between the
     3033two readouts.  Another example is the video sequence produced by the
     3034PanSTARRS Gigapix camera guide cells, each of which represents a
     3035series of many images from a subraster of pixels in the detector
     3036readout portion.  The second level of our image container hierarchy,
     3037\code{psCell}, consists of a collection of readouts from a single
     3038detector.
     3039
     3040In the PanSTARRS Gigapix camera, the basic readout region is a
     3041fraction of the full imaging area of a single CCD chip.  The chip is
     3042divided into 64 cells, any fraction of which may have been readout
     3043for a given exposure.  In other cameras, such as Megacam at CFHT, the
     3044individual CCDs have multiple amplifiers addressing contiguous
     3045portions of the detector.  In such cameras, each amplifier produces a
     3046separate collection of pixels.  In the third level of our image
     3047container hierarchy, the data structure \code{psChip} represents a
     3048collection of different cells.   
     3049
     3050The top level of our image container hierarchy is a complete focal
     3051plane array (\code{psFPA}).  This structure represents the collection
     3052of chips in the camera, all of which are read out in a given
     3053exposure. 
     3054
     3055For example, take a mosaic camera consisting of eight $2k\times 4k$
     3056CCDs, each of which is read out through two amplifiers.  Then there
     3057would be sixteen cells in total, each of which is presumably $2k\times
     30582k$.  There would be eight chips, each consisting of two cells, and
     3059the focal plane consists of these eight chips.
     3060
     3061As another example, consider an observation by PS1.  The focal plane
     3062would consist of 60 chips, each of which consist of 64 cells (or less;
     3063a few cells may be dead).  Some cells (those containing guide stars
     3064for the orthogonal transfer) will contain multiple readouts.
     3065
     3066These data structures represent containers with which to carry around
     3067the collection of related image data.  There is no requirement on the
     3068functions or the structures that each instance of one of these data
     3069structures represent the physical hardware.  For example, it is not
     3070necessary that an instance of \code{psFPA} always carry the data for
     3071all 60 (or 64) Gigapixel camera OTAs.  The usage of these structures
     3072is such that all astronomical operations which apply to a CCD image
     3073should be performed on an instance of \code{psFPA}.  If a particular
     3074circumstance only requires a single 2D image, then that is represented
     3075by an instance of \code{psFPA} with one \code{psChip}, which in turn
     3076has one \code{psCell}, which in turn has one \code{psReadout}. 
     3077
     3078These container levels also include in their definition the information
     3079needed to transform the coordinates in one of the levels to the
     3080coordinate system relevant at the higher levels. 
     3081
     3082\subsubsection{A Readout}
     3083
     3084A readout is the result of a single read of a cell (or a portion
     3085thereof).  It contains a pointer to the pixel data, and additional
     3086pointers to the objects found in the readout, and the readout
     3087metadata.  It also contains the offset from the lower-left corner of
     3088the chip, in the case that the CCD was windowed.
     3089
     3090\begin{verbatim}
     3091typedef struct {
     3092    const int x0, y0;                ///< Offset from the lower-left corner
     3093    const int nx, ny;                ///< Image binning
     3094    psImage *image;                  ///< imaging area of cell
     3095    psDlist *objects;                ///< objects derived from cell
     3096    psMetadata *md;                  ///< Readout-level metadata
     3097} psReadout;
     3098\end{verbatim}   
     3099
     3100\subsubsection{A Cell}
     3101
     3102A cell consists of one or more readouts (usually only one except in the
     3103case that the cell has been used for fast guiding).  It also contains
     3104a pointer to the cell metadata, and a pointer to its parent chip.  On
     3105the astrometry side, it also contains coordinate transforms from the
     3106cell to the chip and, as a convenience, from the cell to the focal
     3107plane.  It is expected that these transforms will consist of two
     3108first-order 2D polynomials, simply specifying a translation, rotation
     3109and magnification; hence they are easily inverted, and there is no
     3110need to add reverse transformations.  We also add an additional
     3111transformation, which is intended to provide a ``quick and dirty''
     3112transform from the cell coordinates to the sky; this transformation
     3113not guaranteed to be as precise as the ``standard'' transformation of
     3114Cell $\rightarrow$ Chip $\rightarrow$ Focal Plane $\rightarrow$
     3115Tangent Plane $\rightarrow$ Sky, but will be faster.
     3116
     3117\begin{verbatim}
     3118typedef struct {
     3119    int nReadouts;                      ///< number of readouts in this cell
     3120    struct psReadout *readouts;         ///< Readouts from the cell
     3121    psMetadata *md;                     ///< Cell-level metadata
     3122    psPlaneTransform *cellToChip;       ///< Transformations from cell to chip coords
     3123    psPlaneTransform *cellToFPA;        ///< Transformations from cell to FPA coords
     3124    psPlaneTransform *cellToSky;        ///< Direct from cell to sky coords
     3125    struct psChip  *parentChip;         ///< chip which contains this cell
     3126} psCell;
     3127\end{verbatim}
     3128
     3129\subsubsection{A Chip}
     3130
     3131A chip consists of one or more cells (according to the number of
     3132amplifiers on the CCD).  It contains a pointer to the chip metadata,
     3133and a pointer to the parent focal plane.  For astrometry, it contains
     3134a coordinate transform from the chip to the focal plane.  It is
     3135expected that this transforms will consist of two second-order 2D
     3136polynomials; hence we think that it is prudent to include a reverse
     3137transformation which will be derived from numerically inverting the
     3138forward transformation.
     3139
     3140\begin{verbatim}
     3141typedef struct {
     3142    int nCells;                         ///< Number of Cells assigned
     3143    struct psCell *cells;               ///< Cells in the Chip
     3144    psMetadata *md;                     ///< Chip-level metadata
     3145    psPlaneTransform *chipToFPA;        ///< Transformations from chip to FPA coords
     3146    psPlaneTransform *FPAtoChip;        ///< Transformations from FPA to chip
     3147    struct psFPA *parentFPA;            ///< FPA which contains this chip
     3148} psChip;
     3149\end{verbatim}
     3150
     3151\subsubsection{A Focal Plane}
     3152
     3153A focal plane consists of one or more chips (according to the number
     3154of pieces of contiguous silicon).  It contains pointers to the focal
     3155plane metadata and the exposure information.  For astrometry, it
     3156contains a transformation from the focal plane to the tangent plane
     3157and the fixed pattern residuals.  It is expected that the
     3158transformation will consist of two 4D polynomials (i.e.\ a function of
     3159two coordinates in position, the magnitude of the object, and the
     3160color of the object) in order to correct for optical distortions and
     3161the effects of the atmosphere; hence we think that it is prudent to
     3162include a reverse transformation which will be derived from
     3163numerically inverting the forward transformation.  Since colors are
     3164involved in the transformation, it is necessary to specify the color
     3165the transformation is defined for.  We also include some values to
     3166characterize the quality of the transformation: the root mean square
     3167deviation for the x and y transformation fits, and the $\chi^2$ for
     3168the transformation fit.
     3169
     3170\begin{verbatim}
     3171typedef struct {
     3172    int nChips;                         ///< Number of Cells assigned
     3173    int nAlloc;                         ///< Number of Cells available
     3174    struct psChip *chips;               ///< Chips in the Focal Plane Array
     3175    psMetadata *md;                     ///< FPA-level metadata
     3176    psPlaneDistort *TPtoFP;             ///< Transformation term from
     3177    psPlaneDistort *FPtoTP;             ///< Transformation term from
     3178    psFixedPattern *pattern;            ///< Fixed pattern residual offsets
     3179    const psExposure *exp;              ///< information about this exposure
     3180    psPhotSystem colorPlus, colorMinus; ///< Colour reference
     3181    float rmsX, rmsY;                   ///< Dispersion in astrometric solution
     3182    float chi2;                         ///< chi^2 of astrometric solution
     3183} psFPA;
     3184\end{verbatim}
     3185
     3186\subsubsection{Exposure information}
     3187
     3188We need several quantities from the telescope in order to make a
     3189first guess at the astrometric solution.  From these quantities,
     3190further quantities can be derived and stored for later use.
     3191
     3192\begin{verbatim}
     3193typedef struct {
     3194    const double ra, dec;               ///< Telescope boresight
     3195    const double ha;                    ///< Hour angle
     3196    const double zd;                    ///< Zenith distance
     3197    const double az;                    ///< Azimuth
     3198    const double lst;                   ///< Local Sidereal Time
     3199    const float mjd;                    ///< MJD of observation
     3200    const float rotAngle;               ///< Rotator position angle
     3201    const float temp;                   ///< Air temperature, for estimating refraction
     3202    const float pressure;               ///< Air pressure, for calculating refraction
     3203    const float humidity;               ///< Relative humidity, for refraction
     3204    const float exptime;                ///< Exposure time
     3205    /* Derived quantities */
     3206    const float posAngle;               ///< Position angle
     3207    const float parallactic;            ///< Parallactic angle
     3208    const float airmass;                ///< Airmass, calculated from zenith distance
     3209    const float pf;                     ///< Parallactic factor
     3210    const char *cameraName;             ///< name of camera which provided exposure
     3211    const char *telescopeName;          ///< name of telescope which provided exposure
     3212} psExposure;
     3213\end{verbatim}
     3214
     3215\subsubsection{Constructors and Destructors}
     3216
     3217Each of the above structures needs an appropriate constructor and
     3218destructor.  Other than \code{psExposure}, which contains significant
     3219non-pointer types, the constructors should not take any arguments, and
     3220the destructors should only take the structure to be destroyed.
     3221The constructor for \code{psExposure} is specified below.
     3222
     3223\begin{verbatim}
     3224psExposure *
     3225psExposureAlloc(double ra, double dec,  ///< Telescope boresight
     3226                double ha,              ///< Hour angle
     3227                double zd,              ///< Zenith distance
     3228                double az,              ///< Azimuth
     3229                double lst,             ///< Local Sidereal Time
     3230                float mjd,              ///< MJD
     3231                float rotAngle,         ///< Rotator position angle
     3232                float temp,             ///< Temperature
     3233                float pressure,         ///< Pressure
     3234                float humidity,         ///< Relative humidity
     3235                float exptime);         ///< Exposure time
     3236\end{verbatim}
     3237
     3238\subsection{Astrometry}
     3239
     3240Astrometry is a basic functionality required for the IPP that will be
     3241used repeatedly, both for low-precision (roughly where is my favorite
     3242object?) and high-precision (what is the proper motion of this star?).
     3243As such, it must be flexible, yet robust.  Accordingly, we will wrap
     3244the StarLink Astronomy Libraries (SLALib), which has already been
     3245developed.
     3246
     3247\subsubsection{Coordinate frames}
     3248\label{sec:coordinateFrames}
     3249
     3250There are five coordinate frames that we need to worry about for the
     3251purposes of astrometry:
     3252\begin{itemize}
     3253\item Cell: $(x,y)$ in pixels --- raw coordinates;
     3254\item Chip: $(X,Y)$ in pixels --- the location on the silicon;
     3255\item Focal Plane: $(p,q)$ in microns --- the location on the focal plane;
     3256\item Tangent Plane: $(l,m)$ in arcsec from the telescope boresight; and
     3257\item Sky: (RA,Dec) --- ICRS.
     3258\end{itemize}
     3259
     3260The following steps are required to convert from the cell coordinates to
     3261the sky:
     3262\begin{itemize}
     3263\item Cell $\longleftrightarrow$ Chip: two 2D polynomials, $(X,Y) = f(x,y)$;
     3264\item Chip $\longleftrightarrow$ FP: two 2D polynomials, $(p,q) = g(X,Y)$;
     3265\item FP $\longleftrightarrow$ TP: two 4D polynomials, $(l,m) =
     3266h(p,q,m,c)$, where $m$ and $c$ are the magnitude and color of the
     3267object, respectively; and
     3268\item TP $\longleftrightarrow$ Sky: SLALib transformation using a
     3269transform pre-computed for each pointing.
     3270\end{itemize}
     3271
     3272Note that the transformation between the Focal Plane and the Tangent
     3273Plane is a four-dimensional polynomial, in order to account for any
     3274possible dependencies in the astrometry on the stellar magnitude and
     3275color; the former serves as a check for charge transfer
     3276inefficiencies, while the latter will correct chromatic refraction,
     3277both through the atmosphere and the corrector lenses.
     3278
     3279We require structures to contain each of the above transformations as
     3280well as the pixel data.
     3281
     3282\subsubsection{SLALib information}
     3283
     3284SLALib requires several elements to perform the transformations
     3285between the tangent plane and the sky.  Pre-computing these quantities
     3286for each exposure means that subsequent transformations are faster.
     3287For historical reasons, this structure is known colloquially as
     3288``Wallace's Grommit''.
     3289
     3290\begin{verbatim}
     3291typedef struct {
     3292    const double latitude;              ///< geodetic latitude (radians)
     3293    const double sinLat, cosLat;        ///< sine and cosine of geodetic latitude
     3294    const double abberationMag;         ///< magnitude of diurnal aberration vector
     3295    const double height;                ///< height (HM)
     3296    const double temperature;           ///< ambient temperature (TDK)
     3297    const double pressure;              ///< pressure (PMB)
     3298    const double humidity;              ///< relative humidity (RH)
     3299    const double wavelength;            ///< wavelength (WL)
     3300    const double lapseRate;             ///< lapse rate (TLR)
     3301    const double refractA, refractB;    ///< refraction constants A and B (radians)
     3302    const double longitudeOffset;       ///< longitude + ... (radians)
     3303    const double siderealTime;          ///< local apparent sidereal time (radians)
     3304} psGrommit;
     3305\end{verbatim}
     3306
     3307The \code{psGrommit} is calculated from telescope information for the
     3308particular exposure:
     3309\begin{verbatim}
     3310psGrommit *psGrommitAlloc(const psExposure *exp);
     3311void psGrommitFree(psGrommit *grommit);
     3312\end{verbatim}
     3313
     3314\subsubsection{Fixed Pattern}
     3315
     3316The fixed pattern is a correction to the general astrometric solution
     3317formed by summing the residuals from many observations.  The intent is
     3318to correct for higher-order distortions in the camera system on a
     3319coarse grid (larger than individual pixels, but smaller than a single
     3320cell).  Hence, in addition to the offsets, we need to specify the size
     3321and scale of the grid in $x$ and $y$, as well as the origin of the
     3322grid.
     3323
     3324\begin{verbatim}
     3325typedef struct {
     3326    int nX, nY;                         ///< Number of elements in x and y
     3327    double x0, y0;                      ///< Position of 0,0 corner on focal plane
     3328    double xScale, yScale;              ///< Scale of the grid
     3329    double **x, **y;                    ///< The grid of offsets in x and y
     3330} psFixedPattern;
     3331\end{verbatim}
     3332
     3333\subsubsection{Position Finding}
     3334
     3335We require functions to return the structure containing given
     3336coordinates.  For example, we want the chip that corresponds to the
     3337focal plane coordinates $(p,q) = (-1.234,+5.678)$.  These routines
     3338handle the one-to-many problem --- i.e., for one given focal plane
     3339coordinate, there are many chips that this coordinate may be
     3340correspond to; these functions will select the correct one.
     3341%
     3342\begin{verbatim}
     3343psCell *psCellInFPA (psCell *out, const psPlane *coord, const psFPA *fpa);
     3344psChip *psChipInFPA (psChip *out, const psPlane *coord, const psFPA *fpa);
     3345psCell *psCellInChip(psCell *out, const psPlane *coord, const psChip *chip);
     3346\end{verbatim}
     3347
     3348\subsubsection{Conversion Functions}
     3349
     3350We require functions to convert between the various coordinate frames
     3351(Section~\ref{sec:coordinateFrames}).  The hierarchy of the coordinate
     3352frames and the transformations between each are shown in
     3353Figure~\ref{fig:coco}.  The functions that employ the transformations
     3354are shown in Figure~\ref{fig:cocoFunc}.  In addition to
     3355transformations between each adjoining coordinate frame in the
     3356hierarchy, we also require higher-level functions to convert between
     3357the Cell and Sky coordinate frames; these will simply perform the
     3358intermediate steps.
     3359
     3360\begin{figure}
     3361\psfig{file=coordinateFrames,height=7in,angle=-90}
     3362\caption{The coordinate systems in the \PS{} IPP, and the relation
     3363between each by transformations contained in the appropriate
     3364structures.}
     3365\label{fig:coco}
     3366\end{figure}
     3367
     3368\begin{figure}
     3369\psfig{file=coordinateConv,height=7in,angle=-90}
     3370\caption{Conversion between coordinate systems by PSLib.}
     3371\label{fig:cocoFunc}
     3372\end{figure}
     3373
     3374We specify the following functions to convert between coordinates in
     3375one type of frame to another type of frame.  The first group consist
     3376of unambiguous transformations: from the coordinates in a low-level
     3377frame to the coordinates in the containing higher-level frame, of
     3378which only one exists.  In all of these functions, the output
     3379coordinate structure may be \code{NULL} or may be supplied by the
     3380calling function.  In the former case, the structure must be
     3381allocated; in the latter case, the supplied structure must be used.
     3382
     3383\begin{verbatim}
     3384psPlane *psCoordCelltoChip (psPlane *out, const psPlane *in, const psCell *cell);
     3385\end{verbatim}
     3386which converts coordindates \code{in} on the specified \code{cell} to
     3387the coordinates on the parent chip.
     3388
     3389\begin{verbatim}
     3390psPlane *psCoordChiptoFPA (psPlane *out, const psPlane *in, const psChip *chip);
     3391\end{verbatim}
     3392which converts the coordinates \code{in} on the specified \code{chip}
     3393to the coordinates on the parent FPA.
     3394
     3395\begin{verbatim}
     3396psPlane *psCoordFPAToTP(psPlane *out, const psPlane *in, const psFPA *fpa);
     3397\end{verbatim}
     3398which converts coordinates \code{in} on the specified focal plane
     3399\code{fpa} to tangent plane coordinates, applying the appropriate
     3400distortion terms.
     3401
     3402\begin{verbatim}
     3403psSphere *psCoordTPtoSky(psSphere *out, const psPlane *in, const psGrommit *grommit);
     3404\end{verbatim}
     3405which converts the tangent plane coordinates \code{in} to (RA,Dec) on
     3406the sky, based on the environmental information specified by
     3407\code{grommit}.
     3408
     3409\begin{verbatim}
     3410psPlane *psCoordCellToFPA(psPlane *out, const psPlane *in, const psCell *cell);
     3411\end{verbatim}
     3412which performs the single-step conversion between Cell coordinates
     3413\code{in} and FPA coordinates.
     3414
     3415\begin{verbatim}
     3416psSphere *psCoordCellToSky(psSphere *out, const psPlane *in, const psCell *cell);
     3417\end{verbatim}
     3418which converts coordinates on the specified cell to (RA,Dec).  This
     3419transformation must be performed using the intermediate stage
     3420transformations of Cell to Chip, Chip to FPA, FPA to Tangent Plane,
     3421Tangent Plane to Sky.  The information needed for each of these
     3422transformations is available in the \code{.parent} elements of
     3423\code{psCell} and \code{psChip}, and the \code{psFPA.exposure}
     3424element.
     3425
     3426\begin{verbatim}
     3427psSphere *psCoordCellToSkyQD(psSphere *out, const psPlane *in, const psCell *cell);
     3428\end{verbatim}
     3429which uses the 'quick-and-dirty' transformation to convert coordinates
     3430on the specified cell to (RA,Dec).  This transformation should use the
     3431locally linear transformation specified by the element
     3432\code{psCell.cellToSky}.  Although the accuracy of this transformation
     3433is lower than the complete transformation above, the calculation is
     3434substantially faster as it only involves linear transformations.
     3435
     3436The following functions convert from high-level frames to the
     3437coordinates of contained lower-level frames. 
     3438
     3439\begin{verbatim}
     3440psPlane *psCoordSkyToTP(psPlane *out, const psSphere *in, const psGrommit *grommit);
     3441\end{verbatim}
     3442which converts (RA,Dec) coordinates \code{in} to tangent plane coords
     3443based on the enviromental information supplied by \code{grommit}.
     3444
     3445\begin{verbatim}
     3446psPlane *psCoordTPtoFPA(psPlane *out, const psPlane *in, const psFPA *fpa);
     3447\end{verbatim}
     3448which converts the tangent plane coordinates \code{in} to focal plane coordinates.
     3449
     3450\begin{verbatim}
     3451psPlane *psCoordFPAtoChip (psPlane *out, const psPlane *in, const psChip *chip);
     3452\end{verbatim}
     3453which converts the specified FPA coordinates \code{in} to the
     3454coordinates on the given Chip.  The specified chip need not contain
     3455the input coordinate.  To find the chip which contains a particular
     3456coordinate, the function \code{psChipInFPA}, defined above, should be
     3457used.
     3458
     3459\begin{verbatim}
     3460psPlane *psCoordChiptoCell (psPlane *out, const psPlane *in, const psCell *cell);
     3461\end{verbatim}
     3462which converts the specified Chip coordinate \code{in} to the
     3463coordinate on the given Cell.  The specified Cell need not contain the
     3464input coordinate.  To find the cell which contains a particular
     3465coordinate, the function \code{psCellInChip}, defined above, should be
     3466used.
     3467
     3468\begin{verbatim}
     3469psPlane *psCoordSkyToCell(psPlane *out, const psSphere *in, psCell *cell);
     3470\end{verbatim}
     3471which directly converts (RA,Dec) \code{in} to coordinates on the
     3472specified cell.  The specified cell need not contain the input
     3473coordinates.
     3474
     3475\begin{verbatim}
     3476psPlane *psCoordSkyToCellQD(psPlane *out, const psSphere *in, psCell *cell);
     3477\end{verbatim}
     3478which directly converts (RA,Dec) \code{in} to coordinates on the
     3479specified cell.  The specified cell need not contain the input
     3480coordinates.  This transformation should use the locally linear
     3481transformation specified by the element \code{psCell.cellToSky}.
     3482Although the accuracy of this transformation is lower than the
     3483complete transformation above, the calculation is substantially faster
     3484as it only involves linear transformations.
     3485
     3486\subsubsection{Additional functions}
     3487
     3488We require additional functions to perform general functions which
     3489will be useful for astrometry.  Given coordinates on the sky, we
     3490need to get the airmass, the parallactic angle, and an estimate of
     3491the atmospheric refraction.
     3492
     3493\begin{verbatim}
     3494float psGetAirmass(const psSphere *coord, double siderealTime, float height);
     3495\end{verbatim}
     3496which returns the airmass for a given position and sidereal time.
     3497
     3498\begin{verbatim}
     3499float psGetParallactic(const psSphere *coord, double siderealTime);
     3500\end{verbatim}
     3501which returns the parallactic angle for a given position and sidereal time.
     3502
     3503\begin{verbatim}
     3504float psGetRefraction(float colour,            ///< Colour of object
     3505                      psPhotSystem colorPlus,  ///< Colour reference
     3506                      psPhotSystem colorMinus, ///< Colour reference
     3507                      const psExposure *exp);  ///< Telescope pointing information
     3508\end{verbatim}
     3509which provides an estimate of the atmospheric refraction, along the parallactic angle.
     3510
     3511\begin{verbatim}
     3512double psGetParallaxFactor(const psExposure *exp)
     3513\end{verbatim}
     3514Calculate the parallax factor for the given exposure \tbd{why do we
     3515  need this?}.
     3516
     3517%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     3518
     3519\subsection{Photometry}
     3520
     3521Photometric observations are performed in an instrumental photometric
     3522system, and must be related to other photometric systems.  We
     3523require a data structure which defines a photometric system, as well
     3524as a structure to define the transformation between photometric
     3525systems.
     3526
     3527The photometric system is defined by the psPhotSystem structure. 
     3528A photometric system is identified by a human-readable \code{name}
     3529(ie, SDSS.g, Landolt92.B, GPC1.OTA32.r).  Each photometric system is
     3530given a unique identifier \code{ID}.  Observations taken with a
     3531specific camera, detector, and filter represent their own photometric
     3532system, and it may be necessary to perform transformations between
     3533these systems.  Photometric systems associated with observations from
     3534a specific camera/detector/filter combination can be associated with
     3535those components.
     3536\begin{verbatim}
     3537typedef struct {
     3538    const int ID;                       ///< ID number for this photometric system
     3539    const char *name;                   ///< Name of photometric system
     3540    const char *camera;                 ///< Camera for photometric system
     3541    const char *filter;                 ///< Filter used for photometric system
     3542    const char *detector;               ///< Detector used for photometric system
     3543} psPhotSystem;
     3544\end{verbatim}
     3545
     3546The following structure defines the transformation between two
     3547photometric systems.
     3548\begin{verbatim}
     3549typedef struct {
     3550    psPhotSystem src;                   ///< Source photometric system
     3551    psPhotSystem dst;                   ///< Destination photometric system
     3552    psPhotSystem pP, pM;                ///< Primary color reference
     3553    psPhotSystem sP, sM;                ///< Secondary color reference
     3554    float pA, sA;                       ///< Color offset for references
     3555    psPolynomial3D transform;           ///< Transformation from source to destination
     3556} psPhotTransform;
     3557\end{verbatim}
     3558
     3559The transformation between two photometric systems may depend on the
     3560airmass of the observation and on the colors of the object of
     3561interest.  For a specific observation, such a transformations can be
     3562defined as a polynomial function of the color of the star and the
     3563airmass of the observations.  If sufficient data exists, the
     3564transformation between the photometric systems may include more than
     3565one color, constraining the curvature of the stellar spectral energy
     3566distributions.  This latter term may be significant for stars which
     3567are highly reddened, for example.  Derived photometric quantities may
     3568have been corrected for airmass variations, in which case only color
     3569terms may be measurable.  The structure defines the transformation
     3570between a source photometric system (\code{src}) and a target
     3571photometric system (\code{dst}).  The photometric system of a primary
     3572color is defined by \code{pP, pM} such that the color is constructed
     3573as $pP - pM$.  A secondary color is defined by \code{sP, sM}.  For
     3574both, a reference color is specified (\code{pA, sA}): the polynomial
     3575transformation terms refer to colors in the form $pP - pM - pA$.  The
     3576transformation is specified as a 3D polynomial.  For a star of
     3577magnitude $M_{\rm src}$ in the source photometric system, with
     3578additional magnitude information in the other systems $M_{\rm pP}$,
     3579$M_{\rm pM}$, $M_{\rm sP}$, $M_{\rm sM}$, observed at an airmass of
     3580$z$, the magnitude of the star in the target system $M_{\rm dst}$ is
     3581given by: $M_{\rm dst} = M_{\rm src} + transform(z, M_{\rm pP} -
     3582M_{\rm pM} - pA, M_{\rm sP} - M_{\rm sM} - sA)$.
     3583
     3584%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     3585
     3586\subsection{Astronomical objects}
     3587
     3588\subsubsection{Positions of Major SS Objects}
     3589
     3590We require the ability to calculate the position of major Solar System
     3591objects, as well as Lunar phase.  These functions all take the
     3592specified modified julian date, \code{mjd}, and the latitude/longitude
     3593of the observer.
     3594
     3595\begin{verbatim}
     3596psSphere *psSunGetPos(psTime time);
     3597psTime *psSunGetRise (psTime *twi15, psTime *twi18, psTime time);
     3598psTime *psSunGetSet (psTime *twi15, psTime *twi18, psTime time);
     3599
     3600psSphere *psMoonGetPos(psTime time, psSphere location);
     3601psTime *psMoonGetRise (psTime *twi15, psTime *twi18, psTime time);
     3602psTime *psMoonGetSet (psTime *twi15, psTime *twi18, psTime time);
     3603float psGetMoonPhase(psTime time);
     3604
     3605psSphere *psPlanetGetPos(psTime time, psSphere location);
     3606psTime *psPlanetGetRise (psTime *twi15, psTime *twi18, psTime time);
     3607psTime *psPlanetGetSet (psTime *twi15, psTime *twi18, psTime time);
     3608
     3609\end{verbatim}
     3610
     3611%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     3612
     3613\appendix
     3614
     3615\pagebreak
     3616\section{API Summary: all functions}
     3617
     3618\subsection{System Utilities}
     3619\input{psSystemGroup.tex}
     3620
     3621\subsection{Data Containers}
     3622\input{psDataGroup.tex}
     3623
     3624\subsection{Math Utilities}
     3625\input{psMathGroup.tex}
     3626 
     3627\subsection{Astronomy Functions}
     3628\input{psAstroGroup.tex}
     3629
     3630\pagebreak
     3631\section{API Summary: all structures}
     3632\input{psStructures.tex}
     3633
     3634\section{Revision Change Log}
     3635\input{ChangeLogSDRS.tex}
     3636
     3637\bibliographystyle{plain} \bibliography{panstarrs}
     3638
     3639\end{document}
     3640
    27583641
    27593642An example of the usage of the metadata APIs is as follows:
     
    27943677\null\qquad\qquad\code{IPP.phase1.ota12.biassec}.
    27953678
    2796 We shall set in place a system for assigning the top-level `domains'
     3679We must set in place a system for assigning the top-level `domains'
    27973680to responsible individuals, and for gathering a complete list of
    27983681all metadata names in use throughout the project.
     
    28153698    }
    28163699\end{verbatim}
    2817 
    2818 It is an unfortunate fact that certain metadata keywords (such as
    2819 \code{COMMENT} and \code{HISTORY} in a FITS header) may be repeated
    2820 with different values.  The \code{psMetadataAppend} routine is
    2821 required to check that all metadata names are unique unless the type
    2822 is qualified as \code{PS_META_NON_UNIQUE}; in this case a unique
    2823 integer will be added to each name that you specify. In this case, you
    2824 may either delete individual element separately or as a complete set:
    2825 \begin{verbatim}
    2826 psMetadataItemFree(psMetadataRemove(ms, "lang.hello.0"));
    2827 psMetadataItemFree(psMetadataRemove(ms, "lang.hello"));
    2828 \end{verbatim}
    2829 
    2830 \subsubsection{Metadata APIs}
    2831 
    2832 In this section, we explain the metadata APIs more fully.
    2833 
    2834 The allocator for \code{psMetadataItem} returns a full
    2835 \code{psMetadataItem} ready for insertion into the
    2836 \code{psMetadata}.  It is important to note that, in order to
    2837 support multiple types, the data being input must be a pointer, even
    2838 if it is a \code{float} or \code{int}, for example.  The name of the
    2839 \code{psMetadataItem} takes a \code{sprintf} format string, with the
    2840 corresponding arguments following.
    2841 
    2842 Note that the destructor for \code{psMetadataItem} must call the
    2843 appropriate destructor for the \code{val} (recall that it is the duty
    2844 of the \code{psMyTypeFree}s to decrement the \code{refCounter} and
    2845 free the memory if and only if the \code{refCounter == 1} --- see
    2846 \S\ref{sec:free}).
    2847 
    2848 \begin{verbatim}
    2849 /** Constructor */
    2850 psMetadataItem *psMetadataItemAlloc(int typeFlags, ///< type of this piece of metadata + flags
    2851                                     const void *val, ///< value of new item N.b. a pointer even if the item
    2852                                                      ///< is of type e.g. int
    2853                                     const char *comment, ///< comment associated with item
    2854                                     const char *name, ///< name of new item of metadata (may be in sprintf
    2855                                                       ///< format)
    2856                                     ... ///< possible arguments for name format
    2857     );
    2858 
    2859 /** Destructor */
    2860 void psMetadataItemFree(psMetadataItem *ms ///< piece of metadata to destroy
    2861     );
    2862 \end{verbatim}
    2863 
    2864 
    2865 The constructor for the collection of metadata, \code{psMetadata},
    2866 simply returns an empty metadata container (employing the constructors
    2867 for the doubly-linked list and hash table).  The destructor needs to
    2868 free each of the \code{psMetadataItem}s using
    2869 \code{psMetadataItemFree}.
    2870 
    2871 \begin{verbatim}
    2872 /** Constructor */
    2873 psMetadata *psMetadataAlloc(void);   ///< make a new set of metadata
    2874 
    2875 /** Destructor */
    2876 void psMetadataFree(psMetadata *md ///< destroy a set of metadata
    2877     );
    2878 \end{verbatim}
    2879 
    2880 
    2881 Items may be added to the metadata in one of two ways --- firstly, an
    2882 item may be added by appending a \code{psMetadataItem} which has
    2883 already been created; and secondly by directly providing the data to
    2884 be appended.  In both cases, the \code{psMetadataItem} that is
    2885 appended to the metadata is returned.
    2886 
    2887 \begin{verbatim}
    2888 /// Add item to the end of the metadata
    2889 psMetadataItem *psMetadataAppendItem(psMetadata *restrict md, ///< metadata to add to
    2890                                      psMetadataItem *restrict item ///< Metatdata to add
    2891     );
    2892 
    2893 /// Add item to the end of the metadata.  Combines psMetadataItemAlloc and psMetadataAppendItem
    2894 psMetadataItem *psMetadataAppend(psMetadata *restrict md, ///< Metadata to add to
    2895                                  int typeFlags ///< type of this piece of metadata + flags
    2896                                  const void *val, ///< value of new item N.b. a pointer even if the item
    2897                                                   ///< is of type e.g. int
    2898                                  const char *comment, ///< comment associated with item
    2899                                  const char *name, ///< name of new item of metadata (may be in sprintf
    2900                                                    ///< format)
    2901                                  ...    ///< possible arguments for name format
    2902     );
    2903 \end{verbatim}
    2904 
    2905 Items may be removed from the metadata by specifying a key.  If the
    2906 key matches a metadata item, the item is removed from the metadata and
    2907 returned; otherwise, \code{NULL} is returned.  If the key is not
    2908 unique, then \emph{all} items corresponding to the key are removed,
    2909 and the \tbd{first} item is returned.
    2910 
    2911 Care should be taken not to leak memory when appending an item for
    2912 which the key already exists in the metadata (and is not
    2913 \code{PS_META_NON_UNIQUE}).
    2914 
    2915 \begin{verbatim}
    2916 /// delete entry from the metadata
    2917 psMetadataItem *psMetadataRemove(psMetadata *restrict md, ///< metadata to delete from
    2918                                  const char *restrict key ///< Key to delete
    2919     );
    2920 \end{verbatim}
    2921 
    2922 The metadata may be iterated over by (re-)setting the iterator for the
    2923 appropriate \code{psMetadata}, and getting the next item.
    2924 \code{psMetadataGetNext} has the ability to match the beginning of a
    2925 key, e.g., if the user only wants to iterate through
    2926 \code{IPP.machines.sky} and doesn't want to bother with
    2927 \code{IPP.machines.detector}.  The iterator should iterate over every
    2928 item of metadata --- even those that are non-unique.
    2929 
    2930 \begin{verbatim}
    2931 /// reset the iterator to the start of the list
    2932 void psMetadataSetIterator(psMetadata *md ///< metadata to set iterator for
    2933     );
    2934 
    2935 /// get the next item in the sequence
    2936 psMetadataItem *psMetadataGetNext(psMetadata *restrict md, ///< metadata to get from
    2937                                   const char *restrict match, ///< Match this
    2938                                   int which ///< Which iterator to use
    2939     );
    2940 \end{verbatim}
    2941 
    2942 Items may be found within the metadata by providing a key.  In the
    2943 event that the key is non-unique, the first item is returned.
    2944 
    2945 \begin{verbatim}
    2946 /// find the metadata with the specified key
    2947 psMetadataItem *psMetadataLookup(const psMetadata *restrict md, ///< metadata to look up
    2948                                  const char *restrict key ///< Key to find
    2949     );
    2950 \end{verbatim}
    2951 
    2952 Metadata items may be printed to an open file descriptor, optionally
    2953 pre-pending a specified string.
    2954 
    2955 \begin{verbatim}
    2956 /// print metadata item to the specified stream
    2957 void psMetadataItemPrint(FILE *fd,              ///< file descriptor to write to
    2958                          const psMetadataItem *restrict md, ///< item of metadata to print
    2959                          const char *prefix        ///< print this at the beginning of each line
    2960     );
    2961 \end{verbatim}
    2962 
    2963 \subsection{Detector and sky positions}
    2964 
    2965 Both detector and sky positions will be used extensively in the IPP.
    2966 The first are linear coordinates which conform to Euclidean geometry
    2967 while the second are angular coordinates for which additional care
    2968 must often be taken.  We put these into two structures,
    2969 \code{psPlaneCoord} and \code{psSphereCoord}, respectively.
    2970 Partitioning these two will enable error-checking.
    2971 
    2972 \begin{verbatim}
    2973 /** A point in 2-D space, with errors. */
    2974 typedef struct {
    2975     double x;                           ///< x position
    2976     double y;                           ///< y position
    2977     double xErr;                        ///< Error in x position
    2978     double yErr;                        ///< Error in y position
    2979 } psPlaneCoord;
    2980 
    2981 /** A point on the surface of a sphere, with errors */
    2982 typedef struct {
    2983     double r;                           ///< RA
    2984     double d;                           ///< Dec
    2985     double rErr;                        ///< Error in RA
    2986     double dErr;                        ///< Error in Dec
    2987 } psSphereCoord;
    2988 \end{verbatim}
    2989 
    2990 Three major classes of coordinate transformations are necessary.
    2991 First, linear coordinates from one frame must be converted to linear
    2992 coordinates in a different frame of references.  Simple transformations
    2993 of this type are independent of other quantities of the positions --
    2994 they are simply mapping between two linear spaces.  In practice, these
    2995 transformations may often be a function of the magnitude or color of
    2996 the imaged object.  The second type of conversion is the
    2997 transformation of linear coordinates to angular coordinates and
    2998 vice-versa.  This conversion depends on the desired projection, and
    2999 may represent the real mapping performed by the telescope or may
    3000 simply represent a convenient mechanism to display 3D coordinates in
    3001 useful forms.  The third conversion of interest is the transformation
    3002 of one set of spherical coordinates to another set.  Frequently in
    3003 astronomy, these conversions consist only of rotations between the two
    3004 spherical coordinates systems, where the coordinates of the pole and
    3005 equatorial rotation between the two systems define the
    3006 transformation.  Conversions between standard coordinate systems such
    3007 as Galactic, Ecliptic, and various epochs of the Celestial coordinates
    3008 are represented by these spherical transformations. 
    3009 
    3010 \subsubsection{Linear Coordinate Transformations}
    3011 
    3012 We specify two types of transforms between coordinate systems.  The
    3013 first consists simply of two 2D polynomials to transform both
    3014 components -- the output coordinates depend only on the input
    3015 coordinates and no other quantities of objects at those coordinates.
    3016 The second consists of two 4D polynomials in which the output
    3017 coordinates are also specified to be a function of the magnitude and
    3018 color of the object with the given coordinates.  This type of
    3019 coordinate transformation is necessary to represent the
    3020 (color-dependent) optical distortions caused by the atmosphere and
    3021 camera optics, and the possibly effects of charge transfer
    3022 inefficiency.  We specify two structures to represent the coefficients
    3023 of these transformations:
    3024 
    3025 \begin{verbatim}
    3026 /** A polynomial transformation between coordinate frames.  This may be a linear relationship, or may
    3027  *  represent a higher-order transformation.
    3028  */
    3029 typedef struct {
    3030     psDPolynomial2D *x;
    3031     psDPolynomial2D *y;
    3032 } psPlaneCoordXform;
    3033 \end{verbatim}
    3034 
    3035 The \code{psDPolynomial2D} structures represent polynomials of
    3036 arbitrary order as a function of two dimensions.  There is one of
    3037 these structures for each of the two output dimensions.  As an
    3038 example, consider the simple transformation from one linear coordinate
    3039 frame \code{x,y} (say a single CCD) to a second frame \code{p,q} (say,
    3040 a second CCD image). If we have only first order terms in the
    3041 transformation \code{psPlaneCoordXform T}, the new coordinates would be
    3042 represented by the terms:
    3043 %
    3044 \begin{verbatim}
    3045 p = T.x->coeff[0][0] + x*T.x->coeff[1][0] + y*T.x->coeff[0][1];
    3046 q = T.y->coeff[0][0] + x*T.y->coeff[1][0] + y*T.y->coeff[0][1];
    3047 \end{verbatim}
    3048 %
    3049 where we have excluded the basic cross-term (\code{x*y}) by using the
    3050 mask: \code{T.x->mask[1][1] = 0; T.y->mask[1][1] = 0;}
    3051 
    3052 \begin{verbatim}
    3053 /** The optical distortion terms.  The lowest two terms are the x and y axis of the target system.  The higher
    3054  *  two terms represent magnitude and color terms.
    3055  */
    3056 typedef struct {
    3057     psDPolynomial4D *x;
    3058     psDPolynomial4D *y;
    3059 } psPlaneDistortion;
    3060 \end{verbatim}
    3061 
    3062 Like \code{psPlaneCoordXform}, \code{psPlaneDistortion} contains two
    3063 \code{psDPolynomial4D} structures representing polynomials of
    3064 arbitrary order as a function of four, rather than two dimensions.
    3065 There is one of these structures for each of the two output
    3066 dimensions.  In this structure, the highest two dimensions could
    3067 represent a magnitude and a color.  As an example, consider the simple
    3068 transformation from one linear coordinate frame \code{x,y} (say a
    3069 single CCD) of an object with magnitude and color \code{m,c} to a
    3070 second frame \code{p,q} (say, a second CCD image). If we have only
    3071 first order terms in the transformation \code{psPlaneCoordXform T}, the new
    3072 coordinates would be represented by the terms:
    3073 %
    3074 \begin{verbatim}
    3075 p = T.x->coeff[0][0][0][0] + x*T.x->coeff[1][0][0][0] + y*T.x->coeff[0][1][0][0] + m*T.x->coeff[0][0][1][0]
    3076     + c*T.x->coeff[0][0][0][1]
    3077 q = T.y->coeff[0][0][0][0] + x*T.y->coeff[1][0][0][0] + y*T.y->coeff[0][1][0][0] + m*T.y->coeff[0][0][1][0]
    3078     + c*T.y->coeff[0][0][0][1]
    3079 \end{verbatim}
    3080 %
    3081 where we have again excluded the cross-terms (\code{x*y}) by using the
    3082 mask.
    3083 
    3084 We require corresponding functions to apply the transformations:
    3085 %
    3086 \begin{verbatim}
    3087 /** apply the coordinate transformation to the given coordinate */
    3088 psPlaneCoord *psPlaneCoordXformApply (psPlaneCoord *out, ///< Output coordinates, or NULL
    3089                                       const psPlaneCoordXform *frame, ///< coordinate transformation
    3090                                       const psPlaneCoord *coords ///< input coordiate
    3091     );
    3092 
    3093 /** apply the optical distortion to the given coordinate, magnitude, color */
    3094 psPlaneCoord *psPlaneDistortionApply (psPlaneCoord *out, ///< Output coordinates, or NULL
    3095                                       const psPlaneDistortion *pattern, ///< optical distortion pattern
    3096                                       const psPlaneCoord *coords, ///< input coordinate
    3097                                       float mag, ///< magnitude of object
    3098                                       float color ///< color of object
    3099     );
    3100 \end{verbatim}
    3101 %
    3102 
    3103 \subsubsection{Celestial Coordinate Conversions}
    3104 
    3105 We need to be able to convert between ICRS, Galactic and Ecliptic
    3106 coordinates, and potentially between arbitrary spherical coordinate
    3107 systems.  All of these basic spherical transformations represent
    3108 rotations of the spherical coordinate reference.  We specify a general
    3109 transformation function which takes a structure,
    3110 \code{psSphereCoordTransformation}, defining the transformation
    3111 between two spherical coordinate systems (the structure contains the
    3112 sines and cosines of the angles involved so as to minimize computation
    3113 time for repeated transformations).  We also define a function to
    3114 generate \code{psSphereCoordTransformation}, based on the three angles
    3115 describing the location of the pole and the relative equatorial
    3116 rotations of the two systems.  We also specify special functions to
    3117 return the \code{psSphereCoordTransformation} for transformations
    3118 between standard coordinate systems.
    3119 
    3120 \begin{verbatim}
    3121 /** General spherical transformation */
    3122 typedef struct {
    3123     double sin1, sin2, sin3, cos1, cos2, cos3; ///< Sines and cosines for transformation
    3124 } psSphereCoordTransformation;
    3125 \end{verbatim}
    3126 
    3127 The constructor and destructor are defined as follows:
    3128 
    3129 \begin{verbatim}
    3130 /** Constructor */
    3131 psSphereCoordTransformation *
    3132 psSphereCoordTransformationAlloc(double pole1, ///< First location of pole
    3133                                  double pole2, ///< Second location of pole
    3134                                  double rotation ///< Rotation between systems
    3135     );
    3136 
    3137 /** Destructor */
    3138 void psSphereCoordTranformationFree(psSphereCoordTransformation *trans ///< Transformation to destroy
    3139     );
    3140 \end{verbatim}
    3141 
    3142 Spherical coordinates may be transformed by providing the transformation to
    3143 \code{psSphereCoordTransform}:
    3144 
    3145 \begin{verbatim}
    3146 /** Apply general spherical transformation */
    3147 psSphereCoord *
    3148 psSphereCoordTransform(const psSphereCoord *coord, ///< Coordinates to convert
    3149                        psSphereCoordSystem *sys ///< System to use to convert
    3150     );
    3151 \end{verbatim}
    3152 
    3153 The following functions simply return the appropriate
    3154 \code{psSphereCoordTransformation} to convert between predefined
    3155 spherical coordinate systems (i.e., ICRS, Ecliptic and Galactic).
    3156 
    3157 \begin{verbatim}
    3158 /** Return transformation structure to convert ICRS to Ecliptic */
    3159 psSphereCoordTransformation *psSphereCoordTransformationItoE(void);
    3160 
    3161 /** Return transformation structure to convert Ecliptic to ICRS */
    3162 psSphereCoordTransformation *psSphereCoordTransformationEtoI(void);
    3163 
    3164 /** Return transformation structure to convert ICRS to Galactic */
    3165 psSphereCoordTransformation *psSphereCoordTransformationItoG(void);
    3166 
    3167 /** Return transformation structure to convert Galactic to ICRS */
    3168 psSphereCoordTransformation *psSphereCoordTransformationGtoI(void);
    3169 \end{verbatim}
    3170 
    3171 
    3172 \subsubsection{Projections}
    3173 
    3174 We require functions to convert between spherical and linear
    3175 coordinate systems based on a variety of projections.  The required
    3176 projections include:
    3177 \begin{itemize}
    3178 \item TAN
    3179 \item SIN
    3180 \item AIT
    3181 \item PAR
    3182 \item GLS
    3183 \end{itemize}
    3184 
    3185 The following functions will project and deproject (respectively)
    3186 spherical coordinates:
    3187 
    3188 \begin{verbatim}
    3189 /** Project spherical system onto a plane */
    3190 psPlaneCoord *
    3191 psCoordProject(const psSphereCoord *coord, ///< Spherical coordinates to project
    3192                const char *projection   ///< Projection to use
    3193     );
    3194 
    3195 /** Deproject plane onto spherical system */
    3196 psSphereCoord *
    3197 psCoordDeproject(const psPlaneCoord *coord, ///< Plane coordinates to deproject
    3198                  const char *projection ///< Projection to use
    3199     );
    3200 \end{verbatim}
    3201 
    3202 \subsubsection{Offsets}
    3203 
    3204 We require a function to calculate the offset between two positions on
    3205 the sky, as well as a function to apply an offset to a position.
    3206 
    3207 \begin{verbatim}
    3208 /** Get offset (RA,Dec) on the sky between two positions position1 and position2 may not be identical */
    3209 psSphereCoord *
    3210 psSphereCoordGetOffset(const psSphereCoord *restrict position1, ///< Position 1
    3211                        const psSphereCoord *restrict position2, ///< Position 2
    3212                        const char *type         ///< Type of offset: Linear, Spherical/Arcsec,
    3213                                                 ///< Spherical/Degreees etc
    3214     );
    3215 
    3216 /** Apply an offset to a position */
    3217 psSphereCoord *
    3218 psSphereCoordApplyOffset(const psSphereCoord *restrict position, ///< Position
    3219                          const psSphereCoord *restrict offset, ///< Offset
    3220                          const char *type               ///< Type of offset: Linear, Spherical/Arcsec,
    3221                                                         ///< Spherical/Degreees etc
    3222     );
    3223 \end{verbatim}
    3224 
    3225 Note that these should propagate the errors appropriately.
    3226 
    3227 
    3228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    3229 
    3230 \subsection{Astronomical Images}
    3231 
    3232 \subsubsection{Overview}
    3233 
    3234 Above, we have defined a basic container for a single 2D collection of
    3235 pixels (\code{psImage}), along with basic operations to manipulate the
    3236 image pixels.  For astronomical applications, this data structure is
    3237 insufficient for two reasons.  First, it does provide sufficient
    3238 additional metadata to describe the data in detail.  Second, astronomy
    3239 applications frequent involve multiple, related images.  For
    3240 PanSTARRS, and for general astronomical applications, we require a
    3241 richer collection of data structures which describe a very general
    3242 image concept.  We have defined several layers in the hierarchy which
    3243 are necessary to describe the image data which will be produced by the
    3244 PanSTARRS Gigapixel cameras as well as other standard astronomical
    3245 images. 
    3246 
    3247 A simple 2D image is a basic data unit for much of astronomical
    3248 imaging.  If we consider various optical and IR array cameras, a
    3249 single readout of the detector produces a collection of pixels
    3250 measurements.  We define our lowest-level astronomical image
    3251 structure, \code{psReadout}, to contain the pixels produced by a
    3252 single readout of the detector, along with metadata needed to define
    3253 that readout: the origin and binning of the image relative to the
    3254 original detector pixels explicitly in the structure, and pointers to
    3255 the general metadata and derived objects, if any.
    3256 
    3257 A single detector may produce more than one read which is associated.
    3258 For example, infrared detectors frequently produce an image
    3259 immediately after the detector is reset followed by an image after the
    3260 basic exposure is complete.  Both readouts correspond to the same
    3261 pixels, though the binning or rastering may be different between the
    3262 two readouts.  Another example is the video sequence produced by the
    3263 PanSTARRS Gigapix camera guide cells, each of which represents a
    3264 series of many images from a subraster of pixels in the detector
    3265 readout portion.  The second level of our image container hierarchy,
    3266 \code{psCell}, consists of a collection of readouts from a single
    3267 detector.
    3268 
    3269 In the PanSTARRS Gigapix camera, the basic readout region is a
    3270 fraction of the full imaging area of a single CCD chip.  The chip is
    3271 divided into 64 cells, any fraction of which may have been readout
    3272 for a given exposure.  In other cameras, such as Megacam at CFHT, the
    3273 individual CCDs have multiple amplifiers addressing contiguous
    3274 portions of the detector.  In such cameras, each amplifier produces a
    3275 separate collection of pixels.  In the third level of our image
    3276 container hierarchy, the data structure \code{psChip} represents a
    3277 collection of different cells.   
    3278 
    3279 The top level of our image container hierarchy is a complete focal
    3280 plane array (\code{psFPA}).  This structure represents the collection
    3281 of chips in the camera, all of which are read out in a given
    3282 exposure. 
    3283 
    3284 For example, take a mosaic camera consisting of eight $2k\times 4k$
    3285 CCDs, each of which is read out through two amplifiers.  Then there
    3286 would be sixteen cells in total, each of which is presumably $2k\times
    3287 2k$.  There would be eight chips, each consisting of two cells, and
    3288 the focal plane consists of these eight chips.
    3289 
    3290 As another example, consider an observation by PS1.  The focal plane
    3291 would consist of 60 chips, each of which consist of 64 cells (or less;
    3292 a few cells may be dead).  Some cells (those containing guide stars
    3293 for the orthogonal transfer) will contain multiple readouts.
    3294 
    3295 These data structures represent containers with which to carry around
    3296 the collection of related image data.  There is no requirement on the
    3297 functions or the structures that each instance of one of these data
    3298 structures represent the physical hardware.  For example, it is not
    3299 necessary that an instance of \code{psFPA} always carry the data for
    3300 all 60 (or 64) Gigapixel camera OTAs.  The usage of these structures
    3301 is such that all astronomical operations which apply to a CCD image
    3302 should be performed on an instance of \code{psFPA}.  If a particular
    3303 circumstance only requires a single 2D image, then that is represented
    3304 by an instance of \code{psFPA} with one \code{psChip}, which in turn
    3305 has one \code{psCell}, which in turn has one \code{psReadout}. 
    3306 
    3307 These container levels also include in their definition the information
    3308 needed to transform the coordinates in one of the levels to the
    3309 coordinate system relevant at the higher levels. 
    3310 
    3311 \tbd{the following discussions include astrometry issues which should
    3312   be deferred to the astrometry section}
    3313 
    3314 \subsubsection{A Readout}
    3315 
    3316 A readout is the result of a single read of a cell (or a portion
    3317 thereof).  It contains a pointer to the pixel data, and additional
    3318 pointers to the objects found in the readout, and the readout
    3319 metadata.  It also contains the offset from the lower-left corner of
    3320 the chip, in the case that the CCD was windowed.
    3321 
    3322 \begin{verbatim}
    3323 /** a Readout: a collection of pixels */
    3324 typedef struct {
    3325     const int x0, y0;                ///< Offset from the lower-left corner
    3326     const int nx, ny;                ///< Image binning
    3327     psImage *image;                  ///< imaging area of cell
    3328     psDlist *objects;                ///< objects derived from cell
    3329     psMetadata *md;                  ///< Readout-level metadata
    3330 } psReadout;
    3331 \end{verbatim}   
    3332 
    3333 \subsubsection{A Cell}
    3334 
    3335 A cell consists of one or more readouts (usually only one except in the
    3336 case that the cell has been used for fast guiding).  It also contains
    3337 a pointer to the cell metadata, and a pointer to its parent chip.  On
    3338 the astrometry side, it also contains coordinate transforms from the
    3339 cell to the chip and, as a convenience, from the cell to the focal
    3340 plane.  It is expected that these transforms will consist of two
    3341 first-order 2D polynomials, simply specifying a translation, rotation
    3342 and magnification; hence they are easily inverted, and there is no
    3343 need to add reverse transformations.  We also add an additional
    3344 transformation, which is intended to provide a ``quick and dirty''
    3345 transform from the cell coordinates to the sky; this transformation
    3346 not guaranteed to be as precise as the ``standard'' transformation of
    3347 Cell $\rightarrow$ Chip $\rightarrow$ Focal Plane $\rightarrow$
    3348 Tangent Plane $\rightarrow$ Sky, but will be faster.
    3349 
    3350 \begin{verbatim}
    3351 /** a Cell: a collection of readouts.
    3352  */
    3353 typedef struct {
    3354     int nReadouts;                      ///< number of readouts in this cell realization; each may have its
    3355                                         ///< own image, objects and overscan.
    3356     struct psReadout *readouts;         ///< Readouts from the cell
    3357     psMetadata *md;                     ///< Cell-level metadata
    3358 
    3359     psPlaneCoordXform *cellToChip;      ///< Transformations from cell coordinates to chip coordinates
    3360     psPlaneCoordXform *cellToFPA;       ///< Transformations from cell coordinates to FPA coordinates
    3361     psPlaneCoordXform *cellToSky;       ///< Quick and Dirty transformations from cell coordinates to sky
    3362 
    3363     struct psChip  *parentChip;         ///< chip which contains this cell
    3364 } psCell;
    3365 \end{verbatim}
    3366 
    3367 
    3368 \subsubsection{A Chip}
    3369 
    3370 A chip consists of one or more cells (according to the number of
    3371 amplifiers on the CCD).  It contains a pointer to the chip metadata,
    3372 and a pointer to the parent focal plane.  For astrometry, it contains
    3373 a coordinate transform from the chip to the focal plane.  It is
    3374 expected that this transforms will consist of two second-order 2D
    3375 polynomials; hence we think that it is prudent to include a reverse
    3376 transformation which will be derived from numerically inverting the
    3377 forward transformation.
    3378 
    3379 \begin{verbatim}
    3380 /** a Chip: a collection of cells.  Not all valid cells in a chip need to be listed in an
    3381  *  instance of psChip.
    3382  */
    3383 typedef struct {
    3384     int nCells;                         ///< Number of Cells assigned
    3385     struct psCell *cells;               ///< Cells in the Chip
    3386 
    3387     psMetadata *md;                     ///< Chip-level metadata
    3388     psPlaneCoordXform *chipToFPA;       ///< Transformations from chip coordinates to FPA coordinates
    3389     psPlaneCoordXform *FPAtoChip;       ///< Transformations from FPA coordinates to chip
    3390 
    3391     struct psFPA *parentFPA;            ///< FPA which contains this chip
    3392 } psChip;
    3393 \end{verbatim}
    3394 
    3395 \subsubsection{A Focal Plane}
    3396 
    3397 A focal plane consists of one or more chips (according to the number
    3398 of pieces of contiguous silicon).  It contains pointers to the focal
    3399 plane metadata and the exposure information.  For astrometry, it
    3400 contains a transformation from the focal plane to the tangent plane
    3401 and the fixed pattern residuals.  It is expected that the
    3402 transformation will consist of two 4D polynomials (i.e.\ a function of
    3403 two coordinates in position, the magnitude of the object, and the
    3404 color of the object) in order to correct for optical distortions and
    3405 the effects of the atmosphere; hence we think that it is prudent to
    3406 include a reverse transformation which will be derived from
    3407 numerically inverting the forward transformation.  Since colors are
    3408 involved in the transformation, it is necessary to specify the color
    3409 the transformation is defined for.  We also include some values to
    3410 characterize the quality of the transformation: the root mean square
    3411 deviation for the x and y transformation fits, and the $\chi^2$ for
    3412 the transformation fit.
    3413 
    3414 \begin{verbatim}
    3415 /** a Focal plane array: a collection of chips.  Not all chips in a camera need to be listed in an instance of
    3416  *  psFPA.
    3417  */
    3418 typedef struct {
    3419     int nChips;                         ///< Number of Cells assigned
    3420     int nAlloc;                         ///< Number of Cells available
    3421     struct psChip *chips;               ///< Chips in the Focal Plane Array
    3422 
    3423     psMetadata *md;                     ///< FPA-level metadata
    3424     psPlaneDistortion *TPtoFP;          ///< Transformation term from
    3425     psPlaneDistortion *FPtoTP;          ///< Transformation term from
    3426     psFixedPattern *pattern;            ///< Fixed pattern residual offsets
    3427     const psExposure *exp;              ///< information about this exposure
    3428     psPhotSystem colorPlus, colorMinus; ///< Colour reference
    3429     float rmsX, rmsY;                   ///< Dispersion in astrometric solution
    3430     float chi2;                         ///< chi^2 of astrometric solution
    3431 } psFPA;
    3432 \end{verbatim}
    3433 
    3434 \subsubsection{Exposure information}
    3435 
    3436 We need several quantities from the telescope in order to make a
    3437 first guess at the astrometric solution.  From these quantities,
    3438 further quantities can be derived and stored for later use.
    3439 
    3440 \begin{verbatim}
    3441 /** Exposure information from the telescope */
    3442 typedef struct {
    3443     // Telescope longitude, latitude and height are stored separately, since they don't change with pointing
    3444     const double ra, dec;               ///< Telescope boresight
    3445     const double ha;                    ///< Hour angle
    3446     const double zd;                    ///< Zenith distance
    3447     const double az;                    ///< Azimuth
    3448     const double lst;                   ///< Local Sidereal Time
    3449     const float mjd;                    ///< MJD of observation
    3450     const float rotAngle;               ///< Rotator position angle
    3451     const float temp;                   ///< Air temperature, for estimating refraction
    3452     const float pressure;               ///< Air pressure, for calculating refraction
    3453     const float humidity;               ///< Relative humidity, for calculating refraction
    3454     const float exptime;                ///< Exposure time
    3455     /* Derived quantities */
    3456     const float posAngle;               ///< Position angle
    3457     const float parallactic;            ///< Parallactic angle
    3458     const float airmass;                ///< Airmass, calculated from zenith distance
    3459     const float pf;                     ///< Parallactic factor
    3460     const char *cameraName;             ///< name of camera which provided exposure
    3461     const char *telescopeName;          ///< name of telescope which provided exposure
    3462 } psExposure;
    3463 \end{verbatim}
    3464 
    3465 
    3466 \subsubsection{Constructors and Destructors}
    3467 
    3468 Each of the above structures needs an appropriate constructor and
    3469 destructor.  Other than \code{psExposure}, which contains significant
    3470 non-pointer types, the constructors should not take any arguments, and
    3471 the destructors should only take the structure to be destroyed.
    3472 The constructor for \code{psExposure} is specified below.
    3473 
    3474 \begin{verbatim}
    3475 /** Constructor */
    3476 psExposure *
    3477 psExposureAlloc(double ra, double dec,  ///< Telescope boresight
    3478                 double ha,              ///< Hour angle
    3479                 double zd,              ///< Zenith distance
    3480                 double az,              ///< Azimuth
    3481                 double lst,             ///< Local Sidereal Time
    3482                 float mjd,              ///< MJD
    3483                 float rotAngle,         ///< Rotator position angle
    3484                 float temp,             ///< Temperature
    3485                 float pressure,         ///< Pressure
    3486                 float humidity,         ///< Relative humidity
    3487                 float exptime           ///< Exposure time
    3488                 );
    3489 \end{verbatim}
    3490 
    3491 
    3492 \subsection{Astrometry}
    3493 
    3494 Astrometry is a basic functionality required for the IPP that will be
    3495 used repeatedly, both for low-precision (roughly where is my favorite
    3496 object?) and high-precision (what is the proper motion of this star?).
    3497 As such, it must be flexible, yet robust.  Accordingly, we will wrap
    3498 the StarLink Astronomy Libraries (SLALib), which has already been
    3499 developed.
    3500 
    3501 \subsubsection{Coordinate frames}
    3502 \label{sec:coordinateFrames}
    3503 
    3504 There are five coordinate frames that we need to worry about for the
    3505 purposes of astrometry:
    3506 \begin{itemize}
    3507 \item Cell: $(x,y)$ in pixels --- raw coordinates;
    3508 \item Chip: $(X,Y)$ in pixels --- the location on the silicon;
    3509 \item Focal Plane: $(p,q)$ in microns --- the location on the focal plane;
    3510 \item Tangent Plane: $(l,m)$ in arcsec from the telescope boresight; and
    3511 \item Sky: (RA,Dec) --- ICRS.
    3512 \end{itemize}
    3513 
    3514 The following steps are required to convert from the cell coordinates to
    3515 the sky \tbd{convert Cell-$>$Chip and Chip-$>$FP to psDistortion}:
    3516 \begin{itemize}
    3517 \item Cell $\longleftrightarrow$ Chip: two 2D polynomials, $(X,Y) = f(x,y)$;
    3518 \item Chip $\longleftrightarrow$ FP: two 2D polynomials, $(p,q) = g(X,Y)$;
    3519 \item FP $\longleftrightarrow$ TP: two 4D polynomials, $(l,m) =
    3520 h(p,q,m,c)$, where $m$ and $c$ are the magnitude and color of the
    3521 object, respectively; and
    3522 \item TP $\longleftrightarrow$ Sky: SLALib transformation using a
    3523 transform pre-computed for each pointing.
    3524 \end{itemize}
    3525 
    3526 Note that the transformation between the Focal Plane and the Tangent
    3527 Plane is a four-dimensional polynomial, in order to account for any
    3528 possible dependencies in the astrometry on the stellar magnitude and
    3529 color; the former serves as a check for charge transfer
    3530 inefficiencies, while the latter will correct chromatic refraction,
    3531 both through the atmosphere and the corrector lenses.
    3532 
    3533 We require structures to contain each of the above transformations as
    3534 well as the pixel data.
    3535 
    3536 \subsubsection{SLALib information}
    3537 
    3538 SLALib requires several elements to perform the transformations
    3539 between the tangent plane and the sky.  Pre-computing these quantities
    3540 for each exposure means that subsequent transformations are faster.
    3541 For historical reasons, this structure is known colloquially as
    3542 ``Wallace's Grommit''.
    3543 
    3544 \begin{verbatim}
    3545 /** Information needed (by SLALIB) to convert Apparent to Observed Position */
    3546 typedef struct {
    3547     const double latitude;              ///< geodetic latitude (radians)
    3548     const double sinLat, cosLat;        ///< sine and cosine of geodetic latitude
    3549     const double abberationMag;         ///< magnitude of diurnal aberration vector
    3550     const double height;                ///< height (HM)
    3551     const double temperature;           ///< ambient temperature (TDK)
    3552     const double pressure;              ///< pressure (PMB)
    3553     const double humidity;              ///< relative humidity (RH)
    3554     const double wavelength;            ///< wavelength (WL)
    3555     const double lapseRate;             ///< lapse rate (TLR)
    3556     const double refractA, refractB;    ///< refraction constants A and B (radians)
    3557     const double longitudeOffset;       ///< longitude + eqn of equinoxes + ``sidereal UT'' (radians)
    3558     const double siderealTime;          ///< local apparent sidereal time (radians)
    3559 } psGrommit;
    3560 \end{verbatim}
    3561 
    3562 The \code{psGrommit} is calculated from telescope information for the
    3563 particular exposure:
    3564 
    3565 \begin{verbatim}
    3566 /** Constructor */
    3567 psGrommit *
    3568 psGrommitAlloc(const psExposure *exp    ///< Relevant exposure
    3569     );
    3570 
    3571 /** Destructor */
    3572 void
    3573 psGrommitFree(psGrommit *grommit        ///< Grommit to destroy
    3574     );
    3575 \end{verbatim}
    3576 
    3577 \subsubsection{Fixed Pattern}
    3578 
    3579 The fixed pattern is a correction to the general astrometric solution
    3580 formed by summing the residuals from many observations.  The intent is
    3581 to correct for higher-order distortions in the camera system on a
    3582 coarse grid (larger than individual pixels, but smaller than a single
    3583 cell).  Hence, in addition to the offsets, we need to specify the size
    3584 and scale of the grid in $x$ and $y$, as well as the origin of the
    3585 grid.
    3586 
    3587 \begin{verbatim}
    3588 /** The fixed pattern residual offsets.  These are specified via a coarse grid of x and y offsets. */
    3589 typedef struct {
    3590     int nX, nY;                         ///< Number of elements in x and y
    3591     double x0, y0;                      ///< Position of the lower-left corner of the grid on the focal plane
    3592     double xScale, yScale;              ///< Scale of the grid
    3593     double **x, **y;                    ///< The grid of offsets in x and y
    3594 } psFixedPattern;
    3595 \end{verbatim}
    3596 
    3597 
    3598 \subsubsection{Position Finding}
    3599 
    3600 We require functions to return the structure containing given
    3601 coordinates.  For example, we want the chip that corresponds to the
    3602 focal plane coordinates $(p,q) = (-1.234,+5.678)$.  These routines
    3603 handle the one-to-many problem --- i.e., for one given focal plane
    3604 coordinate, there are many chips that this coordinate may be
    3605 correspond to; these functions will select the correct one.
    3606 
    3607 
    3608 \begin{verbatim}
    3609 /** returns Chip in FPA which contains the given FPA coordinate */
    3610 psChip *
    3611 psChipInFPA (psChip *out,               ///< Chip to return, or NULL
    3612              const psPlaneCoord *coord  ///< coordinate in FPA
    3613              const psFPA *fpa,          ///< FPA description
    3614              );
    3615 
    3616 /** returns Cell in Chip which contains the given chip coordinate */
    3617 psCell *
    3618 psCellInChip(psCell *out,               ///< Cell to return, or NULL
    3619              const psPlaneCoord *coord  ///< coordinate in chip
    3620              const psChip *chip,        ///< chip description
    3621              );
    3622 
    3623 /** Return the cell in FPA which contains the given FPA coordinates */
    3624 psCell *
    3625 psCellInFPA(psCell *out,                ///< Cell to return, or NULL
    3626             const psPlaneCoord *coord   ///< Coordinate in FPA
    3627             const psFPA *fpa,           ///< FPA description
    3628             );
    3629 \end{verbatim}
    3630 
    3631 
    3632 
    3633 \subsubsection{Conversion Functions}
    3634 
    3635 We require functions to convert between the various coordinate frames
    3636 (Section~\ref{sec:coordinateFrames}).  The hierarchy of the coordinate
    3637 frames and the transformations between each are shown in
    3638 Figure~\ref{fig:coco}.  The functions that employ the transformations
    3639 are shown in Figure~\ref{fig:cocoFunc}.  In addition to
    3640 transformations between each adjoining coordinate frame in the
    3641 hierarchy, we also require higher-level functions to convert between
    3642 the Cell and Sky coordinate frames; these will simply perform the
    3643 intermediate steps.
    3644 
    3645 \begin{figure}
    3646 \psfig{file=coordinateFrames,height=7in,angle=-90}
    3647 \caption{The coordinate systems in the \PS{} IPP, and the relation
    3648 between each by transformations contained in the appropriate
    3649 structures.}
    3650 \label{fig:coco}
    3651 \end{figure}
    3652 
    3653 \begin{figure}
    3654 \psfig{file=coordinateConv,height=7in,angle=-90}
    3655 \caption{Conversion between coordinate systems by PSLib.}
    3656 \label{fig:cocoFunc}
    3657 \end{figure}
    3658 
    3659 The function prototypes are:
    3660 
    3661 \begin{verbatim}
    3662 /** Convert (RA,Dec) to cell and cell coordinates */
    3663 psPlaneCoord *
    3664 psCoordSkyToCell(psPlaneCoord *out,     ///< Coordinates to return, or NULL
    3665                  psCell *cell,          ///< Cell to return
    3666                  const psSphereCoord *in, ///< Input coordinates
    3667                  const psFPA *fpa       ///< FPA description
    3668                  );
    3669 
    3670 /** Convert cell and cell coordinate to (RA,Dec) */
    3671 psSphereCoord *
    3672 psCoordCellToSky(psSphereCoord *out,    ///< Coordinates to return, or NULL
    3673                  const psPlaneCoord *coord ///< cell coordinates to transform
    3674                  const psCell *cell,    ///< Cell to get coordinates for
    3675                  );
    3676 
    3677 /** Quick and dirty cell to (RA,Dec) --- employs cellToSky transformation */
    3678 psSphereCoord *
    3679 psCoordCellToSkyQuick(psSphereCoord *out, ///< Coordinates to return, or NULL
    3680                       const psPlaneCoord *coord ///< cell coordinates to transform
    3681                       const psCell *cell, ///< Cell description
    3682                       );
    3683 
    3684 /** Convert (RA,Dec) to tangent plane coords */
    3685 psPlaneCoord *
    3686 psCoordSkyToTP(psPlaneCoord *out,       ///< Coordinates to return, or NULL
    3687                const psSphereCoord *coord ///< input Sky coordinate
    3688                const psGrommit *grommit, ///< Grommit for fast conversion
    3689                );
    3690 
    3691 /** Convert tangent plane coords to focal plane coordinates */
    3692 psPlaneCoord *
    3693 psCoordTPtoFPA(psPlaneCoord *out,       ///< Coordinates to return, or NULL
    3694                const psPlaneCoord *coord ///< input TP coordinate
    3695                const psFPA *fpa,        ///< FPA description
    3696                );
    3697 
    3698 /** converts the specified FPA coord to the coord on the given Chip */
    3699 psPlaneCoord *
    3700 psCoordFPAtoChip (psPlaneCoord *out,    ///< Coordinates to return, or NULL
    3701                   const psPlaneCoord *coord ///< input FPA coordinate
    3702                   const psChip *chip,   ///< Chip of interest
    3703                   );
    3704 
    3705 /** converts the specified Chip coord to the coord on the given Cell */
    3706 psPlaneCoord *
    3707 psCoordChiptoCell (psPlaneCoord *out,   ///< Coordinates to return, or NULL
    3708                    const psPlaneCoord *coord ///< input Chip coordinate
    3709                    const psCell *cell,  ///< Cell of interest
    3710                    );
    3711 
    3712 /** converts the specified Cell coord to the coord on the parent Chip */
    3713 psPlaneCoord *
    3714 psCoordCelltoChip (psPlaneCoord *out,   ///< Coordinates to return, or NULL
    3715                    const psPlaneCoord *coord ///< input Cell coordinate
    3716                    const psCell *cell,  ///< Cell description
    3717                    );
    3718 
    3719 /** converts the specified Chip coord to the coord on the parent FPA */
    3720 psPlaneCoord *
    3721 psCoordChiptoFPA (psPlaneCoord *out,            ///< Coordinates to return, or NULL
    3722                   const psPlaneCoord *coord     ///< input Chip coordinate
    3723                   const psChip *chip,   ///< Chip description
    3724                   );
    3725 
    3726 /** Convert focal plane coords to tangent plane coordinates */
    3727 psPlaneCoord *
    3728 psCoordFPAToTP(psPlaneCoord *out,               ///< Coordinates to return, or NULL
    3729                const psPlaneCoord *coord ///< input FPA coordinate
    3730                const psFPA *fpa,        ///< FPA description
    3731                );
    3732 
    3733 /** Convert tangent plane coords to (RA,Dec) */
    3734 psSphereCoord *
    3735 psCoordTPtoSky(psSphereCoord *out,      ///< Coordinates to return, or NULL
    3736                const psPlaneCoord *coord ///< input TP coordinate
    3737                const psGrommit *grommit, ///< Grommit for fast conversion
    3738                );
    3739 
    3740 /** Convert Cell coords to FPA coordinates */
    3741 psPlaneCoord *
    3742 psCoordCellToFPA(psPlaneCoord *out,     ///< Coordinates to return, or NULL
    3743                  const psPlaneCoord *coord ///< Input cell coordinates
    3744                  const psCell *cell,    ///< Cell description
    3745                  );
    3746 \end{verbatim}
    3747 
    3748 \subsubsection{Additional functions}
    3749 
    3750 We require additional functions to perform general functions which
    3751 will be useful for astrometry.  Given coordinates on the sky, we
    3752 need to get the airmass, the parallactic angle, and an estimate of
    3753 the atmospheric refraction.
    3754 
    3755 \begin{verbatim}
    3756 /** Get the airmass for a given position and sidereal time */
    3757 float
    3758 psGetAirmass(const psSphereCoord *coord, ///< Position on the sky
    3759              double siderealTime,       ///< Sidereal time
    3760              float height               ///< Height above sea level
    3761              );
    3762 \end{verbatim}
    3763 
    3764 \begin{verbatim}
    3765 /** Get the parallactic angle for a given position and sidereal time */
    3766 float
    3767 psGetParallactic(const psSphereCoord *coord, ///< Position on the sky
    3768                  double siderealTime    ///< Sidereal time
    3769                  );
    3770 \end{verbatim}
    3771 
    3772 \begin{verbatim}
    3773 /** Estimate atmospheric refraction, along the parallactic */
    3774 float
    3775 psGetRefraction(float colour,           ///< Colour of object
    3776                 psPhotSystem colorPlus, ///< Colour reference
    3777                 psPhotSystem colorMinus, ///< Colour reference
    3778                 const psExposure *exp   ///< Telescope pointing information, for airmass, temp and pressure
    3779                 );
    3780 \end{verbatim}
    3781 
    3782 \begin{verbatim}
    3783 /** Calculate the parallax factor */
    3784 double
    3785 psGetParallaxFactor(const psExposure *exp ///< Exposure details
    3786     );
    3787 \end{verbatim}
    3788 
    3789 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    3790 
    3791 \subsection{Photometry}
    3792 
    3793 
    3794 Photometric observations are performed in an instrumental photometric
    3795 system, and must be related to other photometric systems.  We
    3796 require a data structure which defines a photometric system, as well
    3797 as a structure to define the transformation between photometric
    3798 systems.
    3799 
    3800 The photometric system is defined by the psPhotSystem structure. 
    3801 A photometric system is identified by a human-readable \code{name}
    3802 (ie, SDSS.g, Landolt92.B, GPC1.OTA32.r).  Each photometric system is
    3803 given a unique identifier \code{ID}.  Observations taken with a
    3804 specific camera, detector, and filter represent their own photometric
    3805 system, and it may be necessary to perform transformations between
    3806 these systems.  Photometric systems associated with observations from
    3807 a specific camera/detector/filter combination can be associated with
    3808 those components.
    3809 \begin{verbatim}
    3810 typedef struct {
    3811     const int ID;                       ///< ID number for this photometric system
    3812     const char *name;                   ///< Name of photometric system
    3813     const char *camera;                 ///< Camera for photometric system
    3814     const char *filter;                 ///< Filter used for photometric system
    3815     const char *detector;               ///< Detector used for photometric system
    3816 } psPhotSystem;
    3817 \end{verbatim}
    3818 
    3819 The following structure defines the transformation between two
    3820 photometric systems.
    3821 \begin{verbatim}
    3822 typedef struct {
    3823     psPhotSystem src;                   ///< Source photometric system
    3824     psPhotSystem dst;                   ///< Destination photometric system
    3825     psPhotSystem pP, pM;                ///< Primary colour reference
    3826     psPhotSystem sP, sM;                ///< Secondary colour reference
    3827     float pA, sA;                       ///< Colour offset for primary and secondary references
    3828     psPolynomial3D transform;           ///< Transformation from source to destination
    3829 } psPhotTransform;
    3830 \end{verbatim}
    3831 
    3832 The transformation between two photometric systems may depend on the
    3833 airmass of the observation and on the colors of the object of
    3834 interest.  For a specific observation, such a transformations can be
    3835 defined as a polynomial function of the color of the star and the
    3836 airmass of the observations.  If sufficient data exists, the
    3837 transformation between the photometric systems may include more than
    3838 one color, constraining the curvature of the stellar spectral energy
    3839 distributions.  This latter term may be significant for stars which
    3840 are highly reddened, for example.  Derived photometric quantities may
    3841 have been corrected for airmass variations, in which case only color
    3842 terms may be measurable.  The structure defines the transformation
    3843 between a source photometric system (\code{src}) and a target
    3844 photometric system (\code{dst}).  The photometric system of a primary
    3845 color is defined by \code{pP, pM} such that the color is constructed
    3846 as $pP - pM$.  A secondary color is defined by \code{sP, sM}.  For
    3847 both, a reference color is specified (\code{pA, sA}): the polynomial
    3848 transformation terms refer to colors in the form $pP - pM - pA$.  The
    3849 transformation is specified as a 3D polynomial.  For a star of
    3850 magnitude $M_{\rm src}$ in the source photometric system, with
    3851 additional magnitude information in the other systems $M_{\rm pP}$,
    3852 $M_{\rm pM}$, $M_{\rm sP}$, $M_{\rm sM}$, observed at an airmass of
    3853 $z$, the magnitude of the star in the target system $M_{\rm dst}$ is
    3854 given by: $M_{\rm dst} = M_{\rm src} + transform(z, M_{\rm pP} -
    3855 M_{\rm pM} - pA, M_{\rm sP} - M_{\rm sM} - sA)$.
    3856 
    3857 \TBD{Really want a set of polynomials defined for specific colour
    3858 ranges.}
    3859 
    3860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    3861 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    3862 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    3863 
    3864 \subsection{Astronomical objects}
    3865 
    3866 \subsubsection{Positions of Major SS Objects}
    3867 
    3868 We require the ability to calculate the position of major Solar System
    3869 objects, as well as Lunar phase.
    3870 
    3871 \begin{verbatim}
    3872 /** Get Sun Position */
    3873 psSphereCoord *
    3874 psGetSunPos(float mjd                   ///< MJD to get position for
    3875     );
    3876 
    3877 /** Get Moon position */
    3878 psSphereCoord *
    3879 psGetMoonPos(float mjd,                 ///< MJD to get position for
    3880              double latitude,           ///< Latitude for apparent position
    3881              double longitude           ///< Longitude for apparent position
    3882     );
    3883 
    3884 /** Get Moon phase */
    3885 float
    3886 psGetMoonPhase(float mjd                ///< MJD to get phase for
    3887     );
    3888 
    3889 /** Get Planet positions */
    3890 psSphereCoord *
    3891 psGetSolarSystemPos(const char *solarSystemObject, ///< Named S.S. object
    3892                     float mjd           ///< MJD to get position for
    3893     );
    3894 \end{verbatim}
    3895 
    3896 \tbd{The rest of this section is tentative}
    3897 
    3898 We may need a variety of other SLALib-type functions:
    3899 
    3900 \begin{itemize}
    3901 \item Lunation calculations to/from psTime
    3902 \item rise/set for specified object
    3903 \item 12 \& 18 deg twilight for closest sunrise / sunset
    3904 \item length of current night
    3905 \end{itemize}
    3906 
    3907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    3908 
    3909 %\appendix
    3910 %
    3911 %\pagebreak
    3912 %\section{API Summary: all functions}
    3913 %
    3914 %\subsection{System Utilities}
    3915 %\input{psSystemGroup.tex}
    3916 %
    3917 %\subsection{Data Containers}
    3918 %\input{psDataGroup.tex}
    3919 %
    3920 %\subsection{Math Utilities}
    3921 %\input{psMathGroup.tex}
    3922 %
    3923 %\subsection{Astronomy Functions}
    3924 %\input{psAstroGroup.tex}
    3925 %
    3926 %\pagebreak
    3927 %\section{API Summary: all structures}
    3928 %\input{psStructures.tex}
    3929 
    3930 \bibliographystyle{plain} \bibliography{panstarrs}
    3931 
    3932 \end{document}
    3933 
  • trunk/doc/pslib/psMathGroup.tex

    r381 r747  
    11\begin{CompactItemize}
    22\item
    3 {\bf ps\-Bit\-Mask} $\ast$ {\bf ps\-Bit\-Mask\-Alloc} (int n)
     3{\bf ps\-Bitset} $\ast$ {\bf ps\-Bitset\-Alloc} (int n)
    44\begin{CompactList}\small\item\em Constructor.\item\end{CompactList}\item
    5 void {\bf ps\-Bit\-Mask\-Free} ({\bf ps\-Bit\-Mask} $\ast$restrict my\-Mask)
     5void {\bf ps\-Bitset\-Free} ({\bf ps\-Bitset} $\ast$restrict my\-Bits)
    66\begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\item
    7 {\bf ps\-Bit\-Mask} $\ast$ {\bf ps\-Bit\-Mask\-Set} ({\bf ps\-Bit\-Mask} $\ast$my\-Mask, int bit)
    8 \begin{CompactList}\small\item\em Set a bit mask.\item\end{CompactList}\item
    9 int {\bf ps\-Bit\-Mask\-Test} (const {\bf ps\-Bit\-Mask} $\ast$check\-Mask, int bit)
    10 \begin{CompactList}\small\item\em Check a bit mask.\item\end{CompactList}\item
    11 {\bf ps\-Bit\-Mask} $\ast$ {\bf ps\-Bit\-Mask\-Op} ({\bf ps\-Bit\-Mask} $\ast$out\-Mask, const {\bf ps\-Bit\-Mask} $\ast$restrict in\-Mask1, char $\ast$operator, const {\bf ps\-Bit\-Mask} $\ast$restrict in\-Mask2)
    12 \begin{CompactList}\small\item\em apply the given operator to two bit masks\item\end{CompactList}\item
    13 {\bf ps\-FFT} $\ast$ {\bf ps\-FFTAlloc} ({\bf ps\-Image} $\ast$image)
    14 \begin{CompactList}\small\item\em Constructor.\item\end{CompactList}\item
    15 {\bf ps\-FFT} $\ast$ {\bf ps\-FFTAlloc1D} (const {\bf ps\-Float\-Array} $\ast$arr)
    16 \begin{CompactList}\small\item\em Constructor for 1D case.\item\end{CompactList}\item
    17 {\bf ps\-Image} $\ast$ {\bf ps\-FFTFree} ({\bf ps\-Image} $\ast$out, {\bf ps\-FFT} $\ast$restrict fft)
    18 \begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\item
    19 {\bf ps\-FFT} $\ast$ {\bf ps\-FFTForward} ({\bf ps\-FFT} $\ast$fft)
    20 \begin{CompactList}\small\item\em Forward FFT: from real to fourier space.\item\end{CompactList}\item
    21 {\bf ps\-FFT} $\ast$ {\bf ps\-FFTReverse} ({\bf ps\-FFT} $\ast$fft)
    22 \begin{CompactList}\small\item\em Reverse FFT: from fourier to real space.\item\end{CompactList}\item
    23 {\bf ps\-FFT} $\ast$ {\bf ps\-FFTFilter} ({\bf ps\-FFT} $\ast$fft, float($\ast$filter\-Func)(int kx, int ky))
    24 \begin{CompactList}\small\item\em Apply filter function in fourier space.\item\end{CompactList}\item
    25 {\bf ps\-FFT} $\ast$ {\bf ps\-FFTFilter\-Complex} ({\bf ps\-FFT} $\ast$fft, float($\ast$real\-Filter\-Func)(int kx, int ky), float($\ast$imag\-Filter\-Func)(int kx, int ky))
    26 \begin{CompactList}\small\item\em Apply complex filter function.\item\end{CompactList}\item
    27 {\bf ps\-FFT} $\ast$ {\bf ps\-FFTCross\-Correlate} ({\bf ps\-FFT} $\ast$out const {\bf ps\-FFT} $\ast$fft1, const {\bf ps\-FFT} $\ast$fft2)
    28 \begin{CompactList}\small\item\em Calculate FFT of the cross-correlation.\item\end{CompactList}\item
    29 {\bf ps\-FFT} $\ast$ {\bf ps\-FFTConvolve} ({\bf ps\-FFT} $\ast$out, const {\bf ps\-FFT} $\ast$fft1, const {\bf ps\-FFT} $\ast$fft2)
    30 \begin{CompactList}\small\item\em Calculate FFT of the convolution.\item\end{CompactList}\item
    31 {\bf ps\-Float\-Array} $\ast$ {\bf ps\-FFTPower\-Spec} ({\bf ps\-FFT} $\ast$fft)
    32 \begin{CompactList}\small\item\em Calculate power spectrum.\item\end{CompactList}\item
    33 {\bf ps\-Image} $\ast$ {\bf ps\-FFTGet\-Image} ({\bf ps\-Image} $\ast$out, const {\bf ps\-FFT} $\ast$fft)
    34 \item
    35 {\bf ps\-Image} $\ast$ {\bf ps\-FFTGet\-FT} ({\bf ps\-Image} $\ast$out, const {\bf ps\-FFT} $\ast$fft)
    36 \begin{CompactList}\small\item\em Convert the Fourier transform data in the FFT struct to an image of complex numbers.\item\end{CompactList}\item
     7{\bf ps\-Bitset} $\ast$ {\bf ps\-Bitset\-Set} ({\bf ps\-Bitset} $\ast$restrict my\-Bits, int bit)
     8\begin{CompactList}\small\item\em Set a bitset.\item\end{CompactList}\item
     9int {\bf ps\-Bitset\-Test} (const {\bf ps\-Bitset} $\ast$restrict check\-Bits, int bit)
     10\begin{CompactList}\small\item\em Check a bitset.\item\end{CompactList}\item
     11{\bf ps\-Bitset} $\ast$ {\bf ps\-Bitset\-Op} ({\bf ps\-Bitset} $\ast$out\-Bits, const {\bf ps\-Bitset} $\ast$restrict in\-Bits1, char $\ast$operator, const {\bf ps\-Bitset} $\ast$restrict in\-Bits2)
     12\begin{CompactList}\small\item\em apply the given operator to two bitsets\item\end{CompactList}\item
     13{\bf ps\-Bitset} $\ast$ {\bf ps\-Bitset\-Not} ({\bf ps\-Bitset} $\ast$out, {\bf ps\-Bitset} $\ast$in)
     14\begin{CompactList}\small\item\em Apply unary NOT to a bitset.\item\end{CompactList}\item
     15{\bf ps\-Vector} $\ast$ {\bf ps\-Vector\-FFT} (const {\bf ps\-Vector} $\ast$vector) int dir)
     16\begin{CompactList}\small\item\em $<$ FFT direction (1: forward, -1: reverse)\item\end{CompactList}\item
     17{\bf ps\-Vector} $\ast$ {\bf ps\-Vector\-Power\-Spectrum} (const {\bf ps\-Vector} $\ast$vector)
     18\begin{CompactList}\small\item\em Calculate power spectrum of a vector of floating-point numbers.\item\end{CompactList}\item
     19{\bf ps\-Vector} $\ast$ {\bf ps\-Vector\-Real} ({\bf ps\-Vector} $\ast$out, const {\bf ps\-Vector} $\ast$in)
     20\begin{CompactList}\small\item\em Get the real part of a vector.\item\end{CompactList}\item
     21{\bf ps\-Vector} $\ast$ {\bf ps\-Vector\-Imaginary} ({\bf ps\-Vector} $\ast$out, const {\bf ps\-Vector} $\ast$in)
     22\begin{CompactList}\small\item\em Get the imaginary part of a vector.\item\end{CompactList}\item
     23{\bf ps\-Vector} $\ast$ {\bf ps\-Vector\-Complex} ({\bf ps\-Vector} $\ast$out, const {\bf ps\-Vector} $\ast$real) const {\bf ps\-Vector} $\ast$imag)
     24\begin{CompactList}\small\item\em $<$ imaginary part of vector\item\end{CompactList}\item
     25{\bf ps\-Vector} $\ast$ {\bf ps\-Vector\-Conjugate} ({\bf ps\-Vector} $\ast$out, const {\bf ps\-Vector} $\ast$in)
     26\begin{CompactList}\small\item\em Get the complex conjugate of an vector of complex floating-point numbers.\item\end{CompactList}\item
     27{\bf ps\-Image} $\ast$ {\bf ps\-Image\-FFT} (const {\bf ps\-Image} $\ast$image, int dir)
     28\begin{CompactList}\small\item\em FFT an image.\item\end{CompactList}\item
     29{\bf ps\-Image} $\ast$ {\bf ps\-Image\-Power\-Spectrum} (const {\bf ps\-Image} $\ast$image)
     30\begin{CompactList}\small\item\em Calculate power spectrum of an image.\item\end{CompactList}\item
     31{\bf ps\-Image} $\ast$ {\bf ps\-Image\-Real} ({\bf ps\-Image} $\ast$out, const {\bf ps\-Image} $\ast$in)
     32\begin{CompactList}\small\item\em Get the real part of an image.\item\end{CompactList}\item
     33{\bf ps\-Image} $\ast$ {\bf ps\-Image\-Imaginary} ({\bf ps\-Image} $\ast$out, const {\bf ps\-Image} $\ast$in)
     34\begin{CompactList}\small\item\em Get the imaginary part of an image.\item\end{CompactList}\item
     35{\bf ps\-Image} $\ast$ {\bf ps\-Image\-Complex} ({\bf ps\-Image} $\ast$out, const {\bf ps\-Image} $\ast$real, const {\bf ps\-Image} $\ast$imag)
     36\begin{CompactList}\small\item\em Construct a complex image from real \& imaginary parts.\item\end{CompactList}\item
     37{\bf ps\-Image} $\ast$ {\bf ps\-Image\-Conjugate} ({\bf ps\-Image} $\ast$out, const {\bf ps\-Image} $\ast$in)
     38\begin{CompactList}\small\item\em Get the complex conjugate of an image.\item\end{CompactList}\item
    3739{\bf ps\-Polynomial1D} $\ast$ {\bf ps\-Polynomial1DAlloc} (int n)
    3840\begin{CompactList}\small\item\em Constructor.\item\end{CompactList}\item
     
    5153void {\bf ps\-Polynomial4DFree} ({\bf ps\-Polynomial4D} $\ast$restrict my\-Poly)
    5254\begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\item
    53 float {\bf ps\-Eval\-Polynomial1D} (float x, const {\bf ps\-Polynomial1D} $\ast$restrict my\-Poly)
     55float {\bf ps\-Polynomial1DEval} (float x, const {\bf ps\-Polynomial1D} $\ast$restrict my\-Poly)
    5456\begin{CompactList}\small\item\em Evaluate 1D polynomial.\item\end{CompactList}\item
    55 float {\bf ps\-Eval\-Polynomial2D} (float x, float y, const {\bf ps\-Polynomial2D} $\ast$restrict my\-Poly)
     57float {\bf ps\-Polynomial2DEval} (float x, float y, const {\bf ps\-Polynomial2D} $\ast$restrict my\-Poly)
    5658\begin{CompactList}\small\item\em Evaluate 2D polynomial.\item\end{CompactList}\item
    57 float {\bf ps\-Eval\-Polynomial3D} (float x, float y, float z, const {\bf ps\-Polynomial3D} $\ast$restrict my\-Poly)
     59float {\bf ps\-Polynomial3DEval} (float x, float y, float z, const {\bf ps\-Polynomial3D} $\ast$restrict my\-Poly)
    5860\begin{CompactList}\small\item\em Evaluate 3D polynomial.\item\end{CompactList}\item
    59 float {\bf ps\-Eval\-Polynomial4D} (float w, float x, float y, float z, const {\bf ps\-Polynomial4D} $\ast$restrict my\-Poly)
     61float {\bf ps\-Polynomial4DEval} (float w, float x, float y, float z, const {\bf ps\-Polynomial4D} $\ast$restrict my\-Poly)
    6062\begin{CompactList}\small\item\em Evaluate 4D polynomial.\item\end{CompactList}\item
    6163{\bf ps\-DPolynomial1D} $\ast$ {\bf ps\-DPolynomial1DAlloc} (int n)
     
    7577void {\bf ps\-DPolynomial4DFree} ({\bf ps\-DPolynomial4D} $\ast$restrict my\-Poly)
    7678\begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\item
    77 double {\bf ps\-Eval\-DPolynomial1D} (double x, const {\bf ps\-DPolynomial1D} $\ast$restrict my\-Poly)
     79double {\bf ps\-DPolynomial1DEval} (double x, const {\bf ps\-DPolynomial1D} $\ast$restrict my\-Poly)
    7880\begin{CompactList}\small\item\em Evaluate 1D polynomial (double precision).\item\end{CompactList}\item
    79 double {\bf ps\-Eval\-DPolynomial2D} (double x, double y, const {\bf ps\-DPolynomial2D} $\ast$restrict my\-Poly)
     81double {\bf ps\-DPolynomial2DEval} (double x, double y, const {\bf ps\-DPolynomial2D} $\ast$restrict my\-Poly)
    8082\begin{CompactList}\small\item\em Evaluate 2D polynomial (double precision).\item\end{CompactList}\item
    81 double {\bf ps\-Eval\-DPolynomial3D} (double x, double y, double z, const {\bf ps\-DPolynomial3D} $\ast$restrict my\-Poly)
     83double {\bf ps\-DPolynomial3DEval} (double x, double y, double z, const {\bf ps\-DPolynomial3D} $\ast$restrict my\-Poly)
    8284\begin{CompactList}\small\item\em Evaluate 3D polynomial (double precision).\item\end{CompactList}\item
    83 double {\bf ps\-Eval\-DPolynomial4D} (double w, double x, double y, double z, const {\bf ps\-DPolynomial4D} $\ast$restrict my\-Poly)
     85double {\bf ps\-DPolynomial4DEval} (double w, double x, double y, double z, const {\bf ps\-DPolynomial4D} $\ast$restrict my\-Poly)
    8486\begin{CompactList}\small\item\em Evaluate 4D polynomial (double precision).\item\end{CompactList}\item
    8587{\bf ps\-Type} $\ast$ {\bf ps\-Binary\-Op} (void $\ast$out, void $\ast$in1, char $\ast$op, void $\ast$in2)
    86 \begin{CompactList}\small\item\em Perform a binary operation on two data items ({\bf ps\-Image} {\rm (p.\,\pageref{structpsImage})}, ps\-Vector, ps\-Scalar).\item\end{CompactList}\item
     88\begin{CompactList}\small\item\em Perform a binary operation on two data items ({\bf ps\-Image} {\rm (p.\,\pageref{structpsImage})}, {\bf ps\-Vector} {\rm (p.\,\pageref{structpsVector})}, ps\-Scalar).\item\end{CompactList}\item
    8789{\bf ps\-Type} $\ast$ {\bf ps\-Unary\-Op} (void $\ast$out, void $\ast$in, char $\ast$op)
    88 \begin{CompactList}\small\item\em Perform a unary operation on two data items ({\bf ps\-Image} {\rm (p.\,\pageref{structpsImage})}, ps\-Vector, ps\-Scalar).\item\end{CompactList}\item
     90\begin{CompactList}\small\item\em Perform a unary operation on two data items ({\bf ps\-Image} {\rm (p.\,\pageref{structpsImage})}, {\bf ps\-Vector} {\rm (p.\,\pageref{structpsVector})}, ps\-Scalar).\item\end{CompactList}\item
    8991{\bf p\_\-ps\-Scalar} $\ast$ {\bf ps\-Scalar} (double value)
    9092\begin{CompactList}\small\item\em create a {\bf ps\-Type} {\rm (p.\,\pageref{structpsType})}-ed structure from a constant double value.\item\end{CompactList}\item
     
    9597float {\bf ps\-Matrix\-Determinant} (const {\bf ps\-Image} $\ast$restrict my\-Matrix)
    9698\begin{CompactList}\small\item\em Matrix determinant.\item\end{CompactList}\item
    97 {\bf ps\-Image} $\ast$ {\bf ps\-Matrix\-Op} ({\bf ps\-Image} $\ast$out, const {\bf ps\-Image} $\ast$matrix1, const char $\ast$op, const {\bf ps\-Image} $\ast$matrix2)
     99{\bf ps\-Image} $\ast$ {\bf ps\-Matrix\-Multiply} ({\bf ps\-Image} $\ast$out, const {\bf ps\-Image} $\ast$in1, const {\bf ps\-Image} $\ast$in2)
    98100\begin{CompactList}\small\item\em Matrix operation: addition, subtraction, multiplication.\item\end{CompactList}\item
    99 {\bf ps\-Image} $\ast$ {\bf ps\-Matrix\-Transpose} ({\bf ps\-Image} $\ast$out, const {\bf ps\-Image} $\ast$my\-Matrix)
     101{\bf ps\-Image} $\ast$ {\bf ps\-Matrix\-Transpose} ({\bf ps\-Image} $\ast$out, const {\bf ps\-Image} $\ast$in)
    100102\begin{CompactList}\small\item\em Transpose Matrix.\item\end{CompactList}\item
    101 {\bf ps\-Image} $\ast$ {\bf ps\-Matrix\-LUD} ({\bf ps\-Image} $\ast$out, {\bf ps\-Image} $\ast$my\-Matrix)
     103{\bf ps\-Image} $\ast$ {\bf ps\-Matrix\-LUD} ({\bf ps\-Image} $\ast$out, {\bf ps\-Image} $\ast$in)
    102104\begin{CompactList}\small\item\em LU Decomposition of a matrix.\item\end{CompactList}\item
    103 {\bf ps\-Vector} $\ast$ {\bf ps\-Matrix\-LUSolve} ({\bf ps\-Vector} $\ast$out, const {\bf ps\-Image} $\ast$lu\-Matrix, const {\bf ps\-Vector} $\ast$rhs\-Vector)
     105{\bf ps\-Vector} $\ast$ {\bf ps\-Matrix\-LUSolve} ({\bf ps\-Vector} $\ast$out, const {\bf ps\-Image} $\ast$LU, const {\bf ps\-Vector} $\ast$RHS)
    104106\begin{CompactList}\small\item\em LU Solution.\item\end{CompactList}\item
    105 {\bf ps\-Vector} $\ast$ {\bf ps\-Matrix\-To\-Vector} ({\bf ps\-Vector} $\ast$out, {\bf ps\-Image} $\ast$my\-Matrix)
     107{\bf ps\-Vector} $\ast$ {\bf ps\-Matrix\-Eigenvectors} ({\bf ps\-Image} $\ast$my\-Matrix)
     108\begin{CompactList}\small\item\em Eigenvectors of a matrix.\item\end{CompactList}\item
     109{\bf ps\-Vector} $\ast$ {\bf ps\-Matrix\-To\-Vector} ({\bf ps\-Vector} $\ast$out, {\bf ps\-Image} $\ast$in)
    106110\begin{CompactList}\small\item\em Convert matrix to vector.\item\end{CompactList}\item
    107 {\bf ps\-Image} $\ast$ {\bf ps\-Vector\-To\-Matrix} ({\bf ps\-Image} $\ast$out, {\bf ps\-Vector} $\ast$my\-Vector)
     111{\bf ps\-Image} $\ast$ {\bf ps\-Vector\-To\-Matrix} ({\bf ps\-Image} $\ast$out, {\bf ps\-Vector} $\ast$in)
    108112\begin{CompactList}\small\item\em Convert vector to matrix.\item\end{CompactList}\item
    109 {\bf ps\-Float\-Array} $\ast$ {\bf ps\-Minimize} (float($\ast$my\-Function)(const {\bf ps\-Float\-Array} $\ast$restrict), {\bf ps\-Float\-Array} $\ast$restrict initial\-Guess, {\bf ps\-Int\-Array} $\ast$restrict param\-Mask)
    110 \begin{CompactList}\small\item\em Minimize a particular non-linear function.\item\end{CompactList}\item
    111 {\bf ps\-Float\-Array} $\ast$ {\bf ps\-Minimize\-Chi2} (float($\ast$eval\-Model)(const {\bf ps\-Float\-Array} $\ast$restrict, const {\bf ps\-Float\-Array} $\ast$restrict), const {\bf ps\-Float\-Array} $\ast$restrict domain, const {\bf ps\-Float\-Array} $\ast$restrict data, const {\bf ps\-Float\-Array} $\ast$restrict errors, {\bf ps\-Float\-Array} $\ast$restrict initial\-Guess, const {\bf ps\-Int\-Array} $\ast$restrict param\-Mask)
     113{\bf ps\-Vector} $\ast$ {\bf ps\-Minimize} ({\bf ps\-Vector} $\ast$restrict initial\-Guess, float($\ast$my\-Function)(const {\bf ps\-Vector} $\ast$restrict, const {\bf ps\-Vector} $\ast$restrict), float($\ast$my\-Func\-Deriv)(const {\bf ps\-Vector} $\ast$restrict, const {\bf ps\-Vector} $\ast$restrict), const {\bf ps\-Vector} $\ast$restrict param\-Mask)
     114\begin{CompactList}\small\item\em Find the minimum of a particular non-linear function.\item\end{CompactList}\item
     115{\bf ps\-Vector} $\ast$ {\bf ps\-Minimize\-Chi2} ({\bf ps\-Vector} $\ast$restrict initial\-Guess, float($\ast$eval\-Model)(const {\bf ps\-Vector} $\ast$restrict, const {\bf ps\-Vector} $\ast$restrict), const {\bf ps\-Vector} $\ast$restrict domain, const {\bf ps\-Vector} $\ast$restrict data, const {\bf ps\-Vector} $\ast$restrict errors, const {\bf ps\-Vector} $\ast$restrict param\-Mask, float Chi\-Sq)
    112116\begin{CompactList}\small\item\em Minimize chi$^\wedge$2 for input data.\item\end{CompactList}\item
    113 {\bf ps\-Polynomial1D} $\ast$ {\bf ps\-Get\-Array\-Polynomial} ({\bf ps\-Polynomial1D} my\-Poly, const {\bf ps\-Float\-Array} $\ast$restrict x, const {\bf ps\-Float\-Array} $\ast$restrict y, const {\bf ps\-Float\-Array} $\ast$restrict y\-Err)
     117{\bf ps\-Polynomial1D} $\ast$ {\bf ps\-Vector\-Fit\-Polynomial} ({\bf ps\-Polynomial1D} my\-Poly, const {\bf ps\-Vector} $\ast$restrict x, const {\bf ps\-Vector} $\ast$restrict y, const {\bf ps\-Vector} $\ast$restrict y\-Err)
    114118\begin{CompactList}\small\item\em Derive a polynomial fit by chi$^\wedge$2 minimisation --- can be done analytically.\item\end{CompactList}\item
    115 {\bf ps\-Float\-Array} $\ast$ {\bf ps\-Sort} ({\bf ps\-Float\-Array} $\ast$out, const {\bf ps\-Float\-Array} $\ast$my\-Array)
     119{\bf ps\-Vector} $\ast$ {\bf ps\-Sort} ({\bf ps\-Vector} $\ast$out, const {\bf ps\-Vector} $\ast$restrict in)
    116120\begin{CompactList}\small\item\em Sort an array.\item\end{CompactList}\item
    117 {\bf ps\-Int\-Array} $\ast$ {\bf ps\-Sort\-Index} ({\bf ps\-Int\-Array} $\ast$restrict out, const {\bf ps\-Float\-Array} $\ast$restrict my\-Array)
     121{\bf ps\-Vector} $\ast$ {\bf ps\-Sort\-Index} ({\bf ps\-Vector} $\ast$restrict out, const {\bf ps\-Vector} $\ast$restrict in)
    118122\begin{CompactList}\small\item\em Sort an array, along with some other stuff.\item\end{CompactList}\item
    119 {\bf ps\-Stats} $\ast$ {\bf ps\-Array\-Stats} (const {\bf ps\-Float\-Array} $\ast$restrict my\-Array, const {\bf ps\-Int\-Array} $\ast$restrict mask\-Array, unsigned int mask\-Val, {\bf ps\-Stats} $\ast$stats)
    120 \begin{CompactList}\small\item\em Do Statistics on an array.\item\end{CompactList}\item
    121 {\bf ps\-Histogram} $\ast$ {\bf ps\-Histogram\-Alloc} (float lower, float upper, float size)
     123{\bf ps\-Stats} $\ast$ {\bf ps\-Vector\-Stats} ({\bf ps\-Stats} $\ast$stats, const {\bf ps\-Vector} $\ast$restrict my\-Array, const {\bf ps\-Vector} $\ast$restrict mask\-Array, unsigned int mask\-Val)
     124\begin{CompactList}\small\item\em Do Statistics on a vector.\item\end{CompactList}\item
     125{\bf ps\-Histogram} $\ast$ {\bf ps\-Histogram\-Alloc} (float lower, float upper, int n)
    122126\begin{CompactList}\small\item\em Constructor.\item\end{CompactList}\item
    123 {\bf ps\-Histogram} $\ast$ {\bf ps\-Histogram\-Alloc\-Generic} (const {\bf ps\-Float\-Array} $\ast$restrict lower, const {\bf ps\-Float\-Array} $\ast$restrict upper, float min\-Val, float max\-Val)
     127{\bf ps\-Histogram} $\ast$ {\bf ps\-Histogram\-Alloc\-Generic} (const {\bf ps\-Vector} $\ast$restrict bounds)
    124128\begin{CompactList}\small\item\em Generic constructor.\item\end{CompactList}\item
    125129void {\bf ps\-Histogram\-Free} ({\bf ps\-Histogram} $\ast$restrict my\-Hist)
    126130\begin{CompactList}\small\item\em Destructor.\item\end{CompactList}\item
    127 {\bf ps\-Histogram} $\ast$ {\bf ps\-Get\-Array\-Histogram} ({\bf ps\-Histogram} $\ast$restrict my\-Hist, const {\bf ps\-Float\-Array} $\ast$restrict my\-Array)
     131{\bf ps\-Histogram} $\ast$ {\bf ps\-Histogram\-Vector} ({\bf ps\-Histogram} $\ast$restrict my\-Hist, const {\bf ps\-Vector} $\ast$restrict my\-Array)
    128132\begin{CompactList}\small\item\em Calculate a histogram.\item\end{CompactList}\end{CompactItemize}
  • trunk/doc/pslib/psStructures.tex

    r535 r747  
    11\begin{CompactList}
    2 \item\contentsline{section}{{\bf p\_\-ps\-FFTDetails} (Details on FFT implementation (private))}{\pageref{structp__psFFTDetails}}{}
    32\item\contentsline{section}{{\bf p\_\-ps\-Scalar} (Private structure used to pass constant values into the math operators)}{\pageref{structp__psScalar}}{}
    4 \item\contentsline{section}{{\bf ps\-Bit\-Mask} (A bitmask of arbitrary length)}{\pageref{structpsBitMask}}{}
     3\item\contentsline{section}{{\bf ps\-Bitset} (A bitset of arbitrary length)}{\pageref{structpsBitset}}{}
    54\item\contentsline{section}{{\bf ps\-Catalogue\-Objects} (Objects from a catalogue)}{\pageref{structpsCatalogueObjects}}{}
    65\item\contentsline{section}{{\bf ps\-Cell} (A Cell: a collection of readouts)}{\pageref{structpsCell}}{}
    76\item\contentsline{section}{{\bf ps\-Chip} (A Chip: a collection of cells)}{\pageref{structpsChip}}{}
    8 \item\contentsline{section}{{\bf ps\-Complex\-Array} (An array of complex numbers)}{\pageref{structpsComplexArray}}{}
    9 \item\contentsline{section}{{\bf ps\-Coord} (A point in 2-D space, with errors)}{\pageref{unionpsCoord}}{}
    10 \item\contentsline{section}{{\bf ps\-Coord\-Xform} (A polynomial transformation between coordinate frames)}{\pageref{structpsCoordXform}}{}
    11 \item\contentsline{section}{{\bf ps\-Distortion} (The optical distortion terms)}{\pageref{structpsDistortion}}{}
    127\item\contentsline{section}{{\bf ps\-Dlist} (Doubly-linked list)}{\pageref{structpsDlist}}{}
    138\item\contentsline{section}{{\bf ps\-Dlist\-Elem} (Doubly-linked list element)}{\pageref{structpsDlistElem}}{}
    14 \item\contentsline{section}{{\bf ps\-Double\-Array} (An array of double-precision real numbers)}{\pageref{structpsDoubleArray}}{}
    159\item\contentsline{section}{{\bf ps\-DPolynomial1D} (Double-precision one-dimensional polynomial)}{\pageref{structpsDPolynomial1D}}{}
    1610\item\contentsline{section}{{\bf ps\-DPolynomial2D} (Double-precision two-dimensional polynomial)}{\pageref{structpsDPolynomial2D}}{}
     
    1812\item\contentsline{section}{{\bf ps\-DPolynomial4D} (Double-precision four-dimensional polynomial)}{\pageref{structpsDPolynomial4D}}{}
    1913\item\contentsline{section}{{\bf ps\-Err} }{\pageref{structpsErr}}{}
     14\item\contentsline{section}{{\bf ps\-Error\-Description} }{\pageref{structpsErrorDescription}}{}
    2015\item\contentsline{section}{{\bf ps\-Exposure} (Exposure information from the telescope)}{\pageref{structpsExposure}}{}
    21 \item\contentsline{section}{{\bf ps\-FFT} (Fast Fourier Transform)}{\pageref{structpsFFT}}{}
    2216\item\contentsline{section}{{\bf ps\-Fixed\-Pattern} (The fixed pattern residual offsets)}{\pageref{structpsFixedPattern}}{}
    23 \item\contentsline{section}{{\bf ps\-Float\-Array} (An array of real numbers)}{\pageref{structpsFloatArray}}{}
    2417\item\contentsline{section}{{\bf ps\-FPA} (A Focal plane array: a collection of chips)}{\pageref{structpsFPA}}{}
    2518\item\contentsline{section}{{\bf ps\-Grommit} (Information needed (by SLALIB) to convert Apparent to Observed Position)}{\pageref{structpsGrommit}}{}
     
    2720\item\contentsline{section}{{\bf ps\-Image} (Basic image data structure)}{\pageref{structpsImage}}{}
    2821\item\contentsline{section}{{\bf ps\-Image\-Objects} (Associates objects on an image with the image)}{\pageref{structpsImageObjects}}{}
    29 \item\contentsline{section}{{\bf ps\-Int\-Array} (An array of integers)}{\pageref{structpsIntArray}}{}
    3022\item\contentsline{section}{{\bf ps\-Mem\-Block} (Book-keeping data for storage allocator)}{\pageref{structpsMemBlock}}{}
    31 \item\contentsline{section}{{\bf ps\-Meta\-Data\-Item} (A struct to define a single item of metadata)}{\pageref{structpsMetaDataItem}}{}
    32 \item\contentsline{section}{{\bf ps\-Meta\-Data\-Set} (A set of metadata)}{\pageref{structpsMetaDataSet}}{}
     23\item\contentsline{section}{{\bf ps\-Metadata} (A set of metadata)}{\pageref{structpsMetadata}}{}
     24\item\contentsline{section}{{\bf ps\-Metadata\-Item} (A struct to define a single item of metadata)}{\pageref{structpsMetadataItem}}{}
    3325\item\contentsline{section}{{\bf ps\-Object} (Object definition, to handle both objects we detect, and catalogues)}{\pageref{structpsObject}}{}
    3426\item\contentsline{section}{{\bf ps\-Object\-Array} (An assembly of objects)}{\pageref{structpsObjectArray}}{}
    3527\item\contentsline{section}{{\bf ps\-Phot\-System} (Photometry system definition)}{\pageref{structpsPhotSystem}}{}
    3628\item\contentsline{section}{{\bf ps\-Phot\-Transform} (Photometry transformations)}{\pageref{structpsPhotTransform}}{}
     29\item\contentsline{section}{{\bf ps\-Plane} (A point in 2-D space, with errors)}{\pageref{structpsPlane}}{}
     30\item\contentsline{section}{{\bf ps\-Plane\-Distort} (The optical distortion terms)}{\pageref{structpsPlaneDistort}}{}
     31\item\contentsline{section}{{\bf ps\-Plane\-Transform} (A polynomial transformation between coordinate frames)}{\pageref{structpsPlaneTransform}}{}
    3732\item\contentsline{section}{{\bf ps\-Polynomial1D} (One-dimensional polynomial)}{\pageref{structpsPolynomial1D}}{}
    3833\item\contentsline{section}{{\bf ps\-Polynomial2D} (Two-dimensional polynomial)}{\pageref{structpsPolynomial2D}}{}
    3934\item\contentsline{section}{{\bf ps\-Polynomial3D} (Three-dimensional polynomial)}{\pageref{structpsPolynomial3D}}{}
    4035\item\contentsline{section}{{\bf ps\-Polynomial4D} (Four-dimensional polynomial)}{\pageref{structpsPolynomial4D}}{}
     36\item\contentsline{section}{{\bf ps\-Projection} (Spherical $<$-$>$ Linear projections)}{\pageref{structpsProjection}}{}
    4137\item\contentsline{section}{{\bf ps\-Readout} (A Readout: a collection of pixels)}{\pageref{structpsReadout}}{}
     38\item\contentsline{section}{{\bf ps\-Sphere} (A point on the surface of a sphere, with errors)}{\pageref{structpsSphere}}{}
     39\item\contentsline{section}{{\bf ps\-Sphere\-Transform} (General spherical transformation)}{\pageref{structpsSphereTransform}}{}
    4240\item\contentsline{section}{{\bf ps\-Stats} (Generic statistics structure)}{\pageref{structpsStats}}{}
    4341\item\contentsline{section}{{\bf ps\-Super\-Object} (A \char`\"{}super\char`\"{} object --- an object with multiple detections in different images)}{\pageref{structpsSuperObject}}{}
     42\item\contentsline{section}{{\bf ps\-Time} (Ps\-Time is the time structure we will use throughout)}{\pageref{structpsTime}}{}
    4443\item\contentsline{section}{{\bf ps\-Type} (The type of a data type)}{\pageref{structpsType}}{}
    45 \item\contentsline{section}{{\bf ps\-Void\-Ptr\-Array} (Array of pointers to void)}{\pageref{structpsVoidPtrArray}}{}
     44\item\contentsline{section}{{\bf ps\-Vector} (Basic vector data structure)}{\pageref{structpsVector}}{}
    4645\end{CompactList}
  • trunk/doc/pslib/psSystemGroup.tex

    r381 r747  
    11\begin{CompactItemize}
    22\item
    3 int {\bf ps\-Set\-Log\-Destination} (int dest)
     3int {\bf ps\-Log\-Set\-Destination} (int dest)
    44\begin{CompactList}\small\item\em Sets the log destination.\item\end{CompactList}\item
    5 int {\bf ps\-Set\-Log\-Level} (int level)
     5int {\bf ps\-Log\-Set\-Level} (int level)
    66\begin{CompactList}\small\item\em Sets the log level.\item\end{CompactList}\item
    7 void {\bf ps\-Set\-Log\-Format} (const char $\ast$fmt)
     7void {\bf ps\-Log\-Set\-Format} (const char $\ast$fmt)
    88\begin{CompactList}\small\item\em sets the log format\item\end{CompactList}\item
    99void {\bf ps\-Log\-Msg} (const char $\ast$name, int my\-Level, const char $\ast$fmt,...)
    1010\begin{CompactList}\small\item\em Logs a message.\item\end{CompactList}\item
    11 void {\bf p\_\-ps\-VLog\-Msg} (const char $\ast$name, int my\-Level, const char $\ast$fmt, va\_\-list ap)
     11void {\bf ps\-Log\-Msg\-V} (const char $\ast$name, int my\-Level, const char $\ast$fmt, va\_\-list ap)
    1212\begin{CompactList}\small\item\em Logs a message from varargs.\item\end{CompactList}\item
    1313void $\ast$ {\bf p\_\-ps\-Alloc} (size\_\-t size, const char $\ast$file, int lineno)
     
    2727void $\ast$ {\bf ps\-Mem\-Decr\-Ref\-Counter} (void $\ast$vptr)
    2828\begin{CompactList}\small\item\em Decrement reference counter and return the pointer.\item\end{CompactList}\item
    29 {\bf ps\-Mem\-Problem\-CB} {\bf ps\-Mem\-Problem\-CBSet} ({\bf ps\-Mem\-Problem\-CB} func)
     29{\bf ps\-Mem\-Problem\-Callback} {\bf ps\-Mem\-Problem\-Callback\-Set} ({\bf ps\-Mem\-Problem\-Callback} func)
    3030\begin{CompactList}\small\item\em Set callback for problems.\item\end{CompactList}\item
    31 {\bf ps\-Mem\-Exhausted\-CB} {\bf ps\-Mem\-Exhausted\-CBSet} ({\bf ps\-Mem\-Exhausted\-CB} func)
     31{\bf ps\-Mem\-Exhausted\-Callback} {\bf ps\-Mem\-Exhausted\-Callback\-Set} ({\bf ps\-Mem\-Exhausted\-Callback} func)
    3232\begin{CompactList}\small\item\em Set callback for out-of-memory.\item\end{CompactList}\item
    33 ps\-Mem\-CB {\bf ps\-Mem\-Allocate\-CBSet} ({\bf ps\-Mem\-Allocate\-CB} func)
     33{\bf ps\-Mem\-Allocate\-Callback} {\bf ps\-Mem\-Allocate\-Callback\-Set} ({\bf ps\-Mem\-Allocate\-Callback} func)
    3434\begin{CompactList}\small\item\em Set call back for when a particular memory block is allocated.\item\end{CompactList}\item
    35 ps\-Mem\-CB {\bf ps\-Mem\-Free\-CBSet} ({\bf ps\-Mem\-Free\-CB} func)
     35{\bf ps\-Mem\-Free\-Callback} {\bf ps\-Mem\-Free\-Callback\-Set} ({\bf ps\-Mem\-Free\-Callback} func)
    3636\begin{CompactList}\small\item\em Set call back for when a particular memory block is freed.\item\end{CompactList}\item
    3737int {\bf ps\-Mem\-Get\-Id} (void)
     
    4949void {\bf p\_\-ps\-Trace} (const char $\ast$facil, int my\-Level,...)
    5050\begin{CompactList}\small\item\em Send a trace message.\item\end{CompactList}\item
    51 int {\bf ps\-Set\-Trace\-Level} (const char $\ast$facil, int level)
     51int {\bf ps\-Trace\-Set\-Level} (const char $\ast$facil, int level)
    5252\begin{CompactList}\small\item\em Set trace level.\item\end{CompactList}\item
    53 int {\bf ps\-Get\-Trace\-Level} (const char $\ast$facil)
     53int {\bf ps\-Trace\-Get\-Level} (const char $\ast$facil)
    5454\begin{CompactList}\small\item\em Get the trace level.\item\end{CompactList}\item
    5555void {\bf ps\-Trace\-Reset} (void)
    5656\begin{CompactList}\small\item\em turn off all tracing, and free trace's allocated memory\item\end{CompactList}\item
    57 void {\bf ps\-Print\-Trace\-Levels} (void)
    58 \begin{CompactList}\small\item\em print trace levels\item\end{CompactList}\end{CompactItemize}
     57void {\bf ps\-Trace\-Print\-Levels} (void)
     58\begin{CompactList}\small\item\em print trace levels\item\end{CompactList}\item
     59void {\bf ps\-Trace\-Set\-Destination} (FILE $\ast$fp)
     60\begin{CompactList}\small\item\em Set destination for tracing.\item\end{CompactList}\end{CompactItemize}
Note: See TracChangeset for help on using the changeset viewer.