Index: /trunk/doc/modules/CameraImages.tex
===================================================================
--- /trunk/doc/modules/CameraImages.tex	(revision 4554)
+++ /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}
-
Index: /trunk/doc/modules/ChangeLogSDRS.tex
===================================================================
--- /trunk/doc/modules/ChangeLogSDRS.tex	(revision 4554)
+++ /trunk/doc/modules/ChangeLogSDRS.tex	(revision 4555)
@@ -1,3 +1,3 @@
-%%% $Id: ChangeLogSDRS.tex,v 1.22 2005-06-09 05:15:49 eugene Exp $
+%%% $Id: ChangeLogSDRS.tex,v 1.23 2005-07-15 00:54:03 price Exp $
 
 \subsection{Changes from version 00 (16 August 2004) to version 01 (12 October 2004)}
@@ -78,3 +78,10 @@
 \item added object function abstractions to Objects
 \item modified pmSource to include modelPSF and modelFLT
+\item Major changes to configuration.  Modifyied \code{pmConfig}
+  functions, and \code{pmCameraFromHeader}, and added various other
+  functions.
+\item Modifying \code{psReadout, psCell, psChip, psFPA} structures.
+\item Removing \code{psObservatory, psExposure, psGrommit} which were
+  centered on slalib.
+\item Added \code{pmFPAConstruct, pmFPARead, pmFPAMorph, pmFPAWrite}.
 \end{itemize}
Index: /trunk/doc/modules/ModulesSDRS.tex
===================================================================
--- /trunk/doc/modules/ModulesSDRS.tex	(revision 4554)
+++ /trunk/doc/modules/ModulesSDRS.tex	(revision 4555)
@@ -1,3 +1,3 @@
-%%% $Id: ModulesSDRS.tex,v 1.45 2005-06-27 23:28:30 price Exp $
+%%% $Id: ModulesSDRS.tex,v 1.46 2005-07-15 00:54:03 price Exp $
 \documentclass[panstarrs]{panstarrs}
 
@@ -79,5 +79,5 @@
 functions are available to fill a \code{psMetadata} collection from a
 text-based configuration file using a particular syntax, and to fill a
-\code{psMetadata} collection from a properly formatted XML document.  
+\code{psMetadata} collection from a properly formatted XML document.
 
 In the IPP Modules, we use \code{psMetadata} collections to carry
@@ -94,162 +94,179 @@
 
 All modules need to load some configuration information defining
-parameters which may be configured at run-time.  Some module require
-only a basic amount of information, while others require configuration
-information defining the camera or details of an analysis (the {\it
-recipe}).  We define three utility functions to load these files from
-standard locations, with optional command-line override values.
-
-\begin{prototype}
-bool pmConfigLoadSite   (psMetadata **site, int *argc, char **argv);
-bool pmConfigLoadCamera (psMetadata **camera, psMetadata *site, psMetadata *header, int *argc, char **argv);
-bool pmConfigLoadRecipe (psMetadata **recipe, psMetadata *camera, int *argc, char **argv, char *script);
-\end{prototype}
-
-\code{pmConfigLoadSite} loads basic configuration information from a
-general configuration file.  By default, this file has the name
-\code{~/.ipprc} in the user's home directory.  This file may be
-overridden on the command line with the optional flag \code{-site
-(file)}.
-
-% eventually, we should define the complete sequence:
-% $FOO, ~/.foorc, /prefix/config/foorc
-
-\code{pmConfigLoadCamera} loads camera configuration information from
-a file which depends on the camera of interest.  In some cases, the
-camera may be determined from the header of an image currently in
-hand.  In other cases, the camera must be specified without reference
-to a file.  This function attempts to determine the appropriate camera
-configuration file by examining, in order, the command-line options,
-the header data, and the site configuration data.  The camera config
-file may be specified on the command line with the option
-\code{-camera (file)}.  If this does not exist, the
-\code{pmConfigLoadCamera} examines the provided header to determine
-the camera by using the function \code{pmCameraFromHeader} (defined
-below).  If this fails, the function attempts to determine the camera
-from the provided site config data, looking for the keyword
-\code{CAMERA} in the site config data.  The camera name is used to
-select the camera configuration file, defined in the site
-configuration file with the keyword \code{CAMERA.name}, where
-\code{name} is substituted with the name of the camera.
-
-\code{pmConfigLoadRecipe} loads the recipe configuration information
-from a file which depends on the camera of interest and the particular
-analysis task.  The camera configuration file must define recipe files
-for each of the analysis tasks of interest.  The function attempts to
-load the recipe file using the keyword \code{RECIPE.name}, where
-\code{name} is substituted with the name of the analysis task, for
-example \code{PHASE2}.  The choice of the recipe file may be
-overridden on the command line with the option \code{-recipe (file)}.
-
-\subsection{Indirect Configuration Data}
-
-Some configuration data is not provided directly by the configuration
-files.  Instead, the configuration system provides a mechanism to
-define indirect references to configuration data.  Three indirect
-configuration data sources are currently defined: data from a FITS
-header, data from the Metadata Database, and data from the Pan-STARRS
-Status Server.  The configuration data may specify that a certain
-value is provided by one of these mechanisms.  
-
-In order to specify that the configuration data should be derived from
-a FITS header, the data value is given in the form: \code{HD:KEYWORD},
-where \code{KEYWORD} specifies the keyword to be used in search the
-FITS header.  
-
-If the data is to be extracted from the Metadata Database, the data
-value is given in the form: \code{MD:TABLE,FIELD,KEY}.  In this case,
-\code{TABLE} specifies the Metadata Database table to be used to find
-the value, \code{FIELD} specifies the field in that table to be used,
-and \code{KEY} specifies the value of the primary key which gives the
-value of interest.
-
-If the data is to be extracted from the Status Server, the data value
-is given in the form: \code{SS:PATH}.  In this case, \code{PATH}
-specifies the Status Server path to the data value of interest.  
-
-{\bf \it note that the Metadata Database and Status Server
-  interactions require us to define the APIs for these interactions.
-  These two methods are not available until the MD and SS APIs are
-  defined.}
-
-As an example, consider the definition of the data region of an image.
-This value is frequenty represented in the FITS header with the
-keyword \code{DATASEC}.  However, in some cameras, this value may not
-be defined, or another value may be used.  We must be able to flexibly
-define both the appropriate keyword, or the actual value, if known.
-These two cases may be written as follows, using the configuration
-file format parsed by \code{psMetadataParseConfig}:
+parameters which may be configured at run-time.  We break these
+parameters down into three levels:
+\begin{itemize}
+\item Options for the particular site installation of the
+  pipeline: the {\it site};
+\item Options specifying the instrument setup, and in particular the
+  format of the FITS file: the {\it camera}; and
+\item Options specifying the particular parameter choices that affect
+  the details of an analysis: the {\it recipe}.
+\end{itemize}
+Note that these are arranged in an hierarchical order, with the site
+configuration being the most general, and the recipe configuration the
+most specific.  For example, not all sites will have to deal with all
+cameras, and different cameras will have different recipes according
+to their particular quirks.
+
+Each of the levels will have a metadata configuration file.  In the
+case of the site configuration, the filename shall be that specified
+by the \code{-site} option on the command line if provided, the
+environment variable \code{PS_SITE}, if defined, or \code{~/.ipprc}
+otherwise.  The camera configuration shall be specified by the
+\code{camera} option on the command line if provided, or shall be
+inferred from a FITS header (more detail below).  The recipe
+configuration shall be specified by the \code{-recipe} option on the
+command line if provided, or from the the camera configuration (more
+detail below).
+
+\begin{prototype}
+bool pmConfigRead(psMetadata **site, psMetadata **camera, psMetadata **recipe,
+                  int *argc, char **argv, const char *recipeName);
+psMetadata *pmConfigCameraFromHeader(const psMetadata *site, const psMetadata *header);
+psMetadata *pmConfigRecipeFromCamera(const psMetadata *camera, const char *recipeName);
+\end{prototype}
+
+\code{pmConfigRead} shall load the \code{site} configuration
+(according to the above rule for determining the source).  The
+\code{camera} configuration shall also be loaded if it is specified on
+the command line (\code{argc, argv}); otherwise it shall be set to
+\code{NULL}.  The \code{recipe} shall also be loaded from the command
+line (if specified) or, if the camera configuration has been loaded,
+from the camera configuration and recipe specification therein (see
+below).  In dealing with the command line parameters, the functions
+shall use the appropriate functions in psLib to retrieve and remove
+the relevant options from the argument list; this simplifies
+assignment of the mandatory arguments, since all the optional command
+line arguments are removed leaving only the mandatory arguments.
+
+\code{pmConfigCameraFromHeader} shall load the \code{camera}
+configuration based on the contents of the FITS \code{header}, using
+the list of known cameras contained in the \code{site} configuration.
+If more than one camera matches the FITS header, a warning shall be
+generated and the first matching camera returned.
+
+\code{pmConfigRecipeFromCamera} shall load the \code{recipe}
+configuration based on the \code{recipeName} and the list of known
+recipes contained in the \code{camera} configuration (details below).
+
+We also specify an additional function:
+\begin{prototype}
+bool pmConfigValidateCamera(psMetadata *camera, psMetadata *header);
+\end{prototype}
+
+This function, used by \code{pmConfigCameraFromHeader}, shall return
+\code{true} if the FITS \code{header} matches the rule contained in
+the \code{camera} configuration (see \S\ref{sec:camerarule});
+otherwise it shall return \code{false}.
+
+\subsubsection{Example usage}
+
+The following is provided as an example of how the above functions
+are envisioned in use.
+
 \begin{verbatim}
