Index: trunk/doc/modules/CameraImages.tex
===================================================================
--- trunk/doc/modules/CameraImages.tex	(revision 4176)
+++ trunk/doc/modules/CameraImages.tex	(revision 4555)
@@ -1,29 +1,30 @@
-\section{Astronomical Images}
+\section{Focal Plane}
+\label{sec:focalplane}
 
 \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.
+In PSLib, 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 not provide
+sufficient additional metadata to describe the data in detail.
+Second, astronomy applications frequently 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 the 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 pixel measurements
+which is well represented as a single 2D image.  We define our
+lowest-level astronomical image structure, \code{pmReadout}, 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
@@ -33,22 +34,22 @@
 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
+Pan-STARRS GigaPixel 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
+\code{pmCell}, consists of a collection of readouts from a single
 detector.
 
-In the Pan-STARRS Gigapix camera, the basic readout region is a
+In the Pan-STARRS GigaPixel 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
+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.   
+container hierarchy, the data structure \code{pmChip} 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
+plane array (\code{pmFPA}).  This structure represents the collection
 of chips in the camera, all of which are read out in a given
 exposure.  
@@ -56,6 +57,6 @@
 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
+would be sixteen cells in total, each of which is presumably $1k\times
+4k$.  There would be eight chips, each consisting of two cells, and
 the focal plane consists of these eight chips.
 
@@ -69,19 +70,18 @@
 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
+necessary that an instance of \code{pmFPA} always carry the data for
+all 60 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{pmFPA}.  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}.  
+by an instance of \code{pmFPA} with one \code{pmChip}, which in turn
+has one \code{pmCell}, which in turn has one \code{pmReadout}.
 
 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.  
+hierarchy includes hooks for carrying metadata to provide the PS
+concepts and analysis metadata that would be appropriate for that
+level.  The functions within PSLib do not specify the contents of
+those metadata containers.
 
 While the \code{psMetadata} pointers provide a mechanism to carry
@@ -91,6 +91,6 @@
 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
+the location of a given \code{pmCell} with respect to its containing
+\code{pmChip} 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,
@@ -99,5 +99,5 @@
 transformations between one frame and the next are also provided.
 
-\tbd{in the future, it may be worthwhile to migrate all of these
+\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}
@@ -108,112 +108,138 @@
 
 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.
+thereof).  It contains the offset from the lower-left corner of
+the chip, in the case that the CCD was windowed, as well as the
+binning factors and parity (if the binning value is negative, then
+the parity is reversed).  It also contains the pixel data, metadata
+containers for the concepts and analysis, and a link to the parent.
 
 \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;
+    // Position on the cell
+    int col0;                          // Offset from the left of cell.
+    int row0;                          // Offset from the bottom of cell.
+    int colBins;                       // Amount of binning in x-dimension and parity (from sign)
+    int rowBins;                       // Amount of binning in y-dimension and parity (from sign)
+    // Information
+    psImage *image;                    // Imaging area of readout
+    psMetadata *analysis;              // Readout-level analysis metadata
+    psMetadata *concepts;              // Cache for PS concepts
+    pmCell *parent;                    // Parent cell
+} pmReadout;
 \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}.
+The constructor for \code{pmReadout} shall be:
+\begin{verbatim}
+pmReadout *pmReadoutAlloc(pmCell *cell);
+\end{verbatim}
+The constructor shall make an empty \code{pmReadout}.  If the parent
+\code{cell} is not \code{NULL}, the \code{parent} link is made and the
+readout shall be placed in the parent's array of \code{readouts}.  The
+metadata containers shall be allocated.  All other 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.
+A cell consists of one or more readouts (usually only one except in
+the case that the cell has been used for fast guiding, or similar
+situations).  It have values which specifies the position of the cell
+on the chip for rough positioning, along with more precise coordinate
+transforms from the cell to the chip and, as a convenience, from the
+cell directly 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.  The cell also contains metadata containers for the concepts
+and analysis, a link to the parent, and pointers to the various FITS
+data, if that corresponds to this level.
 
 \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}.
