Index: /trunk/doc/modules/ModulesSDRS.tex
===================================================================
--- /trunk/doc/modules/ModulesSDRS.tex	(revision 1435)
+++ /trunk/doc/modules/ModulesSDRS.tex	(revision 1436)
@@ -1,7 +1,7 @@
-%%% $Id: ModulesSDRS.tex,v 1.9 2004-06-30 10:08:52 price Exp $
+%%% $Id: ModulesSDRS.tex,v 1.10 2004-08-09 23:20:02 price Exp $
 \documentclass[panstarrs]{panstarrs}
 
 % basic document variables
-\title{Pan-STARRS IPP Phase 2}
+\title{Pan-STARRS IPP Modules}
 \subtitle{Supplementary Design Requirements}
 \author{Paul Price}
@@ -52,29 +52,34 @@
 
 This document describes the Pan-STARRS Image Processing Pipeline (IPP)
-Phase 2 image processing modules.  Phase 2 is the processing stage wherein
-the instrumental signatures are removed from the detector images, in
-preparation for the combination of multiple images in Phase 4.
-
-The Phase 2 processing \textit{stage} is composed of several
-\textit{modules} which perform the individual steps in the processing,
-each of which will act upon a data element of the appropriate size.
-For example, the bias subtraction module will act upon a detector
-``readout'' (\code{psReadout}).  It will be the responsibility of the
-caller of the Phase 2 processing modules (i.e., the Phase 2 processing
-stage, which will likely be script written in a high-level language
-such as \tbd{Python}) to iterate over the components with which it is
-charged.
+image processing modules.  The modules use the functionality \PS{}
+Library (PSLib) perform more complex tasks.
+
+In order to preserve name space, globally-visible structures and
+functions shall be prefixed with \code{pm}, for ``\PS{} Modules''.
+
+Modules will be constructed to support each of the processing stages.
+
+\section{Phase 2}
+
+Phase 2 is the processing stage wherein the instrumental signatures
+are removed from the detector images, in preparation for the
+combination of multiple images in Phase 4.
+
+The Phase 2 processing stage is composed of several modules which
+perform the individual steps in the processing, each of which will act
+upon a data element of the appropriate size.  For example, the bias
+subtraction module will act upon a detector ``readout''
+(\code{psReadout}).  It will be the responsibility of the caller of
+the Phase 2 processing modules (i.e., the Phase 2 processing stage,
+which will likely be a script written in a high-level language such as
+\tbd{Python}) to iterate over the components with which it is charged.
 
 The Phase 2 processing modules are:
 \begin{itemize}
-\item Read in an FPA;
-\item Calculate the convolution kernel;
-\item Convolve an image with the kernel;
 \item Subtract bias;
-\item Trim an image;
 \item Correct for non-linearity;
 \item Flat-field;
-\item Subtract the background;
 \item Mask bad pixels;
+\item \tbd{Subtract the background;}
 \item \tbd{Mask cosmic rays;}
 \item \tbd{Mask optical defects;}
@@ -89,284 +94,47 @@
 some of which requires further research to define the best algorithm.
 
