Index: trunk/doc/pslib/psLibSDRS_Astrom.tex
===================================================================
--- trunk/doc/pslib/psLibSDRS_Astrom.tex	(revision 1674)
+++ trunk/doc/pslib/psLibSDRS_Astrom.tex	(revision 2502)
@@ -9,9 +9,9 @@
 additional metadata to describe the data in detail.  Second, astronomy
 applications frequent involve multiple, related images.  For
-PanSTARRS, and for general astronomical applications, we require a
+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
-PanSTARRS Gigapixel cameras as well as other standard astronomical
+Pan-STARRS Gigapixel cameras as well as other standard astronomical
 images.  
 
@@ -19,18 +19,19 @@
 imaging.  If we consider various optical and IR array cameras, a
 single readout of the detector produces a collection of pixels
-measurements.  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 produce more than one read which is associated.
-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
-PanSTARRS Gigapix camera guide cells, each of which represents a
+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,
@@ -38,5 +39,5 @@
 detector.
 
-In the PanSTARRS Gigapix camera, the basic readout region is a
+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
@@ -59,5 +60,5 @@
 the focal plane consists of these eight chips.
 
-As another example, consider an observation by PS1.  The focal plane
+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
@@ -76,9 +77,33 @@
 has one \code{psCell}, which in turn has one \code{psReadout}.  
 
-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.  
-
-\subsubsection{A Readout}
+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}
+
+\subsubsection{Image Data Container Hierarchy}
+
+\subsubsubsection{A Readout}
 
 A readout is the result of a single read of a cell (or a portion
@@ -90,15 +115,22 @@
 \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
-    const int col0;                    ///< Offset from the left of chip.
-    const int row0;                    ///< Offset from the bottom of chip.
     psImage* image;                    ///< imaging area of Readout
-    psList*  objects;                  ///< objects derived from Readout
     psMetadata* metadata;              ///< readout-level metadata
 } psReadout;
 \end{verbatim}    
 
-\subsubsection{A Cell}
+The constructor for \code{psReadout} shall be:
+\begin{verbatim}
+psReadout *psReadoutAlloc();
+\end{verbatim}
+All pointers in the structure shall be initialized to \code{NULL}.
+
+\subsubsubsection{A Cell}
 
 A cell consists of one or more readouts (usually only one except in the
@@ -119,4 +151,6 @@
 \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
@@ -124,9 +158,22 @@
     psPlaneTransform* toFPA;           ///< transformations from cell to FPA coordinates
     psPlaneTransform* toSky;           ///< transformations from cell to sky coordinates
-    struct psChip* parent;             ///< chip in which contains this cell
+    psChip *parent;
 } psCell;
 \end{verbatim}
 
-\subsubsection{A Chip}
+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}.
+
+\subsubsubsection{A Chip}
 
 A chip consists of one or more cells (according to the number of
@@ -141,13 +188,27 @@
 \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
-    struct psFPA* parent;              ///< FPA which contains this chip
+    psFPA *parent;
 } psChip;
 \end{verbatim}
 
-\subsubsection{A Focal Plane}
+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}.
+
+\subsubsubsection{A Focal Plane}
 
 A focal plane consists of one or more chips (according to the number
@@ -176,5 +237,5 @@
     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
+    const psGrommit* grommit;          ///< grommit allows conversion from tangent plane to sky
     psPhotSystem* colorPlus;           ///< Color reference
     psPhotSystem* colorMinus;          ///< Color reference
@@ -183,4 +244,108 @@
     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}.
+
+\subsubsection{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}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% add psExposure to metadata?
+% add grommit to metadata?
+% add photsystem data to metadata?
+% add statistics to metadata?
+
+\subsubsection{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}
 
@@ -216,25 +381,4 @@
 \end{verbatim}
 
-\subsubsection{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}
-
-\subsubsection{Constructors}
-
-Each of the above structures needs an appropriate constructor and
-destructor.  In what follows, each of the variables has the same
-meaning as in the appropriate structure.
-
 The constructor for \code{psExposure} shall be:
 \begin{verbatim}
@@ -243,95 +387,4 @@
                             float exptime, float wavelength, const psObservatory *observatory);
 \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}
-
-The constructor for \code{psFPA} shall be:
-\begin{verbatim}
-psFPA *psFPAAlloc(int nAlloc, const psExposure *exp);
-\end{verbatim}
-The constructor shall make an empty \code{psFPA}, with the
-\code{nAlloc} allocated pointers to \code{psChip}s being set to
-\code{NULL}; all other pointers in the structure shall be initialized
-to \code{NULL}, apart from the \code{grommit}, which shall be
-constructed on the basis of the \code{exp}.
-
-The destructor for \code{psFPA} shall destroy the related
-\code{psGrommit}.
-
-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}; all other pointers in the structure shall be initialized
-to \code{NULL}.
-
-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}; all other pointers in the structure shall be initialized
-to \code{NULL}.
-
-The constructor for \code{psReadout} shall be:
-\begin{verbatim}
-psReadout *psReadoutAlloc(int x0, int y0, const psImage *image);
-\end{verbatim}
-All pointers in the structure other than the \code{image} shall be
-initialized to \code{NULL}.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\subsection{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.  Accordingly, we will wrap
-the StarLink Astronomy Libraries (SLALib), which has already been
-developed.
-
-\subsubsection{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: SLALib transformation using a
-transform pre-computed 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.
-
 \subsubsection{SLALib information}
 
@@ -386,5 +439,6 @@
 The constructor for \code{psFixedPattern} shall be:
 \begin{verbatim}
-psFixedPattern *psFixedPatternAlloc(double x0, double y0, double xScale, double yScale,
+psFixedPattern *psFixedPatternAlloc(double x0,        double y0, 
+                                    double xScale,    double yScale,
                                     const psImage *x, const psImage *y);
 \end{verbatim}
@@ -396,4 +450,49 @@
 elements may be derived from the size of the images.
 
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\subsection{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.  Accordingly, we will wrap
+the StarLink Astronomy Libraries (SLALib), which has already been
+developed.
+
+\subsubsection{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: SLALib transformation using a
+transform pre-computed 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.
 
 \subsubsection{Position Finding}
@@ -449,4 +548,5 @@
 \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
@@ -455,4 +555,5 @@
 \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}
@@ -461,4 +562,5 @@
 \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
@@ -477,4 +579,5 @@
 \begin{verbatim}
 psPlane *psCoordCellToFPA(psPlane *out, const psPlane *in, const psCell *cell);
+% astrometry comes from cell
 \end{verbatim}
 which performs the single-step conversion between Cell coordinates
@@ -483,4 +586,5 @@
 \begin{verbatim}
 psSphere *psCoordCellToSky(psSphere *out, const psPlane *in, float color, float mag, const psCell *cell);
+% astrometry comes from cell,chip,fpa (PARENT IS NEEDED HERE)
 \end{verbatim}
 which converts coordinates on the specified cell to (RA,Dec).  This
@@ -496,4 +600,5 @@
 \begin{verbatim}
 psSphere *psCoordCellToSkyQuick(psSphere *out, const psPlane *in, const psCell *cell);
+% astrometry comes from cell (no need for parent)
 \end{verbatim}
 which uses the 'quick-and-dirty' transformation to convert coordinates
@@ -588,4 +693,3 @@
 double psGetParallaxFactor(const psExposure *exp)
 \end{verbatim}
-Calculate the parallax factor for the given exposure.  \tbd{Why do we
-need this?}.
+Calculate the parallax factor for the given exposure.  \tbd{Why do we need this?}.