-DATA.REGION  STR  [1:100,2:400]
-DATA.REGION  STR  HD:DATASEC
+int main(int argc, char *argv[])
+{
+    // Parse other command-line arguments here
+    psMetadata *site = NULL;            // Site configuration
+    psMetadata *camera = NULL;          // Camera configuration
+    psMetadata *recipe = NULL;          // Recipe configuration
+    if (! pmConfigRead(&site, &camera, &recipe, &argc, argv, "moduleName")) {
+        psLogMsg("moduleName", PS_LOG_ERROR, "Can't find site configuration!\n");
+        exit(EXIT_FAILURE);
+    }
+    // Parse other command-line arguments here
+
+    // The command-line argument list now contains only mandatory arguments
+    // Assume the first of these is an input image
+    char *imageName = argv[1];          // Name of FITS file
+    psFits *imageFH = psFitsOpen(imageName, "r"); // File handle for FITS file
+    if (! imageFH) {
+        psLogMsg("moduleName", PS_LOG_ERROR, "Can't open input image %s\n", imageName);
+        exit(EXIT_FAILURE);
+    }
+    psMetadata *header = psFitsReadHeader(NULL, imageFH); // FITS header
+
+    if (!camera && !(camera = pmConfigCameraFromHeader(site, header))) {
+        psLogMsg("moduleName", PS_LOG_ERROR, "Can't find camera configuration!\n");
+        exit(EXIT_FAILURE);
+    }
+
+    if (! recipe && !(recipe = pmConfigRecipeFromCamera(camera, "moduleName"))) {
+        psLogMsg("moduleName", PS_LOG_ERROR, "Can't find recipe configuration!\n");
+        exit(EXIT_FAILURE);
+    }
+
+    // Now go on and do stuff
+    ....
+}
 \end{verbatim}
-In the first case, the data provided in the configuration file is the
-data of interest.  (\code{[1:100,2:400]}).  In the second case, the
-three-character code \code{HD:} specifies that the value of interest
-may be determined by searching for the value associated with the
-header keyword \code{DATASEC}.
-
-We provide utilities functions to extract this type of potentially
-indirect configuration information.  We provide four functions
-returning four data types.  The first three return the value from the
-appropriate location assuming the data type to be \code{char*},
-\code{psS32}, and \code{psF64}.  The fourth version searches for a
-string which is passed to the function \code{psRegionFromString}
-before being returned as a \code{psRegion} pointer.
-
-\begin{prototype}
-psSTR     pmConfigLookupSTR    (psMetadata *config, psMetadata *header, char *name);
-psS32     pmConfigLookupS32    (psMetadata *config, psMetadata *header, char *name);
-psF64     pmConfigLookupF64    (psMetadata *config, psMetadata *header, char *name);
-psRegion *pmConfigLookupRegion (psMetadata *config, psMetadata *header, char *name);
-\end{prototype}
-
-\input{CameraImages.tex}
-
-\section{Camera Data Organization \& Camera Geometry}
-
-We require several utility functions to define the geometry of the
-detectors in a camera and to specify the organization of the camera
-data in real FITS images.  The camera data organization is defined in
-a set of \code{psMetadata} structures, and may be stored on disk in
-the file format parsed by \code{psMetadataParseConfig}.
-
-PSLib defines a hierarchy of data structures related to the
-organization of the pixels in a camera.  These structures, starting
-from the top level, follow the sequence \code{psFPA}, \code{psChip},
-\code{psCell}, \code{psReadout}, \code{psImage}.  Each lower level
-structure is carried as an array in the higher level.  The containers
-as defined by PSLib include functions which specify the astrometric
-relationships between these levels, and provide a single
-\code{psMetadata} container pointer for each level.  In this section,
-we define the type of metadata is stored in these metadata containers
-and how the image headers are parse to define the data hierarchy in
-memory.  
-
-\subsection{Camera Config Data \& the {\tt psFPA}}
-
-A relevant collection of metadata is the externally supplied camera
-definition metadata loaded with the function
-\code{pmConfigLoadCamera}.  This metadata defines the expected layout
-of a specific camera along with information detailing how to interpret
-the headers for an image from that camera.  The camera metadata
-consists of keyword / value pairs which are relevant to the entire
-camera, and a set of metadata collections specified for each cell.
-This top-level metadata is added to the \code{psFPA} with the name
-'CAMERA.LAYOUT'.  For example:
+
+\subsection{Configuration Files}
+
+\subsubsection{Site Configuration}
+
+The site configuration file must contain the following:
+\begin{itemize}
+\item The database configuration:
+  \begin{itemize}
+  \item \code{DBSERVER} of type \code{STR}: The database host name for
+    \code{psDBInit}.
+  \item \code{DBUSER} of type \code{STR}: The database user name for
+    \code{psDBInit}.
+  \item \code{DBPASSWORD} of type \code{STR}: The corresponding
+    database password for \code{psDBInit}.
+  \end{itemize}
+\item \code{CAMERAS} of type \code{METADATA}: A list of instruments
+  that the system can handle.  Cameras are specified as separate
+  metadata entries, with the name of the camera as the key, and the
+  filename of the camera configuration file (of type \code{STR}) as
+  the data.
+\end{itemize}
+
+An example site configuration file:
+
 \begin{verbatim}
-fpa->metadata = psMetadataAdd (fpa->metadata, PS_LIST_TAIL, "CAMERA", PS_META_META, "camera", camera);
+### Example .ipprc file
+
+### Database configuration
+DBSERVER        STR     ippdb.ifa.hawaii.edu    # Database host name (for psDBInit)
+DBUSER          STR     ipp                     # Database user name (for psDBInit)
+DBPASSWORD      STR     password                # Database password (for psDBInit)
+
+### Setups for each camera system
+CAMERAS         METADATA
+        MEGACAM_RAW     STR     megacam_raw.config
+        MEGACAM_SPLICE  STR     megacam_splice.config
+        GPC1_RAW        STR     gpc1_raw.config
+        LRIS_BLUE       STR     lris_blue.config
+        LRIS_RED        STR     lris_red.config
+END
 \end{verbatim}
-The specific cell-level entries are also placed on the correpsonding
-\code{psCell} elements.  These entries are added to the metadata with
-the name 'CELL':
-\begin{verbatim}
-cell->metadata = psMetadataAdd (cell->metadata, PS_LIST_TAIL, "CELL", PS_META_META, "cell", cellMD);
-\end{verbatim}
-
-\subsection{FITS File Data Representations}
+
+\subsubsection{Camera Configuration}
+
+The camera configuration is the most complicated and involved, since
+it must not only specify how to translate the pixels from a FITS file
+into a focal plane hierarchy (\S\ref{sec:focalplane}), but it must
+also specify how to derive the values of the PS concepts
+(\S\ref{sec:concepts}).  Moreover, it must be able to do these for the
+great variety of cameras in use in the astronomical community.
+
+Example camera configuration files are included in an appendix, but
+below we explain the components.
+
+\paragraph{FITS File to Focal Plane Hierarchy}
+
+The Focal Plane hierarchy (\code{pmFPA, pmChip, pmCell, pmReadout}) is
+explained in more detail in \S\ref{sec:focalplane}.  The top level, an
+FPA contains one or more chips, which correspond to a contiguous piece
+of silicon.  A chip contains one or more cells, which correspond to a
+single amplifier.  A cell contains one or more readouts, which
+correspond to individual reads of the detector.
 
 Within the FITS data representation, there are various choices which
-can and have been made for the placement of the pixels in a data file.
+can and have been made for the placement of the pixels in the file.
 In the simplest case, the camera consists of a single chip consisting
 of a single cell always read with a single readout.  In this case, the
@@ -261,317 +278,417 @@
 with separate extensions for each cell (CFH12K.split, GPC).  Another
 camera may write a single file with multiple extensions for each cell
-(Megacam.raw), or multiple extensions per chip, which each cell
+(Megacam.raw), or multiple extensions per chip, with each cell
 representing portions of the chip image (Megacam.splice, CFHT-IR).
 
-In all of these representations, there are only two principal
-distinctions in how the pixel data is stored.  Either a single data
-block (a single FITS image) represents only a single cell, or it
-represents a collection of cells.  This affects the way in which an
-image is read in, the way the header is associated with a level of the
-data hierarchy, and the way in which the header keywords are
-interpretted to define the layout of the pixels in the cell.  We
-distinguish these two cases as 'cell-based' and 'chip-based' layout.
-
-The FITS headers are attached to the \code{psFPA} data hierarchy by
-adding them to the \code{psMetadata} entries for the appropriate data
-level.  Each of the data levels \code{psFPA}, \code{psChip}, and
-\code{psCell} have \code{metadata} elements to store relevant metadata
-of any type.  A FITS header metadata collection may be added to one of
-these metadata collections using the metadata name 'HEADER':
+In all of these representations, there are only two basic distinctions
+in how the pixel data is stored: what level the entire FITS file
+corresponds to (FPA or chip), and what level the extensions correspond
+to (chip, cell or no extensions at all).  Knowing these, and having
+a list of the components, we can construct the focal plane hierarchy.
+
+We therefore specify the following keywords:
+\begin{itemize}
+\item \code{PHU} of type \code{STR}: May be one of \code{CHIP} or
+  \code{CELL}.  This specifies what the scale of the Primary Header
+  Unit (and hence the entire FITS file) is.
+\item \code{EXTENSIONS} of type \code{STR}: May be one of \code{CHIP},
+  \code{CELL} or \code{NONE}, though not of a level higher than that
+  specified by the \code{PHU}.  This specifies what each extension
+  represents.
+\item \code{CONTENTS} which may be of type \code{METADATA} or
+  \code{STR}, depending upon the \code{PHU} and \code{EXTENSIONS},
+  specifies what the contents of the FITS file are:
+  \begin{itemize}
+    \item \code{PHU=FPA, EXTENSIONS=CHIP}: Type \code{METADATA} with
+      the component keywords being the extension names and the values
+      the names of the cells, separated by commas or whitespace.
+    \item \code{PHU=FPA, EXTENSIONS=CELL}: Type \code{METADATA} with
+      the component keywords being the extension names and the values
+      the chip name and the cell type, separated by a colon.
+    \item \code{PHU=FPA, EXTENSIONS=NONE}: Type \code{METADATA} with
+      the component keywords being the chip names and the values the
+      names of the cells, separated by commas or whitespace.
+    \item \code{PHU=CHIP, EXTENSIONS=CELL}: Type \code{METADATA} with
+      the component keywords being the extension names and the values
+      the corresponding cell type.
+    \item \code{PHU=CHIP, EXTENSIONS=NONE}: Type \code{STR} with the
+      value being the cell types separated by commas or whitespace.
+  \end{itemize}
+\item \code{CELLS} of type \code{METADATA} with the component keywords
+  being the cell names or types, each of type \code{METADATA}.  Within
+  each cell should be specified various PS concept values appropriate
+  for each cell.
+\end{itemize}
+
+An example:
+
 \begin{verbatim}