-These modules are built on top of, and are dependent upon, the \PS{}
-Library, PSLib.  Some functions are specified below which should be
-added to PSLib, since we anticipate that these will also find use in
-other modules.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\section{Read in an image}
-
-Of course, before any image manipulation may occur, the image must be
-read in.  This involves populating the FPA with structures to
-represent the true focal plane.  However, different instruments have
-different focal planes, and the images are written to disk in
-different ways.  We have proposed a configuration file format which
-appears to be able to document the structure of a focal plane and
-specify how the IPP can read the required information from the FITS
-files \tbd{A REFERENCE GOES HERE}.
-
-Given an open \code{FILE} pointer to a configuration file,
-\code{config}, and the name of an FPA image, \code{fpaName},
-\code{psFPAGenerate} shall return a \code{psFPA} of the correct
-structure, with all the metadata entries read from the nominated FPA
-image.  Astrometric information shall be initialised to values
-specified by the configuration file.  The API shall be:
-
-\begin{verbatim}
-psFPA *psFPAGenerate(FILE *config, const char *fpaName);
-\end{verbatim}
-
-Once an FPA has been generated, the pixels may all be read in at once,
-or the pixels may be read in a chip, cell or readout at a time.  The
-corresponding APIs are:
-
-\begin{verbatim}
-psFPA *psFPAReadAll(psFPA *in);
-psFPA *psFPAReadChip(psFPA *in, const char *chipName);
-psChip *psChipReadCell(psChip *in, const char *cellName);
-psCell *psCellReadReadout(psCell *in, const char *readoutName);
-\end{verbatim}
-
-Note that reads of a cell or readout do not act upon an FPA, but
-rather a chip and a cell, respectively.  This saves the user from
-specifying the name of the FPA, chip, and cell just to get a readout,
-since this information is already stored in the generated \code{psFPA}
-struct.
-
-\tbd{How to write the output???}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\section{Convolution}
-
-If images on the sky are obtained in Orthogonal Transfer (OT) mode,
-then the calibration frames used to correct them must be convolved by
-a kernel derived from the list of OT shifts made during the exposure.
-
-\subsection{Kernel definition}
-
-In order to perform a convolution, we need to define the convolution
-kernel.  We need a more general object than a \code{psImage} so that
-we can incorporate the offset from the $(0,0)$ pixel to the $(0,0)$
-value of the kernel\footnote{The kernel has both positive and negative
-indices to convey the positive and negative shifts.  One might
-consider setting the \code{x0} and \code{y0} members of a
-\code{psImage} to the appropriate offsets, but this is not the purpose
-of these members, and doing so may affect the behavior of other
-\code{psImage} operations.}.  Hence we define a \code{psKernel}:
-
-\begin{verbatim}
-/** A convolution kernel */
-typedef struct {
-    int xMin, yMin;                     ///< Most negative indices
-    int xMax, yMax;                     ///< Most positive indices
-    float **kernel;                     ///< The kernel data
-} psKernel;
-\end{verbatim}
-
-The \code{kernel} shall contain the kernel values.  The kernel has
-both positive and negative indices to convey the positive and negative
-shifts.  The maximum extent of these shifts shall be defined by the
-\code{xMin}, \code{xMax}, \code{yMin} and \code{yMax} members.  Note
-that \code{xMin} and \code{yMin}, under normal circumstances, should
-be negative numbers.  That is, \code{myKernel->kernel[-3][-2]} may be
-defined if \code{yMin} and \code{xMin} are equal to or more negative
-than -3 and -2, respectively.
-
-Of course, we require the appropriate constructor and destructor:
-\begin{verbatim}
-psKernel *psKernelAlloc(int xMin, int xMax, int yMin, int yMax);
-void psKernelFree(psKernel *myKernel);
-\end{verbatim}
-
-\code{psKernelAlloc} shall allocate a kernel.  In the event that one
-of the minimum values is greater than the corresponding maximum value,
-the function shall generate a warning, and the offending values shall
-be exchanged.
-
-\subsection{Calculate the convolution kernel}
-
-Given a list of pixel shifts made in the course of OT guiding,
-\code{psPhase2GetKernel} shall return the appropriate kernel.  The API
-shall be the following:
-\begin{verbatim}
-psKernel *psPhase2GetKernel(const psVector *xShifts, const psVector *yShifts);
-\end{verbatim}
-
-The shift vectors, \code{xShifts} and \code{yShifts}, will be supplied
-by the user, most probably from the FITS file containing the image.
-
-The elements of the shift vectors should be of an integer type;
-otherwise the values shall be truncated to integers.  The output
-kernel shall be normalized such that the sum over the kernel is unity.
-
-The format of the shifts vectors will be a list of the net shift
-position relative to the starting point for each timestep.  In the
-normal course of \PS{} observations using orthogonal transfer, there
-will likely be about 10~Hz $\times$ 30~sec $=$ 300 timesteps.
-
-If the vectors are not of the same number of elements, then the
-function shall generate a warning shall be generated, following which,
-the longer vector trimmed to the length of the shorter, and the
-function shall continue.
-
-\subsection{Convolve an image with the kernel}
-
-Given an input image and the convolution kernel,
-\code{psPhase2ConvolveWithKernel} shall convolve the input image,
-\code{in}, with the kernel, \code{kernel} and return the convolved
-image, \code{out}.  The API shall be the following:
-\begin{verbatim}
-psImage *psImageConvolve(psImage *out, const psImage *in, const psKernel *kernel, bool direct);
-\end{verbatim}
-
-Two methods shall be available for the convolution: if \code{direct}
-is \code{true}, then the convolution shall be performed in real space
-(appropriate for small kernels); otherwise, the convolution shall be
-performed using Fast Fourier Transforms (FFTs; appropriate for larger
-kernels).
-
-In the event that \code{out} is \code{NULL}, a new \code{psImage}
-shall be allocated and returned.
-
-\subsection{PSLib Routines}
-
-\code{psKernel} and \code{psImageConvolve} shall be incorporated into
-the \PS{} Library, \code{PSLib}, so that they may be re-used for other
-modules.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\section{Bias subtraction and trim}
-
-The following modules correct detector images for the electronic
-pedestal introduced by the readout electronics.
-
-\subsection{Image region specification}
-
-In order to specify regions on the detector image which may be used to
-determine the bias levels (i.e., a prescan or overscan region), we
-define the following structure:
-\begin{verbatim}
-/** Image regions */
-typedef struct {
-    const int x0, y0;                   ///< Offset to region
-    const int nX, nY;                   ///< Size of region
-} psImageRegion;
-\end{verbatim}
-
-A \code{psImageRegion} specifies the offset from $(0,0)$ on the
-detector\footnote{Note that an image may be smaller than the entire
-area of the detector if the detector is windowed, or if a subimage has
-been generated.} and the size of the region.
-
-We also require a corresponding constructor and destructor:
-\begin{verbatim}
-psImageRegion *psImageRegionAlloc(int x0, int y0, int nX, int nY);
-void psImageRegionFree(psImageRegion *reg);
-\end{verbatim}
-
-Multiple image regions may be specified using a linked list
-(\code{psList}) of \code{psImageRegion}s.
-
-\subsection{Splines}
-
-A spline is a popular choice for fitting 1D data, such as overscans,
-but we neglected to define them for PSLib.  We now define
-one-dimensional cubic splines, \code{psSpline1D}, which shall be
-incorporated into PSLib:
-
-\begin{verbatim}
-/** A 1D cubic-spline */
-typedef struct {
-    int n;                              ///< Number of spline pieces
-    float *coeff[4];                    ///< Coefficients.  There are 4 coefficients for each spline piece.
-    float *coeffErr[4];                 ///< Errors in the coefficients.
-    bool *mask[4];                      ///< Mask for the coefficients.
-    float *domains;                     ///< The boundaries between each spline piece.  Size is n+1.
-} psSpline1D;
-\end{verbatim}
-
-The \code{psSpline1D} structure is very similar to that of the
-one-dimensional Chebyshev polynomial, \code{psPolynomial1D},
-except for the following:
-\begin{itemize}
-\item Each spline piece has 4 coefficients (with corresponding error
-and mask), corresponding to each of the zeroth through third order
-coefficients of a cubic; and
-\item It includes an additional member, \code{domains}, which
-specifies the boundaries between each spline piece (including the two
-ends).
-\end{itemize}
-
-Of course, we require the appropriate constructors and destructor:
-\begin{verbatim}
-psSpline1D *psSpline1DAlloc(int n, float min, float max);
-psSpline1D *psSpline1DAllocGeneric(const psVector *bounds);
-void psSpline1DFree(psSpline1D *mySpline);
-\end{verbatim}
-
-\code{psSpline1DAlloc} shall allocate and return a \code{psSpline1D},
-setting the \code{domains} on the basis of the input number of spline
-pieces, \code{n}, and the minimum (\code{min}) and maximum
-(\code{max}) data values.
-
-\code{psSpline1DAllocGeneric} shall allocate and return a
-\code{psSpline1D}, using the \code{bounds} to define the number of
-spline pieces and the \code{domains}.
-
-\code{psSpline1DFree} shall free the given spline, and its members.
-
-Also, as for the polynomials, we require an evaluator.  Given a
-\code{spline} and ordinate at which to evaluate, \code{x},
-\code{psSpline1DEval} shall evaluate and return the value of the
-spline at the ordinate.  If the ordinate is outside the bounds, then
-the function shall generate a warning, and extrapolate the spline to
-the ordinate and return the value.
-
-\begin{verbatim}
-float psSpline1DEval(const psSpline1D *spline, float x);
-\end{verbatim}
-
-
 \subsection{Bias subtraction}
 \label{sec:bias}
 
