Index: /trunk/doc/modules/CameraImages.tex
===================================================================
--- /trunk/doc/modules/CameraImages.tex	(revision 4176)
+++ /trunk/doc/modules/CameraImages.tex	(revision 4176)
@@ -0,0 +1,648 @@
+\section{Astronomical Images}
+
+\subsection{Overview}
+
+Above, we have defined a basic container for a single 2D collection of
+pixels (\code{psImage}), along with basic operations to manipulate the
+image pixels.  For astronomical applications, this data structure is
+insufficient for two reasons.  First, it does provide sufficient
+additional metadata to describe the data in detail.  Second, astronomy
+applications frequent involve multiple, related images.  For
+Pan-STARRS, and for general astronomical applications, we require a
+richer collection of data structures which describe a very general
+image concept.  We have defined several layers in the hierarchy which
+are necessary to describe the image data which will be produced by the
+Pan-STARRS Gigapixel cameras as well as other standard astronomical
+images.  
+
+A simple 2D image is a basic data unit for much of astronomical
+imaging.  If we consider various optical and IR array cameras, a
+single readout of the detector produces a collection of pixels
+measurements which is well represented as a single 2D image.  We
+define our lowest-level astronomical image structure,
+\code{psReadout}, to contain the pixels produced by a single readout
+of the detector, along with metadata needed to define that readout:
+the origin and binning of the image relative to the original detector
+pixels explicitly in the structure, and pointers to the general
+metadata and derived objects, if any.
+
+A single detector may be read multiple times in sequence.  For
+example, infrared detectors frequently produce an image immediately
+after the detector is reset followed by an image after the basic
+exposure is complete.  Both readouts correspond to the same pixels,
+though the binning or rastering may be different between the two
+readouts.  Another example is the video sequence produced by the
+Pan-STARRS Gigapix camera guide cells, each of which represents a
+series of many images from a subraster of pixels in the detector
+readout portion.  The second level of our image container hierarchy,
+\code{psCell}, consists of a collection of readouts from a single
+detector.
+
+In the Pan-STARRS Gigapix camera, the basic readout region is a
+fraction of the full imaging area of a single CCD chip.  The chip is
+divided into 64 cells, any fraction of which may have been readout
+for a given exposure.  In other cameras, such as Megacam at CFHT, the
+individual CCDs have multiple amplifiers addressing contiguous
+portions of the detector.  In such cameras, each amplifier produces a
+separate collection of pixels.  In the third level of our image
+container hierarchy, the data structure \code{psChip} represents a
+collection of different cells.   
+
+The top level of our image container hierarchy is a complete focal
+plane array (\code{psFPA}).  This structure represents the collection
+of chips in the camera, all of which are read out in a given
+exposure.  
+
+For example, take a mosaic camera consisting of eight $2k\times 4k$
+CCDs, each of which is read out through two amplifiers.  Then there
+would be sixteen cells in total, each of which is presumably $2k\times
+2k$.  There would be eight chips, each consisting of two cells, and
+the focal plane consists of these eight chips.
+
+As another example, consider an observation by PS-1.  The focal plane
+would consist of 60 chips, each of which consist of 64 cells (or less;
+a few cells may be dead).  Some cells (those containing guide stars
+for the orthogonal transfer) will contain multiple readouts.
+
+These data structures represent containers with which to carry around
+the collection of related image data.  There is no requirement on the
+functions or the structures that each instance of one of these data
+structures represent the physical hardware.  For example, it is not
+necessary that an instance of \code{psFPA} always carry the data for
+all 60 (or 64) Gigapixel camera OTAs.  The usage of these structures
+is such that all astronomical operations which apply to a CCD image
+should be performed on an instance of \code{psFPA}.  If a particular
+circumstance only requires a single 2D image, then that is represented
+by an instance of \code{psFPA} with one \code{psChip}, which in turn
+has one \code{psCell}, which in turn has one \code{psReadout}.  
+
+The data structures defined below provide two additional features
+beyond the hierarchy of relationships.  First, each level of the
+hierarchy includes a generic \code{psMetadata} pointer to provide
+whatever metadata would be appropriate for that level.  The functions
+within PSLib do not specify the contents of those metadata containers.
+One example of their usage is provided in the documentation for the
+Pan-STARRS IPP collection of data processing modules.  
+
+While the \code{psMetadata} pointers provide a mechanism to carry
+generic information about the image, the hierarchy of data structures
+also provides an explicit set of information defining the geometrical
+relationships between the levels of the hierarchy.  Two types of
+information are provided.  In the first case, basic offsets (and in
+the case of the readouts, binning and flips) are defined to specify
+the location of a given \code{psCell} with respect to its containing
+\code{psChip} in the assumption that the pixels in the entire focal
+plane array are laid out on a uniform grid.  This is a crude
+approximation, and cannot be assumed for careful astrometric analysis,
+but it can be used as a starting point or to place the the pixels in a
+test image.  For higher precision, detailed astrometric
+transformations between one frame and the next are also provided.
+
+\tbd{in the future, it may be worthwhile to migrate all of these
+additional pieces to the psMetadata since there is no pressing need to
+have them visible in the data structures}
+
+\subsection{Image Data Container Hierarchy}
+
+\subsubsection{A Readout}
+
+A readout is the result of a single read of a cell (or a portion
+thereof).  It contains a pointer to the pixel data, and additional
+pointers to the objects found in the readout, and the readout
+metadata.  It also contains the offset from the lower-left corner of
+the chip, in the case that the CCD was windowed.
+
+\begin{verbatim}
+typedef struct {
+    const int col0;                    ///< Offset from the left of cell.
+    const int row0;                    ///< Offset from the bottom of cell.
+    const int colParity;               ///< Readout Direction X
+    const int rowParity;               ///< Readout Direction Y
+    const unsigned int colBins;        ///< Amount of binning in x-dimension
+    const unsigned int rowBins;        ///< Amount of binning in y-dimension
+    psImage* image;                    ///< imaging area of Readout
+    psMetadata* metadata;              ///< readout-level metadata
+} psReadout;
+\end{verbatim}    
+
+The constructor for \code{psReadout} shall be:
+\begin{verbatim}
+psReadout *psReadoutAlloc();
+\end{verbatim}
+All pointers in the structure shall be initialized to \code{NULL}.
+
+\subsubsection{A Cell}
+
+A cell consists of one or more readouts (usually only one except in the
+case that the cell has been used for fast guiding).  It also contains
+a pointer to the cell metadata, and a pointer to its parent chip.  On
+the astrometry side, it also contains coordinate transforms from the
+cell to the chip and, as a convenience, from the cell to the focal
+plane.  It is expected that these transforms will consist of two
+first-order 2D polynomials, simply specifying a translation, rotation
+and magnification; hence they are easily inverted, and there is no
+need to add reverse transformations.  We also add an additional
+transformation, which is intended to provide a ``quick and dirty''
+transform from the cell coordinates to the sky; this transformation
+not guaranteed to be as precise as the ``standard'' transformation of
+Cell $\rightarrow$ Chip $\rightarrow$ Focal Plane $\rightarrow$
+Tangent Plane $\rightarrow$ Sky, but will be faster.
+
+\begin{verbatim}
+typedef struct {
+    const int col0;                    ///< Offset from the left of chip.
+    const int row0;                    ///< Offset from the bottom of chip.
+    psArray* readouts;                 ///< readouts from the cell
+    psMetadata* metadata;              ///< cell-level metadata
+    psPlaneTransform* toChip;          ///< transformations from cell to chip coordinates
+    psPlaneTransform* toFPA;           ///< transformations from cell to FPA coordinates
+    psPlaneTransform* toSky;           ///< transformations from cell to sky coordinates
+    psChip *parent;
+} psCell;
+\end{verbatim}
+
+The constructor for \code{psCell} shall be:
+\begin{verbatim}
+psCell *psCellAlloc(int nReadouts, struct psChip *parentChip);
+\end{verbatim}
+The constructor shall make an empty \code{psCell}, with the
+\code{nReadouts} allocated pointers to \code{psReadout}s being set to
+ \code{NULL}.  If \code{nreadouts} is zero or less, then 1 readout
+shall be allocated.  In either case, the value of
+\code{psCell.readouts.n} should be initially set to 0.  If the
+\code{parentChip} is not NULL, this link is made, otherwise it is set
+to \code{NULL}. All other pointers in the structure shall be
+initialized to \code{NULL}.
+
+\subsubsection{A Chip}
+
+A chip consists of one or more cells (according to the number of
+amplifiers on the CCD).  It contains a pointer to the chip metadata,
+and a pointer to the parent focal plane.  For astrometry, it contains
+a coordinate transform from the chip to the focal plane.  It is
+expected that this transforms will consist of two second-order 2D
+polynomials; hence we think that it is prudent to include a reverse
+transformation which will be derived from numerically inverting the
+forward transformation.
+
+\begin{verbatim}
+typedef struct {
+    const int col0;                    ///< Offset from the left of FPA.
+    const int row0;                    ///< Offset from the bottom of FPA.
+    psArray* cells;                    ///< cells in the chip
+    psMetadata* metadata;              ///< chip-level metadata
+    psPlaneTransform* toFPA;           ///< transformation from chip to FPA coordinates
+    psPlaneTransform* fromFPA;         ///< transformation from FPA to chip coordinates
+    psFPA *parent;
+} psChip;
+\end{verbatim}
+
+The constructor for \code{psChip} shall be:
+\begin{verbatim}
+psChip *psChipAlloc(int nCells, psFPA *parentFPA);
+\end{verbatim}
+The constructor shall make an empty \code{psChip}, with the
+ \code{nCells} allocated pointers to \code{psCell}s being set to
+ \code{NULL}.  If \code{nCells} is zero or less, then 1 cell shall be
+ allocated.  In either case, the value of \code{psChip.cells.n} should
+ be initially set to 0.  If the \code{parentFPA} is not NULL, this
+ link is made, otherwise it is set to \code{NULL}. All other pointers
+ in the structure shall be initialized to \code{NULL}.
+
+\subsubsection{A Focal Plane}
+
+A focal plane consists of one or more chips (according to the number
+of pieces of contiguous silicon).  It contains pointers to the focal
+plane metadata and the exposure information.  For astrometry, it
+contains a transformation from the focal plane to the tangent plane
+and the fixed pattern residuals.  It is expected that the
+transformation will consist of two 4D polynomials (i.e.\ a function of
+two coordinates in position, the magnitude of the object, and the
+color of the object) in order to correct for optical distortions and
+the effects of the atmosphere; hence we think that it is prudent to
+include a reverse transformation which will be derived from
+numerically inverting the forward transformation.  Since colors are
+involved in the transformation, it is necessary to specify the color
+the transformation is defined for.  We also include some values to
+characterize the quality of the transformation: the root mean square
+deviation for the x and y transformation fits, and the $\chi^2$ for
+the transformation fit.
+
+\begin{verbatim}
+typedef struct {
+    psArray* chips;                    ///< chips in the focal plane array
+    psMetadata* metadata;              ///< focal-plane's metadata
+    psPlaneDistort* fromTangentPlane;  ///< transformation from tangent plane to focal plane
+    psPlaneDistort* toTangentPlane;    ///< transformation from focal plane to tangent plane
+    psFixedPattern* pattern;           ///< fixed pattern residual offsets
+    const struct psExposure* exposure; ///< information about this exposure
+    const psGrommit* grommit;          ///< grommit allows conversion from tangent plane to sky
+    psPhotSystem* colorPlus;           ///< Color reference
+    psPhotSystem* colorMinus;          ///< Color reference
+    float rmsX;                        ///< RMS for x transformation fits
+    float rmsY;                        ///< RMS for y transformation fits
+    float chi2;                        ///< chi^2 of astrometric solution
+} psFPA;
+\end{verbatim}
+
+The constructor for \code{psFPA} shall be:
+\begin{verbatim}
+psFPA *psFPAAlloc(int nChips, const psExposure *exp);
+\end{verbatim}
+The constructor shall make an empty \code{psFPA}, with the
+\code{nChips} allocated pointers to \code{psChip}s being set to
+\code{NULL}.  If \code{nChips} is zero or less, then 1 chip shall be
+ allocated.  In either case, the value of \code{psFPA.chips.n} should
+ be initially set to 0.  If the value of \code{exp} is not
+ \code{NULL}, this value shall be assigned an used to set the value of
+ \code{grommit}.  Otherwise both shall be set to \code{NULL}.  All
+ other pointers in the structure shall be initialized to \code{NULL}.
+
+Two utility functions are defined to manage the collection of
+backward-pointing links:
+\begin{verbatim}
+bool psFPASetLinks (psFPA *fpa);
+bool psFPATestLinks (psFPA *fpa);
+\end{verbatim}
+The first of these functions constructs the \code{parent} pointers for
+all entries in a \code{psFPA} structure.  The second structure checks
+the validity of the links in an \code{psFPA} structure and returns
+\code{TRUE} if they are all correctly assigned, otherwise \code{FALSE}.
+
+\subsection{Detector Coordinate Transformations}
+
+\begin{figure}
+\psfig{file=CameraLayout,width=5.5in}
+\caption{Camera Pixel Layout\label{CameraLayout}}
+\end{figure}
+
+These container levels also include in their definition the
+information needed to transform the coordinates in one of the levels
+to the coordinate system relevant at the higher levels.
+
+The data structures define the basic coordinate relationships between
+all of these data elements.  A set of offsets for each level in the
+data hierarchy specifies the location of the particular set of pixels
+in the next level of the hierarchy.  This is illustrated in
+Figure~\ref{CameraLayout}.  These offsets may be used to define the
+complete camera layout in the approximating assumption that all pixels
+in the camera are laid out on a single linear pixel grid.  This
+approximate is sufficient for many basic operations.  For more detail,
+the precise astrometric relationship between each level of the
+hierarchy may also be made available in the metadata of the data
+structures.
+
+In practice, a single readout from a detector may represent only a
+subset of the complete set of pixels addressed by the {\it cell}.  The
+readout may also have binning applied in both of the two dimensions.
+There may also be overscan and pre-scan regions in the set of pixels.
+Finally, the readout direction is not always the same for all detector
+amplifiers.  As shown in Figure~\ref{CameraLayout}, these different
+concepts are represented in the data hierarchy.  The coordinate of the
+origin of the data grid for one level of the hierarchy in the grid of
+the containing hierarchy is defined for each data level.  For example,
+the origin of the coordinates for a single chip are located in the
+camera grid at \code{psChip.cell0,row0}.  The \code{psReadout} data
+level has additional information to specify the details of the readout
+process.  The elements \code{psReadout.colParity,rowParity} specify
+the parity of the specific readout (readout direction), while the
+elements \code{psReadout.colBins,rowBins} specify the binning factor
+in the two dimensions.  Note that the value of
+\code{psReadout.col0,row0} must be assigned in such a way that it
+represents the coordinate of the origin pixel in the actual image: the
+overscan or pre-scan pixels must be accounted for.  Putting all of
+these element together, we can see that the pixel coordinates in the
+camera grid may be determined from the pixel coordinates in the image
+grid from the following relationship:
+
+\begin{verbatim}
+psFPA(cell,row) = psChip.cell0,row0 + psCell.cell0,row0 + psReadout.cell0,row0 + 
+                  psReadout.cellParity,rowParity * psReadout.cellBins,rowBins * 
+                  psImage.data(cell,row)
+\end{verbatim}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{Astrometry}
+
+Astrometry is a basic functionality required for the IPP that will be
+used repeatedly, both for low-precision (roughly where is my favorite
+object?) and high-precision (what is the proper motion of this star?).
+As such, it must be flexible, yet robust.
+
+\subsection{Coordinate frames}
+\label{sec:coordinateFrames}
+
+There are five coordinate frames that we need to worry about for the
+purposes of astrometry:
+\begin{itemize}
+\item Cell: $(x,y)$ in pixels --- raw coordinates;
+\item Chip: $(X,Y)$ in pixels --- the location on the silicon;
+\item Focal Plane: $(p,q)$ in microns --- the location on the focal plane;
+\item Tangent Plane: $(l,m)$ in arcsec from the telescope boresight; and
+\item Sky: (RA,Dec) --- ICRS.
+\end{itemize}
+
+The following steps are required to convert from the cell coordinates to
+the sky:
+\begin{itemize}
+\item Cell $\longleftrightarrow$ Chip: two 2D polynomials, $(X,Y) = f(x,y)$;
+\item Chip $\longleftrightarrow$ FP: two 2D polynomials, $(p,q) = g(X,Y)$;
+\item FP $\longleftrightarrow$ TP: two 4D polynomials, $(l,m) =
+h(p,q,m,c)$, where $m$ and $c$ are the magnitude and color of the
+object, respectively; and
+\item TP $\longleftrightarrow$ Sky:  transformation to the sky using
+pre-computed coefficients for each pointing.
+\end{itemize}
+
+Note that the transformation between the Focal Plane and the Tangent
+Plane is a four-dimensional polynomial, in order to account for any
+possible dependencies in the astrometry on the stellar magnitude and
+color; the former serves as a check for charge transfer
+inefficiencies, while the latter will correct chromatic refraction,
+both through the atmosphere and the corrector lenses.
+
+We require structures to contain each of the above transformations as
+well as the pixel data.
+
+\subsection{Position Finding}
+
+We require functions to return the structure containing given
+coordinates.  For example, we want the chip that corresponds to the
+focal plane coordinates $(p,q) = (-1.234,+5.678)$.  These routines
+handle the one-to-many problem --- i.e., for one given focal plane
+coordinate, there are many chips that this coordinate may be
+correspond to; these functions will select the correct one. 
+%
+\begin{verbatim}
+psCell *psCellInFPA (const psPlane *coord, const psFPA *fpa);
+psChip *psChipInFPA (const psPlane *coord, const psFPA *fpa);
+psCell *psCellInChip(const psPlane *coord, const psChip *chip);
+\end{verbatim}
+
+\subsection{Conversion Functions}
+
+We require functions to convert between the various coordinate frames
+(Section~\ref{sec:coordinateFrames}).  The hierarchy of the coordinate
+frames and the transformations between each are shown in
+Figure~\ref{fig:coco}.  The functions that employ the transformations
+are shown in Figure~\ref{fig:cocoFunc}.  In addition to
+transformations between each adjoining coordinate frame in the
+hierarchy, we also require higher-level functions to convert between
+the Cell and Sky coordinate frames; these will simply perform the
+intermediate steps.
+
+\begin{figure}
+\psfig{file=../pslib/coordinateFrames,height=7in,angle=-90}
+\caption{The coordinate systems in the \PS{} IPP, and the relation
+between each by transformations contained in the appropriate
+structures.}
+\label{fig:coco}
+\end{figure}
+
+\begin{figure}
+\psfig{file=../pslib/coordinateConv,height=7in,angle=-90}
+\caption{Conversion between coordinate systems by PSLib.}
+\label{fig:cocoFunc}
+\end{figure}
+
+We specify the following functions to convert between coordinates in
+one type of frame to another type of frame.  The first group consist
+of unambiguous transformations: from the coordinates in a low-level
+frame to the coordinates in the containing higher-level frame, of
+which only one exists.  In all of these functions, the output
+coordinate structure may be \code{NULL} or may be supplied by the
+calling function.  In the former case, the structure must be
+allocated; in the latter case, the supplied structure must be used.
+
+\begin{verbatim}
+psPlane *psCoordCellToChip (psPlane *out, const psPlane *in, const psCell *cell);
+% astrometry comes from cell (no need for parent)
+\end{verbatim}
+which converts coordindates \code{in} on the specified \code{cell} to
+the coordinates on the parent chip.
+
+\begin{verbatim}
+psPlane *psCoordChipToFPA (psPlane *out, const psPlane *in, const psChip *chip);
+% astrometry comes from chip (no need for parent)
+\end{verbatim}
+which converts the coordinates \code{in} on the specified \code{chip}
+to the coordinates on the parent FPA.
+
+\begin{verbatim}
+psPlane *psCoordFPAToTP(psPlane *out, const psPlane *in, float color, float mag, const psFPA *fpa);
+% astrometry comes from FPA (no need for parent)
+\end{verbatim}
+which converts coordinates \code{in} on the specified focal plane
+\code{fpa} to tangent plane coordinates, applying the appropriate
+distortion terms.  The \code{color} and magnitude (\code{mag}) of the
+source is necessary in order to perform the distortion between the
+focal plane and the tangent plane.
+
+\begin{verbatim}
+psSphere *psCoordTPToSky(psSphere *out, const psPlane *in, const psGrommit *grommit);
+\end{verbatim}
+which converts the tangent plane coordinates \code{in} to (RA,Dec) on
+the sky, based on the environmental information specified by
+\code{grommit}.
+
+% astrometry comes from cell
+\begin{verbatim}
+psPlane *psCoordCellToFPA(psPlane *out, const psPlane *in, const psCell *cell);
+\end{verbatim}
+which performs the single-step conversion between Cell coordinates
+\code{in} and FPA coordinates.
+
+% astrometry comes from cell,chip,fpa (PARENT IS NEEDED HERE)
+\begin{verbatim}
+psSphere *psCoordCellToSky(psSphere *out, const psPlane *in, float color, float mag, const psCell *cell);
+\end{verbatim}
+which converts coordinates on the specified cell to (RA,Dec).  This
+transformation must be performed using the intermediate stage
+transformations of Cell to Chip, Chip to FPA, FPA to Tangent Plane,
+Tangent Plane to Sky.  The information needed for each of these
+transformations is available in the \code{.parent} elements of
+\code{psCell} and \code{psChip}, and the \code{psFPA.exposure}
+element.  The \code{color} and magnitude (\code{mag}) of the source is
+necessary in order to perform the distortion between the focal plane
+and the tangent plane.
+
+% astrometry comes from cell (no need for parent)
+\begin{verbatim}
+psSphere *psCoordCellToSkyQuick(psSphere *out, const psPlane *in, const psCell *cell);
+\end{verbatim}
+which uses the 'quick-and-dirty' transformation to convert coordinates
+on the specified cell to (RA,Dec).  This transformation should use the
+locally linear transformation specified by the element
+\code{psCell.toTP}.  Although the accuracy of this transformation
+is lower than the complete transformation above, the calculation is
+substantially faster as it only involves linear transformations.
+
+The following functions convert from high-level frames to the
+coordinates of contained lower-level frames.  
+
+\begin{verbatim}
+psPlane *psCoordSkyToTP(psPlane *out, const psSphere *in, const psGrommit *grommit);
+\end{verbatim}
+which converts (RA,Dec) coordinates \code{in} to tangent plane coords
+based on the enviromental information supplied by \code{grommit}.
+
+\begin{verbatim}
+psPlane *psCoordTPToFPA(psPlane *out, const psPlane *in, float color, float mag, const psFPA *fpa);
+\end{verbatim}
+which converts the tangent plane coordinates \code{in} to focal plane
+coordinates.  The \code{color} and magnitude (\code{mag}) of the
+source is necessary in order to perform the distortion between the
+focal plane and the tangent plane.
+
+\begin{verbatim}
+psPlane *psCoordFPAToChip (psPlane *out, const psPlane *in, const psChip *chip);
+\end{verbatim}
+which converts the specified FPA coordinates \code{in} to the
+coordinates on the given Chip.  The specified chip need not contain
+the input coordinate.  To find the chip which contains a particular
+coordinate, the function \code{psChipInFPA}, defined above, should be
+used.
+
+\begin{verbatim}
+psPlane *psCoordChipToCell (psPlane *out, const psPlane *in, const psCell *cell);
+\end{verbatim}
+which converts the specified Chip coordinate \code{in} to the
+coordinate on the given Cell.  The specified Cell need not contain the
+input coordinate.  To find the cell which contains a particular
+coordinate, the function \code{psCellInChip}, defined above, should be
+used.
+
+\begin{verbatim}
+psPlane *psCoordSkyToCell(psPlane *out, const psSphere *in, float color, float mag, psCell *cell);
+\end{verbatim}
+which directly converts (RA,Dec) \code{in} to coordinates on the
+specified cell.  The specified cell need not contain the input
+coordinates.  The \code{color} and magnitude (\code{mag}) of the
+source is necessary in order to perform the distortion between the
+focal plane and the tangent plane.
+
+\begin{verbatim}
+psPlane *psCoordSkyToCellQuick(psPlane *out, const psSphere *in, psCell *cell);
+\end{verbatim}
+which directly converts (RA,Dec) \code{in} to coordinates on the
+specified cell.  The specified cell need not contain the input
+coordinates.  This transformation should use the locally linear
+transformation specified by the element \code{psCell.toTP}.
+Although the accuracy of this transformation is lower than the
+complete transformation above, the calculation is substantially faster
+as it only involves linear transformations.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{Astrometry and World Coordinate System}
+
+The FITS World Coordinate System (WCS) headers are commonly employed
+with astronomical images in order to relate pixels to celestial (or
+otherwise) coordinates.  Since it is a FITS standard, we must be able
+to read and write from WCS into our internal format.  For the time
+being, we will consider only celestial WCS (i.e., no spectral
+wavelength calibrations, etc).  Because WCS does not support the
+multiple layers that we have built for \PS{}, we will use a simple
+internal representation: a transformation, which handles any
+distortions (i.e., goes directly from the coordinate frame of the
+image to the tangent plane); and the projection.
+
+\begin{verbatim}
+bool psAstrometryReadWCS(psPlaneTransform **transform, // Output transformation
+                         psProjection **projection, // Output projection
+                         psMetadata *header // Input FITS header
+                         );
+bool psAstrometryWriteWCS(psMetadata *header, // Output FITS header
+                          psPlaneTransform *transform, // Input transformation
+		          psProjection *projection, // Input projection
+			  double color, // Mean color to use
+			  double magnitude, // Mean magnitude to use
+                          );
+bool psAstrometrySimplify(psPlaneTransform **transform, // Output transformation
+                          psProjection **projection, // Output projection
+			  psCell *cell // Cell for which to generate transform and projection
+                          );
+\end{verbatim}			
+
+\code{pmReadAstrometry} shall parse the specified FITS \code{header},
+returning new instances of the \code{transform} and \code{projection}
+that represent the WCS.  The function shall return \code{true} if it
+was able to successfully generate the outputs; otherwise it shall
+return \code{false}.
+
+\code{pmWriteAstrometry} shall add WCS keywords to the supplied FITS
+\code{header} that implement the given \code{transform} and
+\code{projection}.  The function shall return \code{true} if it was
+able to successfully generate the output; otherwise it shall return
+\code{false}.
+
+\code{pmSimplifyAstrometry} shall take a \code{cell} and simplify the
+internal astrometric representation (\code{cell->toFPA} or equivalent,
+\code{cell->parent->parent->toTangentPlane} and
+\code{cell->parent->parent->grommit}) to a single \code{transform} and
+\code{projection}.  This allows the subsequent use of
+\code{pmWriteAstrometry} in the case that we have only the
+multi-layered \PS{} internal astrometric representation.  The function
+shall return \code{true} if it was able to successfully generate the
+output; otherwise it shall return \code{false}.
+
+\section{Observatory data}
+
+We need a container for the observatory data that doesn't change per
+exposure.
+
+\begin{verbatim}
+typedef struct {
+    const char *name;                   ///< Name of observatory
+    const double latitude;              ///< Latitude of observatory, east positive
+    const double longitude;             ///< Longitude of observatory
+    const double height;                ///< Height of observatory
+    const double tlr;                   ///< Tropospheric Lapse Rate
+} psObservatory;
+\end{verbatim}
+
+The constructor for \code{psObservatory} shall be:
+\begin{verbatim}
+psObservatory *psObservatoryAlloc(const char *name, double latitude, double longitude,
+                                  double height, double tlr);
+\end{verbatim}
+
+\section{Exposure information}
+
+We need several quantities from the telescope in order to make a
+first guess at the astrometric solution.  From these quantities,
+further quantities can be derived and stored for later use.
+
+\begin{verbatim}
+typedef struct {
+    const double ra, dec;               ///< Telescope boresight
+    const double ha;                    ///< Hour angle
+    const double zd;                    ///< Zenith distance
+    const double az;                    ///< Azimuth
+    const psTime *time;                 ///< Time of observation
+    const float rotAngle;               ///< Rotator position angle
+    const float temp;                   ///< Air temperature, for estimating refraction
+    const float pressure;               ///< Air pressure, for calculating refraction
+    const float humidity;               ///< Relative humidity, for calculating refraction
+    const float exptime;                ///< Exposure time
+    const float wavelength;             ///< Wavelength of observation
+    const psObservatory *observatory;   ///< Observatory data
+    /* Derived quantities */
+    const psTime lst;                   ///< Local Sidereal Time
+    const float posAngle;               ///< Position angle
+    const float parallactic;            ///< Parallactic angle
+    const float airmass;                ///< Airmass, calculated from zenith distance
+    const float pf;                     ///< Parallactic factor
+    const char *cameraName;             ///< name of camera which provided exposure
+    const char *telescopeName;          ///< name of telescope which provided exposure
+} psExposure;
+\end{verbatim}
+
+The constructor for \code{psExposure} shall be:
+\begin{verbatim}
+psExposure *psExposureAlloc(double ra, double dec, double ha, double zd, double az,
+                            const psTime *time, float rotAngle, float temp, float pressure, float humidity,
+                            float exptime, float wavelength, const psObservatory *observatory);
+\end{verbatim}
+
Index: /trunk/doc/modules/ChangeLogSDRS.tex
===================================================================
--- /trunk/doc/modules/ChangeLogSDRS.tex	(revision 4175)
+++ /trunk/doc/modules/ChangeLogSDRS.tex	(revision 4176)
@@ -1,3 +1,3 @@
-%%% $Id: ChangeLogSDRS.tex,v 1.21 2005-06-02 21:22:40 price Exp $
+%%% $Id: ChangeLogSDRS.tex,v 1.22 2005-06-09 05:15:49 eugene Exp $
 
 \subsection{Changes from version 00 (16 August 2004) to version 01 (12 October 2004)}
