Index: /trunk/archive/pslib/include/psPhotom.h
===================================================================
--- /trunk/archive/pslib/include/psPhotom.h	(revision 273)
+++ /trunk/archive/pslib/include/psPhotom.h	(revision 274)
@@ -26,7 +26,8 @@
     psPhotSystem src;
     psPhotSystem dst;
-    psPhotSystem colorPlus, colorMinus;	///< Colour reference
-    psPolynomial2D transform;
-    psPhotTransformType type;
+    psPhotSystem pP, pM;	///< Colour reference
+    psPhotSystem sP, sM;	///< Colour reference
+    float pA, sA;		///< 
+    psPolynomial3D transform;
 } psPhotTransform;
 
Index: /trunk/doc/pslib/psLibSubset.tex
===================================================================
--- /trunk/doc/pslib/psLibSubset.tex	(revision 274)
+++ /trunk/doc/pslib/psLibSubset.tex	(revision 274)
@@ -0,0 +1,458 @@
+\documentclass[panstarrs]{panstarrs}
+%\documentclass[panstarrs]{panstarrs}
+
+% basic document variables
+\title{Pan-STARRS IPP Library Design}
+\author{}
+\shorttitle{PSLib Design}
+\group{Pan-STARRS Algorithm Group}
+\project{Pan-STARRS Image Processing Pipeline}
+\organization{Institute for Astronomy}
+\version{DR}
+\docnumber{PSDC-xxx-xxx}
+% note the use of the docnumber & version number:
+% the complete PSDC document number is given by
+% \thedocnumber-\theversion
+
+\begin{document}
+\maketitle
+
+\section{Astronomy-Specific Functions}
+
+\subsection{Basic Images}
+
+The most important data product produced by the telescope is an image.
+The simplest image is a 2-D collection of pixels, each with some
+value.  We require a basic image data type:
+
+\begin{verbatim}
+/// basic image data structure.
+typedef struct psImage {
+    psType type;                        ///< image data type and dimension
+    int nx, ny;                         ///< size of image 
+    int x0, y0;                         ///< data region relative to parent 
+    union {
+        psF32 **rows;                   ///< == rows_f32 
+        psS8  **rows_s8;                ///< pointers to psS8 data 
+        psS16 **rows_s16;               ///< pointers to psS16 data 
+        psS32 **rows_s32;               ///< pointers to psS32 data 
+        psU8  **rows_u8;                ///< pointers to psU8 data 
+        psU16 **rows_u16;               ///< pointers to psU16 data 
+        psU32 **rows_u32;               ///< pointers to psU32 data 
+        psF32 **rows_f32;               ///< pointers to psF32 data 
+        psF64 **rows_f64;               ///< pointers to psF64 data 
+    } rows;
+    struct psImage *parent;             ///< parent, if a subimage 
+    struct psImage *children;           ///< children of this region 
+    int Nchildren;                      ///< number of subimages 
+} psImage;
+\end{verbatim}
+
+This structure represents an image consisting of a 2-D array of
+pixels.  The size of this array is given by the elements \code{(nx,
+ny)}.  The data type of the pixel is defined by the \code{psType type}
+entry (see \ref{TBD}).  (n.b. that for FITS images, these values are
+restricted to the datatypes equivalent to the valid BITPIX values 8,
+16, 32, -32, -64).  The image represented in the data structure may
+represent a subset of the pixels in a complete array.  The offset of
+the \code{(0,0)} pixel in this array relative to the parent array is
+given by the elements \code{(x0,y0)}.  The structure may include
+references to subrasters (\code{children, Nchildren}) and/or to a
+containing array (\code{parent}).
+
+We require a variety of functions to manipulate these image
+structures, including creation, destruction, input, output, and
+various manipulations of the pixels.  The required functions are
+listed below.
+
+Create an image of a specified width, height, and data type.  This
+function must allow any of the valid image data types and not restrict
+to the valid FITS BITPIX types.
+\begin{verbatim}
+psImage *
+psImageAlloc (int nx,                   ///< image width 
+              int ny,                   ///< image height 
+              psType type)              ///< image data type 
+\end{verbatim}
+
+Define a subimage of the specified area of the given image.  This
+function must return an error if the requested subset area lies
+outside of the parent image.
+\begin{verbatim}
+psImage *
+psImageSubset (psImage *image,          ///< parent image 
+               int nx,                  ///< subimage width (<= image.nx - x0)  
+               int ny,                  ///< subimage width (<= image.ny - y0)  
+               int x0,                  ///< subimage x-offset (0 <= x0 < nx)   
+               int y0)                  ///< subimage y-offset (0 <= y0 < ny)   
+\end{verbatim}
+
+Free the memory associated with a specific image.  \note{does this
+  free the input structure or just the allocated elements?}  Free the
+  children of the image if they exist.
+\begin{verbatim}
+void 
+psImageFree (psImage *image)            ///< free this image
+\end{verbatim}
+
+Free the memory associated with the children of a specific image.  
+\begin{verbatim}
+int 
+psImageFreeChildren (psImage *image)    ///< free children of this image
+\end{verbatim}
+
+Create a copy of the specified image.  If the output target pointer is
+not NULL, place the result in the specified structure.
+\begin{verbatim}
+psImage *
+psImageCopy (psImage *output,           ///< target structure for output image data
+             psImage *input)            ///< copy this image 
+\end{verbatim}
+
+Extract pixels from rectlinear region to a vector (array of floats).
+The output vector contains either \code{nx} or \code{ny} elements,
+based on the value of the direction: e.g., if \code{direction} is
+\tbd{+x}, there are \code{nx} elements.  The input region is collapsed
+in the perpendicular direction, and each element of the output vectors
+is derived from the statistics of the pixels at that direction
+coordinate.  The statistic used to derive the output vector value is
+specified by \code{psStats stats}.
+\begin{verbatim}
+psFloatArray *
+psImageSlice (psImage *input,           ///< extract slice from this image
+              int x,                    ///< starting x coord of region to slice
+              int y,                    ///< starting y coord of region to slice
+              int nx,                   ///< width of region in x
+              int ny,                   ///< width of region in y
+              int direction,            ///< direction of vector along slice
+              psStats *stats)           ///< defines statistics used to find output values
+\end{verbatim}
+
+Extract pixels from an image along a line to a vector (array of
+floats).  The vector \code{xs,ys} - \code{xe,ye} forms the basis of
+the output vector.  Pixels are considered in a rectangular region of
+width \code{dw} about this vector.  The input region is collapsed in
+the perpendicular direction, and each element of the output vector
+represents a pixel-sized boxes, where the value is derived from the
+statistics of the pixels interpolated along the perpendicular
+direction.  The statistic used to derive the output vector value is
+specified by \code{psStats stats}.
+\begin{verbatim}
+psFloatArray *
+psImageCut (psImage *input,             ///< extract cut from this image
+            float xs,                   ///< starting x coord of cut
+            float ys,                   ///< starting y coord of cut
+            float xe,                   ///< ending x coord of cut
+            float ye,                   ///< ending y coord of cut
+            float dw,                   ///< width of cut
+            psStats *stats)             ///< defines statistics used to find output values
+ \end{verbatim}
+
+
+Extract radial annulii data to a vector.  A vector is constructed
+where each vector elements is derived from the statistics of the
+pixels which land in one of a sequence of annulii.  The annulii are
+centered on the image pixel coordinate \code{x,y}, and have width
+\code{dr}.  The number of annulii is $radius / dr$.  The statistic
+used to derive the output vector value is specified by \code{psStats
+stats}
+\begin{verbatim}
+psFloatArray *
+psImageRadialCut (psImage *input,       ///< extract profile from this image
+                  float x,              ///< center x coord of annulii
+                  float y,              ///< center y coord of annulii
+                  float radius,         ///< outer radius of annulii
+                  float dr,             ///< radial step size of annulii
+                  psStats *stats)       ///< defines statistics used to find output values 
+\end{verbatim}
+
+%/// Extract a 2-d contour from an image at the given threshold.
+%\begin{verbatim}
+%psFloatArray *
+%psImageContour (psImage *input,        ///< create contour for this image
+%               float threshold,        ///< contour image at this threshold
+%               int binning)            ///< bin image by this value for contour calculation
+%\end{verbatim}
+
+Rebin image to new scale.  A new image is constructed in which the
+dimensions are reduced by a factor of \code{scale}.  The output image
+represents a one-to-one mapping of the pixels in the input image,
+except for edge effects.  Each pixel in the output image is derived
+from the statistics of the corresponding input image pixels based on
+the statistics specified by \code{psStats stats}.
+\tbd{interpolation?}
+\begin{verbatim}
+psImage *
+psImageRebin (psImage *input,           ///< rebin this image
+              float scale,              ///< rebinning scale: doutput = scale*dinput
+              psStats *stats)           ///< defines statistics used to find output values
+\end{verbatim}
+
+Rotate the input image by given angle, specified in degrees.  The
+output image must contain all of the pixels from the input image in
+their new frame.  Pixels in the output image which do not map to input
+pixels should be set of \tbd{value}.  The center of rotation is always
+the center pixel of the image.  The rotation is specified in the sense
+that a positive value is a clock-wise rotation.  
+\begin{verbatim}
+psImage *
+psImageRotate (psImage *input,          ///< rotate this image
+               float angle)             ///< rotate by this amount (degrees)
+\end{verbatim}
+
+Shift image by an arbitrary number of pixels (\code{dx,dy}) in either
+direction.  If the shift values are fractional, the output pixel
+values shoul interpolate between the input pixel values.  The output
+image has the same dimensions as the input image.  Pixels which fall
+off the edge of the output image are loast.  Newly exposed pixels are
+set to the value given by \code{exposed}.  
+\begin{verbatim}
+psImage *
+psImageShift (psImage *input,           ///< shift this image
+              float dx,                 ///< shift by this amount in x
+              float dy,                 ///< shift by this amount in y
+              float exposed)            ///< set exposed pixels to this value
+\end{verbatim}
+
+Roll image by an integer number of pixels in either direction.  The
+output image is the same dimensions as the input image.  Edge pixels
+wrap to the other side (no values are lost).
+\begin{verbatim}
+psImage *
+psImageRoll (psImage *input,            ///< roll this image
+             int dx,                    ///< roll this amount in x
+             int dy)                    ///< roll this amount in y
+\end{verbatim}
+
+Determine statistics for image (or subimage).  The statistics to be
+determined are specified by \code{psStats stats}.
+\begin{verbatim}
+psStats *
+psImageGetStats (psImage *input,        ///< image (or subimage) to calculate stats
+                 psStats *stats)        ///< defines statistics to be calculated
+\end{verbatim}
+
+Construct a histogram from an image (or subimage).  The histogram to
+generate is specified by \code{psHistogram hist}.
+\begin{verbatim}
+psHistogram *
+psImageHistogram (psHistogram *hist,    ///< input histogram description & target
+                  psImage *input)       ///< determine histogram of this image
+\end{verbatim}
+
+Fit a 2-D polynomial surface to an image.  The input structure
+\code{coeffs} contains the desired order and terms of interest.
+\tbd{how do we specify the renomalization?}
+\begin{verbatim}
+psPolynomial2D *
+psImageFitPolynomial (psImage *input,   ///< image to fit
+                      psPolynomial2D *coeffs) ///< coefficient structure carries in desired terms
+\end{verbatim}
+
+Evaluate a 2-D polynomial surface to image pixels.  Given the input
+polynomial coefficients, return an image generated on the basis of the
+input image pixels which evaluates the polynomial for all pixels in
+the image.a
+\begin{verbatim}
+int
+psImageEvalPolynomial (psImage *input,  ///< image to fit
+                       psPolynomial2D *coeffs) ///< coefficient structure carries in desired terms
+\end{verbatim}
+
+Read an image or subimage from a named file.  This function is a
+wrapper to the FITS library function.  The input parameters allow or a
+subimage to be read.  The starting pixel of the region is specified by
+\code{x,y}, while the dimensions of the requested region are specified
+by \code{nx,ny}.  A value of -1 for these two parameters specifies the
+full array of the requested image.  If the native image is a cube, the
+value of z specifies the requested slice of the image.  The data is
+read from the extension specified by extname (matching the EXTNAME
+keyword) or by the extnum value (with -1 representing the PHU, 0 the
+first extension, etc).  This function must return an error if any of
+the specified parameters are out of range for the data in the image
+file, if the specified image file does not exist.  \tbd{what do we do
+with a 0D or 1D image?}
+\begin{verbatim}
+psImage *
+psImageReadSection (psImage *output,    ///< place data in this structure for output 
+                    int x,              ///< starting x coord of region
+                    int y,              ///< starting y coord of region
+                    int nx,             ///< x size of region (-1 for full range)
+                    int ny,             ///< y size of region (-1 for full range)
+                    int z,              ///< plane of interest
+                    char *extname,      ///< MEF extension name ("PHU" for primary header)
+                    int extnum,         ///< MEF extension sequence number (-1 for PHU)
+                    char *filename)     ///< file to read data from
+\end{verbatim}
+ 
+Read an image or subimage from file descriptor.  The input parameters
+and their behavior for this function are identical with those in
+\code{psImageReadSection}.
+\begin{verbatim}
+psImage *
+psImageFReadSection (psImage *output,   ///< place data in this structure for output 
+                     int x,             ///< starting x coord of region            
+                     int y,             ///< starting y coord of region            
+                     int dx,            ///< x size of region (-1 for full range)          
+                     int dy,            ///< y size of region (-1 for full range)          
+                     int z,             ///< plane of interest                     
+                     char *extname,     ///< MEF extension name ("PHU" for primary header)                         
+                     FILE *f)           ///< file descriptor to read data from             
+\end{verbatim}
+
+Write an image section to named file, which may exist.  This
+operatation may write a portion of an image over the existing bytes of
+an existing image.  If the file does not exist, it should be created.
+If the specified extention does not exist, it should be created.  If
+an extension is specified and no PHU exists, a basic PHU should be
+created.  
+\begin{verbatim}
+psImage *
+psImageWriteSection (psImage *input,    ///< image to write out
+                     int x,             ///< starting x coord of region            
+                     int y,             ///< starting y coord of region            
+                     int z,             ///< plane of interest                     
+                     char *extname,     ///< MEF extension name ("PHU" for primary header)                         
+                     char *filename)    ///< file to write data to                 
+\end{verbatim}
+
+Write an image section to file descriptor.
+\begin{verbatim}
+psImage *
+psImageFWriteSection(psImage *input,    ///< image to write out
+                     int x,             ///< starting x coord of region            
+                     int y,             ///< starting y coord of region            
+                     int z,             ///< plane of interest                     
+                     char *extname,     ///< MEF extension name                    
+                     FILE *f)           ///< file descriptor to write data to              
+\end{verbatim}
+
+Read header data from a FITS image file into a \code{psMetaData}
+structure.  If the named extension does not exist, the function should
+return an error.  
+\begin{verbatim}
+struct psMetadata *
+psImageReadHeader(struct psMetadata *output,    ///< read data to this structure
+                  char *extname,        ///< MEF extension name ("PHU" for primary header)
+                  int extnum,           ///< MEF extension number (-1 for "PHU", 0 : Nextend - 1)
+                  char *filename)       ///< file to read from
+\end{verbatim}
+
+Read header data from a FITS image file descriptor into a \code{psMetaData}
+structure.  
+\begin{verbatim}
+struct psMetadata *
+psImageFReadHeader (struct psMetadata *output, ///< read data to this structure
+                   char *extname,       ///< MEF extension name ("PHU" for primary header)
+                   int extnum,          ///< MEF extension number (-1 for "PHU", 0 : Nextend - 1)
+                   FILE *f)             ///< file descriptor to read from
+\end{verbatim}
+
+Perform a 2-D FFT on the specified image. 
+\begin{verbatim}
+psImage *
+psImageFFT (psImage *input,             ///< image to FFT
+            int direction)              ///< FFT direction 
+\end{verbatim}
+
+Clip image values outside of range to given values.  All pixels with
+values $<$ min are set to the value vmin. All pixels with values $>$
+max are set to the value vmax.
+\begin{verbatim}
+int
+psImageClip (psImage *input,            ///< clip this image
+             float min,                 ///< clip pixels with values < min
+             float vmin,                ///< set min-clipped pixels to vmin
+             float max,                 ///< clip pixels with values > max
+             float vmax)                ///< set max-clipped pixels to vmax
+\end{verbatim}
+
+Clip NaN image pixels to given value.  Pixels with NaN or Inf values
+are set to the specified value.
+\begin{verbatim}
+int
+psImageClipNaN (psImage *input,         ///< clip this image
+                float value)            ///< set nan pixels to this value
+\end{verbatim}
+
+Overlay subregion of image with another image.  Replace the pixels in
+the \code{image} which correspond to the pixels in \code{overlay} with
+values derived from the values in \code{image} and \code{overlay}
+based on the given operator.  Valid operators are ``='' (set image
+value to overlay value), ``+'' (add overlay value to image value),
+``-'' (subtract overlay from image), ``*'' (multiply overlay times
+image), ``/'' (divide image by overlay).  
+\begin{verbatim}
+int 
+psImageOverlaySection (psImage *image,          ///< input image 
+                psImage *overlay,       ///< image to overlay 
+                int x0,                 ///< x offset of overlay subimage 
+                int y0,                 ///< y offset of overlay subimage 
+                char *operator)         ///< overlay operation 
+\end{verbatim}
+
+\subsection{Photometry}
+
+Photometric observations are performed in a photometric system, and
+are must be related to other photometric systems.  We require a data
+structure which defines a photometric system, as well as a structure
+to define the transformation between photometric systems.  
+
+The photometric system is defined by the psPhotSystem structure.  
+A photometric system is identified by a human-readable \code{name}
+(ie, SDSS.g, Landolt92.B, GPC1.OTA32.r).  Each photometric system is
+given a unique identifier \code{ID}.  Observations taken with a
+specific camera, detector, and filter represent their own photometric
+system, and it may be necessary to perform transformations between
+these systems.  Photometric systems associated with observations from
+a specific camera/detector/filter combination can be associated with
+those components.
+\begin{verbatim}
+typedef struct {
+    int ID;
+    char *name;
+    char *camera;
+    char *filter;
+    char *detector;
+} psPhotSystem;
+\end{verbatim}
+
+The following structure defines the transformation between two
+photometric systems.
+\begin{verbatim}
+typedef struct {
+    psPhotSystem src;
+    psPhotSystem dst;
+    psPhotSystem pP, pM;	///< Colour reference
+    psPhotSystem sP, sM;	///< Colour reference
+    float pA, sA;		///< 
+    psPolynomial3D transform;   
+} psPhotTransform;
+\end{verbatim}
+
+The transformation between two photometric systems may depend on the
+airmass of the observation and on the colors of the object of
+interest.  For a specific observation, such a transformations can be
+defined as a polynomial function of the color the star and the airmass
+of the observations.  If sufficient data exists, the transformation
+between the photometric systems may include more than one color,
+constraining the curvature of the stellar spectral energy
+distributions.  This latter term may be significant for stars which
+are highly reddened, for example.  Derived photometric quantities may
+have been corrected for airmass variations, in which case only color
+terms may be measureable.  The structure defines the transformation
+between a source photometric system (\code{src}) and a target
+photometric system (\code{dst}).  The photometric system of a primary
+color is defined by \code{pP, pM} such that the color is constructed
+as $pP - pM$.  A secondary color is defined by \code{sP, sM}.  For
+both, a reference color is specified (\code{pA, sA}): the polynomial
+transformation terms refer to colors in the form $pP - pM - pA$.  The
+transformation is specified as a 3D polynomial.  For a star of
+magnitude $M_{\rm src}$ in the source photometric system, with
+additional magnitude information in the other systems $M_{\rm pP}$,
+$M_{\rm pM}$, $M_{\rm sP}$, $M_{\rm sM}$, observed at an airmass of
+$z$, the magnitude of the star in the target system $M_{\rm dst}$ is
+given by: 
+$M_{\rm dst} = M_{\rm src} + transform(z, M_{\rm pP} - M_{\rm pM} - pA, M_{\rm sP} - M_{\rm sM} - sA)$
+
+\end{document}