+The bias subtraction module provides a facility to correct detector
+images for the electronic pedestal introduced by the readout
+electronics.
+
 Given an input image and various other parameters,
-\code{psPhase2SubtractBias} shall subtract the bias from the image.
+\code{pmSubtractBias} shall subtract the bias from the image.
 The API shall be the following:
 \begin{verbatim}
-psReadout *psPhase2SubtractBias(psReadout *in, void *fitSpec, psOverscanAxis overscanAxis, psFit fit,
-                                int nBin, const psList *regions, const psStats *stat, const psImage *bias);
+psReadout *pmSubtractBias(psReadout *in, void *fitSpec, const psList *overscans,
+                          pmOverscanAxis overscanAxis, const psStats *stat,
+                          int nBin, psFit fit, const psReadout *bias);
 \end{verbatim}
 
 The input image, \code{in}, shall have the bias subtracted in-place.
 
-The type of the overscan fit specification, \code{fitSpec}, shall be
+The type of the overscan fit function, \code{fitSpec}, shall be
 dependent upon the value of \code{fit}, which specifies the type of
 fit to be employed.  \code{fit} is an enumerated type:
 
 \begin{verbatim}
-/** Fit type */
+/** Fit types */
 typedef enum {
-    PS_FIT_NONE,                ///< No fit
-    PS_FIT_LINEAR,              ///< Do linear interpolation
-    PS_FIT_POLYNOMIAL,          ///< Fit polynomial
-    PS_FIT_CHEBYSHEV,           ///< Fit chebyshev
-    PS_FIT_SPLINE               ///< Fit cubic splines
-} psFit;
-\end{verbatim}
-
-If \code{fitSpec} is \code{NULL}, or \code{fit} is \code{PS_FIT_NONE},
-then no fit shall be performed to the overscan.  If \code{fit} is
-\code{PS_FIT_LINEAR}, then the function shall perform simple linear
-interpolation between points in the overscan.  Otherwise,
+    PM_FIT_NONE,                        ///< No fit
+    PM_FIT_POLYNOMIAL,                  ///< Fit polynomial
+    PM_FIT_SPLINE                       ///< Fit cubic splines
+} pmFit;
+\end{verbatim}
+
+If \code{fitSpec} is \code{NULL}, or \code{fit} is \code{PM_FIT_NONE},
+then no fit shall be performed to the overscan.  Otherwise,
 \code{fitSpec} shall be interpreted to be a structure of the