@@ -74,3 +74,7 @@
 \item Added \code{masks} to \code{pmRejectPixels}.
 \item Added \code{size} and \code{spatialOrder} to \code{pmSubtractionKernels}.
+\item added Image Hierarchy section from psLibSDRS
+\item added photometry section from psLibSDRS
+\item added object function abstractions to Objects
+\item modified pmSource to include modelPSF and modelFLT
 \end{itemize}
Index: /trunk/doc/modules/ModulesSDRS.tex
===================================================================
--- /trunk/doc/modules/ModulesSDRS.tex	(revision 4175)
+++ /trunk/doc/modules/ModulesSDRS.tex	(revision 4176)
@@ -1,3 +1,3 @@
-%%% $Id: ModulesSDRS.tex,v 1.43 2005-06-02 21:22:40 price Exp $
+%%% $Id: ModulesSDRS.tex,v 1.44 2005-06-09 05:15:49 eugene Exp $
 \documentclass[panstarrs]{panstarrs}
 
@@ -204,4 +204,6 @@
 psRegion *pmConfigLookupRegion (psMetadata *config, psMetadata *header, char *name);
 \end{prototype}
+
+\input{CameraImages.tex}
 
 \section{Camera Data Organization \& Camera Geometry}
@@ -573,4 +575,72 @@
 \end{prototype}
 
