IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 15, 2004, 6:50:56 PM (22 years ago)
Author:
eugene
Message:

major edits:

  • psVector defined and used to replace all psFloatArray, etc.
  • moved psImage discussion to follow psVector in data types (only the structure definition and constr/destr were moved, the various image functions remain in math)
  • valid data types for functions operating on psVector, psImage specified
  • cleaned various sections to explain the functions, rather than rely on the corresponding comments.
  • some discussion of threads added
  • some cosmetic work to improve readability
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/pslib/psLibSDRS.tex

    r702 r703  
    1 %%% $Id: psLibSDRS.tex,v 1.44 2004-05-15 02:41:00 price Exp $
     1%%% $Id: psLibSDRS.tex,v 1.45 2004-05-16 04:50:56 eugene Exp $
    22\documentclass[panstarrs]{panstarrs}
    33
     
    9999example, the function which copies an image (of type \code{psImage})
    100100is called \code{psImageCopy()}.
     101
     102%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    101103
    102104\subsection{External Libraries}
     
    129131\subsection{Threads}
    130132
    131 \tbd{discussion of thread safe?}
     133Pan-STARRS does not have a strong requirement for multithreading
     134capability.  The memory management functions, defined below, must be
     135written to be thread-safe. 
    132136
    133137%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    537541    /* No operation if object is NULL */
    538542    if (myType == NULL) {
    539         return;
     543        return;
    540544    }
    541545    /* Only call psFree if reference counter is 1 */
    542546    if (psMemGetRefCounter(myType) == 1) {
    543         psFree(myType);
    544         return;
     547        psFree(myType);
     548        return;
    545549    }
    546550    /* Otherwise, decrement the reference counter only */
     
    12021206\begin{verbatim}
    12031207typedef enum {
    1204     PS_TYPE_S8,                         ///< Character
    1205     PS_TYPE_S16,                        ///< Short integer
    1206     PS_TYPE_S32,                        ///< Integer
    1207     PS_TYPE_S64,                        ///< Long integer
    1208     PS_TYPE_U8,                         ///< Unsigned character
    1209     PS_TYPE_U16,                        ///< Unsigned short integer
    1210     PS_TYPE_U32,                        ///< Unsigned integer
    1211     PS_TYPE_U64,                        ///< Unsigned long integer
    1212     PS_TYPE_F32,                        ///< Floating point
    1213     PS_TYPE_F64,                        ///< Double-precision floating point
    1214     PS_TYPE_C32,                        ///< Complex numbers consisting of floating point
    1215     PS_TYPE_OTHER,                      ///< Something else that's not supported for arithmetic
     1208    PS_TYPE_S8,                         ///< Character
     1209    PS_TYPE_S16,                        ///< Short integer
     1210    PS_TYPE_S32,                        ///< Integer
     1211    PS_TYPE_S64,                        ///< Long integer
     1212    PS_TYPE_U8,                         ///< Unsigned character
     1213    PS_TYPE_U16,                        ///< Unsigned short integer
     1214    PS_TYPE_U32,                        ///< Unsigned integer
     1215    PS_TYPE_U64,                        ///< Unsigned long integer
     1216    PS_TYPE_F32,                        ///< Floating point
     1217    PS_TYPE_F64,                        ///< Double-precision floating point
     1218    PS_TYPE_C32,                        ///< Complex numbers consisting of floating point
     1219    PS_TYPE_OTHER,                      ///< Something else that's not supported for arithmetic
    12161220} psElemType;
    12171221\end{verbatim}
     
    12281232\begin{verbatim}
    12291233typedef struct {
    1230     psType type;                        ///< vector data type and dimension
    1231     const int n;                        ///< size of vector
    1232     const int nalloc;                   ///< data region relative to parent
     1234    psType type;                        ///< vector data type and dimension
     1235    const int n;                        ///< size of vector
     1236    const int nalloc;                   ///< data region relative to parent
    12331237    union {
    1234         psF32 *arr;                     ///< Pointers to floating-point data (default)
    1235         psS8  *arr_S8;                  ///< Pointers to short-integer data
    1236         psS16 *arr_S16;                 ///< Pointers to short-integer data
    1237         psS32 *arr_S32;                 ///< Pointers to integer data
    1238         psS64 *arr_S64;                 ///< Pointers to long-integer data
    1239         psU8  *arr_U18;                 ///< Pointers to unsigned-short-integer data
    1240         psU16 *arr_U16;                 ///< Pointers to unsigned-short-integer data
    1241         psU32 *arr_U32;                 ///< Pointers to unsigned-integer data
    1242         psU64 *arr_U64;                 ///< Pointers to unsigned-long-integer data
    1243         psF32 *arr_F32;                 ///< Pointers to floating-point data
    1244         psF64 *arr_F64;                 ///< Pointers to double-precision data
    1245         psF32 *arr_C32;                 ///< Pointers to complex floating-point data
    1246         void **arr_v;
     1238        psF32 *arr;                     ///< Pointers to floating-point data (default)
     1239        psS8  *arr_S8;                  ///< Pointers to short-integer data
     1240        psS16 *arr_S16;                 ///< Pointers to short-integer data
     1241        psS32 *arr_S32;                 ///< Pointers to integer data
     1242        psS64 *arr_S64;                 ///< Pointers to long-integer data
     1243        psU8  *arr_U18;                 ///< Pointers to unsigned-short-integer data
     1244        psU16 *arr_U16;                 ///< Pointers to unsigned-short-integer data
     1245        psU32 *arr_U32;                 ///< Pointers to unsigned-integer data
     1246        psU64 *arr_U64;                 ///< Pointers to unsigned-long-integer data
     1247        psF32 *arr_F32;                 ///< Pointers to floating-point data
     1248        psF64 *arr_F64;                 ///< Pointers to double-precision data
     1249        psF32 *arr_C32;                 ///< Pointers to complex floating-point data
     1250        void **arr_v;
    12471251    } arr;
    12481252} psVector;
     
    13231327\begin{verbatim}
    13241328typedef struct psImage {
    1325     psType type;                        ///< image data type and dimension
    1326     const int ncols, nrows;             ///< size of image
    1327     const int x0, y0;                   ///< data region relative to parent
     1329    psType type;                        ///< image data type and dimension
     1330    const int ncols, nrows;             ///< size of image
     1331    const int x0, y0;                   ///< data region relative to parent
    13281332    union {
    1329         psF32 **rows;                   ///< Pointers to floating-point data (default)
    1330         psS8  **rows_S8;                ///< Pointers to char data
    1331         psS16 **rows_S16;               ///< Pointers to short-integer data
    1332         psS32 **rows_S32;               ///< Pointers to integer data
    1333         psS64 **rows_S64;               ///< Pointers to long-integer data
    1334         psU8  **rows_U8;                ///< Pointers to unsigned-char data
    1335         psU16 **rows_U16;               ///< Pointers to unsigned-short-integer data
    1336         psU32 **rows_U32;               ///< Pointers to unsigned-integer data
    1337         psU64 **rows_U64;               ///< Pointers to unsigned-long-integer data
    1338         psF32 **rows_F32;               ///< Pointers to floating-point data
    1339         psF64 **rows_F64;               ///< Pointers to double-precision data
    1340         psC32 **rows_C32;               ///< Pointers to complex floating-point data
     1333        psF32 **rows;                   ///< Pointers to floating-point data (default)
     1334        psS8  **rows_S8;                ///< Pointers to char data
     1335        psS16 **rows_S16;               ///< Pointers to short-integer data
     1336        psS32 **rows_S32;               ///< Pointers to integer data
     1337        psS64 **rows_S64;               ///< Pointers to long-integer data
     1338        psU8  **rows_U8;                ///< Pointers to unsigned-char data
     1339        psU16 **rows_U16;               ///< Pointers to unsigned-short-integer data
     1340        psU32 **rows_U32;               ///< Pointers to unsigned-integer data
     1341        psU64 **rows_U64;               ///< Pointers to unsigned-long-integer data
     1342        psF32 **rows_F32;               ///< Pointers to floating-point data
     1343        psF64 **rows_F64;               ///< Pointers to double-precision data
     1344        psC32 **rows_C32;               ///< Pointers to complex floating-point data
    13411345    } rows;
    1342     const struct psImage *parent;       ///< parent, if a subimage
    1343     int Nchildren;                      ///< number of subimages
    1344     struct psImage **children;          ///< children of this region; array of Nchildren pointers
     1346    const struct psImage *parent;       ///< parent, if a subimage
     1347    int Nchildren;                      ///< number of subimages
     1348    struct psImage **children;          ///< children of this region; array of Nchildren pointers
    13451349} psImage;
    13461350\end{verbatim}
     
    16371641array.  Also note that the constructor is passed the number of
    16381642required bits, which implies that \code{ceil(n / 8)} bytes must be
    1639 allocated.
    1640 
    1641 \begin{verbatim}
    1642 /** A bitset of arbitrary length. */
     1643allocated.  The bitset structure is define by:
     1644\begin{verbatim}
    16431645typedef struct {
    16441646    int n;                              ///< Number of chars that form the bitset
     
    16481650
    16491651We also require the corresponding constructor and destructor:
    1650 
    1651 \begin{verbatim}
    1652 /** Constructor */
    1653 psBitset *psBitsetAlloc(int n         ///< Number of bits required
    1654     );
    1655  
    1656 /** Destructor */
    1657 void psBitsetFree(psBitset *restrict myBits ///< bitset to destroy
    1658     );
    1659 \end{verbatim}
     1652\begin{verbatim}
     1653psBitset *psBitsetAlloc(int n);
     1654void psBitsetFree(psBitset *restrict myBits);
     1655\end{verbatim}
     1656where \code{n} is the requested number of bits.
    16601657
    16611658Four basic operations on bitsets are required:
     
    16651662\item \code{OR}, \code{AND} and \code{XOR} two bitsets.
    16661663\end{itemize}
    1667 The corresponding APIs are defined below.
    1668 
    1669 \begin{verbatim}
    1670 /** Set a bitset */
    1671 psBitset *
    1672 psBitsetSet(psBitset *restrict myBits, ///< Input bitset
    1673             int bit                    ///< Bit to set
    1674     );
     1664The corresponding APIs are defined below:
     1665
     1666\begin{verbatim}
     1667psBitset *psBitsetSet(psBitset *restrict myBits, int bit);
     1668psBitset *psBitsetOp(psBitset *outBits,
     1669                     const psBitset *restrict inBits1,
     1670                     char *operator,
     1671                     const psBitset *restrict inBits2);
     1672psBitset *psBitsetNot(psBitset *out, psBitset *in);
     1673int psBitsetTest(const psBitset *restrict checkBits, int bit);
    16751674\end{verbatim}
    16761675
     
    16791678will be modified.
    16801679
    1681 \begin{verbatim}
    1682 /** Check a bitset.  Returns true or false */
    1683 int
    1684 psBitsetTest(const psBitset *restrict checkBits, ///< bitset to check
    1685               int bit                   ///< Bit to check
    1686     );
    1687 \end{verbatim}
    1688 
    1689 \code{psBitsetTest} returns a true value if the specified \code{bit}
    1690 is set; otherwise, it returns a false value.
    1691 
    1692 \begin{verbatim}
    1693 /** apply the given operator to two bitsets */
    1694 psBitset *
    1695 psBitsetOp(psBitset *outBits,         ///< Output bitset or NULL
    1696             const psBitset *restrict inBits1, ///< Input bitset 1
    1697             char *operator,             ///< bitset operator (AND, OR, XOR)
    1698             const psBitset *restrict inBits2 ///< Input bitset 2
    1699     );
    1700 \end{verbatim}
    1701 
    17021680\code{psBitsetOp} returns the \code{psBitset} that is the result of
    17031681performing the specified \code{operator} (one of \code{"AND"},
    17041682\code{"OR"}, or \code{"XOR"}) on \code{inBits1} and \code{inBits2}.
    1705 
    1706 Finally, \code{psBitsetNot} applies a unary \code{NOT} to a bitset:
    1707 
    1708 \begin{verbatim}
    1709 /** Apply unary NOT to a bitset */
    1710 psBitset *
    1711 psBitsetNot(psBitset *out,              ///< Output bitset, or NULL
    1712             psBitset *in                ///< Input bitset to be NOT-ed
    1713     );
    1714 \end{verbatim}
     1683If the output bitset \code{outBits} is \code{NULL}, it is created by
     1684the function.
     1685
     1686\code{psBitsetNot} applies a unary \code{NOT} to a bitset, placing the
     1687answer in the bitset \code{out}, or creating a new bitset if
     1688\code{out} is \code{NULL}.
     1689
     1690Finally, \code{psBitsetTest} returns a true value if the specified
     1691\code{bit} is set; otherwise, it returns a false value.
    17151692
    17161693%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    17211698following function returns the array, sorted from the smallest (i.e.\
    17221699most negative) value in the first element, and the largest (i.e.\ most
    1723 positive) value in the last element.  The input array, \code{myArray},
    1724 may be sorted in-place if it is also specified as the \code{out}
    1725 array.
    1726 
    1727 \begin{verbatim}
    1728 /** Sort an array. Inputs not restrict-ed to allow sort in place */
    1729 psFloatArray *
    1730 psSort(psFloatArray *out,               ///< Sorted array to return. May be NULL
    1731        const psFloatArray *restrict myArray      ///< Array to sort
    1732     );
     1700positive) value in the last element.  The input array, \code{in}, may
     1701be sorted in-place if it is also specified as the \code{out}
     1702array. This function is specified for input types \code{psU8, psU16,
     1703psF32, psF64}.  The input and output vectors must have the same type.
     1704
     1705\begin{verbatim}
     1706psVector *psSort(psVector *out, const psVector *restrict in);
    17331707\end{verbatim}
    17341708
     
    17371711in \code{x}.  In order to facilitate this, we will have a sort
    17381712function return an array containing the indices for the unsorted list
    1739 in the order appropriate for the sorted array:
    1740 
    1741 \begin{verbatim}
    1742 /** Sort an array, along with some other stuff.  Returns an index array */
    1743 psIntArray *
    1744 psSortIndex(psIntArray *restrict out;   ///< Output index array (may be NULL)
    1745             const psFloatArray *restrict myArray ///< Array to sort
    1746     );
    1747 \end{verbatim}
    1748 
    1749 Then the sorted arrays may be accessed in the following manner:
    1750 
     1713in the order appropriate for the sorted array.  The output vector must
     1714be of type \code{psU32}.  This function is specified for input types
     1715\code{psU8, psU16, psF32, psF64}.
     1716
     1717\begin{verbatim}
     1718psVector *psSortIndex(psVector *restrict out; const psVector *restrict in);
     1719\end{verbatim}
     1720
     1721The sorted arrays may be accessed in the following manner:
    17511722\begin{verbatim}
    17521723indexArray = psSortIndex(NULL, x);
    17531724for (int i = 0; i < indexArray.n; i++) {
    1754     doMyFunc(x[indexArray[i]], y[indexArray[i]]);
     1725    doMyFunc(x[indexArray.arr.arr_U32[i]], y[indexArray[i].arr.arr_U32]);
    17551726}
    17561727\end{verbatim}
     
    17881759
    17891760\begin{verbatim}
    1790 /** Do Statistics on an array.  Returns a status value. \ingroup MathGroup */
    1791 psStats *
    1792 psArrayStats(const psFloatArray *restrict myArray, ///< Array to be analysed
    1793              const psIntArray *restrict maskArray, ///< Ignore elements where (maskArray & maskVal) != 0
    1794                                                    ///< May be NULL
    1795              unsigned int maskVal,      ///< Only mask elements with one of these bits set in maskArray
    1796              psStats *stats             ///< stats structure defines stats to be calculated and how
    1797     );
    1798 \end{verbatim}
    1799 %
    1800 This function takes the input data in \code{myArray} (with optional
    1801 masking in \code{maskArray}, so that the user may explicitly reject
    1802 specific entries) and a \code{psStats} structure, which will be
    1803 altered and returned.
     1761psStats *psArrayStats(const psVector *restrict in,
     1762                      const psVector *restrict mask,
     1763                      unsigned int maskVal,
     1764                      psStats *stats);
     1765\end{verbatim}
     1766%
     1767This function takes the input data in \code{in} (with optional masking
     1768in \code{mask}, so that the user may explicitly reject specific
     1769entries) and a \code{psStats} structure, which will be altered and
     1770returned.  The input vector may be of type \code{psU8}, \code{psU16},
     1771\code{psF32}, \code{psF64}; the mask must be of type \code{psU8}.
    18041772
    18051773The \code{psStats} structure is defined with entries for each of the
     
    18141782    double sampleUQ;                    ///< upper quartile of sample
    18151783    double sampleLQ;                    ///< lower quartile of sample
    1816     double robustMean;                  ///< robust mean of array
     1784    double robustMean;                  ///< robust mean of data
    18171785    int    robustMeanNvalues;           ///< number of measurements used for robust mean
    1818     double robustMedian;                ///< robust median of array
     1786    double robustMedian;                ///< robust median of data
    18191787    int    robustMedianNvalues;         ///< number of measurements used for robust median
    1820     double robustMode;                  ///< Robust mode of array
     1788    double robustMode;                  ///< Robust mode of data
    18211789    int    robustModeNvalues;           ///< Number of measurements used for robust mode
    1822     double robustStdev;                 ///< robust standard deviation of array
     1790    double robustStdev;                 ///< robust standard deviation of data
    18231791    double robustUQ;                    ///< robust upper quartile
    18241792    double robustLQ;                    ///< robust lower quartile
     
    18281796    double clipSigma;                   ///< Nsigma used for clipping; user input
    18291797    int    clipIter;                    ///< Number of clipping iterations; user input
    1830     double min;                         ///< minimum data value in array
    1831     double max;                         ///< maximum data value in array
    1832     int    nValues;                     ///< number of data values in array
     1798    double min;                         ///< minimum data value in data
     1799    double max;                         ///< maximum data value in data
     1800    int    nValues;                     ///< number of data values in data
    18331801    psStatsOptions options;             ///< bitmask of calculated values
    18341802} psStats;
     
    18671835
    18681836\begin{verbatim}
    1869 /** Constructor */
    1870 psStats *
    1871 psStatsAlloc(psStatsOptions options     ///< Statistics to measure
    1872     );
    1873 
    1874 /** Destructor */
    1875 void
    1876 psStatsFree(psStats *restrict stats     ///< Stats structure to destroy
    1877     );
    1878 \end{verbatim}
    1879 
     1837psStats *psStatsAlloc(psStatsOptions options);
     1838void psStatsFree(psStats *restrict stats);
     1839\end{verbatim}
    18801840
    18811841\subsubsection{Histograms}
     
    18831843
    18841844We also require to be able to generate histograms, given a list of
    1885 upper and lower bounds for each of the bins.
    1886 
    1887 \begin{verbatim}
    1888 /** Histograms  */
     1845upper and lower bounds for each of the bins.  We define the following
     1846data structure to represent a histogram:
     1847\begin{verbatim}
    18891848typedef struct {
    1890     const psFloatArray *restrict bounds; ///< Bounds for the bins
    1891     psIntArray *nums;                   ///< Number in each of the bins
    1892     const float minVal, maxVal;         ///< Minimum and maximum values
    1893     int minNum, maxNum;                 ///< Number below the minimum and above the maximum
    1894     int uniform;                        ///< Is it a uniform distribution?
     1849    const psVector *restrict bounds;    ///< Bounds for the bins
     1850    psVector *nums;                     ///< Number in each of the bins
     1851    int minNum, maxNum;                 ///< Number below the minimum and above the maximum
     1852    int uniform;                        ///< Is it a uniform distribution?
    18951853} psHistogram;
    18961854\end{verbatim}
     1855In this structure, the vector \code{bounds} specifies the boundaries
     1856of the histogram bins, and must of type \code{psF32}, while
     1857\code{nums} specifies the number of entries in the bin, and must of
     1858type \code{psU32}.  The value of \code{bounds.n} must therefore be 1
     1859greater than than \code{nums.n}.  The two values \code{minNum} and
     1860\code{maxNum} are the number of data values which fell below the lower
     1861limit bound or above the upper limit bound, respectively.
    18971862
    18981863The constructors and destructor follow.  We specify two constructors,
     
    19021867
    19031868\begin{verbatim}
    1904 /** Constructor */
    1905 psHistogram *
    1906 psHistogramAlloc(float lower,           ///< Lower limit for the bins
    1907                  float upper,           ///< Upper limit for the bins
    1908                  int n                  ///< Number of the bins
    1909     );
    1910 \end{verbatim}
    1911 
    1912 \begin{verbatim}
    1913 /** Generic constructor */
    1914 psHistogram *
    1915 psHistogramAllocGeneric(const psFloatArray *restrict bounds, ///< Bounds for the bins
    1916                         float minVal,   ///< Minimum value
    1917                         float maxVal    ///< Maximum value
    1918     );
    1919 \end{verbatim}
    1920 
    1921 \begin{verbatim}
    1922 /** Destructor */
    1923 void
    1924 psHistogramFree(psHistogram *restrict myHist ///< Histogram to destroy
    1925     );
     1869psHistogram *psHistogramAlloc(float lower, float upper, int n);
     1870\end{verbatim}
     1871where \code{lower} specifies the lower bound of the histogram range,
     1872\code{upper} specified the upper bound of the histogram range, and
     1873\code{n} is the number of bins desired across the range.  This
     1874constructor sets the value of \code{uniform} to be true.
     1875
     1876A histogram with a more flexible bin set may be constructed with the
     1877following constructor:
     1878\begin{verbatim}
     1879psHistogram *psHistogramAllocGeneric(const psVector *restrict bounds);
     1880\end{verbatim}
     1881where the \code{psVector *bounds} (of type \code{psF32}) is defined by
     1882the user to specify the boundaries of the histogram bins. This
     1883constructor sets the value of \code{uniform} to be false.
     1884
     1885A histogram is free with the destructor:
     1886\begin{verbatim}
     1887void psHistogramFree(psHistogram *restrict myHist);
    19261888\end{verbatim}
    19271889
    19281890The following function populates the histogram bins from the specified
    1929 array (\code{myArray}), the number of entries less than \code{minVal}
    1930 (\code{minNum}), and the number of entries greater than \code{maxVal}
    1931 (\code{maxNum}).  It alters and returns the \code{psHistogram}
    1932 structure.
    1933 
    1934 \begin{verbatim}
    1935 /** Calculate a histogram \ingroup MathGroup **/
    1936 psHistogram *
    1937 psGetArrayHistogram(psHistogram *restrict myHist, ///< Histogram data
    1938                     const psFloatArray *restrict myArray ///< Array to analyse
    1939     );
    1940 \end{verbatim}
     1891vector (\code{in}).  It alters and returns the histogram \code{out}
     1892structure. 
     1893\begin{verbatim}
     1894psHistogram *psHistogramVector(psHistogram *restrict out, const psVector *restrict in);
     1895\end{verbatim}
     1896The input vector may be of types \code{psU8, psU16, psF32, psF64}.
    19411897
    19421898%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    19471903(\S\ref{sec:arithmetic}), we also require the ability to perform basic
    19481904linear algebra on matrices, in order to solve equations.  We use
    1949 \code{psImage} as a matrix, since it has the correct form; similarly,
    1950 we define a vector, \code{psVector} to be an array of floating-point
    1951 numbers, \code{psFloatArray}.  We define the following basic matrix
    1952 operations:
     1905\code{psImage} as a matrix, since it has the correct form.  We define
     1906the following basic matrix operations:
    19531907\begin{itemize}
    19541908\item $LU$ Decompose a matrix, and solve for $x$ in $Ax = b$;
     
    19631917
    19641918\begin{verbatim}
    1965 /** LU Decomposition of a matrix */
    1966 psImage *
    1967 psMatrixLUD(psImage *out,               ///< Matrix to return, or NULL
    1968             psImage *myMatrix           ///< Matrix to decompose
    1969             );
    1970 
    1971 /** LU Solution.  Solves for and returns x in the equation Ax = b */
    1972 psVector *
    1973 psMatrixLUSolve(psVector *out,          ///< Vector to return, or NULL
    1974                 const psImage *luMatrix, ///< LU-decomposed matrix
    1975                 const psVector *rhsVector ///< right-hand-side of the equation
    1976                 );
    1977 \end{verbatim}
    1978 
    1979 The above functions decompose a matrix, \code{myMatrix}, into its $LU$
     1919psImage *psMatrixLUD(psImage *out, psImage *in);
     1920psVector *psMatrixLUSolve(psVector *out, const psImage *LU, const psVector *RHS);
     1921\end{verbatim}
     1922The above functions decompose a matrix, \code{in}, into its $LU$
    19801923representation (\code{psMatrixLUD}, which returns the decomposed
    19811924matrix), and uses the decomposed matrix to solve for $x$ in the
    19821925equation $Ax = b$.  In this case, the $LU$ decomposed matrix $A$ is
    1983 specified as \code{luMatrix}, and $b$ is \code{rhsVector}; the
    1984 solution for $x$ is returned.
    1985 
    1986 \begin{verbatim}
    1987 /** Invert matrix.  Not using restrict, to allow inversion to be done in-place */
    1988 psImage *
    1989 psMatrixInvert(psImage *out,           ///< Matrix to return, or NULL
    1990                const psImage *myMatrix, ///< Matrix to be inverted
    1991                float *restrict determinant ///< Determinant to return, or NULL
    1992     );
    1993 \end{verbatim}
    1994 
     1926specified as \code{LU}, and $b$ is \code{RHS}; the solution vector for
     1927$x$ is returned.  These functions are specified for data types
     1928\code{psF32, psF64}.  The output and input vectors and images must all
     1929have the same data type.
     1930
     1931\begin{verbatim}
     1932psImage *psMatrixInvert(psImage *out, const psImage *in, float *restrict determinant);
     1933\end{verbatim}
    19951934\code{psMatrixInvert} returns the inverse of the specified matrix
    1996 (\code{myMatrix}), along with the \code{determinant}, if non-NULL.
     1935(\code{in}), along with the \code{determinant}, if the \code{float}
     1936pointer is non-NULL.  The input and output images must have the same
     1937type.  This function is specified for data types \code{psF32, psF64}.
    19971938
    19981939The matrix determinant may be calculated using
    19991940\code{psMatrixDeterminant}, which simply returns the determinant for
    2000 the specified matrix, \code{myMatrix}.
    2001 
    2002 \begin{verbatim}
    2003 /** Matrix determinant */
    2004 float
    2005 psMatrixDeterminant(const psImage *restrict myMatrix //!< Matrix to get determinant for
    2006                     );
     1941the specified matrix, \code{in}.  This function is specified for data
     1942types \code{psF32, psF64}.
     1943\begin{verbatim}
     1944float psMatrixDeterminant(const psImage *restrict in);
    20071945\end{verbatim}
    20081946
     
    20141952\code{psMatrixOp} are identical to that for \code{psBinaryOp} (since
    20151953that is how matrix addition is defined).  Matrix division is not
    2016 defined.
    2017 
    2018 \begin{verbatim}
    2019 /** Matrix operations */
    2020 psImage *
    2021 psMatrixOp(psImage *out,               ///< Matrix to return, or NULL
    2022            const psImage *matrix1,     ///< Matrix 1
    2023            const char *op,              ///< Operation to perform: "+", "-", "*"
    2024            const psImage *matrix2      ///< Matrix 2
    2025            );
    2026 \end{verbatim}
    2027 
    2028 The transpose of an input matrix, \code{myMatrix}, is returned by
    2029 \code{psMatrixTranspose}.
    2030 
    2031 \begin{verbatim}
    2032 /** Transpose Matrix */
    2033 psImage *
    2034 psMatrixTranspose(psImage *out,        ///< Matrix to return, or NULL
    2035                   const psImage *myMatrix ///< Matrix to transpose
    2036                   );
    2037 \end{verbatim}
    2038 
    2039 Eigenvectors of a matrix are calculated by \code{psMatrixEigenvectors}:
    2040 
    2041 \begin{verbatim}
    2042 /** Eigenvectors of a matrix */
    2043 psVector *
    2044 psMatrixEigenvectors(psImage *myMatrix  ///< Matrix to get eigenvectors for
    2045     );
     1954defined.  \tbd{why specify addition as an operator? why not only
     1955define operators which are different for matrices?}.  This function is
     1956specified for data types \code{psF32, psF64}.
     1957
     1958\begin{verbatim}
     1959psImage *psMatrixOp(psImage *out, const psImage *in1, const char *op, const psImage *in2);
     1960\end{verbatim}
     1961
     1962The transpose of an input matrix, \code{in}, is returned by
     1963\code{psMatrixTranspose}, optionally into the provided matrix
     1964\code{out}.  This function is specified for data types \code{psF32,psF64}.
     1965\begin{verbatim}
     1966psImage *psMatrixTranspose(psImage *out, const psImage *in);
     1967\end{verbatim}
     1968
     1969Eigenvectors of a matrix are calculated by
     1970\code{psMatrixEigenvectors}.  This function is specified for data
     1971types \code{psF32, psF64}.  Input and output data types should match.
     1972\begin{verbatim}
     1973psVector *psMatrixEigenvectors(psImage *in);
    20461974\end{verbatim}
    20471975
    20481976Finally, we specify two functions to convert between matrices and
    2049 vectors.  This allows the use of vectors in matrix arithmetic, since
    2050 a vector can be converted to a matrix, utilised, and the result can
    2051 be converted back to a vector if required.
    2052 
    2053 \begin{verbatim}
    2054 /** Convert matrix to vector.  Intended for a 1-d matrix. */
    2055 psVector *
    2056 psMatrixToVector(psVector *out,         ///< Vector to return, or NULL
    2057                  psImage *myMatrix      ///< Matrix to convert
    2058     );
    2059 
    2060 /** Convert vector to matrix. */
    2061 psImage *
    2062 psVectorToMatrix(psImage *out,          //!< Matrix to return, or NULL
    2063                  psVector *myVector     //!< Vector to convert
    2064     );
    2065 \end{verbatim}
    2066 
     1977vectors.  This allows the use of vectors in matrix arithmetic, since a
     1978vector can be converted to a matrix, utilised, and the result can be
     1979converted back to a vector if required.  This function is specified
     1980for data types \code{psF32, psF64}.  Input and output data types
     1981should match.
     1982\begin{verbatim}
     1983psVector *psMatrixToVector(psVector *out, psImage *in);
     1984psImage *psVectorToMatrix(psImage *out, psVector *in);
     1985\end{verbatim}
    20671986
    20681987%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    20711990
    20721991We require the ability to calculate the (fast) fourier transforms of
    2073 floating-point two-dimensional images and one-dimensional arrays.  We
     1992floating-point one-dimensional vectors and two-dimensional images.  We
    20741993expect that these will be implemented through wrapping an external
    2075 library.
    2076 
    2077 The forward and reverse Fourier transforms may be calculated using the
    2078 following APIs:
    2079 
    2080 \begin{verbatim}
    2081 /** Forward FFT an image.  Returns a complex float image. */
    2082 psImage *
    2083 psImageFFT(const psImage *image         ///< Image to transform
    2084     );
    2085 
    2086 /** Forward FFT an array of floating-point numbers. */
    2087 psFloatArray *
    2088 psFloatArrayFFT(const psFloatArray *arr ///< Array to transform
    2089     );
    2090 
    2091 /** Inverse FFT an image. */
    2092 psImage *
    2093 psImageInverseFFT(const psImage *fftImage ///< FFT-ed image to inverse-transform
    2094     );
    2095 
    2096 /** Inverse FFT an array of complex floating-point numbers */
    2097 psComplexArray *
    2098 psComplexArrayInverseFFT(const psComplexArray *fftArray ///< FFT-ed array to inverse-transform
    2099     );
    2100 \end{verbatim}
    2101 
    2102 Neither the forward or inverse transforms shall multiply by $1/N$ (or
    2103 $1/N^{1/2}$), and so it falls to the responsibility of the user to
    2104 multiply an image that has been forward- and reverse-transformed by
    2105 $1/N$.
    2106 
    2107 The \code{psImage}s output by \code{psImageFFT} and
    2108 \code{psImageInverseFFT} should be of complex floating-point type.  Following
    2109 an inverse transform, therefore, the user will likely want to extract the
    2110 real parts:
    2111 
    2112 \begin{verbatim}
    2113 /** Get the real part of an image */
    2114 psImage *
    2115 psImageReal(psImage *out,               ///< Image for output (or NULL)
    2116             const psImage *in           ///< Image to get the real part of
    2117             );
    2118 
    2119 /** Get the real part of an array of complex floating-point numbers */
    2120 psFloatArray *
    2121 psComplexArrayReal(psFloatArray *out,   ///< Array for output (or NULL)
    2122                    const psComplexArray *in ///< Array to get the real part of
    2123     );
    2124 \end{verbatim}
    2125 
    2126 To aid operations on FFT-ed images or arrays, we also specify
    2127 functions to return the complex conjugate of an image or array:
    2128 
    2129 \begin{verbatim}
    2130 /** Get the complex conjugate of an image */
    2131 psImage *
    2132 psImageConjugate(psImage *out,          ///< Image for output (or NULL)
    2133                  const psImage *in      ///< Image to get the complex conjugate of
    2134     );
    2135 
    2136 /** Get the complex conjugate of an array of complex floating-point numbers */
    2137 psComplexArray *
    2138 psComplexArrayConjugate(psComplexArray *out, ///< Array for output (or NULL)
    2139                         const psComplexArray *in ///< Array to get the complex conjugate of
    2140     );
    2141 \end{verbatim}
    2142 
    2143 Finally, the power spectrum may be calculated directly from the
    2144 original image or array:
    2145 
    2146 \begin{verbatim}
    2147 /** Calculate power spectrum of an image */
    2148 psImage *
    2149 psImagePowerSpectrum(const psImage *image ///< Image to obtain power spectrum of
    2150     );
    2151 
    2152 /** Calculate power spectrum of an array of floating-point numbers */
    2153 psFloatArray *
    2154 psFloatArrayPowerSpectrum(const psFloatArray *arr ///< Array to obtain power spectrum of
    2155     );
     1994library.  We define the following APIs to support FFT operations on vectors:
     1995
     1996\begin{verbatim}
     1997psVector *psVectorFFT(const psVector *in, int direction);
     1998psVector *psVectorReal(psVector *out, const psVector *in);
     1999psVector *psVectorImaginary(psVector *out, const psVector *in);
     2000psVector *psVectorComplex(psVector *real, psVector *imag);
     2001psVector *psVectorConjugate(psVector *out, const psVector *in);
     2002psVector *psVectorPowerSpectrum(const psVector *in);
     2003\end{verbatim}
     2004
     2005The forward and reverse FFT is calculated using \code{psVectorFFT},
     2006which takes as input the vector of interest (\code{in}) and the
     2007direction (\code{direction}; 1 is forward, -1 is reverse).  The input
     2008vector may be of type \code{psF32} or \code{psC32}, the result is
     2009always \code{psC32}.  If the input vector is \code{psF32}, the
     2010direction must be forward.  Neither the forward or inverse transforms
     2011shall multiply by $1/N$ (or $1/N^{1/2}$), and so it falls to the
     2012responsibility of the user to multiply a vector that has been forward-
     2013and reverse-transformed by $1/N$.
     2014
     2015Conversions between complex and real vectors requires the functions
     2016\code{psVectorReal}, which returns the real part (\code{psF32}) of the
     2017complex vector \code{in}, \code{psVectorImaginary}, which returns the
     2018the magnitude of the imaginary part (\code{psF32}) of the complex
     2019vector \code{in}, and \code{psVectorComplex}, which constructs a
     2020complex vector (\code{psC32}) from the real and imaginary components
     2021\code{real} and \code{imag}, both of type \code{psF32}.
     2022
     2023We also specify the additional utility functions
     2024\code{psVectorConjuagte} and \code{psVectorPowerSpectrum} which
     2025construct the complex conjugate (\code{psC32}) and the magnitude
     2026(\code{psF32}) vectors of the input complex vector (\code{psC32}).
     2027
     2028In analogy with the vector FFT operations, we also define matching
     2029image operations as follows:
     2030\begin{verbatim}
     2031psImage *psImageFFT(const psImage *image, int direction);
     2032psImage *psImagePowerSpectrum(const psImage *image);
     2033psImage *psImageReal(psImage *out, const psImage *in);
     2034psImage *psImageReal(psImage *out, const psImage *in);
     2035psImage *psImageReal(psImage *out, const psImage *in);
     2036psImage *psImageConjugate(psImage *out, const psImage *in);
    21562037\end{verbatim}
    21572038
     
    21612042
    21622043We require two types of general functions which will be used in fitting:
    2163 Gaussians and Polynomials.  The Gaussian is easily defined:
    2164 
    2165 \begin{verbatim}
    2166 /** Evaluate a non-normalized Gaussian with the given mean and sigma at the given coordianate.  Note that this
    2167  *  is not a Gaussian deviate.  The evaluated Gaussian is:
    2168  *  \f[ 1/(\sqrt(2\pi)\sigma) exp(-\frac{(x-mean)^2}{2\sigma^2}) \f]
    2169  */
    2170 float
    2171 psGaussian(float x,                     ///< Value at which to evaluate
    2172            float mean,                  ///< Mean for the Gaussian
    2173            float stddev                 ///< Standard deviation for the Gaussian
    2174            );
    2175 \end{verbatim}
     2044Gaussians and Polynomials.  The Gaussian is defined as:
     2045\begin{verbatim}
     2046float psGaussian(float x, float mean, float stdev);
     2047\end{verbatim}
     2048
     2049which evaluates a non-normalized Gaussian with the given mean and
     2050sigma at the given coordianate.  Note that this is not a Gaussian
     2051deviate.  The evaluated Gaussian is:
     2052
     2053\[ 1/(\sqrt(2\pi)\sigma) exp(-\frac{(x-mean)^2}{2\sigma^2}) \]
    21762054
    21772055For the polynomial, \PS{} astrometry requirements lead us to specify
     
    22322110The constructor and destructor are:
    22332111\begin{verbatim}
    2234 psDPolynomial2D *psDPolynomial2DAlloc(int nX, int nY ///< Number of terms in x and y
    2235     );
    2236 void psDPolynomial2DFree(psDPolynomial2D *restrict myPoly ///< Polynomial to destroy
    2237     );
    2238 \end{verbatim}
    2239 
    2240 And the polynomials may be evaluated, returning the value of the
    2241 polynomial at the specified coordinates:
    2242 
    2243 \begin{verbatim}
    2244 /** Evaluate 2D polynomial (double precision) */
    2245 double
    2246 psEvalDPolynomial2D(double x,           ///< Value x at which to evaluate
    2247                     double y,           ///< Value y at which to evaluate
    2248                     const psDPolynomial2D *restrict myPoly ///< Coefficients for the polynomial
    2249                     );
     2112psDPolynomial2D *psDPolynomial2DAlloc(int nX, int nY);
     2113void psDPolynomial2DFree(psDPolynomial2D *restrict myPoly);
     2114\end{verbatim}
     2115where \code{nX} and \code{nY} are the number of terms in x and y
     2116respectively.
     2117
     2118To evaluate the polynomials at specific coordinates, we define:
     2119\begin{verbatim}
     2120double psEvalDPolynomial2D(double x, double y, const psDPolynomial2D *restrict myPoly);
    22502121\end{verbatim}
    22512122
     
    22552126
    22562127\subsection{Minimization and fitting routines}
     2128
     2129\tbd{I am concerned the minimization functions defined here are
     2130  missing details - gene}
    22572131
    22582132We require a general minimization routine, a routine that will
    22592133specifically minimize $\chi^2$ given a list of data with associated
    22602134errors, and a function that will analytically determine the best
    2261 polynomial fit by minimizing $\chi^2$.  The APIs are:
    2262 
    2263 \begin{verbatim}
    2264 /** Find the minimum of a particular non-linear function */
    2265 psFloatArray *
    2266 psMinimize(psFloatArray *restrict initialGuess, ///< Initial guess and answer
    2267            float (*myFunction)(const psFloatArray *restrict), ///< Function to minimize
    2268            float (*myFuncDeriv)(const psFloatArray *restrict), ///< Derivatives of function, or NULL
    2269            const psIntArray *restrict paramMask //!< 1 = fit for parameter, 0 = hold parameter constant
    2270            );
    2271 \end{verbatim}
    2272 
    2273 \code{psMinimize} determines and returns the parameters that minimizes
    2274 the specified function.  It takes as input a function,
    2275 \code{myFunction}, an initial guess for the parameters that minimize
    2276 the function, \code{initialGuess} which is returned with the best-fit
    2277 parameters, and an optional mask for the parameters to minimize,
    2278 \code{paramMask} (all parameters are fit if \code{NULL}).
    2279 
    2280 \begin{verbatim}
    2281 /** Minimize chi^2 for input data */
    2282 psFloatArray *
    2283 psMinimizeChi2(psFloatArray *restrict initialGuess, ///< Initial guess and answer
    2284                float (*evalModel)(const psFloatArray *restrict,
    2285                                   const psFloatArray *restrict), ///< Model to fit; (domain and params)
    2286                const psFloatArray *restrict domain, ///< The domain values for the corresponding measurements
    2287                const psFloatArray *restrict data, ///< Data to fit
    2288                const psFloatArray *restrict errors, ///< Errors in the data
    2289                const psIntArray *restrict paramMask ///< 1 = fit for parameter, 0 = hold parameter constant
    2290     );
    2291 \end{verbatim}
    2292 
     2135polynomial fit by minimizing $\chi^2$. 
     2136
     2137First, we define \code{psMinimize}, which returns the vector which
     2138minimizes the specified function, which is itself a function of a
     2139single vector.  The returned vector must be the same length as the
     2140vector argument to the input function. 
     2141\begin{verbatim}
     2142psVector *psMinimize(psVector *restrict initialGuess,
     2143                     float (*myFunction)(const psVector *restrict),
     2144                     float (*myFuncDeriv)(const psVector *restrict),
     2145                     const psVector *restrict paramMask);
     2146\end{verbatim}
     2147
     2148\code{psMinimize} determines and returns the vector that minimizes the
     2149specified function.  It takes as input a function, \code{myFunction},
     2150an initial guess for the vector that minimizes the function,
     2151\code{initialGuess}, and an optional mask for the vector elements
     2152(function parameters) to minimize, \code{paramMask} (all parameters
     2153are fit if \code{NULL}).  Note that \code{paramMask} must be of type
     2154\code{psU8}, while \tbd{what are valid types for the function
     2155parameter lists?}.  The optional function, \code{myFuncDeriv} returns
     2156the derivative of the function.  \tbd{is this sufficient? clear?}
     2157
     2158\begin{verbatim}
     2159psVector *psMinimizeChi2(psVector *restrict initialGuess,
     2160                         float (*evalModel)(const psVector *restrict, const psVector *restrict),
     2161                         const psVector *restrict domain,
     2162                         const psVector *restrict data,
     2163                         const psVector *restrict errors,
     2164                         const psVector *restrict paramMask);
     2165\end{verbatim}
    22932166\code{psMinimizeChi2} fits a model to observations by minimizing
    22942167$\chi^2$, returing the best-fit parameters.  The input parameters are
     
    22972170\code{data}, and \code{errors}); an initial guess at the best-fit
    22982171parameters, \code{initialGuess} which is returned with the best-fit
    2299 parameters, and an optional mask specifying which parameters are to be
    2300 fit, \code{paramMask} (all parameters are fit if \code{NULL}).
    2301 
    2302 \begin{verbatim}
    2303 /** Derive a polynomial fit by chi^2 minimisation --- can be done analytically */
    2304 psPolynomial1D *
    2305 psGetArrayPolynomial(psPolynomial1D myPoly, ///< Polynomial to fit
    2306                      const psFloatArray *restrict x, ///< Ordinates (or NULL to just use the indices)
    2307                      const psFloatArray *restrict y, ///< Coordinates
    2308                      const psFloatArray *restrict yErr ///< Errors in coordinates, or NULL
    2309     );
    2310 \end{verbatim}
    2311 
    2312 \code{psGetArrayPolynomial} calculates analytically and returns the
    2313 polynomial that best fits the observations.  The input parameters are
    2314 a polynomial that specifies the fit order, \code{myPoly}, which will
    2315 be altered and returned with the best-fit coefficients; and the
    2316 observations, \code{x}, \code{y} and \code{yErr}.
    2317 
    2318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    2319 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     2172parameters \tbd{how? unclear!}, and an optional mask specifying which
     2173parameters are to be fit, \code{paramMask}, which must be of type
     2174\code{psU8}.  All parameters are fit if this vector is \code{NULL}.
     2175
     2176\begin{verbatim}
     2177psPolynomial1D *psGetArrayPolynomial(psPolynomial1D myPoly,
     2178                                     const psVector *restrict x,
     2179                                     const psVector *restrict y,
     2180                                     const psVector *restrict yErr);
     2181\end{verbatim}
     2182\code{psGetArrayPolynomial} returns the polynomial that best fits the
     2183observations.  The input parameters are a polynomial that specifies
     2184the fit order, \code{myPoly}, which will be altered and returned with
     2185the best-fit coefficients; and the observations, \code{x}, \code{y}
     2186and \code{yErr}.  The independent variable list, \code{x} may be
     2187\code{NULL}, in which case the vector index is used.  The dependent
     2188variable error, \code{yErr} may be null, in which case the solution is
     2189determined in the assumption that all data errors are equal.
     2190\tbd{valid types?}
     2191
    23202192%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    23212193
     
    23392211starting pixel of the subraster.  The entire subraster must be
    23402212contained within the raster of the parent image.  Note that the
    2341 \code{refCounter} for the parent should be incremented.
     2213\code{refCounter} for the parent should be incremented.  This function
     2214must be defined for the following types: \code{psU8}, \code{psU16},
     2215\code{psS8}, \code{psS16}, \code{psF32}, \code{psF64}, \code{psC32},
     2216\code{psC64}.
    23422217
    23432218Create a copy of the specified image, converting the type in the
     
    23452220in the specified structure.  The output image data must be allocated
    23462221as a single, contiguous block of memory.  The output image may not be
    2347 the input image.
     2222the input image.  This function must be defined for the following
     2223types: \code{psU8}, \code{psU16}, \code{psS8}, \code{psS16},
     2224\code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
    23482225\begin{verbatim}
    23492226psImage *psImageCopy(psImage *output, const psImage *input, psElemType type);
     
    23592236is derived from the statistics of the pixels at that direction
    23602237coordinate.  The statistic used to derive the output vector value is
    2361 specified by \code{stats}.
    2362 \begin{verbatim}
    2363 psFloatArray *psImageSlice(psFloatArray *out, const psImage *input, int x, int y, int nx, int ny,
     2238specified by \code{stats}.  This function must be defined for the
     2239following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
     2240\begin{verbatim}
     2241psVector *psImageSlice(psVector *out, const psImage *input, int x, int y, int nx, int ny,
    23642242                           int direction, const psStats *stats);
    23652243\end{verbatim}
     
    23732251statistics of the pixels interpolated along the perpendicular
    23742252direction.  The statistic used to derive the output vector value is
    2375 specified by \code{stats}.
    2376 \begin{verbatim}
    2377 psFloatArray *psImageCut(psFloatArray *out, const psImage *input, float xs, float ys, float xe, float ye,
     2253specified by \code{stats}.  This function must be defined for the
     2254following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}
     2255\begin{verbatim}
     2256psVector *psImageCut(psVector *out, const psImage *input, float xs, float ys, float xe, float ye,
    23782257                         float dw, const psStats *stats);
    23792258\end{verbatim}
     
    23842263the image pixel coordinate \code{x,y}, and have width \code{dr}.  The
    23852264number of annuli is $radius / dr$.  The statistic used to derive the
    2386 output vector value is specified by \code{stats}
    2387 \begin{verbatim}
    2388 psFloatArray *psImageRadialCut(psFloatArray *out, const psImage *input, float x, float y,
    2389                                const psFloatArray *radii, const psStats *stats);
     2265output vector value is specified by \code{stats}.  This function must be defined for the
     2266following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
     2267\begin{verbatim}
     2268psVector *psImageRadialCut(psVector *out, const psImage *input, float x, float y,
     2269                               const psVector *radii, const psStats *stats);
    23902270\end{verbatim}
    23912271
     
    23982278Each pixel in the output image is derived from the statistics of the
    23992279corresponding set of input image pixels based on the statistics
    2400 specified by \code{stats}.
     2280specified by \code{stats}.  This function must be defined for the following
     2281types: \code{psU8}, \code{psU16}, \code{psS8}, \code{psS16},
     2282\code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
    24012283\begin{verbatim}
    24022284psImage *psImageRebin(psImage *out, const psImage *input, float scale, const psStats *stats);
     
    24082290pixels should be set to \tbd{value}.  The center of rotation is always
    24092291the center pixel of the image.  The rotation is specified in the sense
    2410 that a positive angle is an anti-clockwise rotation. 
     2292that a positive angle is an anti-clockwise rotation.    This function must be defined for the following
     2293types: \code{psU8}, \code{psU16}, \code{psS8}, \code{psS16},
     2294\code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
    24112295\begin{verbatim}
    24122296psImage *psImageRotate(psImage *out, const psImage *input, float angle);
     
    24182302image has the same dimensions as the input image.  Pixels which fall
    24192303off the edge of the output image are lost.  Newly exposed pixels are
    2420 set to the value given by \code{exposed}. 
     2304set to the value given by \code{exposed}.    This function must be defined for the following
     2305types: \code{psU8}, \code{psU16}, \code{psS8}, \code{psS16},
     2306\code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
    24212307\begin{verbatim}
    24222308psImage *psImageShift(psImage *out, const psImage *input, float dx, float dy, float exposed);
     
    24252311Roll image by an integer number of pixels (\code{dx,dy}) in either
    24262312direction.  The output image is the same dimensions as the input
    2427 image.  Edge pixels wrap to the other side (no values are lost).
     2313image.  Edge pixels wrap to the other side (no values are lost).  This function must be defined for the following
     2314types: \code{psU8}, \code{psU16}, \code{psS8}, \code{psS16},
     2315\code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
    24282316\begin{verbatim}
    24292317psImage *psImageRoll(psImage *out, const psImage *input, int dx, int dy);
     
    24332321
    24342322Determine statistics for image (or subimage).  The statistics to be
    2435 determined are specified by \code{stats}.
     2323determined are specified by \code{stats}.  This function must be defined for the
     2324following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
    24362325\begin{verbatim}
    24372326psStats *psImageGetStats(psStats *stats, const psImage *input);
     
    24402329Construct a histogram from an image (or subimage).  The histogram to
    24412330generate is specified by \code{psHistogram hist} (see
    2442 section~\ref{sec:histograms}).
     2331section~\ref{sec:histograms}).  This function must be defined for the
     2332following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
    24432333\begin{verbatim}
    24442334psHistogram *psImageHistogram(psHistogram *hist, const psImage *input);
     
    24472337Fit a 2-D Chebychev polynomial surface to an image.  The input
    24482338structure \code{coeffs} contains the desired order and terms of
    2449 interest.
     2339interest.  This function must be defined for the
     2340following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
    24502341\begin{verbatim}
    24512342psPolynomial2D *psImageFitPolynomial(psPolynomial2D *coeffs, const psImage *input);
     
    24542345Evaluate a 2-D polynomial surface for the image pixels.  Given the
    24552346input polynomial coefficients, set the image pixel values on the basis
    2456 of the polynomial function.
     2347of the polynomial function.  This function must be defined for the
     2348following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
    24572349\begin{verbatim}
    24582350psImage *psImageEvalPolynomial(psImage *input, const psPolynomial2D *coeffs);
     
    25162408\end{verbatim}
    25172409
    2518 Read header data from a FITS image file descriptor into a \code{psMetaData}
    2519 structure. 
     2410Read header data from a FITS image file descriptor into a
     2411\code{psMetaData} structure.
    25202412\begin{verbatim}
    25212413psMetadata *psImageFReadHeader(psMetadata *output, const char *extname, int extnum, FILE *f);
     
    25272419values \code{< min} are set to the value \code{vmin}. All pixels with
    25282420values \code{> max} are set to the value \code{vmax}. Returns the
    2529 number of clipped pixels.
     2421number of clipped pixels.  This function must be defined for the
     2422following types: \code{psU8}, \code{psU16}, \code{psS8}, \code{psS16},
     2423\code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
    25302424\begin{verbatim}
    25312425int psImageClip(psImage *input, float min, float vmin, float max, float vmax);
     
    25342428Clip \code{NaN} image pixels to given value.  Pixels with \code{NaN},
    25352429\code{+Inf} or \code{-Inf} values are set to the specified value.
    2536 Returns the number of clipped pixels.
     2430Returns the number of clipped pixels.  This function must be defined
     2431for the following types: \code{psU8}, \code{psU16}, \code{psS8},
     2432\code{psS16}, \code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
    25372433\begin{verbatim}
    25382434int psImageClipNaN(psImage *input, float value);
     
    25462442image value), \code{-} (subtract overlay from image), \code{*}
    25472443(multiply overlay times image), \code{/} (divide image by overlay).
     2444This function must be defined for the following types: \code{psU8},
     2445\code{psU16}, \code{psS8}, \code{psS16}, \code{psF32}, \code{psF64},
     2446\code{psC32}, \code{psC64}.
    25482447\begin{verbatim}
    25492448int psImageOverlaySection(psImage *image, const psImage *overlay, int x0, int y0, const char *op);
     
    25732472pre-processor macros to perform the onerous task of creating the
    25742473loops.  Also note that \code{psVector} is equivalent to
    2575 \code{psFloatArray}.  An attempt to perform an arithmetic operation on
     2474\code{psVector}.  An attempt to perform an arithmetic operation on
    25762475an object of dimension \code{PS_DIMEN_OTHER} should produce an error.
    25772476
     
    30362935/// get the next item in the sequence
    30372936psMetadataItem *psMetadataGetNext(psMetadata *restrict md, ///< metadata to get from
    3038                                   const char *restrict match, ///< Match this
    3039                                   int which ///< Which iterator to use
     2937                                  const char *restrict match, ///< Match this
     2938                                  int which ///< Which iterator to use
    30402939    );
    30412940\end{verbatim}
     
    30742973/** A point in 2-D space, with errors. */
    30752974typedef struct {
    3076     double x;                           ///< x position
    3077     double y;                           ///< y position
    3078     double xErr;                        ///< Error in x position
    3079     double yErr;                        ///< Error in y position
     2975    double x;                           ///< x position
     2976    double y;                           ///< y position
     2977    double xErr;                        ///< Error in x position
     2978    double yErr;                        ///< Error in y position
    30802979} psPlaneCoord;
    30812980
    30822981/** A point on the surface of a sphere, with errors */
    30832982typedef struct {
    3084     double r;                           ///< RA
    3085     double d;                           ///< Dec
    3086     double rErr;                        ///< Error in RA
    3087     double dErr;                        ///< Error in Dec
     2983    double r;                           ///< RA
     2984    double d;                           ///< Dec
     2985    double rErr;                        ///< Error in RA
     2986    double dErr;                        ///< Error in Dec
    30882987} psSphereCoord;
    30892988\end{verbatim}
     
    31883087/** apply the coordinate transformation to the given coordinate */
    31893088psPlaneCoord *psPlaneCoordXformApply (psPlaneCoord *out, ///< Output coordinates, or NULL
    3190                                       const psPlaneCoordXform *frame, ///< coordinate transformation
    3191                                       const psPlaneCoord *coords ///< input coordiate
     3089                                      const psPlaneCoordXform *frame, ///< coordinate transformation
     3090                                      const psPlaneCoord *coords ///< input coordiate
    31923091    );
    31933092
    31943093/** apply the optical distortion to the given coordinate, magnitude, color */
    31953094psPlaneCoord *psPlaneDistortionApply (psPlaneCoord *out, ///< Output coordinates, or NULL
    3196                                       const psPlaneDistortion *pattern, ///< optical distortion pattern
    3197                                       const psPlaneCoord *coords, ///< input coordinate
    3198                                       float mag, ///< magnitude of object
    3199                                       float color ///< color of object
     3095                                      const psPlaneDistortion *pattern, ///< optical distortion pattern
     3096                                      const psPlaneCoord *coords, ///< input coordinate
     3097                                      float mag, ///< magnitude of object
     3098                                      float color ///< color of object
    32003099    );
    32013100\end{verbatim}
     
    32323131psSphereCoordTransformation *
    32333132psSphereCoordTransformationAlloc(double pole1, ///< First location of pole
    3234                                 double pole2, ///< Second location of pole
    3235                                 double rotation ///< Rotation between systems
     3133                                double pole2, ///< Second location of pole
     3134                                double rotation ///< Rotation between systems
    32363135    );
    32373136
     
    32483147psSphereCoord *
    32493148psSphereCoordTransform(const psSphereCoord *coord, ///< Coordinates to convert
    3250                        psSphereCoordSystem *sys ///< System to use to convert
     3149                       psSphereCoordSystem *sys ///< System to use to convert
    32513150    );
    32523151\end{verbatim}
     
    32913190psPlaneCoord *
    32923191psCoordProject(const psSphereCoord *coord, ///< Spherical coordinates to project
    3293                const char *projection   ///< Projection to use
     3192               const char *projection   ///< Projection to use
    32943193    );
    32953194
     
    32973196psSphereCoord *
    32983197psCoordDeproject(const psPlaneCoord *coord, ///< Plane coordinates to deproject
    3299                  const char *projection ///< Projection to use
     3198                 const char *projection ///< Projection to use
    33003199    );
    33013200\end{verbatim}
     
    33103209psSphereCoord *
    33113210psSphereCoordGetOffset(const psSphereCoord *restrict position1, ///< Position 1
    3312                        const psSphereCoord *restrict position2, ///< Position 2
    3313                        const char *type         ///< Type of offset: Linear, Spherical/Arcsec,
    3314                                                 ///< Spherical/Degreees etc
     3211                       const psSphereCoord *restrict position2, ///< Position 2
     3212                       const char *type         ///< Type of offset: Linear, Spherical/Arcsec,
     3213                                                ///< Spherical/Degreees etc
    33153214    );
    33163215
     
    33183217psSphereCoord *
    33193218psSphereCoordApplyOffset(const psSphereCoord *restrict position, ///< Position
    3320                         const psSphereCoord *restrict offset, ///< Offset
    3321                          const char *type               ///< Type of offset: Linear, Spherical/Arcsec,
    3322                                                         ///< Spherical/Degreees etc
     3219                        const psSphereCoord *restrict offset, ///< Offset
     3220                         const char *type               ///< Type of offset: Linear, Spherical/Arcsec,
     3221                                                        ///< Spherical/Degreees etc
    33233222    );
    33243223\end{verbatim}
     
    34533352 */
    34543353typedef struct {
    3455     int nReadouts;                      ///< number of readouts in this cell realization; each may have its
    3456                                         ///< own image, objects and overscan.
    3457     struct psReadout *readouts;         ///< Readouts from the cell
    3458     psMetadata *md;                     ///< Cell-level metadata
    3459 
    3460     psPlaneCoordXform *cellToChip;      ///< Transformations from cell coordinates to chip coordinates
    3461     psPlaneCoordXform *cellToFPA;       ///< Transformations from cell coordinates to FPA coordinates
    3462     psPlaneCoordXform *cellToSky;       ///< Quick and Dirty transformations from cell coordinates to sky
    3463 
    3464     struct psChip  *parentChip;         ///< chip which contains this cell
     3354    int nReadouts;                      ///< number of readouts in this cell realization; each may have its
     3355                                        ///< own image, objects and overscan.
     3356    struct psReadout *readouts;         ///< Readouts from the cell
     3357    psMetadata *md;                     ///< Cell-level metadata
     3358
     3359    psPlaneCoordXform *cellToChip;      ///< Transformations from cell coordinates to chip coordinates
     3360    psPlaneCoordXform *cellToFPA;       ///< Transformations from cell coordinates to FPA coordinates
     3361    psPlaneCoordXform *cellToSky;       ///< Quick and Dirty transformations from cell coordinates to sky
     3362
     3363    struct psChip  *parentChip;         ///< chip which contains this cell
    34653364} psCell;
    34663365\end{verbatim}
     
    34843383typedef struct {
    34853384    int nCells;                         ///< Number of Cells assigned
    3486     struct psCell *cells;               ///< Cells in the Chip
    3487 
    3488     psMetadata *md;                     ///< Chip-level metadata
    3489     psPlaneCoordXform *chipToFPA;       ///< Transformations from chip coordinates to FPA coordinates
    3490     psPlaneCoordXform *FPAtoChip;       ///< Transformations from FPA coordinates to chip
    3491 
    3492     struct psFPA *parentFPA;            ///< FPA which contains this chip
     3385    struct psCell *cells;               ///< Cells in the Chip
     3386
     3387    psMetadata *md;                     ///< Chip-level metadata
     3388    psPlaneCoordXform *chipToFPA;       ///< Transformations from chip coordinates to FPA coordinates
     3389    psPlaneCoordXform *FPAtoChip;       ///< Transformations from FPA coordinates to chip
     3390
     3391    struct psFPA *parentFPA;            ///< FPA which contains this chip
    34933392} psChip;
    34943393\end{verbatim}
     
    35203419    int nChips;                         ///< Number of Cells assigned
    35213420    int nAlloc;                         ///< Number of Cells available
    3522     struct psChip *chips;               ///< Chips in the Focal Plane Array
    3523 
    3524     psMetadata *md;                     ///< FPA-level metadata
    3525     psPlaneDistortion *TPtoFP;          ///< Transformation term from
    3526     psPlaneDistortion *FPtoTP;          ///< Transformation term from
    3527     psFixedPattern *pattern;            ///< Fixed pattern residual offsets
    3528     const psExposure *exp;              ///< information about this exposure
     3421    struct psChip *chips;               ///< Chips in the Focal Plane Array
     3422
     3423    psMetadata *md;                     ///< FPA-level metadata
     3424    psPlaneDistortion *TPtoFP;          ///< Transformation term from
     3425    psPlaneDistortion *FPtoTP;          ///< Transformation term from
     3426    psFixedPattern *pattern;            ///< Fixed pattern residual offsets
     3427    const psExposure *exp;              ///< information about this exposure
    35293428    psPhotSystem colorPlus, colorMinus; ///< Colour reference
    35303429    float rmsX, rmsY;                   ///< Dispersion in astrometric solution
     
    35433442typedef struct {
    35443443    // Telescope longitude, latitude and height are stored separately, since they don't change with pointing
    3545     const double ra, dec;               ///< Telescope boresight
    3546     const double ha;                    ///< Hour angle
    3547     const double zd;                    ///< Zenith distance
    3548     const double az;                    ///< Azimuth
    3549     const double lst;                   ///< Local Sidereal Time
    3550     const float mjd;                    ///< MJD of observation
    3551     const float rotAngle;               ///< Rotator position angle
    3552     const float temp;                   ///< Air temperature, for estimating refraction
    3553     const float pressure;               ///< Air pressure, for calculating refraction
    3554     const float humidity;               ///< Relative humidity, for calculating refraction
    3555     const float exptime;                ///< Exposure time
     3444    const double ra, dec;               ///< Telescope boresight
     3445    const double ha;                    ///< Hour angle
     3446    const double zd;                    ///< Zenith distance
     3447    const double az;                    ///< Azimuth
     3448    const double lst;                   ///< Local Sidereal Time
     3449    const float mjd;                    ///< MJD of observation
     3450    const float rotAngle;               ///< Rotator position angle
     3451    const float temp;                   ///< Air temperature, for estimating refraction
     3452    const float pressure;               ///< Air pressure, for calculating refraction
     3453    const float humidity;               ///< Relative humidity, for calculating refraction
     3454    const float exptime;                ///< Exposure time
    35563455    /* Derived quantities */
    3557     const float posAngle;               ///< Position angle
    3558     const float parallactic;            ///< Parallactic angle
    3559     const float airmass;                ///< Airmass, calculated from zenith distance
    3560     const float pf;                     ///< Parallactic factor
    3561     const char *cameraName;             ///< name of camera which provided exposure
    3562     const char *telescopeName;          ///< name of telescope which provided exposure
     3456    const float posAngle;               ///< Position angle
     3457    const float parallactic;            ///< Parallactic angle
     3458    const float airmass;                ///< Airmass, calculated from zenith distance
     3459    const float pf;                     ///< Parallactic factor
     3460    const char *cameraName;             ///< name of camera which provided exposure
     3461    const char *telescopeName;          ///< name of telescope which provided exposure
    35633462} psExposure;
    35643463\end{verbatim}
     
    36463545/** Information needed (by SLALIB) to convert Apparent to Observed Position */
    36473546typedef struct {
    3648     const double latitude;              ///< geodetic latitude (radians)
    3649     const double sinLat, cosLat;        ///< sine and cosine of geodetic latitude
    3650     const double abberationMag;         ///< magnitude of diurnal aberration vector
    3651     const double height;                ///< height (HM)
    3652     const double temperature;           ///< ambient temperature (TDK)
    3653     const double pressure;              ///< pressure (PMB)
    3654     const double humidity;              ///< relative humidity (RH)
    3655     const double wavelength;            ///< wavelength (WL)
    3656     const double lapseRate;             ///< lapse rate (TLR)
    3657     const double refractA, refractB;    ///< refraction constants A and B (radians)
    3658     const double longitudeOffset;       ///< longitude + eqn of equinoxes + ``sidereal UT'' (radians)
    3659     const double siderealTime;          ///< local apparent sidereal time (radians)
     3547    const double latitude;              ///< geodetic latitude (radians)
     3548    const double sinLat, cosLat;        ///< sine and cosine of geodetic latitude
     3549    const double abberationMag;         ///< magnitude of diurnal aberration vector
     3550    const double height;                ///< height (HM)
     3551    const double temperature;           ///< ambient temperature (TDK)
     3552    const double pressure;              ///< pressure (PMB)
     3553    const double humidity;              ///< relative humidity (RH)
     3554    const double wavelength;            ///< wavelength (WL)
     3555    const double lapseRate;             ///< lapse rate (TLR)
     3556    const double refractA, refractB;    ///< refraction constants A and B (radians)
     3557    const double longitudeOffset;       ///< longitude + eqn of equinoxes + ``sidereal UT'' (radians)
     3558    const double siderealTime;          ///< local apparent sidereal time (radians)
    36603559} psGrommit;
    36613560\end{verbatim}
     
    36673566/** Constructor */
    36683567psGrommit *
    3669 psGrommitAlloc(const psExposure *exp    ///< Relevant exposure
     3568psGrommitAlloc(const psExposure *exp    ///< Relevant exposure
    36703569    );
    36713570
    36723571/** Destructor */
    36733572void
    3674 psGrommitFree(psGrommit *grommit        ///< Grommit to destroy
     3573psGrommitFree(psGrommit *grommit        ///< Grommit to destroy
    36753574    );
    36763575\end{verbatim}
     
    37103609/** returns Chip in FPA which contains the given FPA coordinate */
    37113610psChip *
    3712 psChipInFPA (psChip *out,               ///< Chip to return, or NULL
    3713              const psPlaneCoord *coord  ///< coordinate in FPA
    3714              const psFPA *fpa,          ///< FPA description
    3715              );
     3611psChipInFPA (psChip *out,               ///< Chip to return, or NULL
     3612             const psPlaneCoord *coord  ///< coordinate in FPA
     3613             const psFPA *fpa,          ///< FPA description
     3614             );
    37163615
    37173616/** returns Cell in Chip which contains the given chip coordinate */
    37183617psCell *
    3719 psCellInChip(psCell *out,               ///< Cell to return, or NULL
    3720              const psPlaneCoord *coord  ///< coordinate in chip
    3721              const psChip *chip,        ///< chip description
    3722              );
     3618psCellInChip(psCell *out,               ///< Cell to return, or NULL
     3619             const psPlaneCoord *coord  ///< coordinate in chip
     3620             const psChip *chip,        ///< chip description
     3621             );
    37233622
    37243623/** Return the cell in FPA which contains the given FPA coordinates */
    37253624psCell *
    3726 psCellInFPA(psCell *out,                ///< Cell to return, or NULL
    3727             const psPlaneCoord *coord   ///< Coordinate in FPA
    3728             const psFPA *fpa,           ///< FPA description
    3729             );
     3625psCellInFPA(psCell *out,                ///< Cell to return, or NULL
     3626            const psPlaneCoord *coord   ///< Coordinate in FPA
     3627            const psFPA *fpa,           ///< FPA description
     3628            );
    37303629\end{verbatim}
    37313630
     
    37633662/** Convert (RA,Dec) to cell and cell coordinates */
    37643663psPlaneCoord *
    3765 psCoordSkyToCell(psPlaneCoord *out,     ///< Coordinates to return, or NULL
    3766                  psCell *cell,          ///< Cell to return
    3767                 const psSphereCoord *in, ///< Input coordinates
    3768                  const psFPA *fpa       ///< FPA description
    3769                 );
     3664psCoordSkyToCell(psPlaneCoord *out,     ///< Coordinates to return, or NULL
     3665                 psCell *cell,          ///< Cell to return
     3666                const psSphereCoord *in, ///< Input coordinates
     3667                 const psFPA *fpa       ///< FPA description
     3668                );
    37703669
    37713670/** Convert cell and cell coordinate to (RA,Dec) */
    37723671psSphereCoord *
    3773 psCoordCellToSky(psSphereCoord *out,    ///< Coordinates to return, or NULL
    3774                 const psPlaneCoord *coord ///< cell coordinates to transform
    3775                  const psCell *cell,    ///< Cell to get coordinates for
    3776                 );
     3672psCoordCellToSky(psSphereCoord *out,    ///< Coordinates to return, or NULL
     3673                const psPlaneCoord *coord ///< cell coordinates to transform
     3674                 const psCell *cell,    ///< Cell to get coordinates for
     3675                );
    37773676
    37783677/** Quick and dirty cell to (RA,Dec) --- employs cellToSky transformation */
    37793678psSphereCoord *
    37803679psCoordCellToSkyQuick(psSphereCoord *out, ///< Coordinates to return, or NULL
    3781                       const psPlaneCoord *coord ///< cell coordinates to transform
    3782                       const psCell *cell, ///< Cell description
    3783                       );
     3680                      const psPlaneCoord *coord ///< cell coordinates to transform
     3681                      const psCell *cell, ///< Cell description
     3682                      );
    37843683
    37853684/** Convert (RA,Dec) to tangent plane coords */
    37863685psPlaneCoord *
    3787 psCoordSkyToTP(psPlaneCoord *out,       ///< Coordinates to return, or NULL
    3788                const psSphereCoord *coord ///< input Sky coordinate
    3789                const psGrommit *grommit, ///< Grommit for fast conversion
    3790                );
     3686psCoordSkyToTP(psPlaneCoord *out,       ///< Coordinates to return, or NULL
     3687               const psSphereCoord *coord ///< input Sky coordinate
     3688               const psGrommit *grommit, ///< Grommit for fast conversion
     3689               );
    37913690
    37923691/** Convert tangent plane coords to focal plane coordinates */
    37933692psPlaneCoord *
    3794 psCoordTPtoFPA(psPlaneCoord *out,       ///< Coordinates to return, or NULL
    3795                const psPlaneCoord *coord ///< input TP coordinate
    3796                const psFPA *fpa,        ///< FPA description
    3797                );
     3693psCoordTPtoFPA(psPlaneCoord *out,       ///< Coordinates to return, or NULL
     3694               const psPlaneCoord *coord ///< input TP coordinate
     3695               const psFPA *fpa,        ///< FPA description
     3696               );
    37983697
    37993698/** converts the specified FPA coord to the coord on the given Chip */
    38003699psPlaneCoord *
    3801 psCoordFPAtoChip (psPlaneCoord *out,    ///< Coordinates to return, or NULL
    3802                   const psPlaneCoord *coord ///< input FPA coordinate
    3803                   const psChip *chip,   ///< Chip of interest
    3804                   );
     3700psCoordFPAtoChip (psPlaneCoord *out,    ///< Coordinates to return, or NULL
     3701                  const psPlaneCoord *coord ///< input FPA coordinate
     3702                  const psChip *chip,   ///< Chip of interest
     3703                  );
    38053704
    38063705/** converts the specified Chip coord to the coord on the given Cell */
    38073706psPlaneCoord *
    3808 psCoordChiptoCell (psPlaneCoord *out,   ///< Coordinates to return, or NULL
    3809                    const psPlaneCoord *coord ///< input Chip coordinate
    3810                    const psCell *cell,  ///< Cell of interest
    3811                    );
     3707psCoordChiptoCell (psPlaneCoord *out,   ///< Coordinates to return, or NULL
     3708                   const psPlaneCoord *coord ///< input Chip coordinate
     3709                   const psCell *cell,  ///< Cell of interest
     3710                   );
    38123711
    38133712/** converts the specified Cell coord to the coord on the parent Chip */
    38143713psPlaneCoord *
    3815 psCoordCelltoChip (psPlaneCoord *out,   ///< Coordinates to return, or NULL
    3816                    const psPlaneCoord *coord ///< input Cell coordinate
    3817                    const psCell *cell,  ///< Cell description
    3818                    );
     3714psCoordCelltoChip (psPlaneCoord *out,   ///< Coordinates to return, or NULL
     3715                   const psPlaneCoord *coord ///< input Cell coordinate
     3716                   const psCell *cell,  ///< Cell description
     3717                   );
    38193718
    38203719/** converts the specified Chip coord to the coord on the parent FPA */
    38213720psPlaneCoord *
    3822 psCoordChiptoFPA (psPlaneCoord *out,            ///< Coordinates to return, or NULL
    3823                   const psPlaneCoord *coord     ///< input Chip coordinate
    3824                   const psChip *chip,   ///< Chip description
    3825                   );
     3721psCoordChiptoFPA (psPlaneCoord *out,            ///< Coordinates to return, or NULL
     3722                  const psPlaneCoord *coord     ///< input Chip coordinate
     3723                  const psChip *chip,   ///< Chip description
     3724                  );
    38263725
    38273726/** Convert focal plane coords to tangent plane coordinates */
    38283727psPlaneCoord *
    3829 psCoordFPAToTP(psPlaneCoord *out,               ///< Coordinates to return, or NULL
    3830                const psPlaneCoord *coord ///< input FPA coordinate
    3831                const psFPA *fpa,        ///< FPA description
    3832                );
     3728psCoordFPAToTP(psPlaneCoord *out,               ///< Coordinates to return, or NULL
     3729               const psPlaneCoord *coord ///< input FPA coordinate
     3730               const psFPA *fpa,        ///< FPA description
     3731               );
    38333732
    38343733/** Convert tangent plane coords to (RA,Dec) */
    38353734psSphereCoord *
    3836 psCoordTPtoSky(psSphereCoord *out,      ///< Coordinates to return, or NULL
    3837                const psPlaneCoord *coord ///< input TP coordinate
    3838                const psGrommit *grommit, ///< Grommit for fast conversion
    3839                );
     3735psCoordTPtoSky(psSphereCoord *out,      ///< Coordinates to return, or NULL
     3736               const psPlaneCoord *coord ///< input TP coordinate
     3737               const psGrommit *grommit, ///< Grommit for fast conversion
     3738               );
    38403739
    38413740/** Convert Cell coords to FPA coordinates */
    38423741psPlaneCoord *
    3843 psCoordCellToFPA(psPlaneCoord *out,     ///< Coordinates to return, or NULL
    3844                 const psPlaneCoord *coord ///< Input cell coordinates
    3845                  const psCell *cell,    ///< Cell description
    3846                 );
     3742psCoordCellToFPA(psPlaneCoord *out,     ///< Coordinates to return, or NULL
     3743                const psPlaneCoord *coord ///< Input cell coordinates
     3744                 const psCell *cell,    ///< Cell description
     3745                );
    38473746\end{verbatim}
    38483747
     
    38583757float
    38593758psGetAirmass(const psSphereCoord *coord, ///< Position on the sky
    3860              double siderealTime,       ///< Sidereal time
    3861              float height               ///< Height above sea level
     3759             double siderealTime,       ///< Sidereal time
     3760             float height               ///< Height above sea level
    38623761             );
    38633762\end{verbatim}
     
    39733872/** Get Sun Position */
    39743873psSphereCoord *
    3975 psGetSunPos(float mjd                   ///< MJD to get position for
     3874psGetSunPos(float mjd                   ///< MJD to get position for
    39763875    );
    39773876
    39783877/** Get Moon position */
    39793878psSphereCoord *
    3980 psGetMoonPos(float mjd,                 ///< MJD to get position for
    3981              double latitude,           ///< Latitude for apparent position
    3982              double longitude           ///< Longitude for apparent position
     3879psGetMoonPos(float mjd,                 ///< MJD to get position for
     3880             double latitude,           ///< Latitude for apparent position
     3881             double longitude           ///< Longitude for apparent position
    39833882    );
    39843883
Note: See TracChangeset for help on using the changeset viewer.