-appropriate type (\code{psPolynomial1D} for \code{PS_FIT_POLYNOMIAL}
-and \code{PS_FIT_CHEBYSHEV}, and \code{psSpline1D} for
-\code{PS_FIT_SPLINE}), and the overscan shall be fit using the
-specified functional form.  Upon return, the \code{fitSpec} shall
-contain the coefficients of the overscan fit.
+appropriate type (\code{psPolynomial1D} for \code{PM_FIT_POLYNOMIAL},
+and \code{psSpline1D} for \code{PM_FIT_SPLINE}), and the overscan
+shall be fit using the specified functional form.  Upon return, the
+\code{fitSpec} shall contain the coefficients of the overscan fit.
+
+The prescan and/or overscan regions to be used are specified in
+\code{overscans}, which is a linked list of subimages.  If
+\code{overscans} is non-\code{NULL} and \code{overscanAxis} is not
+\code{PM_OVERSCAN_NONE}, then the function shall generate a warning.
 
 The \code{overscanAxis} specifies how the prescan/overscan subtraction
@@ -375,35 +143,24 @@
 /** Overscan axis */
 typedef enum {
-    PS_OVERSCAN_NONE,                   ///< No overscan subtraction
-    PS_OVERSCAN_ROWS,                   ///< Subtract rows
-    PS_OVERSCAN_COLUMNS,                ///< Subtract columns
-    PS_OVERSCAN_ALL                     ///< Subtract the statistic of all pixels in overscan region
-} psOverscanAxis;
-\end{verbatim}
-
-If the \code{overscanAxis} is \code{PS_OVERSCAN_NONE}, then the
+    PM_OVERSCAN_NONE,                   ///< No overscan subtraction
+    PM_OVERSCAN_ROWS,                   ///< Subtract rows
+    PM_OVERSCAN_COLUMNS,                ///< Subtract columns
+    PM_OVERSCAN_ALL                     ///< Subtract the statistic of all pixels in overscan region
+} pmOverscanAxis;
+\end{verbatim}
+
+If the \code{overscanAxis} is \code{PM_OVERSCAN_NONE}, then the
 function shall not perform any overscan subtraction.  If the