+\section{Photometry}
+
+\tbd{This section is to be deferred, and for now consists only of
+place holders, with no functional items.}
+
+Photometric observations are performed in an instrumental photometric
+system, and 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{datatype}
+typedef struct {
+    const int ID;                       ///< ID number for this photometric system
+    const char *name;                   ///< Name of photometric system
+    const char *camera;                 ///< Camera for photometric system
+    const char *filter;                 ///< Filter used for photometric system
+    const char *detector;               ///< Detector used for photometric system
+} psPhotSystem;
+\end{datatype}
+
+The following structure defines the transformation between two
+photometric systems.
+\begin{datatype}
+typedef struct {
+    psPhotSystem src;                   ///< Source photometric system
+    psPhotSystem dst;                   ///< Destination photometric system
+    psPhotSystem pP, pM;                ///< Primary color reference
+    psPhotSystem sP, sM;                ///< Secondary color reference
+    float pA, sA;                       ///< Color offset for references
+    psPolynomial3D transform;           ///< Transformation from source to destination
+} psPhotTransform;
+\end{datatype}
+
+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 of 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 measurable.  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)$.
+
 \section{Phase 2}
 
@@ -1112,5 +1182,6 @@
   psImage *mask;           // mask to mark pixels associated with object in region
   pmMoments *moments;      // basic moments measure for the object