-fpa->metadata = psMetadataAdd (fpa->metadata, PS_LIST_TAIL, "HEADER", PS_META_META, "header", header);
+# How to read this data
+PHU             STR     FPA     # The FITS file represents an entire FPA
+EXTENSIONS      STR     CELL    # The extensions represent cells
+ 
+# What's in the FITS file?
+CONTENTS        METADATA
+        # Extension name, chip name:type
+        amp00   STR     ccd00:left
+        amp01   STR     ccd00:right
+        amp02   STR     ccd01:left
+        amp03   STR     ccd01:right
+        amp04   STR     ccd02:left
+END
+
+# Specify the cell data
+CELLS   METADATA
+        left    METADATA        # Left amplifier
+                CELL.BIASSEC            STR     BIASSEC
+                CELL.TRIMSEC            STR     DATASEC
+                CELL.PARITY             S32     1
+        END
+        right   METADATA        # Right amplifier
+                # This cell is read out in the opposite direction
+                CELL.BIASSEC            STR     BIASSEC
+                CELL.TRIMSEC            STR     DATASEC
+                CELL.PARITY             S32     -1
+        END
+END
 \end{verbatim}
 
-In 'cell-based' layout, the headers are attached to the corresponding
-\code{psCell} element.  In 'chip-based' layout, the headers are
-attached to the \code{psChip} element.  This difference is natural
-since a 'cell-based' data file has one FITS extension, and therefore
-one FITS header, for each \code{cell}.  Conversely, in a 'chip-based'
-data file, there is one extension per chip, and therefore multiple
-cells for each FITS header, but only one chip for each FITS header.  
-
-\subsection{Determine the Camera from the Primary Header}
-
-\begin{prototype}
-char *pmCameraFromHeader (psFitsHeader *header, psMetadata *rules);
-\end{prototype}
-
-This function examines a primary header unit (\code{header}) and
-determines the camera which provided the data.  The rules which
-identify the camera are defined as a \code{psMetadata} structure
-containing one element for each known camera.  These are generally to
-be provided as part of the site configuration information.  The
-elements of this \code{psMetadata} container are in turn
-\code{psMetadata} containers consisting of the expected header
-keywords and their required values.  The function
-\code{pmCameraFromHeader} tests each of the defined cameras in
-succession.  For each camera, it searches for each of the given
-keywords and compares the value with the value expected.  If the
-keyword does not exist, or if the keyword has the wrong value, the
-camera is rejected.  The name of first camera which matches the header
-is returned as an allocated string.  If no match is found, the
-returned value must be \code{UNKNOWN}.  This condition may be treated
-by calling functions as either an error or only a warning.  If an
-error is encountered in parsing the metadata containers, then
-\code{NULL} is returned.  An example of the metadata keyword / value
-pairs is given below (note that this uses an undefined metadata config
-file representation \code{METADATA}):
-
+Observe how the \code{CONTENTS} specifies the extension name, which we
+know from the \code{EXTENSIONS} is a cell, and that each extension is
+associated with a chip, and has a cell type.
+
+The \code{_SOURCE} keywords will be explained in \S\ref{sec:concepts}.
+
+\paragraph{Deriving concept values}
+
+The PS concepts are described in more detail in \S\ref{sec:concepts}.
+Basically, astronomical cameras generally store the important details
+(``concepts'') in different ways.  This is generally manifested in the
+choice of different FITS header keywords to describe the same concept,
+but one can also imagine deriving values from a database or a known
+default.
+
+We therefore specify the following keywords:
+\begin{itemize}
+\item \code{TRANSLATION} of type \code{METADATA} is a translation
+  table for understanding PS concepts in terms of FITS headers.  The
+  PS concept (keyword) is derived from the FITS header given in the
+  value.
+\item \code{DATABASE} of type \code{METADATA} is a formula for
+  obtaining a PS concept from the database.  Each component is of a
+  user-specified type containing \code{TABLE}, \code{COLUMN},
+  \code{GIVENDBCOL} and \code{GIVENPS}.  The idea is that to obtain
+  the value of a PS concept, one refers to a particular \code{COLUMN}
+  in a particular \code{TABLE}, where the value of certain PS concepts
+  (\code{GIVENPS}; multiple values separated by a comma or semicolon)
+  match certain database columns (\code{GIVENDBCOL}; multiple values
+  separated by a comma or semicolon).
+\item \code{DEFAULTS} of type \code{METADATA} is a set of default
+  values of PS concepts for the camera.  The PS concept (keyword) is
+  assigned the value.  There is also limited dependency allowed; see
+  \S\ref{sec:concepts}.
+\end{itemize}
+
+An example:
 \begin{verbatim}
-CFH12K.MEF      METADATA
-  TELESCOP      STR   CFHT
-  INSTRUME      STR   CFH12K
-  EXTEND        BOOL  T
-  NEXTEND       S32   12
-END
-
-CFH12K.SPLIT    METADATA
-  TELESCOP      STR   CFHT
-  INSTRUME      STR   CFH12K
-  EXTEND        BOOL  F
+# How to translate PS concepts into FITS headers
+TRANSLATION     METADATA
+        FPA.NAME        STR     EXPNUM
+        FPA.AIRMASS     STR     AIRMASS
+        FPA.FILTER      STR     FILTER
+        FPA.POSANGLE    STR     ROTANGLE
+        FPA.RA          STR     RA
+        FPA.DEC         STR     DEC
+        FPA.RADECSYS    STR     RADECSYS
+        FPA.MJD         STR     MJD-OBS
+        CELL.EXPOSURE   STR     EXPTIME
+        CELL.DARKTIME   STR     DARKTIME
+        CELL.XBIN       STR     CCDBIN1
+        CELL.YBIN       STR     CCDBIN2
+        CELL.SATURATION STR     SATURATE
+END
+
+# Default PS concepts that may be specified by value
+DEFAULTS        METADATA
+        CELL.BAD                S32     0
+        CELL.YPARITY_DEPEND     STR     CHIP.NAME
+        CELL.YPARITY    METADATA
+                ccd00   S32     -1
+                ccd01   S32     -1
+                ccd02   S32     -1
+                ccd03   S32     -1
+        END
+END
+
+# How to translation PS concepts into database lookups
+DATABASE        METADATA
+        TYPE            dbEntry         TABLE           COLUMN          GIVENDBCOL      GIVENPS
+        CELL.GAIN       dbEntry         Camera          gain            chipId,cellId   CHIP.NAME,CELL.NAME
+        CELL.READNOISE  dbEntry         Camera          readNoise       chipId,cellId   CHIP.NAME,CELL.NAME
 END
 \end{verbatim}
 
-\begin{figure}
-\begin{center}
-\psfig{file=CameraHierarchy,width=5.0in}
-\caption{Camera Data and Metadata Hierarchy\label{CameraHierarchy}}
-\end{center}
-\end{figure}
-
-\subsection{Validate the Header set \& Construct the FPA}
-
-\begin{prototype}
-bool  pmCameraValidateHeaders (psMetadata *headers, psMetadata *camera);
-psFPA *pmFPAfromHeader (psMetadata *headers, psMetadata *camera);
-\end{prototype}
-
-These funtions examine the collection of \code{headers} and compare
-them with the camera definitions in the metadata structure
-\code{camera}.  One function (\code{pmFPAfromHeader}) uses the header
-set and camera definition file to construct a \code{psFPA} with all
-\code{psChip} and \code{psCell} entries allocated, but without any
-\code{psReadout} or pixel data.  The other function validates the
-header set against the camera definition, but does not actually
-construct the \code{psFPA}.  
-
-The camera definition metadata collection defines the relationship
-between chips, cells, and the FITS extensions.  An example of the data
-needed by \code{pmCameraValidateHeaders} and \code{pmFPAfromHeader} is
-given below for several types of cameras in the form of a metadata
-config file.  
-
+The \code{_DEPEND} entry in the \code{DEFAULTS} will be explained in
+\S\ref{sec:concepts}.
+
+\paragraph{Indentification by rule}
+\label{sec:camerarule}
+
+The function \code{pmConfigCameraFromHeader} requires that the camera
+configuration also contains a rule on how to recognise that a FITS
+header comes from that camera.
+
+We therefore specify another keyword: \code{RULE} of type
+\code{METADATA}: Contains a list of FITS headers keywords and values
+(of the appropriate type) against which actual headers are compared to
+determine if it matches the camera type.
+
+An example is:
 \begin{verbatim}