-\code{overscanAxis} is \code{PS_OVERSCAN_ALL}, then all the overscan
+\code{overscanAxis} is \code{PM_OVERSCAN_ALL}, then all the overscan
 regions shall be used to generate a single statistic (specified by
 \code{stat}) which shall be subtracted from the entire image.  A
 warning shall be generated if the \code{overscanAxis} is
-\code{PS_OVERSCAN_NONE} or \code{PS_OVERSCAN_ALL} and the \code{fit}
-is not \code{PS_FIT_NONE}.
-
-If the \code{overscanAxis} is \code{PS_OVERSCAN_ROWS} or
-\code{PS_OVERSCAN_COLUMNS}, then the overscan shall be reduced to a
-single vector in the dimension specified using the specified statistic
-(\code{stat}).  If \code{nBin} is positive and less than the dimension
-of the vector, then the vector shall subsequently be binned down into
-\code{nBin} bins, again using the specified statistic (\code{stat}).
-If the overscan is not defined for each row/column, then the function
-shall generate a warning and then interpolate using the provided
-functional form if \code{fit} is not \code{PS_FIT_NONE};
-otherwise, the function shall generate an error.
-
-The prescan and/or overscan regions to be used are specified in
-\code{regions}, which is a linked list of \code{psImageRegion}s.  If
-\code{regions} is non-\code{NULL} and \code{overscanAxis} is not
-\code{PS_OVERSCAN_NONE}, then the function shall generate a warning.
+\code{PM_OVERSCAN_NONE} or \code{PM_OVERSCAN_ALL} and the \code{fit}
+is not \code{PM_FIT_NONE}.
+
+If the \code{overscanAxis} is \code{PM_OVERSCAN_ROWS} or
+\code{PM_OVERSCAN_COLUMNS}, then the overscan shall be reduced to a
+single vector (in the specified dimension) using the specified
+statistic (\code{stat}).
 
 The statistic to use in combining multiple pixels in the
@@ -418,4 +175,19 @@
 \code{PS_STAT_ROBUST_MODE}.
 