-  pmModel *models;         // model parameters and type
+  pmModel *modelPSF;       // PSF model parameters and type
+  pmModel *modelFLT;       // FLT model parameters and type
   pmSourceType type;       // best identification of object
 } pmSource;
@@ -1173,27 +1244,33 @@
 function.  The description of the model includes the model parameters
 and their errors, along with the fit $\chi^2$.  The model type is
-specified by the enum \code{pmObjectModel}, specified below.  We
-discuss the details of these models in section~\ref{ObjectModels}.
+identified by code \code{type}, dynamically assigned based on the
+available models (see below).  We discuss the details of these models
+in section~\ref{ObjectModels}.  The model parameters have 4 special
+elements.  The first four elements represent aspects of the source
+which are not specified by the image PSF, even for point sources.  
+These consist of, in order:
+\begin{itemize}
+\item the local sky
+\item the object normalization
+\item the x-coordinate
+\item the y-coordinate
+\end{itemize}
+
+Every source may have two types of models: a PSF model and a FLT
+(floating) model.  The PSF model represents the best fit of the image
+PSF to the specific object.  In this case, the PSF-dependent
+parameters are specified for the object by the PSF, not by the fit.
+The FLT model represents the best fit of the given model to the
+object, with all parameters floating in the fit.
 
 \begin{datatype}
 typedef struct {
-  pmObjectModel type;       // model to be used
-  psVector *params;            // parameter values
-  psVector *dparams;           // parameter errors
+  psS32 type;               // model to be used
+  psVector *params;         // parameter values
+  psVector *dparams;        // parameter errors
   psF32 chisq;              // fit chisq
-  psS32 nDOF;		// number of degrees of freedom
-  psS32 nIter;          // number of iterations
+  psS32 nDOF;		    // number of degrees of freedom
+  psS32 nIter;              // number of iterations
 } pmModel;