-MEGACAM.RAW     METADATA    
-  NCELL         S32    72
-  CELL.FMT      STR    CELL.%02d
-  EXT.TYPE      STR    CELL
-  EXT.KEY       STR    EXTNAME
-  PHU           STR    FPA
-  #
-  #                    EXT.KEY  CHIP  
-  CELL.00       CELL   amp00    CHIP.00
-  CELL.01       CELL   amp01    CHIP.00
-  CELL.02       CELL   amp02    CHIP.01
-  CELL.03       CELL   amp03    CHIP.01
-  ...
-END
-
-MEGACAM.SPLICE  METADATA      
-  NCELL         S32    36
-  CELL.FMT      STR    CELL.%02d
-  EXT.TYPE      STR    CHIP
-  EXT.KEY       STR    EXTNAME
-  PHU           STR    FPA
-  #
-  #                    EXT.KEY  CHIP  
-  CELL.00       CELL   ccd00    CHIP.00
-  CELL.01       CELL   ccd00    CHIP.00
-  CELL.02       CELL   ccd01    CHIP.01
-  CELL.03       CELL   ccd01    CHIP.01
-  ...
-END
-
-CFH12K.SPLIT    METADATA
-  NCELL         S32    12
-  CELL.FMT      STR    CELL.%02d
-  EXT.TYPE      STR    CELL
-  EXT.KEY       STR    EXTNAME
-  PHU           STR    NONE
-  #
-  #                    EXT.KEY  CHIP   
-  CELL.00       CELL   chip00   CHIP.00
-  CELL.01       CELL   chip01   CHIP.01
-  CELL.02       CELL   chip02   CHIP.02
-  ...
-END
-
-GPC.RAW         METADATA    
-  NCELL         S32    4096
-  CELL.FMT      STR    CELL.%04d
-  EXT.TYPE      STR    CELL
-  EXT.KEY       STR    EXTNAME
-  PHU           STR    CHIP
-  #
-  #                    EXT.KEY  CHIP  
-  CELL.0000     CELL   amp00    CHIP.00
-  CELL.0001     CELL   amp01    CHIP.00
-  CELL.0002     CELL   amp02    CHIP.00
-  CELL.0003     CELL   amp03    CHIP.00
-  ...
-  CELL.0065     CELL   amp03    CHIP.01
-  CELL.0066     CELL   amp03    CHIP.01
-  ...
+# How to identify this type
+RULE    METADATA
+        TELESCOP        STR     CFHT 3.6m
+        DETECTOR        STR     MegaCam
+        EXTEND          BOOL    T
+        NEXTEND         S32     72
 END
 \end{verbatim}
 
-Among the important elements of the camera definition information are:
+\paragraph{Recipes}
+
+The camera configuration file must also contain filenames for the
+recipe configuration files.  We include \code{RECIPES} of type
+\code{METADATA} with component keywords being the various recipe names
+and the values (of type \code{STR}) the corresponding recipe
+configuration filename.
+
+\subsubsection{Recipe Configuration}
+
+\tbd{The contents of the recipe configuration file are dependent upon
+the particular module, and hence are not specified here at this time.}
+
+
+\subsection{PS Concepts}
+\label{sec:concepts}
+
+Each image has associated with it what we will call {\it concepts}
+(for want of a better word).  These are values corresponding to
+general quantities and qualities relevant to the IPP such as airmass,
+date, read noise and filter.  These concepts are not always known by
+the same name, or are obtained in the same manner for all cameras, and
+so their source or value must be specified in the camera configuration
+file.  Some of these concepts make most sense to be defined at the FPA
+level, while others are logically defined at the cell level.
+
+Below is a list of concepts that the IPP should require, with the
+expected type and a short description.
+
 \begin{itemize}
-\item \code{NCELL} - this defines the possible number of cells from this
-  camera.
-\item \code{CELL.FMT} - this defines the format of the \code{CELL.nn}
-  keywords below in the metadata collection, one for each of the
-  \code{NCELL} values
-\item \code{EXT.TYPE} - this defines the lowest data level
-  corresponding to a single FITS extension: \code{CELL} or
-  \code{CHIP}.  In some cases, a single extension represents a chip,
-  and is subdivided into cells by header keywords specifying certain
-  regions.  In other cases, a single extension represents only the
-  data from a single amplifier, ie, a cell.  These two cases require
-  somewhat different handling.
-\item \code{EXT.KEY} - this entry defines a header keyword which
-  allows the unique identification of a given header with one of the
-  cell or chip entries (depending on the value of \code{EXT.TYPE}).
-\item \code{PHU} - this entry defines the meaning of the FITS file
-  primary header unit. 
+\item \code{FPA.AIRMASS} (F32): Airmass at which the observation is made
+  (boresight).
+\item \code{FPA.FILTER} (STR): Filter used in observation
+\item \code{FPA.POSANGLE} (F32): Position angle for camera
+\item \code{FPA.RA}: Right Ascension of boresight
+\item \code{FPA.DEC}: Declination of boresight
+\item \code{FPA.RADECSYS}: System of RA,Dec (e.g., J2000 or ICRS)
+\item \code{FPA.NAME}: An identifier (e.g., observation number) for the FPA instance
+\item \code{CHIP.NAME}: The name of the chip (unique within the FPA) --- set at FITS read
+\item \code{CELL.NAME}: The name of the cell (unique within the parent chip) --- set at FITS read
+\item \code{CELL.TIME}: Time of observation start
+\item \code{CELL.TIMESYS}: Time system in use (e.g., UTC)
+\item \code{CELL.BIASSEC}: Overscan region(s)
+\item \code{CELL.TRIMSEC}: Trim region
+\item \code{CELL.GAIN}: CCD gain (e/ADU)
+\item \code{CELL.READNOISE}: CCD read noise (e)
+\item \code{CELL.SATURATION}: CCD saturation point (ADU)
+\item \code{CELL.BAD}: CCD bad pixel point (ADU)
+\item \code{CELL.BINNING}: CCD Binning
+\item \code{CELL.PARITY}: Direction of CCD readout
+\item \code{READOUT.EXPOSURE}: Exposure time of image (sec)
+\item \code{READOUT.DARKTIME}: Dark time for image (sec)
 \end{itemize}
-In addition to these generic parameters, the camera definition
-metadata includes an entry for each cell giving specific values
-required to define that cell.  
-
-Both functions \code{pmCameraValidateHeaders} and
-\code{pmFPAfromHeader} must start with the set of headers and attempt
-to identify the corresponding cell or chip.  All available cells and
-chips must be identified, and the cells corresponding to each chip
-must be tracked.  In the case of \code{pmCameraValidateHeaders}, the
-function must only verify the headers contain valid extensions,
-without allocating the correpsonding \code{psFPA}, while
-\code{pmFPAfromHeader} must also allocate the \code{psFPA}, the
-contained \code{psChip} arrays, and the correct number of
-\code{psCell} arrays for each \code{psChip}.
-
-These functions also add to the metadata containers for the chips and
-cells, following the rules discussed above. Each \code{psCell} entry
-should have the \code{CELL} metadata lines from above attached to the
-\code{psCell.metadata} element as an additional metadata collection
-with the name \code{CELL.LAYOUT}.  The complete camera metadata
-collection (including the cells), are attached to the
-\code{psFPA.metadata} element with the name \code{CAMERA.LAYOUT}.  The
-image header data are also attached to metadata entries, at a level
-which depends on the value of \code{EXT.TYPE} in the camera layout
-data above.  If the value is \code{CELL}, the header metadata
-collections are attached to the \code{psCell.metadata} elements with
-the name \code{HEADER}.  If the value of \code{EXT.TYPE} is chip, the
-header metadata is attached to the \code{psChip.metadata} element,
-again with the name \code{HEADER}.  
-
-An image file may also have a primary header unit which is not
-associated with a data block.  This metadata block must also be added
-to the data heirarchy so successive operations may update the metadata
-as needed.  The disposition of the primary header unit is defined by
-the camera layout key \code{PHU}.  If this has a value of \code{NONE},
-there is no primary header unit, or it should be ignored.  If the
-value is \code{FPR}, the primary header data is attached to the
-\code{psFPA.metadata} element with the value PHU.  Alternatively, if
-it has the value \code{CHIP}, then the primary header metadata is
-attached to the \code{psChip.metadata} element.
-
-\subsection{Coordinate Transforms and Header Data}
-\tbd{the algorithms for three functions in this section are not
-  well-defined.  do not code yet}.
-
-Astrometric and geometric information about an image from a camera may
-be represented in a variety of ways.  A crude representation of the
-pixel geometry is specified in many image headers using the IRAF-style
-region keywords \code{DATASEC}, \code{DETSEC}, etc.  These keywords
-are used to define the location of a single image's pixels in the
-frame of the full mosaic of detectors in the assumption that the
-mosaic can be represented as a single uniform grid of pixels.  An
-alternative set of keywords have been used in cases where multiple
-cells are saved together in a single FITS image extension.  More
-sophisticated astrometric representations require elements to define
-projections, scaling, distortion, etc.  Several versions of header
-keywords have been used to represent these astrometric
-transformations.  In this section, we define three functions to
-interpret a collection of image headers and construct the appropriate
-offset and/or astrometry parameters.
-
-\begin{prototype}
-bool  pmFPADefineOffsets (psFPA fpa);
-bool  pmFPADefineWCS (psFPA fpa);
-bool  pmFPADefineWCSfromOffsets (psFPA fpa);
-\end{prototype}
-
-The first function takes a \code{psFPA} structure which has been
-populated with header and camera configuration metadata in the
-appropriate locations as discussed above.  Using the information in
-the camera config metadata and the headers, the function sets the
-values for the elements \code{psChip.col0,row0},
-\code{psCell.col0,row0}, \code{psReadout.col0,row0},
-\code{psReadout.colParity,rowParity}, and
-\code{psReadout.colBinning,rowBinning}.  This information is
-determined by examining the regions defined by the following names.
-
-% how do we handle the CCDSUM keyword case?
+
+The value of a concept shall be found by searching in the following
+order:
+\begin{itemize}
+\item A cache of values.
+\item The FITS header via the \code{TRANSLATION} table.
+\item The \code{DATABASE} lookup.
+\item The \code{DEFAULTS} value.
+\end{itemize}
+When a concept is retrieved, it shall be stored in the cache to
+optimise future retrieval.  We have specified a cache and FITS header
+storage in the various focal plane structures for the purposes of
+concept retrieval.
+
+Because of the variety of methods for specifying these concepts
+(especially in FITS headers), we must also specify additional
+information in the camera configuration that specifies how to
+interpret the data provided.  
+
+In the \code{DEFAULTS} table in the camera configuration, we allow the
+specification of the concept with an additional suffix,
+\code{_DEPEND}.  The value (of type \code{STR}) of the
+\code{CONCEPT_DEPEND} is the name of a concept on which the first
+concept depends.  For example, it might depend on the chip name.  Then
+the first concept becomes of type \code{METADATA}, with the component
+keywords being the value of the second concept (on which the first
+depends).  To avoid infinite recursion, no further dependency is
+permitted.  An example of the dependency:
+
 \begin{verbatim}