+If \code{nBin} is positive and less than the dimension
+of the vector, then the vector shall subsequently be binned down into
+\code{nBin} bins, again using the specified statistic (\code{stat}).
+If the overscan is not defined for each row/column, then the function
+shall generate a warning and then interpolate using the provided
+functional form if \code{fit} is not \code{PM_FIT_NONE};
+otherwise, the function shall generate an error.
+
+Following any binning, the vector shall be fit by the functional form
+specified by \code{fit} (see above).  Then the overscan shall be
+subtracted from the image, using values from the fit if \code{fit} is
+not \code{PM_FIT_NONE}; otherwise using values from the overscan vector
+if \code{overscanAxis} is not \code{PM_OVERSCAN_ALL}; otherwise using
+the appropriate statistic applied to all the prescan/overscan pixels.
+
 A bias (or dark) image shall be subtracted pixel-by-pixel from the
 input image if \code{bias} is non-NULL.  Note that the input image,
@@ -426,37 +198,8 @@
 image is too small (i.e., pixels on the input image refer to pixels
 outside the range of the \code{bias} image), the function shall
-generate an error.
-
-
-\subsection{Trim}
-
-Given an input image and region to keep, \code{psPhase2Trim} shall
-trim the input image, \code{in}, leaving only the specified region,
-\code{region}.  The API shall be the following:
-\begin{verbatim}
-psReadout *psPhase2Trim(psReadout *in, const psImageRegion *region);
-\end{verbatim}
-
-Note that the trim shall be performed on the input image in-place, so
-that the input image is modified.
-
-The offset of the input image (\code{in->x0} and \code{in->y0}) shall
-be updated to reflect the trim.
-
-The function shall generate an error if the \code{region} is outside
-the bounds of the input image.
-
-\subsection{PSLib}
-
-The \code{psSpline1D} and \code{psFit} shall be incorporated into
-PSLib.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\section{Preparation for photometry}
-
-The following modules take an image and process it so that counts are
-proportional to the flux from an astronomical source.
+generate an error.  Any pixels masked in the \code{bias} shall also be
+masked in the output.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 \subsection{Non-linearity}
@@ -466,12 +209,11 @@
 the correction.
 
-The first, \code{psPhase2NonLinearityPolynomial} shall correct the
-input image for non-linearity by applying the given polynomial,
+The first, \code{pmNonLinearityPolynomial} shall correct the input
+image for non-linearity by applying the given polynomial,
 \code{coeff}, to the flux of each pixel in the input image, \code{in}.
 The API shall be the following:
 
 \begin{verbatim}
-/** Applies the correction for detector non-linearity. */
-psReadout *psPhase2CorrectNonLinearity(psReadout *in, const psPolynomial1D *coeff);
+psReadout *pmNonLinearityPolynomial(psReadout *in, const psPolynomial1D *coeff);
 \end{verbatim}
 
@@ -479,10 +221,10 @@
 caller, likely from the image metadata.
 
-The second function, \code{psPhase2NonLinearityLookup} shall correct
+The second function, \code{pmNonLinearityLookup} shall correct
 the input image for non-linearity by using a lookup table.  The API
 shall be the following:
 
 \begin{verbatim}
-psReadout *psPhase2NonLinearityLookup(psReadout *in, const psVector *inFlux, const psVector *outFlux);
+psReadout *pmNonLinearityLookup(psReadout *in, const psVector *inFlux, const psVector *outFlux);
 \end{verbatim}
 
@@ -495,15 +237,22 @@
 to be pre-sorted.
 
-Both \code{psPhase2NonLinearityPolynomial} and
-\code{psPhase2NonLinearityLookup} shall modify the input image
-in-place.
+If the particular value of a pixel is not found in the \code{inFlux}
+vector, the corresponding \code{outFlux} shall be calculated through
+linear interpolation.
+
+In the event that the \code{inFlux} vector does not contain two or
+more entries (necessary for linear interpolation), then the function
+shall generate a warning, and make no correction to any of the pixels.
+
+Both \code{pmNonLinearityPolynomial} and \code{pmNonLinearityLookup}
+shall modify the input image in-place.
 
 \subsection{Flat-fielding}
 
