Index: /trunk/doc/pslib/psLibSDRS.tex
===================================================================
--- /trunk/doc/pslib/psLibSDRS.tex	(revision 9536)
+++ /trunk/doc/pslib/psLibSDRS.tex	(revision 9537)
@@ -1,3 +1,3 @@
-%%% $Id: psLibSDRS.tex,v 1.431 2006-10-13 00:30:38 price Exp $
+%%% $Id: psLibSDRS.tex,v 1.432 2006-10-13 20:46:29 price Exp $
 \documentclass[panstarrs,spec]{panstarrs}
 
@@ -276,5 +276,5 @@
 
 \begin{prototype}
-const char *psLibVersion(void);
+psString psLibVersion(void);
 \end{prototype}
 
@@ -735,20 +735,22 @@
 psMemFreeCallback psMemFreeCallbackSet(psMemFreeCallback func);
 psMemId psMemGetId(void);
+psMemId psMemGetLastId(void);
 \end{prototype}
 %
 The callback functions are called with a pointer to the corresponding
 memory block.  The routines \code{psMemFreeCallbackIDSet} and
-\code{psMemAllocCallbackIDSet} accept the desired ID value and return the
-old value to the user.  The return values of the handlers installed by
-\code{psMemAllocCallbackSet} and \code{psMemFreeCallbackSet} are
-used to increment the values of \code{p_psMemAllocID} and
-\code{p_psMemFreeID} respectively.  For example, a return value of
-\code{0} implies that the value is unchanged; if the value is \code{2}
-the callback will be called again when the memory ID counter has
-increased by two.  This functionality may be useful to check, for
-example, every 100th block allocated.  The function \code{psMemGetId}
-returns the next identification number to be assigned to a memory
-block.  This function can be used to guide the choice of ID set with
-the functions above.
+\code{psMemAllocCallbackIDSet} accept the desired ID value and return
+the old value to the user.  The return values of the handlers
+installed by \code{psMemAllocCallbackSet} and
+\code{psMemFreeCallbackSet} are used to increment the values of
+\code{p_psMemAllocID} and \code{p_psMemFreeID} respectively.  For
+example, a return value of \code{0} implies that the value is
+unchanged; if the value is \code{2} the callback will be called again
+when the memory ID counter has increased by two.  This functionality
+may be useful to check, for example, every 100th block allocated.  The
+function \code{psMemGetId} returns the next identification number to
+be assigned to a memory block, while \code{psMemGetLastId} returns the
+last identification number to be assigned.  These functions can be
+used to guide the choice of ID set with the functions above.
 
 \subsubsection{Memory Tracing and Corruption Checks}
@@ -794,4 +796,16 @@
 argument \code{abort_on_error} is true, \code{psMemCheckCorruption}
 must call \code{psAbort} as soon as memory corruption is detected.
+
+\begin{prototype}
+size_t psMemStats(const bool print, size_t *allocated, size_t *persistent, size_t *freelist);
+\end{prototype}
+
+\code{psMemStats} returns the total amount of memory consumed by
+psLib.  If \code{print} is \code{true}, also prints a summary of the
+memory usage.  If \code{allocated}, \code{persistent} or
+\code{freelist} are non-\code{NULL}, the function returns in those
+variables the amount of memory that's allocated and non-persistent,
+allocated and persistent, or waiting to be recycled, respectively.
+
 
 \subsubsection{Reference Counting}
@@ -818,4 +832,5 @@
 psPtr psMemIncrRefCounter(const psPtr ptr);
 psPtr psMemDecrRefCounter(psPtr ptr);
+psPtr psMemSetRefCounter(psPtr ptr, psReferenceCount count);
 \end{prototype}
 %
@@ -824,6 +839,8 @@
 If \code{vptr} is \code{NULL}, this function must return a value of
 NULL.  The next two functions increment or decrement the reference
-counter, returning the pointer which was passed in. These functions
-must validate the memory pointer by determining the corresponding
+counter, returning the pointer which was passed in.  The final
+function explicitly sets the value of the reference counter (and
+should therefore be used sparingly, if ever!).  These functions must
+validate the memory pointer by determining the corresponding
 \code{psMemBlock.id} and checking for consistency in the internal
 memory block table (the table pointer for \code{psMemBlock.id} must be
@@ -922,18 +939,23 @@
 a string into \code{psAlloc}-ed memory:
 \begin{prototype}
+psString psStringAlloc(long nChar);
 psString psStringCopy(const char *string);
 psString psStringNCopy(const char *string, unsigned int nChar);
 \end{prototype}
 
-\code{psStringCopy} shall perform a deep copy of the \code{string} into
-\code{psAlloc}-ed memory.  \code{psStringNCopy} shall do the same, up to a
-maximum of \code{nChar} characters.  Both copy functions shall ``pass through''
-\code{NULL} values without generating an error.
+\code{psStringAlloc} shall allocate a \code{psString} of length
+\code{nChar}.  \code{psStringCopy} shall perform a deep copy of the
+\code{string} into a new \code{psString}.  \code{psStringNCopy} shall
+do the same, up to a maximum of \code{nChar} characters.  Both copy
+functions shall ``pass through'' \code{NULL} values without generating
+an error.
 
 We also specify two useful functions:
 
 \begin{prototype}
-ssize_t psStringAppend(char **dest, const char *format, ...)
-ssize_t psStringPrepend(char **dest, const char *format, ...)
+ssize_t psStringAppend(char **dest, const char *format, ...);
+ssize_t psStringPrepend(char **dest, const char *format, ...);
+ssize_t psStringAppendV(char **dest, const char *format, va_list va);
+ssize_t psStringPrependV(char **dest, const char *format, va_list va);
 \end{prototype}
 
@@ -943,4 +965,6 @@
 terminator) shall be returned.  \code{psStringPrepend} shall do
 similarly, except it shall prepend to the \code{dest} string.
+\code{psStringAppendV} and \code{psStringPrependV} are the var-args
+versions of these functions.
 
 Other string manipulation functions are listed below.
@@ -948,4 +972,5 @@
 \begin{prototype}
 psList *psStringSplit(const char *string, const char *splitters, bool multipleAreSignificant);
+psArray *psStringSplitArray(const char *string, const char *splitters, bool multipleAreSignificant);
 \end{prototype}
 