-psCell.metadata:CELL:CCDBIN1 $\rightarrow$ psReadout.colBins
-psCell.metadata:CELL:CCDBIN2 $\rightarrow$ psReadout.rowBins
-
-DETSEC from psCell.metadata:CELL:DETSEC
-CCDSEC from psCell.metadata:CELL:CCDSEC
-DATASEC from psCell.metadata:CELL:DATASEC
-
-if (DETSEC.x0 > DETSEC.x1) then psReadout.colParity = -1
-if (DETSEC.y0 > DETSEC.y1) then psReadout.rowParity = -1
+# Default PS concepts that may be specified by value
+DEFAULTS        METADATA
+        CELL.GAIN_DEPEND     STR     CHIP.NAME
+        CELL.GAIN    METADATA
+                ccd00   F32     1.2
+                ccd01   F32     3.4
+                ccd02   F32     5.6
+        END
+END
 \end{verbatim}
 
-The second function examines the contents of the headers of the chips
-and cells and constructs the collection of astrometric coordinate
-transformations.. 
-
-The third function uses the offset information and the basic telescope
-pointing information to construct a approximate guess at the
-astrometric coefficients based on the detector geometry.
-
-\begin{figure}
-\begin{center}
-\psfig{file=CameraLayout,width=5.5in}
-\caption{Camera Pixel Layout\label{CameraLayout}}
-\end{center}
-\end{figure}
-
-\begin{figure}
-\begin{center}
-\psfig{file=CameraRegionKeywords.ps,width=5.5in}
-\caption{Camera Region Keyword Definitions\label{CameraRegionKeywords}}
-\end{center}
-\end{figure}
-
-\subsection{Chip \& Cell from FITS File}
-\tbd{the algorithm for the function in this section is not
-  well-defined.  do not code yet}.
-
-When loading data from disk, it is may be necessary to use the
-information in the DATASEC and DETSEC entries to determine which part
-of the image should be read.  If the data is stored in a chip-based
-format, then the data for each cell corresponds to only a fraction of
-the pixels stored in a single image extension.  We specify the
-following function to perform the correct read of data from a FITS
-file into the corresponding \code{psCell} entry respecting the
-boundaries of the cells within chip-based images.
-
-\begin{prototype}
-psReadout *pmReadoutLoad (psReadout *input, psFits *f, psCell *cell, int plane);
-\end{prototype}
+In the FITS \code{TRANSLATION} table in the camera configuration, for
+certain concepts we allow the specification of the concept with an
+additional suffix, \code{_FORMAT} which specifies the format of the
+FITS header.  The value is dependent upon the particular concept.
+
+\paragraph{CELL.TIME}
+
+The time at which the shutter opens is represented in a variety of
+ways in FITS files, so care must be taken to specify what the format
+is in the file under consideration.  Permitted values of
+\code{CELL.TIME_FORMAT} are:
+
+\begin{itemize}
+\item \code{JD}: The value pointed to by \code{CELL.TIME} is to be
+  interpreted as a Julian Date.
+\item \code{MJD}: The value pointed to by \code{CELL.TIME} is to be
+  interpreted as a Modified Julian Date.
+\item \code{ISO}: The value pointed to by \code{CELL.TIME} is to be
+  interpreted as an ISO date-time (yyyy-mm-ddThh:mm:ss.ss).
+\item \code{SEPARATE}: The date and time are specified separately, and
+  the \code{CELL.TIME} contains the headers for the date and the time
+  separated by whitespace or a comma.  Then it might be necessary to
+  add additional qualifiers to specify the formats of these:
+  \begin{itemize}
+  \item \code{PRE2000}: The year is in the old style two-digit format
+    popular before the year 2000, and it should be assumed that the
+    date is in the twentieth century.
+  \item \code{BACKWARDS}: The date is in the format dd-mm-yyyy or
+    dd/mm/yyyy.
+  \item \code{SOD}: The time is specified as seconds-of-day.
+  \end{itemize}
+\end{itemize}
+
+Note that the FITS standard is that the time in the header refers to
+the {\it start} of the observation.  \tbd{In the future, we might add
+additional qualifiers that calculate the start time of the observation
+based on someone foolishly putting the end- or mid-time in the header.}
+
+\paragraph{CELL.BINNING}
+
+The binning is usually specified in FITS headers either as separate
+headers for the x and the y, or in the same FITS header separated by a
+space or a comma.  Permitted values of \code{CELL.BINNING_FORMAT} are:
+
+\begin{itemize}
+\item \code{SEPARATE}: The \code{CELL.BINNING} contains the headers
+  for the x and the y binning separated by whitespace or a comma.
+\item \code{TOGETHER}: The value pointed to by \code{CELL.BINNING}
+  contains the x and y binning separated by whitespace and/or a comma.
+\end{itemize}
+
+\paragraph{FPA.RA and FPA.DEC}
+
+The RA and Declination of the boresight might be specified in a few
+ways.  We need to specify both how the value is interpreted and the
+units.  \code{FPA.RA_FORMAT} and \code{FPA.DEC_FORMAT} should be one
+of the following:
+
+\begin{itemize}
+\item \code{HOURS}: The value pointed to by the concept should be
+  interpreted as being in hours.
+\item \code{DEGREES}: The value pointed to by the concept should be
+  interpreted as being in degrees.
+\item \code{RADIANS}: The value pointed to by the concept should be
+  interpreted as being in radians.
+\end{itemize}
+
+How the value is interpreted can be determined from the type of the
+header: if it is of type \code{STR}, then we can reasonably assume
+that it is in sexagesimal format with colons or spaces as separators;
+and if it is of type \code{F32} (or \code{F64}), then we can assume
+that it is in decimal format.
+
+\subsubsection{CELLS}
+
+The \code{CELLS} entry in the camera configuration contains data
+appropriate to each cell.  These will generally consist of the
+\code{CELL.BIASSEC} and \code{CELL.TRIMSEC} concepts, though it might
+contain \code{CELL.GAIN} and \code{CELL.READNOISE} values as well
+instead of going to the trouble of specifying these in the
+\code{DEFAULTS} with a long \code{_DEPENDS} listing.
+
+However, we need to specify for these where the value comes from.  It
+should be sufficient to declare the following rules:
+
+\begin{itemize}
+\item If the type is other than \code{STR}, then the concept has that
+  value for the cell.
+\item If the type is \code{STR} and contains square brackets
+  \code{[]}, then it shall be interpreted as a value for one of the
+  image section concepts (\code{CELL.BIASSEC} and
+  \code{CELL.TRIMSEC}).
+\item Otherwise, it shall be interpreted as a FITS header keyword
+  which will provide the value.
+\end{itemize}
+
+These rules mean that we don't have to bother adding an additional
+suffix like \code{_SOURCE}.
+
+\subsubsection{Lookups}
+
+We here specify a series of ``one-stop shops'' for lookups of the
+concepts.  These will be what the user utilises, so the goal is to
+provide a simple interface providing a single type back, so the user
+doesn't have to go to the trouble of checking types, etc.
+
+\begin{prototype}
+float pmFPAGetAirmass(pmFPA *fpa);     // FPA.AIRMASS
+psString pmFPAGetFilter(pmFPA *fpa);   // FPA.FILTER
+float pmFPAGetPosAngle(pmFPA *fpa);    // FPA.POSANGLE
+double pmFPAGetRA(pmFPA *fpa);         // FPA.RA
+double pmFPAGetDec(pmFPA *fpa);        // FPA.DEC
+psString pmFPAGetRADecSys(pmFPA *fpa); // FPA.RADECSYS
+psString pmFPAGetName(pmFPA *fpa);     // FPA.NAME
+psString pmChipGetName(pmChip *chip);  // CHIP.NAME
+psString pmCellGetName(pmCell *cell);  // CELL.NAME
+psTime *pmCellGetTime(pmCell *cell);   // CELL.TIME
+psList *pmCellGetBiasSec(pmCell *cell); // CELL.BIASSEC
+psRegion pmCellGetTrimSec(pmCell *cell); // CELL.TRIMSEC
+float pmCellGetGain(pmCell *cell);     // CELL.GAIN
+float pmCellGetReadNoise(pmCell *cell); // CELL.READNOISE
+float pmCellGetSaturation(pmCell *cell); // CELL.SATURATION
+float pmCellGetBad(pmCell *cell);      // CELL.BAD
+psPixelCoord pmCellGetBin(pmCell *cell); // CELL.BIN
+psPixelCoord pmCellGetParity(pmCell *cell); // CELL.PARITY
+float pmReadoutGetExposure(pmReadout *readout); // READOUT.EXPOSURE
+float pmReadoutGetDarkTime(pmReadout *readout); // READOUT.DARKTIME
+\end{prototype}
+
+Most of these are straight-forward, but some need some explanation.
+
+\code{pmCellGetBiasSec} shall return a list of \code{psRegion}s, one
+for each bias section.
+
+\code{pmCellGetBin} shall return a \code{psPixelCoord} with the
+binning factors appropriately set in the \code{x} and \code{y}
+members.  Similarly with \code{pmCellGetParity}.
+
+
+\input{CameraImages.tex}
+
+%\input{CameraGeometry.tex}
 
 \section{Photometry}