-Given an input image and a flat-field image, \code{psPhase2FlatField}
+Given an input image and a flat-field image, \code{pmFlatField}
 shall divide the input image by the flat-field image.  The API shall
 be the following:
 \begin{verbatim}
-psReadout *psPhase2FlatField(psReadout *in, const psImage *flat);
+psReadout *pmFlatField(psReadout *in, const psReadout *flat);
 \end{verbatim}
 
@@ -519,10 +268,77 @@
 
 Pixels which are negative or zero in the \code{flat} shall be masked
-in the input image with the value \code{PS_MASK_FLAT} (see
-\S\ref{sec:maskValues}).
+in the input image with the value \code{PM_MASK_FLAT} (see
+\S\ref{sec:maskValues}).  Negative pixels in the \code{flat} may be
+set to zero so that they are treated identically to zeroes.  And
+pixels masked in the \code{flat} shall be masked in the \code{output}.
 
 The function shall not normalize the \code{flat}; this responsibility
 is left to the caller.  This function is basically equivalent to a
-divide, but with care for the region that is divided.
+divide (with \code{psImageOp}), but with care for the region that is
+divided, checking for negative pixels, and copying of the mask from
+the \code{flat} to the output.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\subsection{Masking}
+
+The following modules mask various defects on an image.
+
+\subsubsection{Mask values}
+\label{sec:maskValues}
+
+We define several mask values for use in the phase 2 processing:
+\begin{verbatim}
+/** Mask values */
+typedef enum {
+    PM_MASK_TRAP,                       ///< The pixel is a charge trap
+    PM_MASK_BADCOL,                     ///< The pixel is a bad column
+    PM_MASK_SAT,                        ///< The pixel is saturated
+    PM_MASK_FLAT,                       ///< The pixel is non-positive in the flat-field
+    PM_MASK_CR_MORPH                    ///< The pixel is determined to be a cosmic ray, from morphology
+} pmMaskValue;
+\end{verbatim}
+
+Of these, masks for the charge traps need to be grown by the extent of
+the OT convolution kernel.  For other pixel types, orthogonal transfer
+of the flux in this pixel will not (necessarily) affect the flux in
+neighbouring pixels.
+
+\subsubsection{Bad pixels}
+
+Given an input image, \code{in}, a bad pixel \code{mask}, a
+corresponding value in the bad pixel mask to mask in the input image,
+\code{maskVal}, a saturation level, and a growing radius,
+\code{pmMaskBadPixels} shall mask in the input image those
+pixels in the bad pixel mask that match the value to mask.  The API
+shall be the following:
+\begin{verbatim}
+psReadout *pmMaskBadPixels(psReadout *in, const psImage *mask, int maskVal, float sat, int grow);
+\end{verbatim}
+
+Note that the input image, \code{in}, is modified in-place.  All
+pixels in the \code{mask} which satisfy the \code{maskVal} shall have
+their corresponding pixels in the input image, \code{in}, along with
+all pixels within the \code{grow} radius masked.  Pixels which have
+flux greater than \code{sat} shall also be masked, but not grown.
+
+Note that the input image, \code{in}, and the \code{mask} need not be
+the same size, since the input image may already have been trimmed
+(following overscan subtraction), but the function shall use the
+offsets in the image (\code{in->x0} and \code{in->y0}) to determine
+the appropriate offsets to obtain the correct pixel on the mask.  In
+the event that the \code{mask} image is too small (i.e., pixels on the
+input image refer to pixels outside the range of the \code{mask}
+image), the function shall generate an error.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\bibliographystyle{plain}
+\bibliography{panstarrs}
+
+\end{document}
+
+
+
+
 
 \subsection{Subtract sky}