+    // Offset specifying position on chip
+    int col0;                          // Offset from the left of chip.
+    int row0;                          // Offset from the bottom of chip.
+    // Astrometric transformations
+    psPlaneTransform* toChip;          // Transformations from cell to chip coordinates
+    psPlaneTransform* toFPA;           // Transformations from cell to FPA coordinates
+    psPlaneTransform* toSky;           // Transformations from cell to sky coordinates
+    // Information
+    psMetadata *concepts;              // Cache for PS concepts
+    psMetadata *analysis;              // Cell-level analysis metadata
+    psArray *readouts;                 // The readouts (referred to by number)
+    pmChip *parent;                    // Parent chip
+    // FITS data
+    const char *extname;               // Extension name, if it corresponds to this level
+    psArray *pixels;                   // The pixel data, if it corresponds to this level
+    psMetadata *header;                // The FITS header, if it corresponds to this level
+} pmCell;
+\end{verbatim}
+
+The constructor for \code{pmCell} shall be:
+\begin{verbatim}
+pmCell *pmCellAlloc(pmChip *chip);
+\end{verbatim}
+The constructor shall make an empty \code{pmCell}.  If the parent
+\code{chip} is not \code{NULL}, the \code{parent} link is made and the
+cell shall be placed in the parent's array of \code{cells}.  The
+\code{readouts} array shall be allocated with a zero size, and the
+metadata containers constructed.  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.
+amplifiers on the device).  The chip contains metadata containers for
+the concepts and analysis, a link to the parent, and pointers to the
+various FITS data, if that corresponds to this level.  For astrometry,
+in addition to the rough positioning information, it contains a
+coordinate transform from the chip to the focal plane.  It is expected
+that this transform 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}.
+    // Offset specifying position on focal plane
+    int col0;                          // Offset from the left of FPA.
+    int row0;                          // Offset from the bottom of FPA.
+    // Astrometric transformations
+    psPlaneTransform* toFPA;           // Transformation from chip to FPA coordinates
+    psPlaneTransform* fromFPA;         // Transformation from FPA to chip coordinates
+    // Information
+    psMetadata *concepts;              // Cache for PS concepts
+    psMetadata *analysis;              // Chip-level analysis metadata
+    psArray *cells;                    // The cells (referred to by name)
+    pmFPA *parent;                     // Parent FPA
+    // FITS data
+    const char *extname;               // Extension name, if it corresponds to this level
+    psArray *pixels;                   // The pixel data, if it corresponds to this level
+    psMetadata *header;                // The FITS header, if it corresponds to this level
+} pmChip;
+\end{verbatim}
+
+The constructor for \code{pmChip} shall be:
+\begin{verbatim}
+pmChip *pmChipAlloc(pmFPA *fpa);
+\end{verbatim}
+The constructor shall make an empty \code{pmChip}.  If the parent
+\code{fpa} is not NULL, the \code{parent} link is made and the chip
+shall be placed in the parent's array of \code{chips}.  The
+\code{cells} array shall be allocated with a zero size, and the
+metadata containers constructed. 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
+of pieces of contiguous silicon).  It contains metadata containers for
+the concepts and analysis, a link to the parent, and pointers to the
+various FITS data, if that corresponds to this level.  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
@@ -222,51 +248,48 @@
 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.
+numerically inverting the forward transformation.
 
 \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}.
+    // Astrometric transformations
+    psPlaneDistort* fromTangentPlane;  // Transformation from tangent plane to focal plane
+    psPlaneDistort* toTangentPlane;    // Transformation from focal plane to tangent plane
+    psProjection *projection;          // Projection from tangent plane to sky
+    // Information
+    psMetadata *concepts;              // Cache for PS concepts
+    psMetadata *analysis;              // FPA-level analysis metadata
+    const psMetadata *camera;          // Camera configuration
+    psDB *db;                          // Database handle
+    psArray *chips;                    // The chips
+    // FITS data
+    const char *extname;               // Extension name, if it corresponds to this level
+    psArray *pixels;                   // The pixel data, if it corresponds to this level
+    psMetadata *header;                // The FITS header, if it corresponds to this level
+} pmFPA;
+\end{verbatim}
+
+The constructor for \code{pmFPA} shall be:
+\begin{verbatim}
+pmFPA *pmFPAAlloc(const psMetadata *camera, psDB *db);
+\end{verbatim}
+The constructor shall make an empty \code{pmFPA}.  The \code{chips}
+array shall be allocated with a zero size, the \code{camera} and
+\code{db} pointers set to the values provided, and the \code{concepts}
+metadata constructed. All other pointers in the structure shall be
+initialized to \code{NULL}.
+
+
+The inclusion of hierarchical links pointing both down (via the
+arrays) and up (via the \code{parent}) could make for difficulties.
+For this reason, we specify a utility function to manage the
+collection of upward-pointing links:
+\begin{verbatim}
+bool pmFPACheckParents(pmFPA *fpa);
+\end{verbatim}
+This function checks the validity of the \code{parent} links in the
+FPA hierarchy.  If a \code{parent} link is not set (or not set
+correctly), it is corrected, and the function shall return
+\code{false}.  If all the \code{parent} pointers were correct, the
+function shall return \code{true}.
 
 \subsection{Detector Coordinate Transformations}
@@ -303,22 +326,77 @@
 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