@@ -665,5 +782,5 @@
 
 Each of these shall be discussed in turn, below.  Those modules which
-are \tbd{TBD} will be deferred until they may be properly defined,
+are \tbd{} will be deferred until they may be properly defined,
 some of which requires further research to define the best algorithm.
 
@@ -679,7 +796,7 @@
 The API shall be the following:
 \begin{prototype}
-psReadout *pmSubtractBias(psReadout *in, void *fitSpec, const psList *overscans,
+pmReadout *pmSubtractBias(pmReadout *in, void *fitSpec, const psList *overscans,
                           pmOverscanAxis overscanAxis, const psStats *stat,
-                          int nBin, pmFit fit, const psReadout *bias);
+                          int nBin, pmFit fit, const pmReadout *bias);
 \end{prototype}
 
@@ -809,5 +926,5 @@
 
 \begin{prototype}
-psReadout *pmNonLinearityPolynomial(psReadout *in, const psPolynomial1D *coeff);
+pmReadout *pmNonLinearityPolynomial(pmReadout *in, const psPolynomial1D *coeff);
 \end{prototype}
 
@@ -820,5 +937,5 @@
 
 \begin{prototype}
-psReadout *pmNonLinearityLookup(psReadout *in, const psVector *inFlux, const psVector *outFlux);
+pmReadout *pmNonLinearityLookup(pmReadout *in, const psVector *inFlux, const psVector *outFlux);
 \end{prototype}
 
@@ -856,5 +973,5 @@
 updating the mask as appropriate.  The API shall be the following:
 \begin{prototype}
-bool pmFlatField(psReadout *in, psReadout *mask, const psReadout *flat);
+bool pmFlatField(pmReadout *in, pmReadout *mask, const pmReadout *flat);
 \end{prototype}
 
@@ -921,5 +1038,5 @@
 shall be the following:
 \begin{prototype}
-psReadout *pmMaskBadPixels(psReadout *in, const psImage *mask, unsigned int maskVal,
+pmReadout *pmMaskBadPixels(pmReadout *in, const psImage *mask, unsigned int maskVal,
                            float sat, unsigned int growVal, int grow);
 \end{prototype}
@@ -953,5 +1070,5 @@
 the following:
 \begin{prototype}
-psReadout *pmSubtractSky(psReadout *in, psPolynomial2D *poly, psImage *mask, psU8 maskVal, 
+pmReadout *pmSubtractSky(pmReadout *in, psPolynomial2D *poly, psImage *mask, psU8 maskVal, 
                          int binFactor, psStats *stats, float clipSD);
 \end{prototype}
@@ -1040,6 +1157,6 @@
 If the \code{inputs} is \code{NULL}, the module shall generate an
 error and return \code{NULL}.  Otherwise, the \code{inputs} shall be a
-list of \code{psReadout}s.  The images contained within the
-\code{psReadout}s need not all be of the same size, but the module
+list of \code{pmReadout}s.  The images contained within the
+\code{pmReadout}s need not all be of the same size, but the module
 shall take into account the offsets (\code{col0,row0}) from the corner
 of the detector when comparing pixels, so that it is the same
@@ -1052,5 +1169,5 @@
 this structure instead of supplying the values separately in order to
 keep down the number of parameters to \code{pmReadoutCombine}; the
-\code{psCombineParams} may be recycled for subsequent calls to
+\code{pmCombineParams} may be recycled for subsequent calls to
 \code{pmReadoutCombine} since the values are not dependent upon the
 choice of inputs, but merely specify how the combination is to be
@@ -1063,5 +1180,5 @@
 
 If the \code{maskVal} is non-zero, then pixels in the \code{mask} of
-each \code{psReadout} in the \code{inputs} which satisfy the
+each \code{pmReadout} in the \code{inputs} which satisfy the
 \code{maskVal} shall not have the corresponding pixels placed in the
 stack for combination.
@@ -1270,5 +1387,5 @@
   psVector *dparams;        // parameter errors
   psF32 chisq;              // fit chisq
-  psS32 nDOF;		    // number of degrees of freedom
+  psS32 nDOF;               // number of degrees of freedom
   psS32 nIter;              // number of iterations
 } pmModel;
@@ -1307,7 +1424,7 @@
 typedef struct {
     psS32 type;             ///< PSF Model in use
-    psArray *params;	    ///< Model parameters (psPolynomial2D)
+    psArray *params;        ///< Model parameters (psPolynomial2D)
     psF32 chisq;            ///< PSF goodness statistic
-    psS32 nPSFstars;	    ///< number of stars used to measure PSF
+    psS32 nPSFstars;        ///< number of stars used to measure PSF
 } pmPSF;
 \end{datatype}
@@ -1776,4 +1893,8 @@
                         );
 \end{prototype}
+
+\tbd{This algorithm will change: an addition will be made to avoid
+masking pixels in the wings of a star when combining images taken in
+different seeing, and the gradient limit criteria will be changed.}
 
 \code{pmRejectPixels} inspects those questionable \code{pixels}
@@ -1944,5 +2065,5 @@
     pmSubtractionKernelType type;       // Type of kernels --- allowing the use of multiple kernels
     int size;                           // Size of kernel in x and y
-    int spatialOrder;		        // Maximum order of spatial variations
+    int spatialOrder;                   // Maximum order of spatial variations
     psVector *u, *v;                    // Offset (for POIS) or polynomial order (for ISIS)
     psVector *sigma;                    // Width of Gaussian (for ISIS)
@@ -2019,5 +2140,5 @@
     psImage *matrix;                    // Associated matrix
     psVector *vector;                   // Associated vector
-    psStampStatus status;               // Status of stamp
+    pmStampStatus status;               // Status of stamp
 } pmStamp;
 \end{datatype}