@@ -955,4 +980,6 @@
 length should not be included in the output list if
 \code{multipleAreSignificant} is \code{true}.
+\code{psStringSplitArray} does the same, but returns the result as a
+\code{psArray}.
 
 String whitespace from head and tail of string:
@@ -1002,4 +1029,16 @@
 bool psLineAdd(psLine *line, const char *format, ...);
 \end{prototype}
+
+\subsubsection{File Input}
+
+To simplify the process of reading a file, we define:
+\begin{prototype}
+psString psSlurpFD(int fd);
+psString psSlurpFile(FILE *stream);
+\end{prototype}
+
+\code{psSlurpFD} shall read the nominated file descriptor, \code{fd},
+and return the contents as a \code{psString}.  \code{psSlurpFile} does
+similarly, but based on a file \code{stream}.
 
 \subsubsection{Type information}
@@ -1120,4 +1159,5 @@
 bool psMemCheckImage(psPtr ptr);
 bool psMemCheckKernel(psPtr ptr);
+bool psMemCheckLine(psPtr ptr);
 bool psMemCheckList(psPtr ptr);
 bool psMemCheckLookupTable(psPtr ptr);
@@ -1134,4 +1174,5 @@
 bool psMemCheckPolynomial4D(psPtr ptr);
 bool psMemCheckProjection(psPtr ptr);
+bool psMemCheckRegion(psPtr ptr);
 bool psMemCheckScalar(psPtr ptr);
 bool psMemCheckSphere(psPtr ptr);
@@ -1139,4 +1180,5 @@
 bool psMemCheckSpline1D(psPtr ptr);
 bool psMemCheckStats(psPtr ptr);
+bool psMemCheckString(psPtr ptr);
 bool psMemCheckTime(psPtr ptr);
 bool psMemCheckVector(psPtr ptr);
@@ -1351,6 +1393,9 @@
 of the code is compiled.  This can be implemented via macro front-ends
 to private versions of the user APIs.  In addition, a function
-\code{void psTraceReset(void)} will free memory used by \code{psTrace}
-functions, effectively resetting all trace levels to 0.
+\code{psTraceReset} will free memory used by \code{psTrace}
+functions, effectively resetting all trace levels to 0:
+\begin{prototype}
+void psTraceReset(void);
+\end{prototype}
 
 The trace may optionally be written to a file or other output
@@ -1659,5 +1704,5 @@
 \code{psErrorCodeLast} returns the last error code:
 \begin{prototype}
-psErrorCode psErrorCodeLast(void)
+psErrorCode psErrorCodeLast(void);
 \end{prototype}
 
@@ -2027,11 +2072,17 @@
 
 \begin{prototype}
-bool psArrayRemove(psArray *array, const psPtr data);
-\end{prototype}
-
-This function removes all entries of \code{value} in the \code{array},
-reducing the total number of elements of \code{array} as needed.
+bool psArrayRemoveData(psArray *array, const psPtr data);
+\end{prototype}
+
+This function removes all entries of \code{data} in the \code{array},.
 Returns \code{TRUE} if any elements were removed, otherwise
 \code{FALSE}.
+
+\begin{prototype}
+bool psArrayRemoveIndex(psArray *array, long index);
+\end{prototype}
+
+This function removes the \code{array} element at the specified
+\code{index}, returning \code{true} upon success.
 
 \begin{prototype}
@@ -2285,5 +2336,5 @@
 
 \begin{prototype}
-bool psListRemove(psList *list, long location)
+bool psListRemove(psList *list, long location);
 bool psListRemoveData(psList *list, psPtr data);
 \end{prototype}
@@ -2533,5 +2584,6 @@
 psBitSet *psBitSetSet(psBitSet *bitSet, long bit);
 psBitSet* psBitSetClear(psBitSet *bitSet, long bit);
-psBitSet *psBitSetOp(psBitSet *outBitSet, const psBitSet *inBitSet1, const char *operator, const psBitSet *inBitSet2);
+psBitSet *psBitSetOp(psBitSet *outBitSet, const psBitSet *inBitSet1,
+                     const char *operator, const psBitSet *inBitSet2);
 psBitSet *psBitSetNot(psBitSet *outBitSet, const psBitSet *inBitSet);
 bool psBitSetTest(const psBitSet *bitSet, long bit);
@@ -2756,5 +2808,12 @@
 psMetadataItem* psMetadataItemAllocF32(const char* name, const char* comment, psF32 value);
 psMetadataItem* psMetadataItemAllocF64(const char* name, const char* comment, psF64 value);
+psMetadataItem* psMetadataItemAllocS8(const char* name, const char* comment, psS8 value);
+psMetadataItem* psMetadataItemAllocS16(const char* name, const char* comment, psS16 value);
 psMetadataItem* psMetadataItemAllocS32(const char* name, const char* comment, psS32 value);
+psMetadataItem* psMetadataItemAllocS64(const char* name, const char* comment, psS64 value);
+psMetadataItem* psMetadataItemAllocU8(const char* name, const char* comment, psU8 value);
+psMetadataItem* psMetadataItemAllocU16(const char* name, const char* comment, psU16 value);
+psMetadataItem* psMetadataItemAllocU32(const char* name, const char* comment, psU32 value);
+psMetadataItem* psMetadataItemAllocU64(const char* name, const char* comment, psU64 value);
 psMetadataItem* psMetadataItemAllocBool(const char* name, const char* comment, bool value);
 psMetadataItem* psMetadataItemAllocPtr(const char* name, psDataType type, const char* comment, psPtr value);
@@ -2913,4 +2972,6 @@
 are specified:
 \begin{prototype}
+bool psMetadataAddPtr(psMetadata* md, long location, const char* name, psDataType type,
+                      const char* comment, psPtr value);
 bool psMetadataAddStr(psMetadata* md, long location, const char* name, int format,
                       const char* comment, const char* value);
@@ -2923,6 +2984,22 @@
 bool psMetadataAddBool(psMetadata* md, long location, const char* name, int format,
                        const char* comment, bool value);