+camera grid at \code{pmChip.cell0,row0}.  The \code{pmReadout} 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 * 
+process.  The elements \code{pmReadout.colBins,rowBins} specify the
+binning factor in the two dimensions, while the sign indicates the
+parity of the specific readout (readout direction).  Note that the
+value of \code{pmReadout.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}
+pmFPA(cell,row) = pmChip.cell0,row0 + pmCell.cell0,row0 + pmReadout.cell0,row0 + 
+                  pmReadout.cellParity,rowParity * pmReadout.cellBins,rowBins * 
                   psImage.data(cell,row)
 \end{verbatim}
+
+\subsection{Input/Output of a Focal Plane Hierarchy}
+
+We specify two functions to construct a focal plane hierarchy from a
+camera configuration and read from a FITS file.  These two operations
+are decoupled so that the big investment of memory from the read only
+occurs when it is necessary.
+
+\begin{prototype}
+pmFPA *pmFPAConstruct(const psMetadata *camera, psDB *db);
+bool pmFPARead(pmFPA *fpa, psFits *fits);
+\end{prototype}
+
+\code{pmFPAConstruct} shall construct a focal plane hierarchy from a
+\code{camera} configuration.  A \code{db} handle is also provided so
+that may be set in the \code{pmFPA}.  The resultant \code{pmFPA} and
+its lower-down components shall be ready for to read a FITS file into
+it by setting the \code{extname} pointers at the appropriate levels to
+the appropriate FITS extension name.
+
+\code{pmFPARead} shall read a \code{fits} file (the contents of which
+are described by the previous \code{camera} configuration) into an
+extant \code{fpa}.
+
+\tbd{Functions to remove things from an fpa so that only certain
+pieces of the FITS file are read in, and not the whole thing?}
+
+We specify an additional two functions to write out a focal plane
+hierarchy to a FITS file.
+
+\begin{prototype}
+bool pmFPAMorph(pmFPA *toFPA, pmFPA *fromFPA, int chipNum, int cellNum);
+bool pmFPAWrite(psFits *fits, pmFPA *fpa);
+\end{prototype}
+
+\code{pmFPAMorph} shall morph the \code{fromFPA} focal plane hierarchy
+to the \code{toFPA} focal plane hierarchy.  This allows us to write
+the pixels out using a different (though consistent) camera
+configuration.  In the event that the \code{toFPA} has different
+levels than the \code{fromFPA}, only the chip and cell specified by
+\code{chipNum} and \code{cellNum} shall be written; if the levels are
+the same, these numbers are ignored.  This function shall break apart
+pixel regions or splice them together where required in order to
+satisfy the demands of the \code{toFPA}.  If the bias and trim
+sections are specified by headers in the \code{toFPA}, these shall be
+updated appropriately; otherwise, the function is permitted to fail,
+in which case it shall return \code{false}.
+
+\tbd{pmFPAMorph is a fairly involved operation, since it must cover
+several combinations.  IfA is working on a prototype --- do not
+attempt to code yet.}
+
+\code{pmFPAWrite} shall write the focal plane hierarchy, \code{fpa},
+to the specified \code{fits} file, returning \code{true} upon success
+and \code{false} otherwise.  The \code{fpa} should contain sufficient
+information with which to write the FITS images.
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -376,7 +454,7 @@
 %
 \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);
+pmCell *pmCellInFPA (const psPlane *coord, const pmFPA *fpa);
+pmChip *pmChipInFPA (const psPlane *coord, const pmFPA *fpa);
+pmCell *pmCellInChip(const psPlane *coord, const pmChip *chip);
 \end{verbatim}
 
@@ -417,5 +495,5 @@
 
 \begin{verbatim}
-psPlane *psCoordCellToChip (psPlane *out, const psPlane *in, const psCell *cell);
+psPlane *pmCoordCellToChip (psPlane *out, const psPlane *in, const pmCell *cell);
 % astrometry comes from cell (no need for parent)
 \end{verbatim}
@@ -424,5 +502,5 @@
 
 \begin{verbatim}
-psPlane *psCoordChipToFPA (psPlane *out, const psPlane *in, const psChip *chip);
+psPlane *pmCoordChipToFPA (psPlane *out, const psPlane *in, const pmChip *chip);
 % astrometry comes from chip (no need for parent)
 \end{verbatim}
@@ -431,5 +509,5 @@
 
 \begin{verbatim}
-psPlane *psCoordFPAToTP(psPlane *out, const psPlane *in, float color, float mag, const psFPA *fpa);
+psPlane *pmCoordFPAToTP(psPlane *out, const psPlane *in, float color, float mag, const pmFPA *fpa);
 % astrometry comes from FPA (no need for parent)
 \end{verbatim}