@@ -2362,4 +2483,623 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+\section{Example Camera Configuration Files}
+
+\tbd{Some of these don't exactly match the specifications of this
+document yet, because they have been changed from the prototype, but
+it is hoped that they will be useful.  Questions are welcome.}
+
+\subsection{MegaCam Raw}
+
+\begin{verbatim}
+# The raw MegaCam data comes off the telescope with each of the chips stored in extensions of a MEF file.
+
+# How to identify this type
+RULE    METADATA
+        TELESCOP        STR     CFHT 3.6m
+        DETECTOR        STR     MegaCam
+        EXTEND          BOOL    T
+        NEXTEND         S32     72
+END
+
+# How to read this data
+PHU             STR     FPA     # The FITS file represents an entire FPA
+EXTENSIONS      STR     CELL    # The extensions represent cells
+
+# What's in the FITS file?
+CONTENTS        METADATA
+        # Extension name, chip name:type
+        amp00   STR     ccd00:left
+        amp01   STR     ccd00:right
+        amp02   STR     ccd01:left
+        amp03   STR     ccd01:right
+        amp04   STR     ccd02:left
+        amp05   STR     ccd02:right
+        amp06   STR     ccd03:left
+        amp07   STR     ccd03:right
+        amp08   STR     ccd04:left
+        amp09   STR     ccd04:right
+        amp10   STR     ccd05:left
+        amp11   STR     ccd05:right
+        amp12   STR     ccd06:left
+        amp13   STR     ccd06:right
+        amp14   STR     ccd07:left
+        amp15   STR     ccd07:right
+        amp16   STR     ccd08:left
+        amp17   STR     ccd08:right
+        amp18   STR     ccd09:left
+        amp19   STR     ccd09:right
+        amp20   STR     ccd10:left
+        amp21   STR     ccd10:right
+        amp22   STR     ccd11:left
+        amp23   STR     ccd11:right
+        amp24   STR     ccd12:left
+        amp25   STR     ccd12:right
+        amp26   STR     ccd13:left
+        amp27   STR     ccd13:right
+        amp28   STR     ccd14:left
+        amp29   STR     ccd14:right
+        amp30   STR     ccd15:left
+        amp31   STR     ccd15:right
+        amp32   STR     ccd16:left
+        amp33   STR     ccd16:right
+        amp34   STR     ccd17:left
+        amp35   STR     ccd17:right
+        amp36   STR     ccd18:left
+        amp37   STR     ccd18:right
+        amp38   STR     ccd19:left
+        amp39   STR     ccd19:right
+        amp40   STR     ccd20:left
+        amp41   STR     ccd20:right
+        amp42   STR     ccd21:left
+        amp43   STR     ccd21:right
+        amp44   STR     ccd22:left
+        amp45   STR     ccd22:right
+        amp46   STR     ccd23:left
+        amp47   STR     ccd23:right
+        amp48   STR     ccd24:left
+        amp49   STR     ccd24:right
+        amp50   STR     ccd25:left
+        amp51   STR     ccd25:right
+        amp52   STR     ccd26:left
+        amp53   STR     ccd26:right
+        amp54   STR     ccd27:left
+        amp55   STR     ccd27:right
+        amp56   STR     ccd28:left
+        amp57   STR     ccd28:right
+        amp58   STR     ccd29:left
+        amp59   STR     ccd29:right
+        amp60   STR     ccd30:left
+        amp61   STR     ccd30:right
+        amp62   STR     ccd31:left
+        amp63   STR     ccd31:right
+        amp64   STR     ccd32:left
+        amp65   STR     ccd32:right
+        amp66   STR     ccd33:left
+        amp67   STR     ccd33:right
+        amp68   STR     ccd34:left
+        amp69   STR     ccd34:right
+        amp70   STR     ccd35:left
+        amp71   STR     ccd35:right
+END
+
+# Specify the cell data
+CELLS   METADATA
+        left    METADATA        # Left amplifier
+                CELL.BIASSEC    STR     HEADER:BIASSEC
+                CELL.TRIMSEC    STR     HEADER:DATASEC
+                CELL.XPARITY    S32     1       # We could have specified this as a DEFAULT, but this works
+        END
+        right   METADATA        # Right amplifier
+                CELL.BIASSEC    STR     HEADER:BIASSEC
+                CELL.TRIMSEC    STR     HEADER:DATASEC
+                CELL.XPARITY    S32     -1      # This cell is read out in the opposite direction
+        END
+END
+
+# How to translate PS concepts into FITS headers
+TRANSLATION     METADATA
+        FPA.NAME        STR     EXPNUM
+        FPA.AIRMASS     STR     AIRMASS
+        FPA.FILTER      STR     FILTER
+        FPA.POSANGLE    STR     ROTANGLE
+        FPA.RA          STR     RA
+        FPA.DEC         STR     DEC
+        FPA.RADECSYS    STR     RADECSYS
+        FPA.MJD         STR     MJD-OBS
+        CELL.EXPOSURE   STR     EXPTIME
+        CELL.DARKTIME   STR     DARKTIME
+        CELL.XBIN       STR     CCDBIN1
+        CELL.YBIN       STR     CCDBIN2
+        CELL.GAIN       STR     GAIN
+        CELL.READNOISE  STR     RDNOISE
+        CELL.SATURATION STR     SATURATE
+END
+
+# Default PS concepts that may be specified by value
+DEFAULTS        METADATA
+        CELL.BAD                S32     0
+        CELL.YPARITY_DEPEND     STR     CHIP.NAME
+        CELL.YPARITY    METADATA
+                ccd00   S32     -1
+                ccd01   S32     -1
+                ccd02   S32     -1
+                ccd03   S32     -1
+                ccd04   S32     -1
+                ccd05   S32     -1
+                ccd06   S32     -1
+                ccd07   S32     -1
+                ccd08   S32     -1
+                ccd09   S32     -1
+                ccd10   S32     -1
+                ccd11   S32     -1
+                ccd12   S32     -1
+                ccd13   S32     -1
+                ccd14   S32     -1
+                ccd15   S32     -1
+                ccd16   S32     -1
+                ccd17   S32     -1
+                ccd18   S32     1
+                ccd19   S32     1
+                ccd20   S32     1
+                ccd21   S32     1
+                ccd22   S32     1
+                ccd23   S32     1
+                ccd24   S32     1
+                ccd25   S32     1
+                ccd26   S32     1
+                ccd27   S32     1
+                ccd28   S32     1
+                ccd29   S32     1
+                ccd30   S32     1
+                ccd31   S32     1
+                ccd32   S32     1
+                ccd33   S32     1
+                ccd34   S32     1
+                ccd35   S32     1
+        END
+END
+
+# How to translation PS concepts into database lookups
+DATABASE        METADATA
+        TYPE            dbEntry         TABLE           COLUMN          GIVENDBCOL      GIVENPS
+#       CELL.GAIN       dbEntry         Camera          gain            chipId,cellId   CHIP.NAME,CELL.NAME
+#       CELL.READNOISE  dbEntry         Camera          readNoise       chipId,cellId   CHIP.NAME,CELL.NAME
+
+# A database entry refers to a particular column (COLUMN) in a
+# particular table (TABLE), given certain PS concepts (GIVENPS) that
+# match certain database columns (GIVENDBCOL).
+
+END
+\end{verbatim}
+
+\subsection{MegaCam Splice}
+
+\begin{verbatim}
+# The spliced MecaCam data is stored in single extensions for each chip
+
+# How to recognise this type
+RULE    METADATA
+        TELESCOP        STR     CFHT 3.6m
+        DETECTOR        STR     MegaCam
+        EXTEND          BOOL    T
+        NEXTEND         S32     36
+END
+
+# How to read this data
+PHU             STR     FPA     # The FITS file represents an entire FPA
+EXTENSIONS      STR     CHIP    # The extensions represent chips
+
+# What's in the FITS file?
+CONTENTS        METADATA
+        # Extension name, components
+        ccd00           STR     left right
+        ccd01           STR     left right
+        ccd02           STR     left right
+        ccd03           STR     left right
+        ccd04           STR     left right
+        ccd05           STR     left right
+        ccd06           STR     left right
+        ccd07           STR     left right
+        ccd08           STR     left right
+        ccd09           STR     left right
+        ccd10           STR     left right
+        ccd11           STR     left right
+        ccd12           STR     left right
+        ccd13           STR     left right
+        ccd14           STR     left right
+        ccd15           STR     left right
+        ccd16           STR     left right
+        ccd17           STR     left right
+        ccd18           STR     left right
+        ccd19           STR     left right
+        ccd20           STR     left right
+        ccd21           STR     left right
+        ccd22           STR     left right
+        ccd23           STR     left right
+        ccd24           STR     left right
+        ccd25           STR     left right
+        ccd26           STR     left right
+        ccd27           STR     left right
+        ccd28           STR     left right
+        ccd29           STR     left right
+        ccd30           STR     left right
+        ccd31           STR     left right
+        ccd32           STR     left right
+        ccd33           STR     left right
+        ccd34           STR     left right
+        ccd35           STR     left right
+END
+
+# Specify the cells
+CELLS           METADATA
+        left            METADATA
+                CELL.BIASSEC    STR     HEADER:BSECA
+                CELL.TRIMSEC    STR     HEADER:TSECA
+        END
+
+        right           METADATA
+                CELL.BIASSEC    STR     HEADER:BSECB
+                CELL.TRIMSEC    STR     HEADER:TSECB
+        END
+END
+
+# How to translate PS concepts into FITS headers
+TRANSLATION     METADATA
+        FPA.NAME        STR     EXPNUM
+        FPA.AIRMASS     STR     AIRMASS
+        FPA.FILTER      STR     FILTER
+        FPA.POSANGLE    STR     ROTANGLE
+        FPA.RA          STR     RA
+        FPA.DEC         STR     DEC
+        FPA.RADECSYS    STR     RADECSYS
+        FPA.MJD         STR     MJD-OBS
+        CELL.EXPOSURE   STR     EXPTIME
+        CELL.DARKTIME   STR     DARKTIME
+        CELL.XBIN       STR     CCDBIN1
+        CELL.YBIN       STR     CCDBIN2
+        CELL.GAIN       STR     GAIN
+        CELL.READNOISE  STR     RDNOISE
+        CELL.SATURATION STR     SATURATE
+END
+
+# Default PS concepts that may be specified by value
+DEFAULTS        METADATA
+        CELL.BAD                S32     0
+        CELL.XPARITY            S32     1
+        CELL.YPARITY            S32     1
+END
+
+
+# How to translation PS concepts into database lookups
+DATABASE        METADATA
+        TYPE            dbEntry         TABLE           COLUMN          GIVENDBCOL      GIVENPS
+#       CELL.GAIN       dbEntry         Camera          gain            chipId,cellId   CHIP.NAME,CELL.NAME
+#       CELL.READNOISE  dbEntry         Camera          readNoise       chipId,cellId   CHIP.NAME,CELL.NAME
+
+# A database entry refers to a particular column (COLUMN) in a
+# particular table (TABLE), given certain PS concepts (GIVENPS) that
+# match certain database columns (GIVENDBCOL).
+
+END             
+\end{verbatim}
+
+\subsection{LRIS Blue}
+
+\begin{verbatim}
+# The Low Resolution Imager and Spectrograph (LRIS) blue side
+
+# We have no choice but to hard-code the various regions, because Keck
+# only stores them as:
+# WINDOW  = '1,0,0,2048,4096'
+# PREPIX  =                   51
+# POSTPIX =                   80
+# BINNING = '1,1     '
+# AMPPSIZE= '[1:1024,1:4096]'
+
+# I don't know how we would get the IPP to react to changes in the
+# windowing on the fly --- we have no mechanism for setting the region
+# sizes on the basis of the above keywords.  Therefore, we hard-code
+# the regions and assert on our assumptions in the RULE.
+
+
+# How to identify this type
+RULE    METADATA
+        TELESCOP        STR     Keck I
+        INSTRUME        STR     LRISBLUE
+        AMPLIST         STR     1,4,0,0
+        WINDOW          STR     1,0,0,2048,4096
+        PREPIX          S32     51
+        POSTPIX         S32     80
+        BINNING         STR     1,1
+        AMPPSIZE        STR     [1:1024,1:4096]
+        NAXIS1          S32     4620
+        NAXIS2          S32     4096
+END
+
+# How to read this data
+PHU             STR     FPA     # The FITS file represents an entire FPA
+EXTENSIONS      STR     NONE    # There are no extensions
+
+# What's in the FITS file?
+CONTENTS        METADATA
+        LeftChip        STR     amp1 amp2
+        RightChip       STR     amp3 amp4
+END
+
+# Specify the cell data
+CELLS   METADATA
+        amp1            METADATA
+                CELL.BIASSEC    STR     VALUE:[1:51,1:4096];[4301:4380,1:4096]
+                CELL.TRIMSEC    STR     VALUE:[205:1228,1:4096]
+                CELL.GAIN       STR     VALUE:1.2
+                CELL.READNOISE  STR     VALUE:5.6
+        END
+
+        amp2    METADATA
+                CELL.BIASSEC    STR     VALUE:[52:102,1:4096];[4381:4460,1:4096]
+                CELL.TRIMSEC    STR     VALUE:[1229:2252,1:4096]
+                CELL.GAIN       STR     VALUE:1.3
+                CELL.READNOISE  STR     VALUE:6.7
+        END
+
+        amp3            METADATA
+                CELL.BIASSEC    STR     VALUE:[103:153,1:4096];[4461:4540,1:4096]
+                CELL.TRIMSEC    STR     VALUE:[2253:3276,1:4096]
+                CELL.GAIN       STR     VALUE:1.4
+                CELL.READNOISE  STR     VALUE:7.8
+        END
+
+        amp4    METADATA
+                CELL.BIASSEC    STR     VALUE:[154:204,1:4096];[4541:4620,1:4096]
+                CELL.TRIMSEC    STR     VALUE:[3277:4300,1:4096]
+                CELL.GAIN       STR     VALUE:1.5
+                CELL.READNOISE  STR     VALUE:8.9
+        END
+END
+
+# How to translate PS concepts into FITS headers
+TRANSLATION     METADATA
+        FPA.AIRMASS     STR     AIRMASS
+        FPA.FILTER      STR     BLUFILT
+        FPA.POSANGLE    STR     ROTPOSN
+        FPA.RA          STR     RA
+        FPA.DEC         STR     DEC
+        CELL.EXPOSURE   STR     EXPOSURE
+        CELL.DARKTIME   STR     EXPOSURE        // No special darktime header; use exposure time
+        CELL.DATE       STR     DATE            // NOTE: There are TWO keywords called "DATE" (creation, exp)!
+        CELL.TIME       STR     UT
+END
+
+# Default PS concepts that may be specified by value
+DEFAULTS        METADATA
+        FPA.RADECSYS    STR     ICRS
+END
+\end{verbatim}
+
+\subsection{LRIS Red}
+
+\begin{verbatim}
+# The Low Resolution Imager and Spectrograph (LRIS) red side
+
+# We have no choice but to hard-code the various regions, because Keck
+# only stores them as:
+# WINDOW  = '0,0,0,2048,2048'
+# PREPIX  =                   20
+# POSTPIX =                   80
+# BINNING = '1,1     '
+# AMPPSIZE= '[1:1024,1:4096]'
+
+# I don't know how we would get the IPP to react to changes in the
+# windowing on the fly --- we have no mechanism for setting the region
+# sizes on the basis of the above keywords.  Therefore, we hard-code
+# the regions and assert on our assumptions in the RULE.
+
+
+# How to identify this type
+RULE    METADATA
+        TELESCOP        STR     Keck I
+        INSTRUME        STR     LRIS
+        AMPLIST         STR     2,1,0,0
+        WINDOW          STR     0,0,0,2048,2048
+        PREPIX          S32     20
+        POSTPIX         S32     80
+        BINNING         STR     1, 1
+        CCDPSIZE        STR     [1:2048,1:2048]
+        NAXIS1          S32     2248
+        NAXIS2          S32     2048
+        IMTYPE          STR     TWOAMPTOP
+END
+
+# How to read this data
+PHU             STR     CHIP    # The FITS file represents a single chip
+EXTENSIONS      STR     NONE    # There are no extensions
+
+# What's in the FITS file?
+CONTENTS        STR     LeftSide RightSide
+
+# Specify the cell data
+CELLS   METADATA
+        LeftSide        METADATA
+                CELL.BIASSEC    STR     VALUE:[1:20,1:2048];[2089:2168,1:2048]
+                CELL.TRIMSEC    STR     VALUE:[41:1064,1:2048]
+                CELL.GAIN       STR     VALUE:1.2
+                CELL.READNOISE  STR     VALUE:5.6
+        END
+
+        RightSide       METADATA
+                CELL.BIASSEC    STR     VALUE:[21:40,1:2048];[2169:2248,1:2048]
+                CELL.TRIMSEC    STR     VALUE:[1065:2088,1:2048]
+                CELL.GAIN       STR     VALUE:1.3
+                CELL.READNOISE  STR     VALUE:6.5
+        END
+END
+
+# How to translate PS concepts into FITS headers
+TRANSLATION     METADATA
+        FPA.AIRMASS     STR     AIRMASS
+        FPA.FILTER      STR     FILTER
+        FPA.POSANGLE    STR     POSANG
+        FPA.RA          STR     OBJ-RA
+        FPA.DEC         STR     OBJ-DEC
+        CELL.EXPOSURE   STR     EXPTIME
+        CELL.DARKTIME   STR     DARKTIME
+        CELL.DATE       STR     DATE-OBS
+        CELL.TIME       STR     TIME-OBS
+END
+
+# Default PS concepts that may be specified by value
+DEFAULTS        METADATA
+        FPA.RADECSYS    STR     ICRS
+END
+\end{verbatim}
+
+\subsection{GPC OTA}
+
+\begin{verbatim}
+# The raw GPC data comes off the telescope with each of the chips stored in separate files
+
+# How to identify this type
+RULE    METADATA
+#       TELESCOP        STR     PS1
+#       DETECTOR        STR     GPC1
+        EXTEND          BOOL    T
+        NEXTEND         S32     64
+        NAMPS           S32     64
+END
+
+# How to read this data
+PHU             STR     CHIP    # The FITS file represents a single chip
+EXTENSIONS      STR     CELL    # The extensions represent cells
+
+# What's in the FITS file?
+CONTENTS        METADATA
+        # Extension name, type
+        xy00    STR     pitch10u
+        xy01    STR     pitch10u
+        xy02    STR     pitch10u
+        xy03    STR     pitch10u
+        xy04    STR     pitch10u
+        xy05    STR     pitch10u
+        xy06    STR     pitch10u
+        xy07    STR     pitch10u
+        xy10    STR     pitch10u
+        xy11    STR     pitch10u
+        xy12    STR     pitch10u
+        xy13    STR     pitch10u
+        xy14    STR     pitch10u
+        xy15    STR     pitch10u
+        xy16    STR     pitch10u
+        xy17    STR     pitch10u
+        xy20    STR     pitch10u
+        xy21    STR     pitch10u
+        xy22    STR     pitch10u
+        xy23    STR     pitch10u
+        xy24    STR     pitch10u
+        xy25    STR     pitch10u
+        xy26    STR     pitch10u
+        xy27    STR     pitch10u
+        xy30    STR     pitch10u
+        xy31    STR     pitch10u
+        xy32    STR     pitch10u
+        xy33    STR     pitch10u
+        xy34    STR     pitch10u
+        xy35    STR     pitch10u
+        xy36    STR     pitch10u
+        xy37    STR     pitch10u
+        xy40    STR     pitch10u
+        xy41    STR     pitch10u
+        xy42    STR     pitch10u
+        xy43    STR     pitch10u
+        xy44    STR     pitch10u
+        xy45    STR     pitch10u
+        xy46    STR     pitch10u
+        xy47    STR     pitch10u
+        xy50    STR     pitch10u
+        xy51    STR     pitch10u
+        xy52    STR     pitch10u
+        xy53    STR     pitch10u
+        xy54    STR     pitch10u
+        xy55    STR     pitch10u
+        xy56    STR     pitch10u
+        xy57    STR     pitch10u
+        xy60    STR     pitch10u
+        xy61    STR     pitch10u
+        xy62    STR     pitch10u
+        xy63    STR     pitch10u
+        xy64    STR     pitch10u
+        xy65    STR     pitch10u
+        xy66    STR     pitch10u
+        xy67    STR     pitch10u
+        xy70    STR     pitch10u
+        xy71    STR     pitch10u
+        xy72    STR     pitch10u
+        xy73    STR     pitch10u
+        xy74    STR     pitch10u
+        xy75    STR     pitch10u
+        xy76    STR     pitch10u
+        xy77    STR     pitch10u
+END
+
+# Specify the cell data
+CELLS   METADATA
+        pitch10u        METADATA
+                CELL.BIASSEC    STR     VALUE:[575:606,1:594]
+                CELL.TRIMSEC    STR     VALUE:[1:574,1:594]
+        #       CELL.BIASSEC    STR     HEADER:BIASSEC
+        #       CELL.TRIMSEC    STR     HEADER:DATASEC
+        END
+
+        # This is just in here for fun
+        pitch12u        METADATA
+                CELL.BIASSEC    STR     VALUE:[1:10,1:512];[523:574,1:512]
+                CELL.TRIMSEC    STR     VALUE:[11:522,1:512]
+        #       CELL.BIASSEC    STR     HEADER:BIASSEC
+        #       CELL.TRIMSEC    STR     HEADER:TRIMSEC
+        END
+END
+
+
+# How to translate PS concepts into FITS headers
+TRANSLATION     METADATA
+        CELL.BIN        STR     CCDSUM
+        CELL.SATURATION STR     SATURATE
+END
+
+# Default PS concepts that may be specified by value
+DEFAULTS        METADATA
+        FPA.AIRMASS     F32     0.0
+        FPA.FILTER      STR     NONE
+        FPA.POSANGLE    F32     0.0
+        FPA.RA          STR     0:0:0
+        FPA.DEC         STR     0:0:0
+        FPA.RADECSYS    STR     ICRS
+        FPA.NAME        S32     0
+        FPA.MJD         F32     12345.6789
+        CELL.EXPOSURE   F32     0.0
+        CELL.DARKTIME   F32     0.0
+        CELL.GAIN       F32     1.0
+        CELL.READNOISE  F32     0.0
+        CELL.BAD        S32     0
+        CELL.BIN        S32     1
+        CELL.XPARITY    S32     1
+        CELL.YPARITY    S32     1
+END
+
+# How to translation PS concepts into database lookups
+DATABASE        METADATA
+        TYPE            dbEntry         TABLE           COLUMN          GIVENDBCOL      GIVENPS
+        CELL.GAIN       dbEntry         Camera          gain            chipId,cellId   CHIP,CELL
+        CELL.READNOISE  dbEntry         Camera          readNoise       chipId,cellId   CHIP,CELL
+
+# A database entry refers to a particular column (COLUMN) in a
+# particular table (TABLE), given certain PS concepts (GIVENPS) that
+# match certain database columns (GIVENDBCOL).
+
+END
+\end{verbatim}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 \section{Revision Change Log}
 \input{ChangeLogSDRS.tex}