-bool psMetadataAddPtr(psMetadata* md, long location, const char* name, psDataType type,
-                      const char* comment, psPtr value);
+bool psMetadataAddList(psMetadata* md, long location, const char* name, int format,
+                       const char* comment, psList *value);
+bool psMetadataAddVector(psMetadata* md, long location, const char* name, int format,
+                       const char* comment, psVector *value);
+bool psMetadataAddArray(psMetadata* md, long location, const char* name, int format,
+                       const char* comment, psArray *value);
+bool psMetadataAddImage(psMetadata* md, long location, const char* name, int format,
+                       const char* comment, psImage *value);
+bool psMetadataAddTime(psMetadata* md, long location, const char* name, int format,
+                       const char* comment, psTime *value);
+bool psMetadataAddHash(psMetadata* md, long location, const char* name, int format,
+                       const char* comment, psHash *value);
+bool psMetadataAddLookupTable(psMetadata* md, long location, const char* name, int format,
+                       const char* comment, psLookupTable *value);
+bool psMetadataAddMetadata(psMetadata* md, long location, const char* name, int format,
+                       const char* comment, psMetadata *value);
+bool psMetadataAddUnknown(psMetadata* md, long location, const char* name, int format,
+                       const char* comment, psPtr value);
 \end{prototype}
 
@@ -2955,10 +3032,18 @@
 is set to reflect the success or failure of the lookup.
 \begin{prototype}
-psString psMetadataLookupStr(bool *status, const psMetadata *md, const char *key);
+bool psMetadataLookupBool(bool *status, const psMetadata *md, const char *key);
+psS8  psMetadataLookupS8(bool *status, const psMetadata *md, const char *key);
+psS16 psMetadataLookupS16(bool *status, const psMetadata *md, const char *key);
 psS32 psMetadataLookupS32(bool *status, const psMetadata *md, const char *key);
+psS64 psMetadataLookupS64(bool *status, const psMetadata *md, const char *key);
+psU8  psMetadataLookupU8(bool *status, const psMetadata *md, const char *key);
+psU16 psMetadataLookupU16(bool *status, const psMetadata *md, const char *key);
+psU32 psMetadataLookupU32(bool *status, const psMetadata *md, const char *key);
+psU64 psMetadataLookupU64(bool *status, const psMetadata *md, const char *key);
 psF32 psMetadataLookupF32(bool *status, const psMetadata *md, const char *key);
 psF64 psMetadataLookupF64(bool *status, const psMetadata *md, const char *key);
-bool psMetadataLookupBool(bool *status, const psMetadata *md, const char *key);
 psPtr psMetadataLookupPtr(bool *status, const psMetadata *md, const char *key);
+psString psMetadataLookupStr(bool *status, const psMetadata *md, const char *key);
+psMetadata *psMetadataLookupMetadata(bool *status, const psMetadata *md, const char *key);
 \end{prototype}
 
@@ -3079,6 +3164,8 @@
 
 \begin{prototype}
-psMetadata *psMetadataConfigParse(psMetadata *md, unsigned int *nFail, const char *str, bool overwrite);
-psMetadata *psMetadataConfigRead(psMetadata *md, unsigned int *nFail, const char *filename, bool overwrite);
+psMetadata *psMetadataConfigParse(psMetadata *md, unsigned int *nFail,
+                                  const char *str, bool overwrite);
+psMetadata *psMetadataConfigRead(psMetadata *md, unsigned int *nFail,
+                                 const char *filename, bool overwrite);
 \end{prototype}
 
@@ -3378,8 +3465,6 @@
 The constructor shall be:
 \begin{prototype}
-psLookupTable *psLookupTableAlloc(const char *filename, ///< File from which to read
-                                  const char *format,   ///< scanf-like format string
-                                  long indexCol         ///< Column of the index vector (starting at zero)
-                                  );
+psLookupTable *psLookupTableAlloc(const char *filename, const char *format,
+                                  long indexCol);
 \end{prototype}
 This function shall allocate a \code{psLookupTable}, and set the
@@ -3391,8 +3476,6 @@
 
 \begin{prototype}
-psLookupTable *psLookupTableImport(psLookupTable *table,    ///< Lookup table into which to import
-                                   const psArray *vectors,  ///< Array of vectors
-                                   long indexCol            ///< Index of the index vector in the array of vectors
-                                   );
+psLookupTable *psLookupTableImport(psLookupTable *table, const psArray *vectors,
+                                   long indexCol);
 \end{prototype}
 \code{psLookupTableImport} shall import an array of vectors into a
@@ -3681,6 +3764,12 @@
 the data range starting at \code{lower}, running to \code{upper}, in
 steps of \code{delta}.  The upper-end value is {\em exclusive}; the
-sequence is equivalent to \code{for (x = lower; x < upper; x +=
-  delta)}.
+sequence is equivalent to \code{for (x = lower; x < upper; x += delta)}.
+
+\begin{prototype}
+psString psVectorToString(const psVector *vector);
+\end{prototype}
+
+This function returns a string containing the values in the \code{vector},
+separated by whitespace.  This function is useful for testing and output.
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -3755,10 +3844,5 @@
 
 \begin{prototype}
-psImage* psImageRecycle(
-    psImage* old,                       ///< the psImage to recycle by resizing image buffer
-    int numCols,                        ///< the desired number of columns in image
-    int numRows,                        ///< the desired number of rows in image
-    const psElemType type               ///< the desired datatype of the image
-);
+psImage* psImageRecycle(psImage* old, int numCols, int numRows, const psElemType type);
 \end{prototype}
 \code{psImageRecycle} shall recycle the input \code{old} image, such
@@ -3906,4 +3990,7 @@
 \subsection{XML Functions}
 
+\tbd{The XML code is currently disabled in psLib.  Instead, we use the
+metadata config files as a transport mechanism.}
+
 Within Pan-STARRS, we will use XML documents as a transport mechanism
 to carry data between programs and between IPP and other subsystems.
@@ -4091,5 +4178,6 @@
 
 \begin{prototype}
-psArray *psDBSelectRows(psDB *dbh, const char *tableName, const psMetadata *where, unsigned long long limit);
+psArray *psDBSelectRows(psDB *dbh, const char *tableName, const psMetadata *where,
+                        unsigned long long limit);
 \end{prototype}
 
@@ -4145,5 +4233,6 @@
 
 \begin{prototype}