@@ -441,13 +519,12 @@
 
 \begin{verbatim}
-psSphere *psCoordTPToSky(psSphere *out, const psPlane *in, const psGrommit *grommit);
+psSphere *pmCoordTPToSky(psSphere *out, const psPlane *in, const psProjection *projection);
 \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}.
+the sky, using the specified \code{projection}.
 
 % astrometry comes from cell
 \begin{verbatim}
-psPlane *psCoordCellToFPA(psPlane *out, const psPlane *in, const psCell *cell);
+psPlane *pmCoordCellToFPA(psPlane *out, const psPlane *in, const pmCell *cell);
 \end{verbatim}
 which performs the single-step conversion between Cell coordinates
@@ -456,5 +533,5 @@
 % 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);
+psSphere *pmCoordCellToSky(psSphere *out, const psPlane *in, float color, float mag, const pmCell *cell);
 \end{verbatim}
 which converts coordinates on the specified cell to (RA,Dec).  This
@@ -463,17 +540,17 @@
 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.
+\code{pmCell} and \code{pmChip}, and the \code{pmFPA.projection}.  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);
+psSphere *pmCoordCellToSkyQuick(psSphere *out, const psPlane *in, const pmCell *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
+\code{pmCell.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.
@@ -483,11 +560,11 @@
 
 \begin{verbatim}
-psPlane *psCoordSkyToTP(psPlane *out, const psSphere *in, const psGrommit *grommit);
+psPlane *pmCoordSkyToTP(psPlane *out, const psSphere *in, const psProjection *projection);
 \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);
+using the specified \code{projection}.
+
+\begin{verbatim}
+psPlane *pmCoordTPToFPA(psPlane *out, const psPlane *in, float color, float mag, const pmFPA *fpa);
 \end{verbatim}
 which converts the tangent plane coordinates \code{in} to focal plane
@@ -497,23 +574,23 @@
 
 \begin{verbatim}
-psPlane *psCoordFPAToChip (psPlane *out, const psPlane *in, const psChip *chip);
+psPlane *pmCoordFPAToChip (psPlane *out, const psPlane *in, const pmChip *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
+coordinate, the function \code{pmChipInFPA}, defined above, should be
 used.
 
 \begin{verbatim}
-psPlane *psCoordChipToCell (psPlane *out, const psPlane *in, const psCell *cell);
+psPlane *pmCoordChipToCell (psPlane *out, const psPlane *in, const pmCell *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
+coordinate, the function \code{pmCellInChip}, defined above, should be
 used.
 
 \begin{verbatim}
-psPlane *psCoordSkyToCell(psPlane *out, const psSphere *in, float color, float mag, psCell *cell);
+psPlane *pmCoordSkyToCell(psPlane *out, const psSphere *in, float color, float mag, pmCell *cell);
 \end{verbatim}
 which directly converts (RA,Dec) \code{in} to coordinates on the
@@ -524,10 +601,10 @@
 
 \begin{verbatim}
-psPlane *psCoordSkyToCellQuick(psPlane *out, const psSphere *in, psCell *cell);
+psPlane *pmCoordSkyToCellQuick(psPlane *out, const psSphere *in, pmCell *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}.
+transformation specified by the element \code{pmCell.toTP}.
 Although the accuracy of this transformation is lower than the
 complete transformation above, the calculation is substantially faster
@@ -536,5 +613,5 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-\section{Astrometry and World Coordinate System}
+\subsection{FITS World Coordinate System}
 
 The FITS World Coordinate System (WCS) headers are commonly employed
@@ -550,19 +627,19 @@
 
 \begin{verbatim}
-bool psAstrometryReadWCS(psPlaneTransform **transform, // Output transformation
+bool pmAstrometryReadWCS(psPlaneTransform **transform, // Output transformation
                          psProjection **projection, // Output projection
                          psMetadata *header // Input FITS header
                          );
-bool psAstrometryWriteWCS(psMetadata *header, // Output FITS header
+bool pmAstrometryWriteWCS(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
+                          psProjection *projection, // Input projection
+                          double color, // Mean color to use
+                          double magnitude, // Mean magnitude to use
                           );
-bool psAstrometrySimplify(psPlaneTransform **transform, // Output transformation
+bool pmAstrometrySimplify(psPlaneTransform **transform, // Output transformation
                           psProjection **projection, // Output projection
-			  psCell *cell // Cell for which to generate transform and projection
+                          pmCell *cell // Cell for which to generate transform and projection
                           );
-\end{verbatim}			
+\end{verbatim}
 
 \code{pmReadAstrometry} shall parse the specified FITS \code{header},
@@ -588,61 +665,2 @@
 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}
-