@@ -577,59 +393,4 @@
 
 
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\section{Masking}
-
-The following modules mask various defects on an image.
-
-\subsection{Mask values}
-\label{sec:maskValues}
-
-We define several mask values for use in the phase 2 processing:
-\begin{verbatim}
-/** Mask values */
-typedef enum {
-    PS_MASK_TRAP,                       ///< The pixel is a charge trap
-    PS_MASK_BADCOL,                     ///< The pixel is a bad column
-    PS_MASK_SAT,                        ///< The pixel is saturated
-    PS_MASK_FLAT,                       ///< The pixel is non-positive in the flat-field
-    PS_MASK_CR_MORPH                    ///< The pixel is determined to be a cosmic ray, from morphology
-} psMaskValue;
-\end{verbatim}
-
-Of these, masks for the charge traps need to be grown by the
-extent of the OT convolution kernel.  For other pixel types,
-orthogonal transfer of the flux in this pixel will not (necessarily)
-affect the flux in neighbouring pixels
-
-\subsection{Bad pixels}
-
-Given an input image, \code{in}, a bad pixel \code{mask}, a
-corresponding value in the bad pixel mask to mask in the input image,
-\code{maskVal}, a saturation level, and a growing radius,
-\code{psPhase2MaskBadPixels} shall mask in the input image those
-pixels in the bad pixel mask that match the value to mask.  The API
-shall be the following:
-\begin{verbatim}
-psReadout *psPhase2MaskBadPixels(psReadout *in, const psImage *mask, int maskVal, float sat, int grow);
-\end{verbatim}
-
-Note that the input image, \code{in}, is modified in-place.  All
-pixels in the \code{mask} which satisfy the \code{maskVal} shall have
-their corresponding pixels in the input image, \code{in}, along with
-all pixels within the \code{grow} radius masked.  Pixels which have
-flux greater than \code{sat} shall also be masked, but not grown.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\bibliographystyle{plain}
-\bibliography{panstarrs}
-
-\end{document}
-
 \subsection{Cosmic rays}
 
@@ -776,2 +537,52 @@
 not all of which may correspond to legal positions on the input chip,
 \code{in}.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{Read in an FPA}
+
+\TBD{This section on reading in an FPA is all TBD and should not be
+implemented yet.}
+
+Of course, before any image manipulation may occur, the image must be
+read in.  This involves populating the FPA with structures to
+represent the true focal plane.  However, different instruments have
+different focal planes, and the images are written to disk in
+different ways.  We have proposed a configuration file format which
+appears to be able to document the structure of a focal plane and
+specify how the IPP can read the required information from the FITS
+files \tbd{REFERENCE}.
+
+Given an open \code{FILE} pointer to a configuration file,
+\code{config}, and the name of an FPA image, \code{fpaName},
+\code{psFPAGenerate} shall return a \code{psFPA} of the correct
+structure, with all the metadata entries read from the nominated FPA
+image.  Astrometric information shall be initialised to values
+specified by the configuration file.  The API shall be:
+
+\begin{verbatim}
+psFPA *psFPAGenerate(FILE *config, const char *fpaName);
+\end{verbatim}
+
+Once an FPA has been generated, the pixels may all be read in at once,
+or the pixels may be read in a chip, cell or readout at a time.  The
+corresponding APIs are:
+
+\begin{verbatim}
+psFPA *psFPAReadAll(psFPA *in);
+psFPA *psFPAReadChip(psFPA *in, const char *chipName);
+psChip *psChipReadCell(psChip *in, const char *cellName);
+psCell *psCellReadReadout(psCell *in, const char *readoutName);
+\end{verbatim}
+
+Note that reads of a cell or readout do not act upon an FPA, but
+rather a chip and a cell, respectively.  This saves the user from
+specifying the name of the FPA, chip, and cell just to get a readout,
+since this information is already stored in the generated \code{psFPA}
+struct.
+
+\tbd{Writing the output}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