-long psDBDeleteRows(psDB *dbh, const char *tableName, const psMetadata *where, unsigned long long limit);
+long psDBDeleteRows(psDB *dbh, const char *tableName, const psMetadata *where,
+                    unsigned long long limit);
 \end{prototype}
 
@@ -4154,10 +4243,21 @@
 
 \begin{prototype}
-long psDBLastInsertID(
-    psDB *dbh                          ///< Database handle
-);
+long psDBLastInsertID(psDB *dbh);
 \end{prototype}
 
 Returns the last value created in an ``auto-increment'' field.
+
+
+\begin{prototype}
+psString psDBGenerateWhereConditionSQL(const psMetadata *where, const char *tableName);
+psString psDBGenerateWhereSQL(const psMetadata *where, const char *tableName);
+\end{prototype}
+
+\code{psDBGenerateWhereConditionSQL} shall generate a SQL fragment
+consisting of the \code{WHERE} condition, based on the \code{where}
+metadata format.
+
+\code{psDBGenerateWhereSQL} shall append ``where'' to the front of
+the SQL fragment returned by \code{psDBGenerateWhereConditionSQL}.
 
 
@@ -4170,17 +4270,13 @@
 
 \begin{prototype}
-bool psDBExplicitTrans(
-    psDB *dbh,                          ///< Database handle
-    bool mode                           ///< transactions enable/disable
-);
-\end{prototype}
-
-Enable/Disable explicit transactions.  When enabled \code{psDBCommit()} must
-be called to make changes to the database's state persistent.
-
-\begin{prototype}
-bool psDBTransaction(
-    psDB *dbh                           ///< Database handle
-);
+bool psDBExplicitTrans(psDB *dbh, bool mode);
+\end{prototype}
+
+Enable/Disable explicit transactions (accordinte to \code{mode}).
+When enabled \code{psDBCommit()} must be called to make changes to the
+database's state persistent.
+
+\begin{prototype}
+bool psDBTransaction(psDB *dbh);
 \end{prototype}
 
@@ -4188,7 +4284,5 @@
 
 \begin{prototype}
-bool psDBCommit(
-    psDB *dbh                           ///< Database handle
-);
+bool psDBCommit(psDB *dbh);
 \end{prototype}
 
@@ -4196,7 +4290,5 @@
 
 \begin{prototype}
-bool psDBRollback(
-    psDB *dbh                           ///< Database handle
-);
+bool psDBRollback(psDB *dbh);
 \end{prototype}
 
@@ -4212,10 +4304,6 @@
 
 \begin{prototype}
-long p_psDBRunQueryPrepared(
-    psDB *dbh,                          ///< Database handle
-    const psArray *rowSet,              ///< row data as psArray of psMetadata
-    const char *format,                 ///< SQL string to execute
-    ...
-);
+long p_psDBRunQueryPrepared(psDB *dbh, const psArray *rowSet,
+                            const char *format, ...);
 \end{prototype}
 
@@ -4226,7 +4314,5 @@
 
 \begin{prototype}
-psArray *p_psDBFetchResult(
-    psDB *dbh                          ///< Database handle
-);
+psArray *p_psDBFetchResult(psDB *dbh);
 \end{prototype}
 
@@ -4449,4 +4535,11 @@
 \code{psF32}, \code{psF64}).  The user is expected to convert the data
 type as needed with \code{psImageCopy}.
+
+\begin{prototype}
+psImage *psFitsReadImageBuffer(psImage *output, const psFits *fits,
+                               psRegion region, int z);
+\end{prototype}
+As for \code{psFitsReadImage}, but read into the extant
+\code{output} image.                              
  
 \begin{prototype}
@@ -4502,8 +4595,8 @@
 psArray *psFitsReadImageCube(const psFits *fits, psRegion region);
 bool psFitsUpdateImageCube(psFits *fits, const psArray *input, int x0, int y0);
-bool psFitsWriteImageCube(psFits *fits, psMetadata *header, const psArray
-*input, const char *extname);
-bool psFitsInsertImageCube(psFits *fits, psMetadata *header, const psArray
-*input, const char *extname, bool after);
+bool psFitsWriteImageCube(psFits *fits, psMetadata *header, const psArray *input,
+                          const char *extname);
+bool psFitsInsertImageCube(psFits *fits, psMetadata *header, const psArray *input,
+                           const char *extname, bool after);
 \end{prototype}
 
@@ -4723,9 +4816,6 @@
 
 \begin{prototype}
-psStats *psVectorStats(psStats *stats,
-                       const psVector *in, 
-                       const psVector *errors,
-                       const psVector *mask,
-                       psMaskType maskVal);
+psStats *psVectorStats(psStats *stats, const psVector *in, const psVector *errors,
+                       const psVector *mask, psMaskType maskVal);
 \end{prototype}
 %
@@ -4914,8 +5004,6 @@
 values.  It alters and returns the histogram \code{out} structure.
 \begin{prototype}