-\end{datatype}
-
-\begin{datatype}
-typedef enum {
-  PM_MODEL_GAUSS;
-  PM_MODEL_PGAUSS;
-  PM_MODEL_TWIST_GAUSS;
-  PM_MODEL_WAUSS;
-  PM_MODEL_SERSIC;
-  PM_MODEL_SERSIC_CORE;
-} pmModelType; 
 \end{datatype}
 
@@ -1217,4 +1294,23 @@
 \end{datatype}
 
+It is useful to generate a model to define the point-spread-function
+which describes the flux distribution for unresolved sources in an
+image.  In general, the PSF varies with position in the image.  We
+allow any of the source models defined for the \code{pmModel} to
+represent the PSF.  For a given source model, the 2D spatial variation
+of all of the source parameters, except the first four PSF-independent
+parameters, are represented as polynomial, stored in a \code{psArray}.
+The other elements of the structure define the quality of the PSF
+determination.
+
+\begin{datatype}
+typedef struct {
+    psS32 type;             ///< PSF Model in use
+    psArray *params;	    ///< Model parameters (psPolynomial2D)
+    psF32 chisq;            ///< PSF goodness statistic
+    psS32 nPSFstars;	    ///< number of stars used to measure PSF
+} pmPSF;
+\end{datatype}
+
 \begin{datatype}
 typedef enum {
@@ -1230,4 +1326,70 @@
 pmModel    *pmModelAlloc (pmModelType type);
 \end{prototype}
+
+\subsection{Object Model Abstraction}
+
+The object model functions are defined to allow for the flexible
+addition of new object models.  Every object model, with parameters
+represented by \code{pmModel}, has an associated set of functions
+which provide necessary support operations.  A set of abstract
+functions allow the programmer to select the approriate function or
+property for a specific named object model.
+
+The following function concepts are provided by each model.
+
+\begin{prototype}
+typedef psMinimizeLMChi2Func psModelFunc;
+\end{prototype}
+This function is the model chi-square minimization function for this
+model.
+
+\begin{prototype}
+typedef psF64 (*psModelFlux)(const psVector *params);
+\end{prototype}
+This function returns the integrated flux for the given model
+parameters.
+
+\begin{prototype}
+typedef bool (*psModelGuessFunc)(psModel *model, psSource *source);
+\end{prototype}
+This function provides the model guess parameters based on the details
+of the given source.
+
+\begin{prototype}
+typedef bool (*psModelFromPSFFunc)(psModel *modelPSF, psModel *modelFLT, pmPSF *psf);
+\end{prototype}
+This function constructs the PSF model for the given source based on
+the supplied \code{psf} and the FLT model for the object.  
+
+\begin{prototype}
+typedef psF64 (*psModelRadius)(const psVector *params, double flux);
+\end{prototype}
+This function returns the radius at which the given model and
+parameters achieves the given flux.
+
+Each of the function types above has a corresponding function which
+returns the function given the model type:
+\begin{prototype}
+psModelFunc psModelFunc_GetFunction (psModelType type);
+psModelFlux psModelFlux_GetFunction (psModelType type);
+psModelGuessFunc psModelGuessFunc_GetFunction (psModelType type);
+psModelFromPSFFunc psModelFromPSFFunc_GetFunction (psModelType type);
+psModelRadius psModelRadius_GetFunction (psModelType type);
+\end{prototype}
+
+In addition, the following utility functions return information about
+the specified model:
+
+\begin{prototype}
+psS32 psModelParameterCount (psModelType type);
+psS32 psModelSetType (char *name);
+char *psModelGetType (psModelType type);
+\end{prototype}
+\code{psModelParameterCount} returns the number of parameters for the
+given model.  The remaining functions lookup the name or identifying
+code for the model from the other concept.  Model names are character
+strings in all caps of the form \code{GAUSS}.  Names are invarient
+between multiple compliations of the library, but the model numbers
+are not and should only be used within programs.
 
 \subsection{Basic Object Detection APIs}