-psHistogram *psVectorHistogram(psHistogram *out, 
-                               const psVector *values,
-                               const psVector *errors,
-                               const psVector *mask,
+psHistogram *psVectorHistogram(psHistogram *out, const psVector *values,
+                               const psVector *errors, const psVector *mask,
                                psMaskType maskVal);
 \end{prototype}
@@ -4997,35 +5085,19 @@
 To evaluate the polynomials at specific coordinates, we define:
 \begin{prototype}
-psF64 psPolynomial1DEval(const psPolynomial1D *poly, 
-                         psF64 x);
-psF64 psPolynomial2DEval(const psPolynomial2D *poly, 
-                         psF64 x, 
-                         psF64 y);                
-psF64 psPolynomial3DEval(const psPolynomial3D *poly, 
-                         psF64 x, 
-                         psF64 y, 
-                         psF64 z);                 
-psF64 psPolynomial4DEval(const psPolynomial4D *poly, 
-                         psF64 x, 
-                         psF64 y, 
-                         psF64 z, 
-                         psF64 t);
+psF64 psPolynomial1DEval(const psPolynomial1D *poly, psF64 x);
+psF64 psPolynomial2DEval(const psPolynomial2D *poly, psF64 x, psF64 y);                
+psF64 psPolynomial3DEval(const psPolynomial3D *poly, psF64 x, psF64 y, psF64 z);                 
+psF64 psPolynomial4DEval(const psPolynomial4D *poly, psF64 x, psF64 y, psF64 z, psF64 t);
 \end{prototype}
 
 In the event that several evaluations are required, we also define:
 \begin{prototype}
-psVector *psPolynomial1DEvalVector(const psPolynomial1D *poly, 
-                                   const psVector *x);
-psVector *psPolynomial2DEvalVector(const psPolynomial2D *poly, 
-                                   const psVector *x, 
+psVector *psPolynomial1DEvalVector(const psPolynomial1D *poly, const psVector *x);
+psVector *psPolynomial2DEvalVector(const psPolynomial2D *poly, const psVector *x, 
                                    const psVector *y);
-psVector *psPolynomial3DEvalVector(const psPolynomial3D *poly, 
-                                   const psVector *x, 
-                                   const psVector *y, 
-                                   const psVector *z);
-psVector *psPolynomial4DEvalVector(const psPolynomial4D *poly, 
-                                   const psVector *x, 
-                                   const psVector *y, 
-                                   const psVector *z, 
+psVector *psPolynomial3DEvalVector(const psPolynomial3D *poly, const psVector *x, 
+                                   const psVector *y, const psVector *z);
+psVector *psPolynomial4DEvalVector(const psPolynomial4D *poly, const psVector *x, 
+                                   const psVector *y, const psVector *z, 
                                    const psVector *t);
 \end{prototype}
@@ -5037,4 +5109,45 @@
 evaluation, those coefficients that have the corresponding \code{mask}
 element non-zero shall not be evaluated.
+
+\subsubsubsection{Conversion to Metadata}
+
+In order to facilitate storing polynomials in metadata configuration
+files, we supply functions to convert between polynomials and
+metadata containers.
+
+\begin{prototype}
+psPOlynomial2D *psPolynomial2DfromMetadata(psMetadata *folder);
+psPOlynomial3D *psPolynomial3DfromMetadata(psMetadata *folder);
+psPOlynomial4D *psPolynomial4DfromMetadata(psMetadata *folder);
+psPOlynomial2D *psPolynomial2DtoMetadata(psMetadata *md,
+                                         const psPolynomial2D *poly,
+                                         const char *format, ...);
+psPOlynomial3D *psPolynomial3DtoMetadata(psMetadata *md,
+                                         const psPolynomial3D *poly,
+                                         const char *format, ...);
+psPOlynomial4D *psPolynomial4DtoMetadata(psMetadata *md,
+                                         const psPolynomial4D *poly,
+                                         const char *format, ...);
+\end{prototype}
+
+The \code{psPolynomial?DfromMetadata} functions shall create a
+\code{psMetadata} folder with \code{psPolynomial?D} information.  The
+first two elements of the metadata folder shall specify the order of
+the x and y variables, \code{NORDER_X}, \code{NORDER_Y}, etc.  The
+following elements shall be the values of the coefficients and the
+coefficient errors (i.e., \code{VAL_X00_Y00}, \code{ERR_X00_Y00},
+etc.).  The input polynomial must be of ordinary type and have a valid
+name format.  \code{false} is returned if any inputs are \code{NULL}.
+If a particular mask element is non-zero, that polynomial coefficient
+(and error) are skipped.
+
+The \code{psPolynomial?DtoMetadata} functions shall parse a psMetadata
+container with \code{psPolynomial?D} information.  The first three
+elements of the metadata folder specify the order of the x, y, & z
+variables.  (i.e., \code{NORDER_X}, \code{NORDER_Y}, etc.).  The
+following elements are the values of the coefficients and the
+coefficient errors.  (i.e., \code{VAL_X00_Y00}, \code{ERR_X00_Y00},
+etc.).  If the orders or any coefficients are missing or have
+incorrect syntax, \code{NULL} is returned.
 
 \subsubsection{Splines}
@@ -5193,11 +5306,7 @@
 
 \begin{prototype}
-bool psMinimizeLMChi2(psMinimization *min, 
-                      psImage *covar, 
-                      psVector *params,
-		      psMinConstrain *constrain,
-                      const psArray  *x, 
-                      const psVector *y,
-                      const psVector *yWt, 
+bool psMinimizeLMChi2(psMinimization *min, psImage *covar, psVector *params,
+		      psMinConstrain *constrain, const psArray  *x, 
+                      const psVector *y, const psVector *yWt, 
                       psMinimizeLMChi2Func func);
 \end{prototype}
@@ -5242,10 +5351,7 @@
 
 \begin{prototype}
-bool psMinimizeGaussNewtonDelta(psVector *delta, 
-                                const psVector *params,
-                                const psVector *paramMask, 
-                                const psArray  *x, 
-                                const psVector *y,
-                                const psVector *yErr, 
+bool psMinimizeGaussNewtonDelta(psVector *delta, const psVector *params,
+                                const psVector *paramMask, const psArray  *x, 
+                                const psVector *y, const psVector *yErr, 
                                 psMinimizeLMChi2Func func);
 \end{prototype}
@@ -5275,9 +5381,6 @@
 
 \begin{prototype}
-bool psMinimizePowell(psMinimization *min, 
-                      psVector *params, 
-		      const psVector *paramMask,
-                      const psArray *coords, 
-                      psMinimizePowellFunc func);
+bool psMinimizePowell(psMinimization *min, psVector *params, const psVector *paramMask,
+                      const psArray *coords, psMinimizePowellFunc func);
 \end{prototype}
 
@@ -5296,10 +5399,7 @@
 
 \begin{prototype}
-bool psMinimizeChi2Powell(psMinimization *min, 
-                          psVector *params, 
-			  psMinConstrain *constrain,
-                          const psArray *coords, 
-			  const psVector *value, 
-			  const psVector *error,
+bool psMinimizeChi2Powell(psMinimization *min, psVector *params,
+                          psMinConstrain *constrain, const psArray *coords,
+                          const psVector *value, const psVector *error,
                           psMinimizeChi2PowellFunc model);
 \end{prototype}
@@ -5333,33 +5433,19 @@
 
 \begin{prototype}
-psPolynomial1D *psVectorFitPolynomial1D(psPolynomial1D *poly, 
-                                        const psVector *mask, 
-                                        psMaskType      maskValue,
-                                        const psVector *f,
-                                        const psVector *fErr,
-                                        const psVector *x);
-psPolynomial2D *psVectorFitPolynomial2D(psPolynomial2D *poly, 
-                                        const psVector *mask, 
-                                        psMaskType      maskValue,
-                                        const psVector *f,
-                                        const psVector *fErr,
-                                        const psVector *x, 
+psPolynomial1D *psVectorFitPolynomial1D(psPolynomial1D *poly, const psVector *mask, 
+                                        psMaskType maskValue, const psVector *f,
+                                        const psVector *fErr, const psVector *x);
+psPolynomial2D *psVectorFitPolynomial2D(psPolynomial2D *poly, const psVector *mask, 
+                                        psMaskType maskValue, const psVector *f,
+                                        const psVector *fErr, const psVector *x, 
                                         const psVector *y);
-psPolynomial3D *psVectorFitPolynomial3D(psPolynomial3D *poly, 
-                                        const psVector *mask, 
-                                        psMaskType      maskValue,
-                                        const psVector *f,
-                                        const psVector *fErr,
-                                        const psVector *x, 
-                                        const psVector *y, 
-                                        const psVector *z);
-psPolynomial4D *psVectorFitPolynomial4D(psPolynomial4D *poly, 
-                                        const psVector *mask, 
-                                        psMaskType      maskValue,
-                                        const psVector *f,
-                                        const psVector *fErr,
-                                        const psVector *x, 
-                                        const psVector *y, 
-                                        const psVector *z, 
+psPolynomial3D *psVectorFitPolynomial3D(psPolynomial3D *poly, const psVector *mask, 
+                                        psMaskType maskValue, const psVector *f,
+                                        const psVector *fErr, const psVector *x, 
+                                        const psVector *y, const psVector *z);
+psPolynomial4D *psVectorFitPolynomial4D(psPolynomial4D *poly, const psVector *mask, 
+                                        psMaskType maskValue, const psVector *f,
+                                        const psVector *fErr, const psVector *x, 
+                                        const psVector *y, const psVector *z, 
                                         const psVector *t);
 \end{prototype}
@@ -5380,38 +5466,22 @@
 
 \begin{prototype}
-psPolynomial1D *psVectorClipFitPolynomial1D(psPolynomial1D *poly, 
-                                        psStats            *stats,
-                                        const psVector     *mask, 
-                                        psMaskType          maskValue,
-                                        const psVector     *f,
-                                        const psVector     *fErr,
-                                        const psVector     *x);
-psPolynomial2D *psVectorClipFitPolynomial2D(psPolynomial2D *poly, 
-                                        psStats            *stats,
-                                        const psVector     *mask, 
-                                        psMaskType          maskValue,
-                                        const psVector     *f,
-                                        const psVector     *fErr,
-                                        const psVector     *x, 
-                                        const psVector     *y);
+psPolynomial1D *psVectorClipFitPolynomial1D(psPolynomial1D *poly, psStats *stats,
+                                            const psVector *mask, psMaskType maskValue,
+                                            const psVector *f, const psVector *fErr,
+                                            const psVector *x);
+psPolynomial2D *psVectorClipFitPolynomial2D(psPolynomial2D *poly, psStats *stats,
+                                            const psVector *mask, psMaskType maskValue,
+                                            const psVector *f, const psVector *fErr,
+                                            const psVector *x, const psVector *y);
 psPolynomial3D *psVectorClipFitPolynomial3D(psPolynomial3D *poly, 
-                                        psStats            *stats,
-                                        const psVector     *mask, 
-                                        psMaskType          maskValue,
-                                        const psVector     *f,
-                                        const psVector     *fErr,
-                                        const psVector     *x, 
-                                        const psVector     *y, 
-                                        const psVector     *z);
-psPolynomial4D *psVectorClipFitPolynomial4D(psPolynomial4D *poly, 
-                                        psStats            *stats,
-                                        const psVector     *mask, 
-                                        psMaskType          maskValue,
-                                        const psVector     *f,
-                                        const psVector     *fErr,
-                                        const psVector     *x, 
-                                        const psVector     *y, 
-                                        const psVector     *z, 
-                                        const psVector     *t);
+                                            psStats *stats, const psVector *mask, 
+                                            psMaskType maskValue, const psVector *f,
+                                            const psVector *fErr, const psVector *x, 
+                                            const psVector *y, const psVector *z);
+psPolynomial4D *psVectorClipFitPolynomial4D(psPolynomial4D *poly, psStats *stats,
+                                            const psVector *mask, psMaskType maskValue,
+                                            const psVector *f, const psVector *fErr,
+                                            const psVector *x, const psVector *y, 
+                                            const psVector *z, const psVector *t);
 \end{prototype}
 These functions replicate the capability of the vector fitting
@@ -5443,15 +5513,9 @@
 
 \begin{prototype}
-psPolynomial4D *psVectorChiClipFitPolynomial4D(
-    psPolynomial4D *poly,
-    psStats *stats,
-    const psVector *mask,
-    psMaskType maskValue,
-    const psVector *f,
-    const psVector *fErr,
-    const psVector *x,
-    const psVector *y,
-    const psVector *z,
-    const psVector *t);
+psPolynomial4D *psVectorChiClipFitPolynomial4D(psPolynomial4D *poly, psStats *stats,
+                                               const psVector *mask, psMaskType maskValue,
+                                               const psVector *f, const psVector *fErr,
+                                               const psVector *x, const psVector *y,
+                                               const psVector *z, const psVector *t);
 \end{prototype}
 
@@ -5546,10 +5610,6 @@
 
 \begin{prototype}
-psVector *psImageRow(psVector *out, 
-                     const psImage *input,
-		     int row);
-psVector *psImageCol(psVector *out, 
-                     const psImage *input,
-		     int column);
+psVector *psImageRow(psVector *out, const psImage *input, int row);
+psVector *psImageCol(psVector *out, const psImage *input, int column);
 \end{prototype}
 
@@ -5563,12 +5623,7 @@
 
 \begin{prototype}
-psVector *psImageSlice(psVector *out, 
-                       psPixels *coords,
-                       const psImage *input,
-                       const psImage *mask, 
-                       psMaskType maskVal, 
-                       psRegion region,
-                       psImageCutDirection direction, 
-                       const psStats *stats);
+psVector *psImageSlice(psVector *out, psPixels *coords, const psImage *input,
+                       const psImage *mask, psMaskType maskVal, psRegion region,
+                       psImageCutDirection direction, const psStats *stats);
 \end{prototype}
 Extract pixels from a rectilinear region to a vector (array of
@@ -5600,13 +5655,7 @@
 
 \begin{prototype}
-psVector *psImageCut(psVector *out, 
-                     psVector *cutCols, 
-                     psVector *cutRows, 
-                     const psImage *input, 
-                     const psImage *mask, 
-                     psMaskType maskVal,
-		     psPlane *start,
-		     psPlane *stop,
-                     unsigned int nSamples, 
+psVector *psImageCut(psVector *out, psVector *cutCols, psVector *cutRows, 
+                     const psImage *input, const psImage *mask, psMaskType maskVal,
+		     psPlane *start, psPlane *stop, unsigned int nSamples, 
                      psImageInterpolateMode mode);
 \end{prototype}
@@ -5627,11 +5676,6 @@
 
 \begin{prototype}
-psVector *psImageRadialCut(psVector *out, 
-                           const psImage *input, 
-                           const psImage *mask, 
-                           psMaskType maskVal,
-                           float x, 
-                           float y,
-                           const psVector *radii, 
+psVector *psImageRadialCut(psVector *out, const psImage *input, const psImage *mask, 
+                           psMaskType maskVal, float x, float y, const psVector *radii, 
                            const psStats *stats);
 \end{prototype}
@@ -5680,8 +5724,6 @@
 
 \begin{prototype}
-psImage *psImageRebin(psImage *out, const psImage *in, 
-                      const psImage *mask, 
-                      psMaskType maskVal,
-                      int scale, const psStats *stats);
+psImage *psImageRebin(psImage *out, const psImage *in, const psImage *mask, 
+                      psMaskType maskVal, int scale, const psStats *stats);
 \end{prototype}
 Rebin image to new scale.  A new image is constructed in which the
@@ -5728,6 +5770,6 @@
 
 \begin{prototype}
-psImage *psImageShift(psImage *out, const psImage *input, 
-                      float dx, float dy, double complex exposed, psImageInterpolateMode mode);
+psImage *psImageShift(psImage *out, const psImage *input, float dx, float dy,
+                      double complex exposed, psImageInterpolateMode mode);
 \end{prototype}
 Shift image by an arbitrary number of pixels (\code{dx,dy}) in either
@@ -5752,13 +5794,8 @@
 
 \begin{prototype}
-psImage *psImageTransform(psImage *output, 
-                          psPixels **blankPixels, 
-                          const psImage *input,
-                          const psImage *inputMask, 
-                          psMaskType inputMaskVal, 
-                          const psPlaneTransform *outToIn,
-                          psRegion region, 
-                          const psPixels *pixels, 
-                          psImageInterpolateMode mode,
+psImage *psImageTransform(psImage *output, psPixels **blankPixels, const psImage *input,
+                          const psImage *inputMask, psMaskType inputMaskVal,
+                          const psPlaneTransform *outToIn, psRegion region, 
+                          const psPixels *pixels, psImageInterpolateMode mode,
                           double exposedValue);
 \end{prototype}
@@ -5803,8 +5840,6 @@
 
 \begin{prototype}
-psStats *psImageStats(psStats *stats, 
-                      const psImage *in,
-                      const psImage *mask,
-                      psMaskType maskVal);
+psStats *psImageStats(psStats *stats, const psImage *in,
+                      const psImage *mask, psMaskType maskVal);
 \end{prototype}
 Determine statistics for image (or subimage).  The statistics to be
@@ -5816,8 +5851,6 @@
 
 \begin{prototype}
-psHistogram *psImageHistogram(psHistogram *out, 
-                              const psImage *in,
-                              const psImage *mask, 
-                              psMaskType maskVal);
+psHistogram *psImageHistogram(psHistogram *out, const psImage *in,
+                              const psImage *mask, psMaskType maskVal);
 \end{prototype}
 Construct a histogram from an image (or subimage).  The histogram to
@@ -5870,12 +5903,7 @@
 
 \begin{prototype}
-psStats *psImageBackground(const psImage *image, // Image for which to get the background
-                           const psImage *mask, // Mask image
-                           psMaskType maskValue, // Mask pixels which this mask value
-                           double fmin, // Fraction to return in the lower quartile field (0.25 for LQ)
-                           double fmax, // Fraction to return in the upper quartile field (0.75 for LQ)
-                           long nMax,   // Maximum number of pixels to subsample
-                           psRandom *rng // Random number generator (for pixel selection)
-    );
+psStats *psImageBackground(const psImage *image, const psImage *mask,
+                           psMaskType maskValue, double fmin, double fmax,
+                           long nMax, psRandom *rng);
 \end{prototype}
 \code{psImageBackground} shall measure the median background level for
@@ -6038,5 +6066,6 @@
 
 \begin{prototype}
-psImage *psPixelsToMask(psImage *out, const psPixels *pixels, psRegion region, psMaskType maskVal);
+psImage *psPixelsToMask(psImage *out, const psPixels *pixels, psRegion region,
+                        psMaskType maskVal);
 psPixels *psPixelsFromMask(psPixels *out, const psImage *mask, psMaskType maskVal);
 \end{prototype}
@@ -6213,5 +6242,6 @@
 \begin{prototype}
 psImage *psMatrixLUD(psImage *out, psVector **perm, const psImage *in);
-psVector *psMatrixLUSolve(psVector *out, const psImage *LU, const psVector *RHS, const psVector *perm);
+psVector *psMatrixLUSolve(psVector *out, const psImage *LU, const psVector *RHS,
+                          const psVector *perm);
 \end{prototype}
 The above functions decompose a matrix, \code{in}, into its $LU$
@@ -6229,4 +6259,12 @@
 standard manner.  In order to avoid memory leaks, \code{perm} must be
 \code{NULL} on calling \code{psMatrixLUD}.
+
+\begin{prototype}
+bool psMatrixGJSolve(psImage *A, psVector *b);
+\end{prototype}
+This function solves the matrix equation $Ax = b$ for $x$ using the
+Gauss-Jordan method.  On completion, the input matrix has been
+inverted, and the input vector contains the solution, $x$.  The
+function is specified for data type \code{F64} only.
 
 \begin{prototype}
@@ -6547,5 +6585,6 @@
 image, \code{out}.  The API shall be the following:
 \begin{prototype}
-psImage *psImageConvolve(psImage *out, const psImage *in, const psKernel *kernel, bool direct);
+psImage *psImageConvolve(psImage *out, const psImage *in,
+                         const psKernel *kernel, bool direct);
 \end{prototype}
 
@@ -7201,11 +7240,8 @@
 %
 \begin{prototype}
-psPlane *psPlaneTransformApply(psPlane *out, 
-                               const psPlaneTransform *transform, 
+psPlane *psPlaneTransformApply(psPlane *out, const psPlaneTransform *transform, 
                                const psPlane *coords);
-psPlane *psPlaneDistortApply(psPlane *out, 
-                             const psPlaneDistort *distort, 
-                             const psPlane *coords, 
-                             float mag, float color);
+psPlane *psPlaneDistortApply(psPlane *out, const psPlaneDistort *distort, 
+                             const psPlane *coords, float mag, float color);
 \end{prototype}
 
@@ -7268,5 +7304,6 @@
 
 \begin{prototype}
-psPlane *psPlaneTransformDeriv(psPlane *out, const psPlaneTransform *transformation, const psPlane *coord);
+psPlane *psPlaneTransformDeriv(psPlane *out, const psPlaneTransform *transformation,
+                               const psPlane *coord);
 \end{prototype}
 
@@ -7281,5 +7318,6 @@
 
 \begin{prototype}
-psPixels *psPixelsTransform(psPixels *out, const psPixels *input, const psPlaneTransform *inToOut);
+psPixels *psPixelsTransform(psPixels *out, const psPixels *input,
+                            const psPlaneTransform *inToOut);
 \end{prototype}
 
@@ -7348,4 +7386,10 @@
 not be normalized.
 
+\begin{prototype}
+psSphereRot *psSphereRotConjugate(psSphereRot *out, const psSphereRot *in);
+\end{prototype}
+This function shall return the conjugate of the \code{in} rotation,
+and store it in the \code{out} rotation, if non-\code{NULL}.
+
 Spherical coordinates may be transformed by providing the
 transformation and the coordinate in the input system to
@@ -7354,5 +7398,6 @@
 
 \begin{prototype}
-psSphere *psSphereRotApply(psSphere *out, const psSphereRot *transform, const psSphere *coord);
+psSphere *psSphereRotApply(psSphere *out, const psSphereRot *transform,
+                           const psSphere *coord);
 \end{prototype}
 
@@ -7363,5 +7408,6 @@
 
 \begin{prototype}
-psSphereRot *psSphereRotCombine(psSphereRot *out, const psSphereRot *rot1, const psSphereRot *rot2)
+psSphereRot *psSphereRotCombine(psSphereRot *out, const psSphereRot *rot1,
+                                const psSphereRot *rot2);
 \end{prototype}
 
@@ -7369,5 +7415,5 @@
 
 \begin{prototype}
-psSphereRot *psSphereRotInvert(psSphereRot *rot)
+psSphereRot *psSphereRotInvert(psSphereRot *rot);
 \end{prototype}
 
@@ -7395,13 +7441,8 @@
 
 \begin{prototype}
-psSphere *psSphereGetOffset(const psSphere *position1, 
-                            const psSphere *position2, 
-                            psSphereOffsetMode mode,
-                            psSphereOffsetUnit unit);
-
-psSphere *psSphereSetOffset(const psSphere *position,
-                            const psSphere *offset,
-                            psSphereOffsetMode mode,
-                            psSphereOffsetUnit unit);
+psSphere *psSphereGetOffset(const psSphere *position1, const psSphere *position2, 
+                            psSphereOffsetMode mode, psSphereOffsetUnit unit);
+psSphere *psSphereSetOffset(const psSphere *position, const psSphere *offset,
+                            psSphereOffsetMode mode, psSphereOffsetUnit unit);
 \end{prototype}
 
@@ -7497,5 +7538,6 @@
 observer, represented as a speed and a direction:
 \begin{prototype}
-psSphere *psAberration(psSphere *apparent, const psSphere *actual, const psSphere *direction, double speed);
+psSphere *psAberration(psSphere *apparent, const psSphere *actual,
+                       const psSphere *direction, double speed);
 \end{prototype}
 The \code{actual} and \code{apparent} positions are represented as
@@ -7556,5 +7598,5 @@
 %
 \begin{prototype}
-psEarthPole *psEOC_PrecessionModel(const psTime *time)
+psEarthPole *psEOC_PrecessionModel(const psTime *time);
 \end{prototype}
 %
@@ -7576,5 +7618,5 @@
 generated by providing the polar coordinate to the following function:
 \begin{prototype}
-psSphereRot *psSphereRot_CEOtoGCRS(const psEarthPole *pole)
+psSphereRot *psSphereRot_CEOtoGCRS(const psEarthPole *pole);
 \end{prototype}
 This function constructs the rotation element as described in the ADD (
@@ -7587,5 +7629,5 @@
 The following routine calculates the rotation of the Earth about the CIP:
 \begin{prototype}
-psSphereRot *psSphereRot_TEOtoCEO(const psTime *time, psEarthPole *tidalCorr)
+psSphereRot *psSphereRot_TEOtoCEO(const psTime *time, psEarthPole *tidalCorr);
 \end{prototype}
 The IERS code to create the comparable rotation is embedded in
@@ -7769,7 +7811,9 @@
 The constructor is straight-forward:
 \begin{prototype}
-psProjection *psProjectionAlloc(double R, double D, double Xs, double Ys, psProjectionType type);
-\end{prototype}
-where the units of \code{R} and \code{D} are radians, while \code{Xs} and \code{Ys} are in radians per pixel.
+psProjection *psProjectionAlloc(double R, double D, double Xs, double Ys,
+                                psProjectionType type);
+\end{prototype}
+where the units of \code{R} and \code{D} are radians, while \code{Xs}
+and \code{Ys} are in radians per pixel.
 
 The following functions will project and deproject (respectively)
