IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 627


Ignore:
Timestamp:
May 7, 2004, 5:15:51 PM (22 years ago)
Author:
Paul Price
Message:

Lots of changes to clean up, and implement RHL's comments:

Large section on error-handling functions added.

Clarified description about destructors, reference counters and
psFree, including the ground rule: the destructor for every structure
should only call psFree if refCounter == 1; otherwise, it decrements
the reference counter and returns.

Added psTraceSetDestination.

Renamed several of the trace functions to conform to the psTypeAction
standard naming system.

Renamed several of the logging functions to conform to the
psTypeAction standard naming system.

Added PS_LOG_TO_NONE, and specified the behaviour of psLogSetFormat
when passed NULL and "".

Renamed several of the error-handling functions to conform to the
psTypeAction standard naming system.

Added "which" to psDlist{SetIterator,GetNext,GetPrev} to enable
multiple iteration cursors.

Specified a sort function for psDlist. Motivation is primarily to
be able to iterate on a sorted list of keys from a hash.

Added unary NOT operator for a psBitSet.

Changed order of variables for psArrayStats --- output goes first

Reorganised psHistogram --- no longer specify both upper and lower
bounds, and now include a "simple" flag which indicates if the bounds
are distributed uniformly (impacts choice of algorithm). Also altered
the constructors.

Added psMatrixEigenvectors to get eigenvectors of a matrix.

Major reworking of Fourier Transforms section --- poor design
previously. Want to work with images, not some generic FFT type.

Fixed the definition of the Gaussian to include 1/sqrt(2pi)/sigma.

Added possibility of available derivative information in psMinimize,
and changed the order of variables for psMinimize and psMinimizeChi2.

Removed "output" in psImageSubset --- always want a new image. Also
added note that the parent should have its memory counter incremented.

Removed psImageFreeChildren --- it produces dangling pointers, so it's
dangerous.

Added element type to psImageCopy, which allows type conversion.

Added "const" to psImage functions, and changed the order of variables
in some of the functions to put the output first.

Changed psImageRadialCut to specify radii directly.

Specified that a negative value for nx,ny in reading pixels from FITS
means the whole image, less the absolute value of the variable. e.g.,
nx = -5 means 5 pixels less than the whole range.

Added a "which" to psMetadataGetNext so that multiple iteration cursors
may be used. Iterator should go over every entry in the metadata, even
if non-unique.

Removed the overscan in a psReadout --- it's specified in the metadata.
Changed the names of two members, and made some const.

Removed psGrommit from psExposure (it doesn't need to replicate the
grommit's information), and const-ed all of psGrommit and psExposure
--- no-one should fiddle with these values.

Specified constructor and destructor for psGrommit.

Made psPhotSystem members const.

Split psCoord into psPlaneCoord and psSphereCoord --- substantive
changes to the APIs of position and astrometry functions. Also
rearranged the order of variables in some of the astrometry functions.

Added function psCoordDeproject to deproject coordinates from a plane
to a spherical system.

Reworked the spherical coordinate transforms.

Renamed the offset functions (psGetOffset, psApplyOffset).

File:
1 edited

Legend:

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

    r573 r627  
    1 %%% $Id: psLibSDRS.tex,v 1.40 2004-05-04 04:13:29 price Exp $
     1%%% $Id: psLibSDRS.tex,v 1.41 2004-05-08 03:15:51 price Exp $
    22\documentclass[panstarrs]{panstarrs}
    33
     
    8282The installed base of code for PSLib consists of header files, the
    8383binary library code, \code{libpslib.a} and the shared-library
    84 equivalent, \code{libpslib.so}.  Assuming these components have been
    85 installed into the library and search path, PSLib may be used within a
    86 program by including the line \code{#include <pslib.h>} into the C
    87 code and linking with \code{-lpslib}.
     84equivalent, \code{libpslib.so} (or \code{libpslib.dylib} in the case
     85of OS/X).  Assuming these components have been installed into the
     86library and search path, PSLib may be used within a program by
     87including the line \code{#include <pslib.h>} into the C code and
     88linking with \code{-lpslib}.
    8889
    8990This document describes the data structures and details the functions
     
    113114(\href{heasarc.gsfc.nasa.gov/docs/software/fitsio/}{\tt
    114115heasarc.gsfc.nasa.gov/docs/software/fitsio/}); and
    115 \item Many of the astronomy routines will wrap the StarLink Astronomy
    116 libraries (SLALib;
     116\item Many of the astronomy routines will wrap the StarLink Positional
     117Astronomy libraries (SLALib;
    117118\href{star-www.rl.ac.uk/star/docs/sun67.htx/sun67.html}{\tt
    118119star-www.rl.ac.uk/star/docs/sun67.htx/sun67.html}.
     120\item \tbd{Some graphics library, possibly the SM library.}
    119121\end{itemize}
    120122
     
    486488management routines respect the use of the \code{refCounter} field:
    487489\code{psFree} will not free a block for which \code{refCounter != 1},
    488 and \code{psAlloc} will initialize the field to 1.  \tbd{\code{psFree}
    489 should generate an error if \code{refCounter != 1}.}  However, they do
     490and \code{psAlloc} will initialize the field to 1.  \code{psFree}
     491must generate an error if \code{refCounter != 1}.  However, they do
    490492not (and cannot practically) enforce the use of the counters; this is
    491493a requirement of external APIs which intend to use the feature.
     
    512514(\S\ref{sec:psDlist}).
    513515
     516\paragraph{Destructors}
     517
    514518\subsubsection{Relation of Memory Management to Structures}
    515519\label{sec:free}
     
    517521In this document, we specify several C \code{struct}s.  It is expected
    518522that instances of, for example, \code{struct psMyType} will be
    519 constructed using \code{psMyTypeAlloc()} calls, and destructed using
     523constructed using \code{psMyTypeAlloc()} calls, and destroyed using
    520524\code{psMyTypeFree()} calls.  The allocator will allocate the required
    521525memory with \code{psAlloc} and increment the appropriate
    522 \code{refCounter}.  The destructor will decrement the appropriate
    523 \code{refCounter} and free the memory with \code{psFree} \emph{if and
    524 only if} the new value of the \code{refCounter} is zero.
    525 
    526 This allows the \code{psMyType} to be imported into the metadata
    527 (\S\ref{sec:metadata}) without the user worrying about the details of
    528 the memory allocation/deallocation.  For example:
     526\code{refCounter}.
     527
     528The existence of complicated structures which include pointers to
     529other structures require that we lay out a rule regarding destructors
     530(i.e., \code{psMyTypeFree}) and reference counters.  Simply put,
     531\textit{the destructor for every structure should only call
     532\code{psFree} if \code{refCounter == 1}; otherwise, it decrements the
     533reference counter and returns.}  An example destructor is shown below:
     534
     535\begin{verbatim}
     536void psMyTypeFree(psMyType *myType ///< Object to destroy
     537    )
     538{
     539    /* No operation if object is NULL */
     540    if (myType == NULL) {
     541        return;
     542    }
     543    /* Only call psFree if reference counter is 1 */
     544    if (psMemGetRefCounter(myType) == 1) {
     545        psFree(myType);
     546        return;
     547    }
     548    /* Otherwise, decrement the reference counter only */
     549    psMemDecrRefCounter(myType);
     550}
     551\end{verbatim}
     552
     553This allows, for example, the \code{psMyType} to be imported into the
     554metadata (\S\ref{sec:metadata}) without the user worrying about the
     555details of the memory allocation/deallocation:
    529556
    530557\begin{verbatim}
     
    596623relationship is seen in two ways.  First, a facility inherits the
    597624trace level of its parent unless explicitly specified.  Second, the
    598 hierarchy is used to format the listing of the trace facilities.  The
    599 first of these rules provides a mechanism to define the default trace
    600 levels for any facility even if it has not been registered explicitly
    601 since all named facilities are implicitly children of the top level
    602 facility (\code{.}).  The second rule is simply an organizational
    603 technique to make the listing of facility information clear.
     625hierarchy is used to format the listing of the trace facilities so
     626that they are easy to read.  The first of these rules provides a
     627mechanism to define the default trace levels for any facility even if
     628it has not been registered explicitly since all named facilities are
     629implicitly children of the top level facility (\code{.}).  The second
     630rule is simply an organizational technique to make the listing of
     631facility information clear.
    604632
    605633The API to place a trace message in the code, and simultaneously set
     
    621649%
    622650\begin{verbatim}
    623 int psSetTraceLevel(char *facil, int level);
     651int psTraceSetLevel(char *facil, int level);
    624652\end{verbatim}
    625653%
     
    629657%
    630658\begin{verbatim}
    631 int psGetTraceLevel(char *facil);
     659int psTraceGetLevel(char *facil);
    632660\end{verbatim}
    633661%
     
    635663rules specified above.  A specified trace message (identified by
    636664\code{psTrace}) shall be printed if and only if
    637 \code{psGetTraceLevel(facil)} returns a value greater than or equal to
     665\code{psTraceGetLevel(facil)} returns a value greater than or equal to
    638666the value of \code{myLevel} for that message.  That is, a larger
    639667number for the trace level corresponds to lower-level statements, and
     
    641669
    642670PSLib will include a utility function for examining the current
    643 tracing levels of all facilities: \code{void psPrintTraceLevels(void);}.
     671tracing levels of all facilities: \code{void psTracePrintLevels(void);}.
    644672This function will print the hierarchy of trace facilities along with
    645673the current trace level for each facility.  For example, a particular
    646674program may have a few facilities defined, along with their trace
    647 levels.  A call to \code{psPrintTraceLevels} may produce a listing
     675levels.  A call to \code{psTracePrintLevels} may produce a listing
    648676which appears as:
    649677\begin{verbatim}
    650 .                    0
    651 .debias              1
    652 .flatten             1
    653 .flatten.divide      2
    654 .object.findpeak     1
    655 .object.getsky       1
     678.                        0
     679 .IPP                    0
     680 .IPP.debias             1
     681 .IPP.flatten            1
     682  .IPP.flatten.divide    2
     683  .IPP.object.findpeak   1
     684  .IPP.object.getsky     1
    656685\end{verbatim}
    657686
     
    661690%
    662691\begin{verbatim}
    663 psTrace("flatten", 2, "starting flatten function\n");
    664 psTrace("flatten", 0, "ERROR: flat-field image \%s is invalid\n", filename);
    665 psTrace("flatten.divide", 2, "doing the divide\n");
    666 psTrace("flatten.divide", 3, "trying the loop, i = \%d\n", i);
    667 psTrace("flatten.divide", 1, "got an invalid pixel value (NaN) at \%d,\%d\n");
    668 psTrace("flatten.divide", 2, "divide is done\n");
     692psTrace("IPP.flatten", 2, "starting flatten function\n");
     693psTrace("IPP.flatten", 0, "flat-field image is \%s\n", filename);
     694psTrace("IPP.flatten.divide", 2, "doing the divide\n");
     695psTrace("IPP.flatten.divide", 3, "trying the loop, i = \%d\n", i);
     696psTrace("IPP.flatten.divide", 1, "got an invalid pixel value (NaN) at \%d,\%d\n");
     697psTrace("IPP.flatten.divide", 2, "divide is done\n");
    669698\end{verbatim}
    670699%
     
    673702%
    674703\begin{verbatim}
    675 ERROR: flat-field image foo.fits is invalid
    676 doing the divide
    677 got an invalid pixel value (NaN) at 500,20
    678 divide is done
     704flat-field image is foo.fits
     705  doing the divide
     706 got an invalid pixel value (NaN) at 500,20
     707  divide is done
    679708\end{verbatim}
    680709%
     
    683712%
    684713\begin{verbatim}
    685 starting flatten function
    686 trying the loop, i = 0   
    687 trying the loop, i = 1   
    688 trying the loop, i = 2   
     714  starting flatten function
     715   trying the loop, i = 0   
     716   trying the loop, i = 1   
     717   trying the loop, i = 2   
    689718...
    690719\end{verbatim}
     
    698727\code{void psTraceReset(void)} will set all trace levels to 0.
    699728
    700 \tbd{ability to send trace messages to output locations other than stdout?}
     729
     730The trace may optionally be written to a file on specifying a filename
     731with \code{psTraceSetDestination}:
     732\begin{verbatim}
     733void psTraceSetDestination(const char *filename // File to write to
     734    );
     735\end{verbatim}
     736If the \code{filename} is \code{NULL}, then the trace is sent to
     737standard output.
    701738
    702739\subsubsection{Message Logging}
     
    722759\begin{verbatim}
    723760void psLogMsg(char *name, int myLevel, char *fmt, ...);
    724 void psVLogMsg(char *name, int myLevel, char *fmt, va_list ap);
     761void psLogVMsg(char *name, int myLevel, char *fmt, va_list ap);
    725762\end{verbatim}
    726763where \code{name} is a word to describe the source of the message,
     
    728765is a printf-style formatting statement defining the actual message,
    729766and is followed by the arguments to the formatting code.  The second
    730 form, \code{psVLogMsg} is an equivalent command which takes a
     767form, \code{psLogVMsg} is an equivalent command which takes a
    731768\code{va_list} argument.
    732769
     
    744781%
    745782\begin{verbatim}
    746 int psSetLogLevel(int level);           
     783int psLogSetLevel(int level);           
    747784\end{verbatim}
    748785%
     
    750787invoked with \code{psLogMsg} is only printed if its value of
    751788\code{myLevel} is less than the current value set by
    752 \code{psSetLogLevel}.
     789\code{psLogSetLevel}.
    753790
    754791Log messages are sent to the destination most recently set using:
    755792%
    756793\begin{verbatim}
    757 int psSetLogDestination(int dest);     
    758 \end{verbatim}
    759 %
    760 The only two values that are initially defined are
    761 \code{PS_LOG_TO_STDERR} and \code{PS_LOG_TO_STDOUT} to write to
    762 \code{stderr} and \code{stdout} respectively.  \tbd{define other
    763 destinations? why not use file descriptors?, etc?}.
     794int psLogSetDestination(int dest);     
     795\end{verbatim}
     796%
     797The only values that are initially defined are \code{PS_LOG_TO_STDERR}
     798and \code{PS_LOG_TO_STDOUT} to write to \code{stderr} and
     799\code{stdout} respectively, and \code{PS_LOG_TO_NONE} to turn off
     800logging.  \tbd{Log to a server via TCP/IP; will possibly set these
     801values to negative integers and allow psLogSetDestination to take
     802a positive-integer file descriptor.}.
    764803
    765804The output format is controlled with the function:
    766805%
    767806\begin{verbatim}
    768 void psSetLogFormat(const char *fmt);   
     807void psLogSetFormat(const char *fmt);   
    769808\end{verbatim}
    770809%
     
    795834%
    796835The possible order of the format entries is fixed and not determined
    797 by the order of the letters used in \code{psSetLogFormat}.  Selecting
     836by the order of the letters used in \code{psLogSetFormat}.  Selecting
    798837an output format with fewer than the complete set of 5 entries simply
    799838removes those entries from the output messages.
     839
     840Specifying a \code{fmt} of \code{NULL} turns off logging (equivalent
     841to calling \code{psLogSetDestination(PS_LOG_TO_NONE)}, whereas if the
     842\code{fmt} is \code{""}, then the format reverts to the default.
    800843
    801844%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    833876error that has already resulted in a call to \code{psError}.  The
    834877final required argument, \code{fmt}, is a \code{printf}-style format
    835 that is passed to \code{psLogMsg} with code \code{PS_LOG_ERROR}.
     878that is passed to \code{psLogVMsg} with code \code{PS_LOG_ERROR}.
    836879
    837880The result of a call to \code{psError} shall be to push an error onto
     
    855898
    856899\begin{verbatim}
    857 const psErr *psGetError(int which);     ///< return specified error (or an "error" with code PS_ERR_NONE)
    858 const psErr *psLastError(void);         ///< return last error (or an "error" with code PS_ERR_NONE)
     900const psErr *psErrorGet(int which);     ///< return specified error (or an "error" with code PS_ERR_NONE)
     901const psErr *psErrorLast(void);         ///< return last error (or an "error" with code PS_ERR_NONE)
    859902\end{verbatim}
    860903
     
    866909
    867910The entire error stack may be printed to an open file descriptor by
    868 calling \code{psErrorStackPrint} (or \code{psVErrorStackPrint}); if
     911calling \code{psErrorStackPrint} (or \code{psErrorVStackPrint}); if
    869912and only if there are current errors, the printf-style string
    870913\code{fmt} is first printed to the file descriptor \code{fd}. In this
     
    872915defined in the next section.  Note that these are also available in
    873916the \code{psErr} structure. The successive lines of the traceback
    874 should be indented by an additional space (see
    875 example). \code{psVErrorStackPrint} shall not invoke \code{va_end}.
     917should be indented by an additional space (see example).
     918\code{psErrorVStackPrint} shall not invoke \code{va_end}.
    876919
    877920\begin{verbatim}
    878921void psErrorStackPrint(FILE *fd, const char *fmt, ...); ///< print the errorstack to this file descriptor
    879 void psVErrorStackPrint(FILE *fd, const char *fmt, va_list va); ///< print the errorstack to this file
     922void psErrorVStackPrint(FILE *fd, const char *fmt, va_list va); ///< print the errorstack to this file
    880923                                                                ///< descriptor
    881924\end{verbatim}
     
    916959\begin{verbatim}
    917960typedef struct {
    918     psErrorCode code;                  // An error code
    919     char *descrip;                     // the associated description
     961    psErrorCode code;                  ///< An error code
     962    const char *descrip;               ///< the associated description
    920963} psErrorDescription;
    921964\end{verbatim}
     
    9981041to be valid values of \code{errno}.
    9991042
    1000 The implementation may add extra fields (e.g., \code{PS_ERR_N_ERR_CLASSES}).
    1001 
    10021043\file{psErrorCodes.c} shall define the necessary function to register
    10031044the error codes.
     
    10421083        psErrorStackPrint(stdout, "Traceback:\n");
    10431084
    1044         if (psLastError()->code == PS_ERR_UNKNOWN) {
     1085        if (psErrorLast()->code == PS_ERR_UNKNOWN) {
    10451086            fprintf(stderr, "Last error is of unknown type\n");
    10461087        }
    1047         if (psGetError(2)->code == PS_ERR_IO) {
     1088        if (psErrorGet(2)->code == PS_ERR_IO) {
    10481089            fprintf(stderr, "Third oldest error is of type IO\n");
    10491090        }
     
    10531094    psErrorStackPrint(stdout, "Traceback:\n");
    10541095
    1055     if (psLastError()->code == PS_ERR_NONE) {
     1096    if (psErrorLast()->code == PS_ERR_NONE) {
    10561097        fprintf(stderr, "No errors. Hurrah\n");
    10571098    }
     
    11781219\end{verbatim}
    11791220We discuss the application of \code{psType} in more detail in
    1180 section~\ref{arithmetic}. 
     1221section~\ref{sec:arithmetic}. 
    11811222
    11821223\subsection{Arrays of Simple Types}
     
    12691310array.\footnote{\eg{} \code{va->arr[i] = psMemIncrRefCounter(ptr);}}
    12701311If \code{psVoidPtrArrayFree}'s argument \code{elemFree} is NULL, the
    1271 list should be deleted, but not the elements on it (although their
    1272 \code{refcounter}'s should be decremented).
     1312list should be deleted, but not the elements on it (an error should be
     1313raised if the \code{refCounter} is 1; otherwise their
     1314\code{refCounter}'s should be decremented) --- this is to account for
     1315an array of heterogeneous types.
    12731316
    12741317\subsection{Doubly-linked lists}
     
    13791422\code{iter} is provided by the functions:
    13801423\begin{verbatim}
    1381 void psDlistSetIterator(psDlist *list, int where);
    1382 void *psDlistGetNext(psDlist *list);
    1383 void *psDlistGetPrev(psDlist *list);
     1424void psDlistSetIterator(psDlist *list, int where, int which);
     1425void *psDlistGetNext(psDlist *list, int which);
     1426void *psDlistGetPrev(psDlist *list, int which);
    13841427\end{verbatim}
    13851428The first of these functions uses the value of \code{where} to set the
    13861429iteration cursor for the given list to the beginning
    1387 \code{PS_DLIST_HEAD} or the end \code{PS_DLIST_TAIL}.  The next two
    1388 functions move the iteration cursor forward or backwards, returning
    1389 the data item from the resulting list entry, or returning \code{NULL}
    1390 at the end of the list.  Explicit traversal of the list using the
    1391 \code{psDlistElem}s \code{prev} and \code{next} pointers is also
    1392 supported.
     1430\code{PS_DLIST_HEAD} or the end \code{PS_DLIST_TAIL} for the iterator
     1431specified by \code{which}.  The next two functions move the iteration
     1432cursor forward or backwards, returning the data item from the
     1433resulting list entry, or returning \code{NULL} at the end of the list.
     1434Explicit traversal of the list using the \code{psDlistElem}s
     1435\code{prev} and \code{next} pointers is also supported.
     1436
     1437A list may be sorted using \code{psDlistSort}, which requires the
     1438specification of a comparison function to specify how the objects on
     1439the list should be sorted.  The motivation is primarily to be able to
     1440iterate on a sorted list of keys from a hash.
     1441\begin{verbatim}
     1442psDlist *psDlistSort(psDlist *list, int (*compare)(const void *a, const void *b) );
     1443\end{verbatim}
    13931444
    13941445\subsection{Hash Tables}
     
    14111462
    14121463For PSLib, we define a hash table and hash buckets as follows:
    1413 \footnote{ We choose not to use the posix function \code{hcreate},
     1464\footnote{ We choose not to use the POSIX function \code{hcreate},
    14141465\code{hdestroy}, and \code{hsearch} as they only support a single hash
    14151466table at any one time.}
     
    15501601psBitset *
    15511602psBitsetSet(psBitset *restrict myBits, ///< Input bitset
    1552              int bit                     ///< Bit to set
     1603            int bit                    ///< Bit to set
    15531604    );
    15541605\end{verbatim}
     
    15821633performing the specified \code{operator} (one of \code{"AND"},
    15831634\code{"OR"}, or \code{"XOR"}) on \code{inBits1} and \code{inBits2}.
     1635
     1636Finally, \code{psBitsetNot} applies a unary \code{NOT} to a bitset:
     1637
     1638\begin{verbatim}
     1639/** Apply unary NOT to a bitset */
     1640psBitset *
     1641psBitsetNot(psBitset *out,              ///< Output bitset, or NULL
     1642            psBitset *in                ///< Input bitset to be NOT-ed
     1643    );
     1644\end{verbatim}
    15841645
    15851646%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    17491810
    17501811\subsubsection{Histograms}
     1812\label{sec:histograms}
    17511813
    17521814We also require to be able to generate histograms, given a list of
     
    17541816
    17551817\begin{verbatim}
    1756 /** Histograms */
     1818/** Histograms  */
    17571819typedef struct {
    1758     const psFloatArray *restrict lower; ///< Lower bounds for the bins
    1759     const psFloatArray *restrict upper; ///< Upper bounds for the bins
    1760     psIntArray *nums;                   ///< Number in each of the bins
    1761     const float minVal, maxVal;         ///< Minimum and maximum values
    1762     int minNum, maxNum;                 ///< Number below the minimum and above the maximum
     1820    const psFloatArray *restrict bounds; ///< Bounds for the bins
     1821    psIntArray *nums;                   ///< Number in each of the bins
     1822    const float minVal, maxVal;         ///< Minimum and maximum values
     1823    int minNum, maxNum;                 ///< Number below the minimum and above the maximum
     1824    int uniform;                        ///< Is it a uniform distribution?
    17631825} psHistogram;
    17641826\end{verbatim}
     
    17721834/** Constructor */
    17731835psHistogram *
    1774 psHistogramAlloc(float lower,           ///< Lower limit for the bins
    1775                  float upper,           ///< Upper limit for the bins
    1776                  float size             ///< Size of the bins
     1836psHistogramAlloc(float lower,           ///< Lower limit for the bins
     1837                 float upper,           ///< Upper limit for the bins
     1838                 int n                  ///< Number of the bins
    17771839    );
    17781840\end{verbatim}
     
    17811843/** Generic constructor */
    17821844psHistogram *
    1783 psHistogramAllocGeneric(const psFloatArray *restrict lower, ///< Lower bounds for the bins
    1784                         const psFloatArray *restrict upper, ///< Upper bounds for the bins
     1845psHistogramAllocGeneric(const psFloatArray *restrict bounds, ///< Bounds for the bins
    17851846                        float minVal,   ///< Minimum value
    17861847                        float maxVal    ///< Maximum value
     
    18251886\item Calculate a matrix determinant;
    18261887\item Perform matrix addition, subtraction and multiplication;
    1827 \item Transpose a matrix; and
     1888\item Transpose a matrix;
     1889\item Get eigenvectors for a matrix; and
    18281890\item Convert a matrix to a vector.
    18291891\end{itemize}
     
    19051967\end{verbatim}
    19061968
     1969Eigenvectors of a matrix are calculated by \code{psMatrixEigenvectors}:
     1970
     1971\begin{verbatim}
     1972/** Eigenvectors of a matrix */
     1973psVector *
     1974psMatrixEigenvectors(psImage *myMatrix  ///< Matrix to get eigenvectors for
     1975    );
     1976\end{verbatim}
     1977
    19071978Finally, we specify two functions to convert between matrices and
    19081979vectors.  This allows the use of vectors in matrix arithmetic, since
     
    19302001
    19312002We require the ability to calculate the (fast) fourier transforms of
    1932 floating-point two-dimensional arrays (including one-dimensional
    1933 arrays as a limiting case), and use these to perform filtering, and
    1934 calculate the power spectrum and cross-correlation.  We expect that
    1935 these will be implemented through wrapping an external library.  We
    1936 define a FFT type:
    1937 
    1938 \begin{verbatim}
    1939 /** Fast Fourier Transform */
    1940 typedef struct {
    1941     p_psFFTDetails *details;            ///< Details on FFT implementation (private)
    1942     int nx, ny;                         ///< Size in x and y
    1943     float *real;                        ///< Data in real space: a 2D array using the [nx*y + x] stuff
    1944     void *fourier;                      ///< Data in fourier space; implementation dependent
    1945 } psFFT;
    1946 \end{verbatim}
    1947 
    1948 The \code{details} entry allows us to wrap the external library in the
    1949 event that it carries information around from one transform to the
    1950 next (as is the case for FFTW), and hence it is
    1951 implementation-dependent.  The size of the data in real space are
    1952 stored in \code{nx} and \code{ny}, and the data is stored as a
    1953 Fortran-style array, \code{real}.  Since different libraries store the
    1954 data in the Fourier space differently, \code{fourier}, we have
    1955 specified it as of type \code{void*}.
    1956 
    1957 The intent is that every function that employs a FFT will act on a
    1958 \code{psFFT}.  A user will create a \code{psFFT} by stuffing it with
    1959 the real data, perform operations in Fourier space using the
    1960 \code{psFFT}, and then extract the output as an image when done.
    1961 
    1962 We specify two constructors --- one for use with images, and the other
    1963 for use with a one-dimensional array.  The destructor returns an image
    1964 that includes the real space data.
    1965 
    1966 \begin{verbatim}
    1967 /** Constructor */
    1968 psFFT *
    1969 psFFTAlloc(psImage *image               //!< Image to transform
    1970            );
    1971 
    1972 /** Constructor for 1D case */
    1973 psFFT *
    1974 psFFTAlloc1D(const psFloatArray *arr    //!< Array to transform
    1975              );
    1976 
    1977 /** Destructor. Returns the data in the real space as an image. */
     2003floating-point two-dimensional images and one-dimensional arrays.  We
     2004expect that these will be implemented through wrapping an external
     2005library.
     2006
     2007The forward and reverse Fourier transforms may be calculated using the
     2008following APIs:
     2009
     2010\begin{verbatim}
     2011/** Forward FFT an image.  Returns a complex float image. */
    19782012psImage *
    1979 psFFTFree(psImage *out,                 //!< Image to write the data to, or NULL
    1980           psFFT *restrict fft           //!< FFT to destroy
    1981           );
    1982 \end{verbatim}
    1983 
    1984 The forward and reverse Fourier transforms may be calculated,
    1985 returning the altered \code{psFFT}:
    1986 
    1987 \begin{verbatim}
    1988 /** Forward FFT: from real to fourier space */
    1989 psFFT *
    1990 psFFTForward(psFFT *fft                 ///< FFT to apply (input and output)
    1991              );
    1992 
    1993 /** Reverse FFT: from fourier to real space */
    1994 psFFT *
    1995 psFFTReverse(psFFT *fft                 ///< FFT to apply (input and output)
    1996              );
    1997 \end{verbatim}
    1998 
    1999 The data in Fourier space may be filtered using functions that return
    2000 a multiplicative factor for a given position in Fourier space.  These
    2001 function return the altered \code{psFFT}.  If the filter function
    2002 specified for \code{psFFTFilter()} returns a real value, $r$, then the
    2003 corresponding value in the Fourier plane should be multiplied by $r$.
    2004 If the real and imaginary filter functions specified for
    2005 \code{psFFTFilterComplex()} return the values $r$ and $s$,
    2006 respectively, then the corresponding value in the Fourier plane should
    2007 be multiplied by the complex number $r + si$.
    2008 
    2009 \begin{verbatim}
    2010 /** Apply filter function in fourier space */
    2011 psFFT *
    2012 psFFTFilter(psFFT *fft,                 //!< FFT to use (input and output)
    2013             float (*filterFunc)(int kx, int ky) //!< External filter function
    2014             );
    2015 
    2016 /** Apply complex filter function */
    2017 psFFT *
    2018 psFFTFilterComplex(psFFT *fft,          //!< FFT to use (input and output)
    2019                    float (*realFilterFunc)(int kx, int ky), //!< External filter function, real part
    2020                    float (*imagFilterFunc)(int kx, int ky) //!< External filter function, imaginary part
    2021                    );
    2022 \end{verbatim}
    2023 
    2024 The cross-correlation function may be calculated from two Fourier transforms,
    2025 and returns a new \code{psFFT}:
    2026 
    2027 \begin{verbatim}
    2028 /** Calculate FFT of the cross-correlation.  Multiplication of the first FFT with the complex conjugate of
    2029  *  the second.
    2030  */
    2031 psFFT *
    2032 psFFTCrossCorrelate(psFFT *out          //!< Output FFT (or NULL)
    2033                     psFFT *fft1, psFFT *fft2 //!< FFTs to use in cross-correlation
    2034                     );
    2035 \end{verbatim}
    2036 
    2037 In convolution, two Fourier transforms are multiplied, and the resultant
    2038 \code{psFFT} is returned.
    2039 
    2040 \begin{verbatim}
    2041 /** Calculate FFT of the convolution.  Straight multiplication of the FFTs */
    2042 psFFT *
    2043 psFFTConvolve(psFFT *out,               ///< Output FFT (or NULL)
    2044               const psFFT *fft1, const psFFT *fft2 ///< FFTs to multiply
    2045               );
    2046 \end{verbatim}
    2047 
    2048 The power spectrum is calculated from the Fourier transform, returning
    2049 an array of floating-point values containing the power spectrum.
    2050 
    2051 \begin{verbatim}
    2052 /** Calculate power spectrum */
     2013psImageFFT(const psImage *image         ///< Image to transform
     2014    );
     2015
     2016/** Forward FFT an array of floating-point numbers. */
    20532017psFloatArray *
    2054 psFFTPowerSpec(psFFT *fft               ///< FFT to use (input and output)
    2055                );
    2056 \end{verbatim}
    2057 
    2058 And finally, the user may extract both the real data and the complex
    2059 Fourier space data as \code{psImage}s (without needing to destroy the
    2060 \code{psFFT}).  For \code{psFFTGetFT}, note that the output image will be of
    2061 type \code{complex float}, since it extracts the data in the Fourier plane,
    2062 which is complex.
    2063 
    2064 \begin{verbatim}
    2065 /* Convert the real data in the FFT struct to an image again */
     2018psFloatArrayFFT(const psFloatArray *arr ///< Array to transform
     2019    );
     2020
     2021/** Inverse FFT an image. */
    20662022psImage *
    2067 psFFTGetImage(psImage *out,             //!< Image to write to (or NULL)
    2068               const psFFT *fft          //!< FFT to get image from
    2069               );
    2070 
    2071 /** Convert the Fourier transform data in the FFT struct to an image of complex numbers */
     2023psImageInverseFFT(const psImage *fftImage ///< FFT-ed image to inverse-transform
     2024    );
     2025
     2026/** Inverse FFT an array of complex floating-point numbers */
     2027psComplexArray *
     2028psComplexArrayInverseFFT(const psComplexArray *fftArray ///< FFT-ed array to inverse-transform
     2029    );
     2030\end{verbatim}
     2031
     2032Neither the forward or inverse transforms shall multiply by $1/N$ (or
     2033$1/N^{1/2}$), and so it falls to the responsibility of the user to
     2034multiply an image that has been forward- and reverse-transformed by
     2035$1/N$.
     2036
     2037The \code{psImage}s output by \code{psImageFFT} and
     2038\code{psImageInverseFFT} should be of complex floating-point type.  Following
     2039an inverse transform, therefore, the user will likely want to extract the
     2040real parts:
     2041
     2042\begin{verbatim}
     2043/** Get the real part of an image */
    20722044psImage *
    2073 psFFTGetFT(psImage *out,                //!< Image to write to (or NULL)
    2074            const psFFT *fft             //!< FFT to get Fourier transform from
    2075            );
     2045psImageReal(psImage *out,               ///< Image for output (or NULL)
     2046            const psImage *in           ///< Image to get the real part of
     2047            );
     2048
     2049/** Get the real part of an array of complex floating-point numbers */
     2050psFloatArray *
     2051psComplexArrayReal(psFloatArray *out,   ///< Array for output (or NULL)
     2052                   const psComplexArray *in ///< Array to get the real part of
     2053    );
     2054\end{verbatim}
     2055
     2056To aid operations on FFT-ed images or arrays, we also specify
     2057functions to return the complex conjugate of an image or array:
     2058
     2059\begin{verbatim}
     2060/** Get the complex conjugate of an image */
     2061psImage *
     2062psImageConjugate(psImage *out,          ///< Image for output (or NULL)
     2063                 const psImage *in      ///< Image to get the complex conjugate of
     2064    );
     2065
     2066/** Get the complex conjugate of an array of complex floating-point numbers */
     2067psComplexArray *
     2068psComplexArrayConjugate(psComplexArray *out, ///< Array for output (or NULL)
     2069                        const psComplexArray *in ///< Array to get the complex conjugate of
     2070    );
     2071\end{verbatim}
     2072
     2073Finally, the power spectrum may be calculated directly from the
     2074original image or array:
     2075
     2076\begin{verbatim}
     2077/** Calculate power spectrum of an image */
     2078psImage *
     2079psImagePowerSpectrum(const psImage *image ///< Image to obtain power spectrum of
     2080    );
     2081
     2082/** Calculate power spectrum of an array of floating-point numbers */
     2083psFloatArray *
     2084psFloatArrayPowerSpectrum(const psFloatArray *arr ///< Array to obtain power spectrum of
     2085    );
    20762086\end{verbatim}
    20772087
     
    20852095\begin{verbatim}
    20862096/** Evaluate a non-normalized Gaussian with the given mean and sigma at the given coordianate.  Note that this
    2087     is not a Gaussian deviate.  The evaluated Gaussian is: \f[ exp(-\frac{(x-mean)^2}{2\sigma^2}) \f] */
     2097 *  is not a Gaussian deviate.  The evaluated Gaussian is:
     2098 *  \f[ 1/(\sqrt(2\pi)\sigma) exp(-\frac{(x-mean)^2}{2\sigma^2}) \f]
     2099 */
    20882100float
    20892101psGaussian(float x,                     ///< Value at which to evaluate
     
    21802192
    21812193\begin{verbatim}
    2182 /** Minimize a particular non-linear function */
     2194/** Find the minimum of a particular non-linear function */
    21832195psFloatArray *
    2184 psMinimize(float (*myFunction)(const psFloatArray *restrict), ///< Function to minimize
    2185            psFloatArray *restrict initialGuess, ///< Initial guess
    2186            psIntArray *restrict paramMask //!< 1 = fit for parameter, 0 = hold parameter constant
    2187            );
     2196psMinimize(psFloatArray *restrict initialGuess, ///< Initial guess and answer
     2197           float (*myFunction)(const psFloatArray *restrict), ///< Function to minimize
     2198           float (*myFuncDeriv)(const psFloatArray *restrict), ///< Derivatives of function, or NULL
     2199           const psIntArray *restrict paramMask //!< 1 = fit for parameter, 0 = hold parameter constant
     2200           );
    21882201\end{verbatim}
    21892202
     
    21912204the specified function.  It takes as input a function,
    21922205\code{myFunction}, an initial guess for the parameters that minimize
    2193 the function, \code{initialGuess}, and an optional mask for the
    2194 parameters to minimize, \code{paramMask}.
     2206the function, \code{initialGuess} which is returned with the best-fit
     2207parameters, and an optional mask for the parameters to minimize,
     2208\code{paramMask} (all parameters are fit if \code{NULL}).
    21952209
    21962210\begin{verbatim}
    21972211/** Minimize chi^2 for input data */
    21982212psFloatArray *
    2199 psMinimizeChi2(float (*evalModel)(const psFloatArray *restrict,
    2200                                   const psFloatArray *restrict), ///< Model to fit; (domain and params)
    2201                const psFloatArray *restrict domain, ///< The domain values for the corresponding measurements
    2202                const psFloatArray *restrict data, ///< Data to fit
    2203                const psFloatArray *restrict errors, ///< Errors in the data
    2204                psFloatArray *restrict initialGuess, ///< Initial guess
    2205                const psIntArray *restrict paramMask ///< 1 = fit for parameter, 0 = hold parameter constant
     2213psMinimizeChi2(psFloatArray *restrict initialGuess, ///< Initial guess and answer
     2214               float (*evalModel)(const psFloatArray *restrict,
     2215                                  const psFloatArray *restrict), ///< Model to fit; (domain and params)
     2216               const psFloatArray *restrict domain, ///< The domain values for the corresponding measurements
     2217               const psFloatArray *restrict data, ///< Data to fit
     2218               const psFloatArray *restrict errors, ///< Errors in the data
     2219               const psIntArray *restrict paramMask ///< 1 = fit for parameter, 0 = hold parameter constant
    22062220    );
    22072221\end{verbatim}
     
    22122226parameters, \code{evalModel}; a list of observations, (\code{domain},
    22132227\code{data}, and \code{errors}); an initial guess at the best-fit
    2214 parameters, \code{initialGuess}, and an optional mask specifying which
    2215 parameters are to be fit, \code{paramMask}.
     2228parameters, \code{initialGuess} which is returned with the best-fit
     2229parameters, and an optional mask specifying which parameters are to be
     2230fit, \code{paramMask} (all parameters are fit if \code{NULL}).
    22162231
    22172232\begin{verbatim}
     
    22432258\begin{verbatim}
    22442259typedef struct psImage {
    2245     psType type;                        ///< image data type and dimension
    2246     int nx, ny;                         ///< size of image
    2247     int x0, y0;                         ///< data region relative to parent
     2260    psType type;                        ///< image data type and dimension
     2261    const int nx, ny;                   ///< size of image
     2262    const int x0, y0;                   ///< data region relative to parent
    22482263    union {
    2249         float **rows;                   ///< Pointers to floating-point data (default)
    2250         short int **rows_si;            ///< Pointers to short-integer data
    2251         int **rows_i;                   ///< Pointers to integer data
    2252         long int **rows_li;             ///< Pointers to long-integer data
    2253         unsigned short int **rows_usi;  ///< Pointers to unsigned-short-integer data
    2254         unsigned int **rows_ui;         ///< Pointers to unsigned-integer data
    2255         unsigned long int **rows_uli;   ///< Pointers to unsigned-long-integer data
    2256         float **rows_f;                 ///< Pointers to floating-point data
    2257         double **rows_d;                ///< Pointers to double-precision data
    2258         complex float **rows_complex;   ///< Pointers to complex floating-point data
     2264        float **rows;                   ///< Pointers to floating-point data (default)
     2265        short int **rows_si;            ///< Pointers to short-integer data
     2266        int **rows_i;                   ///< Pointers to integer data
     2267        long int **rows_li;             ///< Pointers to long-integer data
     2268        unsigned short int **rows_usi;  ///< Pointers to unsigned-short-integer data
     2269        unsigned int **rows_ui;         ///< Pointers to unsigned-integer data
     2270        unsigned long int **rows_uli;   ///< Pointers to unsigned-long-integer data
     2271        float **rows_f;                 ///< Pointers to floating-point data
     2272        double **rows_d;                ///< Pointers to double-precision data
     2273        complex float **rows_complex;   ///< Pointers to complex floating-point data
    22592274    } rows;
    2260     struct psImage *parent;             ///< parent, if a subimage
    2261     int Nchildren;                      ///< number of subimages
    2262     struct psImage *children;           ///< children of this region; array of Nchildren pointers
     2275    const struct psImage *parent;       ///< parent, if a subimage
     2276    int Nchildren;                      ///< number of subimages
     2277    struct psImage *children;           ///< children of this region; array of Nchildren pointers
    22632278} psImage;
    22642279\end{verbatim}
     
    22662281This structure represents an image consisting of a 2-D array of
    22672282pixels.  The size of this array is given by the elements \code{(nx,
    2268 ny)}.  The data type of the pixel is defined by the \code{psType type}
    2269 entry (see \ref{arithmetic}).  (n.b. that for FITS images, these
    2270 values are restricted to the datatypes equivalent to the valid BITPIX
    2271 values 8, 16, 32, -32, -64).  The image represented in the data
    2272 structure may represent a subset of the pixels in a complete array, in
    2273 which case the image is considered to be the child of that parent
    2274 array.  The offset of the \code{(0,0)} pixel in this array relative to
    2275 the parent array is given by the elements \code{(x0,y0)}.  The
    2276 structure may include references to subrasters (\code{children,
    2277 Nchildren}) and/or to a containing array (\code{parent}).  Unless this
    2278 is image is a child of another image (represents a subset of the
    2279 pixels of another image), the image data is allocated in a contiguous
    2280 block.
     2283ny)}.  The data type of the pixel is defined in the \code{psType type}
     2284entry (specifically, the \code{psElemType} member, \code{type}; see
     2285\ref{sec:arithmetic}).  (n.b. that for FITS images, these values are
     2286restricted to the datatypes equivalent to the valid BITPIX values 8,
     228716, 32, -32, -64).  The image represented in the data structure may
     2288represent a subset of the pixels in a complete array, in which case
     2289the image is considered to be the child of that parent array.  The
     2290offset of the \code{(0,0)} pixel in this array relative to the parent
     2291array is given by the elements \code{(x0,y0)}.  The structure may
     2292include references to subrasters (\code{children, Nchildren}) and/or
     2293to a containing array (\code{parent}).  Unless this is image is a
     2294child of another image (represents a subset of the pixels of another
     2295image), the image data is allocated in a contiguous block.
    22812296
    22822297We require a variety of functions to manipulate these image
     
    22912306to the valid FITS BITPIX types.
    22922307\begin{verbatim}
    2293 psImage *psImageAlloc (int nx, int ny, psType type);
     2308psImage *psImageAlloc (int nx, int ny, psElemType type);
    22942309\end{verbatim}
    22952310where \code{nx} and \code{ny} specify the size of the image and
     
    23012316outside of the parent image.
    23022317\begin{verbatim}
    2303 psImage *psImageSubset(psImage *out, psImage *image, int nx, int ny, int x0, int y0);
     2318psImage *psImageSubset(const psImage *image, int nx, int ny, int x0, int y0);
    23042319\end{verbatim}
    23052320where \code{image} is the parent image, \code{nx,ny} specify the
    23062321dimensions of the desired subraster, and \code{x0, y0} specify the
    23072322starting pixel of the subraster.  The entire subraster must be
    2308 contained within the raster of the parent image.  An image structure
    2309 to populate may be specified by \code{out}, or if this is \code{NULL},
    2310 a new structure is allocated. 
     2323contained within the raster of the parent image.  Note that the
     2324\code{refCounter} for the parent should be incremented.
    23112325
    23122326Free the memory associated with a specific image, including the pixel
     
    23212335\end{verbatim}
    23222336
    2323 Free the image structure memory associated with the children of a
    2324 specific image, returning the number of children freed.  Do not free
    2325 the pixel data:
    2326 \begin{verbatim}
    2327 int psImageFreeChildren(psImage *image);
    2328 \end{verbatim}
    2329 
    2330 Create a copy of the specified image.  If the output target pointer is
    2331 not NULL, place the result in the specified structure.  The output
    2332 image data must be allocated as a single, contiguous block of memory.
    2333 \begin{verbatim}
    2334 psImage *psImageCopy(psImage *output, psImage *input);
     2337Create a copy of the specified image, converting the type in the
     2338process.  If the output target pointer is not NULL, place the result
     2339in the specified structure.  The output image data must be allocated
     2340as a single, contiguous block of memory.  The output image may not be
     2341the input image.
     2342\begin{verbatim}
     2343psImage *psImageCopy(psImage *output, const psImage *input, psElemType type);
    23352344\end{verbatim}
    23362345
     
    23462355specified by \code{stats}.
    23472356\begin{verbatim}
    2348 psFloatArray *psImageSlice(psFloatArray *out, psImage *input, int x, int y, int nx, int ny,
     2357psFloatArray *psImageSlice(psFloatArray *out, const psImage *input, int x, int y, int nx, int ny,
    23492358                           int direction, const psStats *stats);
    23502359\end{verbatim}
    23512360
    23522361Extract pixels from an image along a line to a vector (array of
    2353 floats).  The vector \code{xs,ys} - \code{xe,ye} forms the basis of
     2362floats).  The vector \code{(xs,ys)} - \code{(xe,ye)} forms the basis of
    23542363the output vector.  Pixels are considered in a rectangular region of
    23552364width \code{dw} about this vector.  The input region is collapsed in
     
    23602369specified by \code{stats}.
    23612370\begin{verbatim}
    2362 psFloatArray *psImageCut(psFloatArray *out, psImage *input, float xs, float ys, float xe, float ye,
    2363                          float dw, psStats *stats);
     2371psFloatArray *psImageCut(psFloatArray *out, const psImage *input, float xs, float ys, float xe, float ye,
     2372                         float dw, const psStats *stats);
    23642373\end{verbatim}
    23652374
     
    23712380output vector value is specified by \code{stats}
    23722381\begin{verbatim}
    2373 psFloatArray *psImageRadialCut(psFloatArray *out, psImage *input, float x, float y, float radius, float dr,
    2374                                psStats *stats);
     2382psFloatArray *psImageRadialCut(psFloatArray *out, const psImage *input, float x, float y,
     2383                               const psFloatArray *radii, const psStats *stats);
    23752384\end{verbatim}
    23762385
     
    23792388Rebin image to new scale.  A new image is constructed in which the
    23802389dimensions are reduced by a factor of \code{scale} $\le 1$ (it is an
    2381 error for \code{scale} $> 1$).  The output image is generated from all
    2382 input image pixels.  Each pixel in the output image is derived from
    2383 the statistics of the corresponding set of input image pixels based on
    2384 the statistics specified by \code{stats}.
    2385 \begin{verbatim}
    2386 psImage *psImageRebin(psImage *out, psImage *input, float scale, psStats *stats);
     2390error for \code{scale} $> 1$).  The \code{scale} is equal in each
     2391dimension.  The output image is generated from all input image pixels.
     2392Each pixel in the output image is derived from the statistics of the
     2393corresponding set of input image pixels based on the statistics
     2394specified by \code{stats}.
     2395\begin{verbatim}
     2396psImage *psImageRebin(psImage *out, const psImage *input, float scale, const psStats *stats);
    23872397\end{verbatim}
    23882398
     
    23942404that a positive angle is an anti-clockwise rotation. 
    23952405\begin{verbatim}
    2396 psImage *psImageRotate(psImage *out, psImage *input, float angle);
     2406psImage *psImageRotate(psImage *out, const psImage *input, float angle);
    23972407\end{verbatim}
    23982408
     
    24042414set to the value given by \code{exposed}. 
    24052415\begin{verbatim}
    2406 psImage *psImageShift(psImage *out, psImage *input, float dx, float dy, float exposed);
     2416psImage *psImageShift(psImage *out, const psImage *input, float dx, float dy, float exposed);
    24072417\end{verbatim}
    24082418
     
    24112421image.  Edge pixels wrap to the other side (no values are lost).
    24122422\begin{verbatim}
    2413 psImage *psImageRoll(psImage *out, psImage *input, int dx, int dy);
     2423psImage *psImageRoll(psImage *out, const psImage *input, int dx, int dy);
    24142424\end{verbatim}
    24152425
     
    24192429determined are specified by \code{stats}.
    24202430\begin{verbatim}
    2421 psStats *psImageGetStats(psImage *input, psStats *stats);
     2431psStats *psImageGetStats(psStats *stats, const psImage *input);
    24222432\end{verbatim}
    24232433
    24242434Construct a histogram from an image (or subimage).  The histogram to
    24252435generate is specified by \code{psHistogram hist} (see
    2426 section~\ref{histogram}).
    2427 \begin{verbatim}
    2428 psHistogram *psImageHistogram(psHistogram *hist, psImage *input);
     2436section~\ref{sec:histograms}).
     2437\begin{verbatim}
     2438psHistogram *psImageHistogram(psHistogram *hist, const psImage *input);
    24292439\end{verbatim}
    24302440
     
    24332443interest.
    24342444\begin{verbatim}
    2435 psPolynomial2D *psImageFitPolynomial(psImage *input, psPolynomial2D *coeffs);
     2445psPolynomial2D *psImageFitPolynomial(psPolynomial2D *coeffs, const psImage *input);
    24362446\end{verbatim}
    24372447
    24382448Evaluate a 2-D polynomial surface for the image pixels.  Given the
    24392449input polynomial coefficients, set the image pixel values on the basis
    2440 of the polynomial function.  \tbd{Return value is not yet specified.}
    2441 \begin{verbatim}
    2442 int psImageEvalPolynomial(psImage *input, psPolynomial2D *coeffs);
     2450of the polynomial function.
     2451\begin{verbatim}
     2452psImage *psImageEvalPolynomial(psImage *input, const psPolynomial2D *coeffs);
    24432453\end{verbatim}
    24442454
     
    24492459full image or a subimage to be read.  The starting pixel of the region
    24502460is specified by \code{x,y}, while the dimensions of the requested
    2451 region are specified by \code{nx,ny}.  A value of -1 for these two
    2452 parameters specifies the full array of the requested image.  If the
    2453 native image is a cube, the value of z specifies the requested slice
    2454 of the image.  The data is read from the extension specified by
    2455 extname (matching the EXTNAME keyword) or by the extnum value (with 0
    2456 representing the PHU, 1 the first extension, etc).  This function must
    2457 generate an error and return \code{NULL} if any of the specified
    2458 parameters are out of range for the data in the image file, if the
    2459 specified image file does not exist, or the image on disk is zero- or
    2460 one-dimensional.
    2461 \begin{verbatim}
    2462 psImage *psImageReadSection(psImage *output, int x, int y, int nx, int ny, int z,
    2463                             char *extname, int extnum, char *filename);
     2461region are specified by \code{nx,ny}.  A negative value of -1 for
     2462these two parameters specifies the full array of the requested image,
     2463less absolute value of the variable.  If the native image is a cube,
     2464the value of z specifies the requested slice of the image.  The data
     2465is read from the extension specified by extname (matching the EXTNAME
     2466keyword) or by the extnum value (with 0 representing the PHU, 1 the
     2467first extension, etc).  This function must call \code{psError} and
     2468return \code{NULL} if any of the specified parameters are out of range
     2469for the data in the image file, if the specified image file does not
     2470exist, or the image on disk is zero- or one-dimensional.
     2471\begin{verbatim}
     2472psImage *psImageReadSection(psImage *output, int x0, int y0, int nx, int ny, int z,
     2473                            const char *extname, int extnum, const char *filename);
    24642474\end{verbatim}
    24652475 
     
    24692479\begin{verbatim}
    24702480psImage *psImageFReadSection(psImage *output, int x, int y, int nx, int ny, int z,
    2471                              char *extname, int extnum, FILE *f);
     2481                             const char *extname, int extnum, FILE *f);
    24722482\end{verbatim}
    24732483\tbd{The use of \code{FILE*} to carry around the file descriptor is to be reviewed.}
     
    24802490created.
    24812491\begin{verbatim}
    2482 psImage *psImageWriteSection(psImage *input, int x, int y, int z,
    2483                              char *extname, int extnum, char *filename);
     2492psImage *psImageWriteSection(const psImage *input, int x, int y, int z,
     2493                             const char *extname, int extnum, const char *filename);
    24842494\end{verbatim}
    24852495
    24862496Write an image section to file descriptor as above:
    24872497\begin{verbatim}
    2488 psImage *psImageFWriteSection(psImage *input, int x, int y, int z,
    2489                               char *extname, int extnum, FILE *f);
     2498psImage *psImageFWriteSection(const psImage *input, int x, int y, int z,
     2499                              const char *extname, int extnum, FILE *f);
    24902500\end{verbatim}
    24912501\tbd{The use of \code{FILE*} to carry around the file descriptor is to be reviewed.}
    24922502
    24932503Read header data from a FITS image file into a \code{psMetaData}
    2494 structure (see section~\ref{metadata}.  The \code{extname} and
     2504structure (see section~\ref{sec:metadata}.  The \code{extname} and
    24952505\code{extnum} parameters specify the extension of interest as above.
    24962506If the named extension does not exist, the function should return an
    24972507error.
    24982508\begin{verbatim}
    2499 psMetadata *psImageReadHeader(psMetadata *output, char *extname, int extnum, char *filename);
     2509psMetadata *psImageReadHeader(psMetadata *output, const char *extname, int extnum, const char *filename);
    25002510\end{verbatim}
    25012511
     
    25032513structure. 
    25042514\begin{verbatim}
    2505 psMetadata *psImageFReadHeader(psMetadata *output, char *extname, int extnum, FILE *f);
     2515psMetadata *psImageFReadHeader(psMetadata *output, const char *extname, int extnum, FILE *f);
    25062516\end{verbatim}
    25072517
     
    25312541(multiply overlay times image), \code{/} (divide image by overlay).
    25322542\begin{verbatim}
    2533 int psImageOverlaySection(psImage *image, psImage *overlay, int x0, int y0, char *op);
     2543int psImageOverlaySection(psImage *image, const psImage *overlay, int x0, int y0, const char *op);
    25342544\end{verbatim}
    25352545
     
    29282938appropriate destructor for the \code{val} (recall that it is the duty
    29292939of the \code{psMyTypeFree}s to decrement the \code{refCounter} and
    2930 free the memory if and only if the new value of the \code{refCounter}
    2931 is zero --- see \S\ref{sec:free}).
     2940free the memory if and only if the \code{refCounter == 1} --- see
     2941\S\ref{sec:free}).
    29322942
    29332943\begin{verbatim}
     
    30103020key, e.g., if the user only wants to iterate through
    30113021\code{IPP.machines.sky} and doesn't want to bother with
    3012 \code{IPP.machines.detector}.
     3022\code{IPP.machines.detector}.  The iterator should iterate over every
     3023item of metadata --- even those that are non-unique.
    30133024
    30143025\begin{verbatim}
     
    30173028    );
    30183029
    3019 /// get the next entry in the sequence
     3030/// get the next item in the sequence
    30203031psMetadataItem *psMetadataGetNext(psMetadata *restrict md, ///< metadata to get from
    3021                                   const char *restrict match ///< Match this
     3032                                  const char *restrict match, ///< Match this
     3033                                  int which ///< Which iterator to use
    30223034    );
    30233035\end{verbatim}
     
    30463058\subsection{Detector and sky positions}
    30473059
    3048 \tbd{the definition of psCoord must be review: split into psSphere and psPlane?}
    3049 
    30503060Both detector and sky positions will be used extensively in the IPP.
    30513061The first are linear coordinates which conform to Euclidean geometry
    30523062while the second are angular coordinates for which additional care
    3053 must often be taken.  Since these both consist of two coordinates with
    3054 their associated errors, we bundle these into a single generic
    3055 structure, \code{psCoord}, containing \code{union}s to handle the
    3056 semantic differences.  A variety of functions should operate
    3057 equivalently on both types of structures (\tbd{list}), while other
    3058 functions must behave differently when the operand is an angular vs a
    3059 linear coordinate system.
    3060 
    3061 \begin{verbatim}
    3062 /** A point in 2-D space, with errors.
    3063  */
    3064 typedef union {
    3065     struct {
    3066         double x;                       ///< x position
    3067         double y;                       ///< y position
    3068         double xErr;                    ///< Error in x position
    3069         double yErr;                    ///< Error in y position
    3070     } xy;
    3071     struct {
    3072         double r;                       ///< RA
    3073         double d;                       ///< Dec
    3074         double rErr;                    ///< Error in RA
    3075         double dErr;                    ///< Error in Dec
    3076     } rd;
    3077 } psCoord;
     3063must often be taken.  We put these into two structures,
     3064\code{psPlaneCoord} and \code{psSphereCoord}, respectively.
     3065Partitioning these two will enable error-checking.
     3066
     3067\begin{verbatim}
     3068/** A point in 2-D space, with errors. */
     3069typedef struct {
     3070    double x;                           ///< x position
     3071    double y;                           ///< y position
     3072    double xErr;                        ///< Error in x position
     3073    double yErr;                        ///< Error in y position
     3074} psPlaneCoord;
     3075
     3076/** A point on the surface of a sphere, with errors */
     3077typedef struct {
     3078    double r;                           ///< RA
     3079    double d;                           ///< Dec
     3080    double rErr;                        ///< Error in RA
     3081    double dErr;                        ///< Error in Dec
     3082} psSphereCoord;
    30783083\end{verbatim}
    30793084
     
    31203125    psDPolynomial2D *x;
    31213126    psDPolynomial2D *y;
    3122 } psCoordXform;
     3127} psPlaneCoordXform;
    31233128\end{verbatim}
    31243129
     
    31293134frame \code{x,y} (say a single CCD) to a second frame \code{p,q} (say,
    31303135a second CCD image). If we have only first order terms in the
    3131 transformation \code{psCoordXform T}, the new coordinates would be
     3136transformation \code{psPlaneCoordXform T}, the new coordinates would be
    31323137represented by the terms:
    31333138%
     
    31473152    psDPolynomial4D *x;
    31483153    psDPolynomial4D *y;
    3149 } psDistortion;
    3150 \end{verbatim}
    3151 
    3152 Like \code{psCoordXform}, \code{psDistortion} contains two
     3154} psPlaneDistortion;
     3155\end{verbatim}
     3156
     3157Like \code{psPlaneCoordXform}, \code{psPlaneDistortion} contains two
    31533158\code{psDPolynomial4D} structures representing polynomials of
    31543159arbitrary order as a function of four, rather than two dimensions.
     
    31593164single CCD) of an object with magnitude and color \code{m,c} to a
    31603165second frame \code{p,q} (say, a second CCD image). If we have only
    3161 first order terms in the transformation \code{psCoordXform T}, the new
     3166first order terms in the transformation \code{psPlaneCoordXform T}, the new
    31623167coordinates would be represented by the terms:
    31633168%
     
    31763181\begin{verbatim}
    31773182/** apply the coordinate transformation to the given coordinate */
    3178 psCoord *psCoordXformApply (psCoord *out, ///< Output coordinates, or NULL
    3179                             const psCoordXform *frame, ///< coordinate transformation
    3180                             const psCoord *coords ///< input coordiate
    3181     );
    3182 \end{verbatim}
    3183 %
    3184 \begin{verbatim}
     3183psPlaneCoord *psPlaneCoordXformApply (psPlaneCoord *out, ///< Output coordinates, or NULL
     3184                                      const psPlaneCoordXform *frame, ///< coordinate transformation
     3185                                      const psPlaneCoord *coords ///< input coordiate
     3186    );
     3187
    31853188/** apply the optical distortion to the given coordinate, magnitude, color */
    3186 psCoord *psDistortionApply (psCoord *out, ///< Output coordinates, or NULL
    3187                             const psdistortion *pattern, ///< optical distortion pattern
    3188                             const psCoord *coords, ///< input coordinate
    3189                             float mag, ///< magnitude of object
    3190                             float color ///< color of object
     3189psPlaneCoord *psPlaneDistortionApply (psPlaneCoord *out, ///< Output coordinates, or NULL
     3190                                      const psPlaneDistortion *pattern, ///< optical distortion pattern
     3191                                      const psPlaneCoord *coords, ///< input coordinate
     3192                                      float mag, ///< magnitude of object
     3193                                      float color ///< color of object
    31913194    );
    31923195\end{verbatim}
     
    31993202systems.  All of these basic spherical transformations represent
    32003203rotations of the spherical coordinate reference.  We specify a general
    3201 transformation function which takes a structure \code{psCoordSphere}
    3202 defining the relationship between two spherical coordinate systems.
    3203 We also define a function to generate \code{psCoordSphere}, which
    3204 contains the appropriate sines and cosines of the angles, based on the
    3205 three angles describing the location of the pole and the relative
    3206 equatorial rotations of the two systems.  We also specify special
    3207 coordinate transformations between standard coordinate systems which
    3208 define the value of psCoordSphere internally and automatically.
    3209 
    3210 \begin{verbatim}
    3211 /** Convert to new spherical coordinate system */
    3212 psCoord *
    3213 psCoordTransform (psCoord *coord,
    3214                   psCoordSphere *sphere) ///< ICRS coordinates to convert
    3215 ;
    3216 \end{verbatim}
    3217 
    3218 \begin{verbatim}
    3219 /** Construct  to new spherical coordinate system */
    3220 psCoordSphere *
    3221 psCoordSphereDefine (double pole1, double pole2, double rotation);
    3222 \end{verbatim}
    3223 
    3224 \begin{verbatim}
    3225 /** Convert ICRS to Ecliptic */
    3226 psCoord *
    3227 psCoordinatesItoE(const psCoord *restrict coordinates ///< ICRS coordinates to convert
    3228     );
    3229 \end{verbatim}
    3230 
    3231 \begin{verbatim}
    3232 /** Convert Ecliptic to ICRS */
    3233 psCoord *
    3234 psCoordinatesEtoI(const psCoord *restrict coordinates ///< Ecliptic coordinates to convert
    3235     );
    3236 \end{verbatim}
    3237 
    3238 \begin{verbatim}
    3239 /** Convert ICRS to Galactic */
    3240 psCoord *
    3241 psCoordinatesItoG(const psCoord *restrict coordinates ///< ICRS coordinates to convert
    3242     );
    3243 \end{verbatim}
    3244 
    3245 \begin{verbatim}
    3246 /** Convert Galactic to ICRS */
    3247 psCoord *
    3248 psCoordinatesGtoI(const psCoord *restrict coordinates ///< Galactic coordinates to convert
    3249     );
     3204transformation function which takes a structure,
     3205\code{psSphereCoordTransformation}, defining the transformation
     3206between two spherical coordinate systems (the structure contains the
     3207sines and cosines of the angles involved so as to minimize computation
     3208time for repeated transformations).  We also define a function to
     3209generate \code{psSphereCoordTransformation}, based on the three angles
     3210describing the location of the pole and the relative equatorial
     3211rotations of the two systems.  We also specify special functions to
     3212return the \code{psSphereCoordTransformation} for transformations
     3213between standard coordinate systems.
     3214
     3215\begin{verbatim}
     3216/** General spherical transformation */
     3217typedef struct {
     3218    double sin1, sin2, sin3, cos1, cos2, cos3; ///< Sines and cosines for transformation
     3219} psSphereCoordTransformation;
     3220\end{verbatim}
     3221
     3222The constructor and destructor are defined as follows:
     3223
     3224\begin{verbatim}
     3225/** Constructor */
     3226psSphereCoordTransformation *
     3227psSphereCoordTransformationAlloc(double pole1, ///< First location of pole
     3228                                 double pole2, ///< Second location of pole
     3229                                 double rotation ///< Rotation between systems
     3230    );
     3231
     3232/** Destructor */
     3233void psSphereCoordTranformationFree(psSphereCoordTransformation *trans ///< Transformation to destroy
     3234    );
     3235\end{verbatim}
     3236
     3237Spherical coordinates may be transformed by providing the transformation to
     3238\code{psSphereCoordTransform}:
     3239
     3240\begin{verbatim}
     3241/** Apply general spherical transformation */
     3242psSphereCoord *
     3243psSphereCoordTransform(const psSphereCoord *coord, ///< Coordinates to convert
     3244                       psSphereCoordSystem *sys ///< System to use to convert
     3245    );
     3246\end{verbatim}
     3247
     3248The following functions simply return the appropriate
     3249\code{psSphereCoordTransformation} to convert between predefined
     3250spherical coordinate systems (i.e., ICRS, Ecliptic and Galactic).
     3251
     3252\begin{verbatim}
     3253/** Return transformation structure to convert ICRS to Ecliptic */
     3254psSphereCoordTransformation *psSphereCoordTransformationItoE(void);
     3255
     3256/** Return transformation structure to convert Ecliptic to ICRS */
     3257psSphereCoordTransformation *psSphereCoordTransformationEtoI(void);
     3258
     3259/** Return transformation structure to convert ICRS to Galactic */
     3260psSphereCoordTransformation *psSphereCoordTransformationItoG(void);
     3261
     3262/** Return transformation structure to convert Galactic to ICRS */
     3263psSphereCoordTransformation *psSphereCoordTransformationGtoI(void);
    32503264\end{verbatim}
    32513265
     
    32643278\end{itemize}
    32653279
    3266 \begin{verbatim}
    3267 psCoord *psCoordProject (psCoord *coord, char *projection);
     3280The following functions will project and deproject (respectively)
     3281spherical coordinates:
     3282
     3283\begin{verbatim}
     3284/** Project spherical system onto a plane */
     3285psPlaneCoord *
     3286psCoordProject(const psSphereCoord *coord, ///< Spherical coordinates to project
     3287               const char *projection   ///< Projection to use
     3288    );
     3289
     3290/** Deproject plane onto spherical system */
     3291psSphereCoord *
     3292psCoordDeproject(const psPlaneCoord *coord, ///< Plane coordinates to deproject
     3293                 const char *projection ///< Projection to use
     3294    );
    32683295\end{verbatim}
    32693296
     
    32753302\begin{verbatim}
    32763303/** Get offset (RA,Dec) on the sky between two positions position1 and position2 may not be identical */
    3277 psCoord *
    3278 psGetOffset(const psCoord *restrict position1, ///< Position 1
    3279             const psCoord *restrict position2, ///< Position 2
    3280             const char *type            ///< Type of offset: Linear, Spherical/Arcsec, Spherical/Degreees etc
    3281     );
    3282 \end{verbatim}
    3283 
    3284 \begin{verbatim}
     3304psSphereCoord *
     3305psSphereCoordGetOffset(const psSphereCoord *restrict position1, ///< Position 1
     3306                       const psSphereCoord *restrict position2, ///< Position 2
     3307                       const char *type         ///< Type of offset: Linear, Spherical/Arcsec,
     3308                                                ///< Spherical/Degreees etc
     3309    );
     3310
    32853311/** Apply an offset to a position */
    3286 psCoord *
    3287 psApplyOffset(const psCoord *restrict position, ///< Position
    3288               const psCoord *restrict offset, ///< Offset
    3289               const char *type          ///< Type of offset: Linear, Spherical/Arcsec, Spherical/Degreees etc
    3290     );
    3291 \end{verbatim}
     3312psSphereCoord *
     3313psSphereCoordApplyOffset(const psSphereCoord *restrict position, ///< Position
     3314                         const psSphereCoord *restrict offset, ///< Offset
     3315                         const char *type               ///< Type of offset: Linear, Spherical/Arcsec,
     3316                                                        ///< Spherical/Degreees etc
     3317    );
     3318\end{verbatim}
     3319
     3320Note that these should propagate the errors appropriately.
    32923321
    32933322
     
    33183347single readout of the detector, along with metadata needed to define
    33193348that readout: the origin and binning of the image relative to the
    3320 original detector pixels explicitly in the structure, a pointer to the
    3321 appropriate overscan region, and pointers to the general metadata and
    3322 derived objects, if any.
     3349original detector pixels explicitly in the structure, and pointers to
     3350the general metadata and derived objects, if any.
    33233351
    33243352A single detector may produce more than one read which is associated.
     
    33823410
    33833411A readout is the result of a single read of a cell (or a portion
    3384 thereof).  It contains a pointer to the pixel data, a separate pointer
    3385 to the overscan pixels, and additional pointers to the objects found
    3386 in the readout, and the readout metadata.  It also contains the offset
    3387 from the lower-left corner of the chip, in the case that the CCD was
    3388 windowed.
     3412thereof).  It contains a pointer to the pixel data, and additional
     3413pointers to the objects found in the readout, and the readout
     3414metadata.  It also contains the offset from the lower-left corner of
     3415the chip, in the case that the CCD was windowed.
    33893416
    33903417\begin{verbatim}
    33913418/** a Readout: a collection of pixels */
    33923419typedef struct {
    3393     int x0, y0;                         ///< Offset from the lower-left corner
    3394     int nx, ny;                         ///< Image binning
    3395     psImage *image;                     ///< imaging area of cell
    3396     psDlist *objects;                   ///< objects derived from cell
    3397     psImage *overscan;                  ///< bias region (subimage) of cell
     3420    const int x0, y0;                ///< Offset from the lower-left corner
     3421    const int nx, ny;                ///< Image binning
     3422    psImage *image;                  ///< imaging area of cell
     3423    psDlist *objects;                ///< objects derived from cell
    33983424    psMetadata *md;                  ///< Readout-level metadata
    33993425} psReadout;
     
    34213447 */
    34223448typedef struct {
    3423     int nReadouts;                      ///< number of readouts in this cell realization; each may have its own
    3424                                         ///< image, objects and overscan.
    3425     struct psReadout *readouts;         ///< Readouts from the cell
    3426     psMetadata *md;                  ///< Cell-level metadata
    3427 
    3428     psCoordXform *cellToChip;           ///< Transformations from cell coordinates to chip coordinates
    3429     psCoordXform *cellToFPA;            ///< Transformations from cell coordinates to FPA coordinates
    3430     psCoordXform *cellToSky;            ///< Quick and Dirty transformations from cell coordinates to sky
    3431 
    3432     struct psChip  *parentChip;         ///< chip which contains this cell
     3449    int nReadouts;                      ///< number of readouts in this cell realization; each may have its
     3450                                        ///< own image, objects and overscan.
     3451    struct psReadout *readouts;         ///< Readouts from the cell
     3452    psMetadata *md;                     ///< Cell-level metadata
     3453
     3454    psPlaneCoordXform *cellToChip;      ///< Transformations from cell coordinates to chip coordinates
     3455    psPlaneCoordXform *cellToFPA;       ///< Transformations from cell coordinates to FPA coordinates
     3456    psPlaneCoordXform *cellToSky;       ///< Quick and Dirty transformations from cell coordinates to sky
     3457
     3458    struct psChip  *parentChip;         ///< chip which contains this cell
    34333459} psCell;
    34343460\end{verbatim}
     
    34423468a coordinate transform from the chip to the focal plane.  It is
    34433469expected that this transforms will consist of two second-order 2D
    3444 polynomials; hence we expect that it is prudent to include a reverse
     3470polynomials; hence we think that it is prudent to include a reverse
    34453471transformation which will be derived from numerically inverting the
    34463472forward transformation.
     
    34523478typedef struct {
    34533479    int nCells;                         ///< Number of Cells assigned
    3454     psCell *cells;                      ///< Cells in the Chip
    3455 
    3456     psMetadata *md;                  ///< Chip-level metadata
    3457     psCoordXform *chipToFPA;            ///< Transformations from chip coordinates to FPA coordinates
    3458     psCoordXform *FPAtoChip;            ///< Transformations from FPA coordinates to chip
    3459 
    3460     struct psFPA *parentFPA;            ///< FPA which contains this chip
     3480    struct psCell *cells;               ///< Cells in the Chip
     3481
     3482    psMetadata *md;                     ///< Chip-level metadata
     3483    psPlaneCoordXform *chipToFPA;       ///< Transformations from chip coordinates to FPA coordinates
     3484    psPlaneCoordXform *FPAtoChip;       ///< Transformations from FPA coordinates to chip
     3485
     3486    struct psFPA *parentFPA;            ///< FPA which contains this chip
    34613487} psChip;
    34623488\end{verbatim}
     
    34723498two coordinates in position, the magnitude of the object, and the
    34733499color of the object) in order to correct for optical distortions and
    3474 the effects of the atmosphere; hence we expect that it is prudent to
     3500the effects of the atmosphere; hence we think that it is prudent to
    34753501include a reverse transformation which will be derived from
    34763502numerically inverting the forward transformation.  Since colors are
     
    34883514    int nChips;                         ///< Number of Cells assigned
    34893515    int nAlloc;                         ///< Number of Cells available
    3490     psChip *chips;                      ///< Chips in the Focal Plane Array
    3491 
    3492     psMetadata *md;                     ///< FPA-level metadata
    3493     psDistortion *TPtoFP;               ///< Transformation term from
    3494     psDistortion *FPtoTP;               ///< Transformation term from
    3495     psFixedPattern *pattern;            ///< Fixed pattern residual offsets
    3496     psExposure *exp;                    ///< information about this exposure
     3516    struct psChip *chips;               ///< Chips in the Focal Plane Array
     3517
     3518    psMetadata *md;                     ///< FPA-level metadata
     3519    psPlaneDistortion *TPtoFP;          ///< Transformation term from
     3520    psPlaneDistortion *FPtoTP;          ///< Transformation term from
     3521    psFixedPattern *pattern;            ///< Fixed pattern residual offsets
     3522    const psExposure *exp;              ///< information about this exposure
    34973523    psPhotSystem colorPlus, colorMinus; ///< Colour reference
    34983524    float rmsX, rmsY;                   ///< Dispersion in astrometric solution
     
    35113537typedef struct {
    35123538    // Telescope longitude, latitude and height are stored separately, since they don't change with pointing
    3513     double ra, dec;                     ///< Telescope boresight
    3514     double ha;                          ///< Hour angle
    3515     double zd;                          ///< Zenith distance
    3516     double az;                          ///< Azimuth
    3517     double lst;                         ///< Local Sidereal Time
    3518     float mjd;                          ///< MJD of observation
    3519     float rotAngle;                     ///< Rotator position angle
    3520     float temp;                         ///< Air temperature, for estimating refraction
    3521     float pressure;                     ///< Air pressure, for calculating refraction
    3522     float humidity;                     ///< Relative humidity, for calculating refraction
    3523     float exptime;                      ///< Exposure time
     3539    const double ra, dec;               ///< Telescope boresight
     3540    const double ha;                    ///< Hour angle
     3541    const double zd;                    ///< Zenith distance
     3542    const double az;                    ///< Azimuth
     3543    const double lst;                   ///< Local Sidereal Time
     3544    const float mjd;                    ///< MJD of observation
     3545    const float rotAngle;               ///< Rotator position angle
     3546    const float temp;                   ///< Air temperature, for estimating refraction
     3547    const float pressure;               ///< Air pressure, for calculating refraction
     3548    const float humidity;               ///< Relative humidity, for calculating refraction
     3549    const float exptime;                ///< Exposure time
    35243550    /* Derived quantities */
    3525     float posAngle;                     ///< Position angle
    3526     float parallactic;                  ///< Parallactic angle
    3527     float airmass;                      ///< Airmass, calculated from zenith distance
    3528     float pf;                           ///< Parallactic factor
    3529     char *cameraName;                   ///< name of camera which provided exposure
    3530     char *telescopeName;                ///< name of telescope which provided exposure
    3531     psGrommit *grommit;                 ///< Data needed to convert from the sky to the tangent plane
     3551    const float posAngle;               ///< Position angle
     3552    const float parallactic;            ///< Parallactic angle
     3553    const float airmass;                ///< Airmass, calculated from zenith distance
     3554    const float pf;                     ///< Parallactic factor
     3555    const char *cameraName;             ///< name of camera which provided exposure
     3556    const char *telescopeName;          ///< name of telescope which provided exposure
    35323557} psExposure;
    35333558\end{verbatim}
     
    35833608
    35843609The following steps are required to convert from the cell coordinates to
    3585 the sky \tbd{convert Cell->Chip and Chip->FP to psDistortion}:
     3610the sky \tbd{convert Cell-$>$Chip and Chip-$>$FP to psDistortion}:
    35863611\begin{itemize}
    35873612\item Cell $\longleftrightarrow$ Chip: two 2D polynomials, $(X,Y) = f(x,y)$;
     
    36133638
    36143639\begin{verbatim}
    3615 /** Information needed (by SLALib) to convert Apparent to Observed Position */
     3640/** Information needed (by SLALIB) to convert Apparent to Observed Position */
    36163641typedef struct {
    3617     double latitude;                    ///< geodetic latitude (radians)
    3618     double sinLat, cosLat;              ///< sine and cosine of geodetic latitude
    3619     double abberationMag;               ///< magnitude of diurnal aberration vector
    3620     double height;                      ///< height (HM)
    3621     double temperature;                 ///< ambient temperature (TDK)
    3622     double pressure;                    ///< pressure (PMB)
    3623     double humidity;                    ///< relative humidity (RH)
    3624     double wavelength;                  ///< wavelength (WL)
    3625     double lapseRate;                   ///< lapse rate (TLR)
    3626     double refractA, refractB;          ///< refraction constants A and B (radians)
    3627     double longitudeOffset;             ///< longitude + eqn of equinoxes + ``sidereal UT'' (radians)
    3628     double siderealTime;                ///< local apparent sidereal time (radians)
     3642    const double latitude;              ///< geodetic latitude (radians)
     3643    const double sinLat, cosLat;        ///< sine and cosine of geodetic latitude
     3644    const double abberationMag;         ///< magnitude of diurnal aberration vector
     3645    const double height;                ///< height (HM)
     3646    const double temperature;           ///< ambient temperature (TDK)
     3647    const double pressure;              ///< pressure (PMB)
     3648    const double humidity;              ///< relative humidity (RH)
     3649    const double wavelength;            ///< wavelength (WL)
     3650    const double lapseRate;             ///< lapse rate (TLR)
     3651    const double refractA, refractB;    ///< refraction constants A and B (radians)
     3652    const double longitudeOffset;       ///< longitude + eqn of equinoxes + ``sidereal UT'' (radians)
     3653    const double siderealTime;          ///< local apparent sidereal time (radians)
    36293654} psGrommit;
     3655\end{verbatim}
     3656
     3657The \code{psGrommit} is calculated from telescope information for the
     3658particular exposure:
     3659
     3660\begin{verbatim}
     3661/** Constructor */
     3662psGrommit *
     3663psGrommitAlloc(const psExposure *exp    ///< Relevant exposure
     3664    );
     3665
     3666/** Destructor */
     3667void
     3668psGrommitFree(psGrommit *grommit        ///< Grommit to destroy
     3669    );
    36303670\end{verbatim}
    36313671
     
    36643704/** returns Chip in FPA which contains the given FPA coordinate */
    36653705psChip *
    3666 psChipInFPA (psChip *out,               ///< Chip to return, or NULL
    3667              const psFPA *fpa,          ///< FPA description
    3668              const psCoord *coord       ///< coordinate in FPA
    3669              );
    3670 \end{verbatim}
    3671 
    3672 \begin{verbatim}
     3706psChipInFPA (psChip *out,               ///< Chip to return, or NULL
     3707             const psPlaneCoord *coord  ///< coordinate in FPA
     3708             const psFPA *fpa,          ///< FPA description
     3709             );
     3710
    36733711/** returns Cell in Chip which contains the given chip coordinate */
    36743712psCell *
    3675 psCellInChip(psCell *out,               ///< Cell to return, or NULL
    3676              const psChip *chip,        ///< chip description
    3677              const psCoord *coord       ///< coordinate in chip
    3678              );
    3679 \end{verbatim}
    3680 
    3681 Usually we will want to go directly from the FPA to the Cell, so we
    3682 also specify the following function, which performs the above two
    3683 functions in order.
    3684 
    3685 \begin{verbatim}
     3713psCellInChip(psCell *out,               ///< Cell to return, or NULL
     3714             const psPlaneCoord *coord  ///< coordinate in chip
     3715             const psChip *chip,        ///< chip description
     3716             );
     3717
    36863718/** Return the cell in FPA which contains the given FPA coordinates */
    36873719psCell *
    3688 psCellInFPA(psCell *out,                ///< Cell to return, or NULL
    3689             const psFPA *fpa,           ///< FPA description
    3690             const psCoord *coord        ///< Coordinate in FPA
    3691             );
     3720psCellInFPA(psCell *out,                ///< Cell to return, or NULL
     3721            const psPlaneCoord *coord   ///< Coordinate in FPA
     3722            const psFPA *fpa,           ///< FPA description
     3723            );
    36923724\end{verbatim}
    36933725
     
    37243756\begin{verbatim}
    37253757/** Convert (RA,Dec) to cell and cell coordinates */
    3726 psCoord *
    3727 psCoordSkyToCell(psCoord *out,          ///< Coordinates to return, or NULL
    3728                  psCell *cell,          ///< Cell to return
    3729                  const psFPA *fpa       ///< FPA description
    3730                  );
    3731 \end{verbatim}
    3732 
    3733 \begin{verbatim}
     3758psPlaneCoord *
     3759psCoordSkyToCell(psPlaneCoord *out,     ///< Coordinates to return, or NULL
     3760                 psCell *cell,          ///< Cell to return
     3761                 const psSphereCoord *in, ///< Input coordinates
     3762                 const psFPA *fpa       ///< FPA description
     3763                 );
     3764
    37343765/** Convert cell and cell coordinate to (RA,Dec) */
    3735 psCoord *
    3736 psCoordCellToSky(psCoord *out,          ///< Coordinates to return, or NULL
    3737                  const psCell *cell,    ///< Cell to get coordinates for
    3738                  const psCoord *coord   ///< cell coordinates to transform
    3739                  );
    3740 \end{verbatim}
    3741 
    3742 \begin{verbatim}
     3766psSphereCoord *
     3767psCoordCellToSky(psSphereCoord *out,    ///< Coordinates to return, or NULL
     3768                 const psPlaneCoord *coord ///< cell coordinates to transform
     3769                 const psCell *cell,    ///< Cell to get coordinates for
     3770                 );
     3771
    37433772/** Quick and dirty cell to (RA,Dec) --- employs cellToSky transformation */
    3744 psCoord *
    3745 psCoordCellToSkyQuick(psCoord *out,     ///< Coordinates to return, or NULL
    3746                       const psCell *cell, ///< Cell description
    3747                       const psCoord *coord ///< cell coordinates to transform
    3748                       );
    3749 \end{verbatim}
    3750 
    3751 \begin{verbatim}
     3773psSphereCoord *
     3774psCoordCellToSkyQuick(psSphereCoord *out, ///< Coordinates to return, or NULL
     3775                      const psPlaneCoord *coord ///< cell coordinates to transform
     3776                      const psCell *cell, ///< Cell description
     3777                      );
     3778
    37523779/** Convert (RA,Dec) to tangent plane coords */
    3753 psCoord *
    3754 psCoordSkyToTP(psCoord *out,            ///< Coordinates to return, or NULL
    3755                const psExposure *exp,   ///< Exposure description
    3756                const psCoord *coord     ///< input Sky coordinate
    3757                );
    3758 \end{verbatim}
    3759 
    3760 \begin{verbatim}
     3780psPlaneCoord *
     3781psCoordSkyToTP(psPlaneCoord *out,       ///< Coordinates to return, or NULL
     3782               const psSphereCoord *coord ///< input Sky coordinate
     3783               const psGrommit *grommit, ///< Grommit for fast conversion
     3784               );
     3785
    37613786/** Convert tangent plane coords to focal plane coordinates */
    3762 psCoord *
    3763 psCoordTPtoFPA(psCoord *out,            ///< Coordinates to return, or NULL
    3764                const psFPA *fpa,        ///< FPA description
    3765                const psCoord *coord     ///< input TP coordinate
    3766                );
    3767 \end{verbatim}
    3768 
    3769 \begin{verbatim}
     3787psPlaneCoord *
     3788psCoordTPtoFPA(psPlaneCoord *out,       ///< Coordinates to return, or NULL
     3789               const psPlaneCoord *coord ///< input TP coordinate
     3790               const psFPA *fpa,        ///< FPA description
     3791               );
     3792
    37703793/** converts the specified FPA coord to the coord on the given Chip */
    3771 psCoord *
    3772 psCoordFPAtoChip (psCoord *out,         ///< Coordinates to return, or NULL
    3773                   const psChip *chip,   ///< Chip of interest
    3774                   const psCoord *coord  ///< input FPA coordinate
    3775                   );
    3776 \end{verbatim}
    3777 
    3778 \begin{verbatim}
     3794psPlaneCoord *
     3795psCoordFPAtoChip (psPlaneCoord *out,    ///< Coordinates to return, or NULL
     3796                  const psPlaneCoord *coord ///< input FPA coordinate
     3797                  const psChip *chip,   ///< Chip of interest
     3798                  );
     3799
    37793800/** converts the specified Chip coord to the coord on the given Cell */
    3780 psCoord *
    3781 psCoordChiptoCell (psCoord *out,        ///< Coordinates to return, or NULL
    3782                    const psCell *cell,  ///< Cell of interest
    3783                    const psCoord *coord ///< input Chip coordinate
    3784                    );
    3785 \end{verbatim}
    3786 
    3787 \begin{verbatim}
     3801psPlaneCoord *
     3802psCoordChiptoCell (psPlaneCoord *out,   ///< Coordinates to return, or NULL
     3803                   const psPlaneCoord *coord ///< input Chip coordinate
     3804                   const psCell *cell,  ///< Cell of interest
     3805                   );
     3806
    37883807/** converts the specified Cell coord to the coord on the parent Chip */
    3789 psCoord *
    3790 psCoordCelltoChip (psCoord *out,        ///< Coordinates to return, or NULL
    3791                    const psCell *cell,  ///< Cell description
    3792                    const psCoord *coord ///< input Cell coordinate
    3793                    );
    3794 \end{verbatim}
    3795 
    3796 \begin{verbatim}
     3808psPlaneCoord *
     3809psCoordCelltoChip (psPlaneCoord *out,   ///< Coordinates to return, or NULL
     3810                   const psPlaneCoord *coord ///< input Cell coordinate
     3811                   const psCell *cell,  ///< Cell description
     3812                   );
     3813
    37973814/** converts the specified Chip coord to the coord on the parent FPA */
    3798 psCoord *
    3799 psCoordChiptoFPA (psCoord *out,         ///< Coordinates to return, or NULL
    3800                   const psChip *chip,   ///< Chip description
    3801                   const psCoord *coord  ///< input Chip coordinate
    3802                   );
    3803 \end{verbatim}
    3804 
    3805 \begin{verbatim}
     3815psPlaneCoord *
     3816psCoordChiptoFPA (psPlaneCoord *out,            ///< Coordinates to return, or NULL
     3817                  const psPlaneCoord *coord     ///< input Chip coordinate
     3818                  const psChip *chip,   ///< Chip description
     3819                  );
     3820
    38063821/** Convert focal plane coords to tangent plane coordinates */
    3807 psCoord *
    3808 psCoordFPAToTP(psCoord *out,            ///< Coordinates to return, or NULL
    3809                const psFPA *fpa,        ///< FPA description
    3810                const psCoord *coord     ///< input FPA coordinate
    3811                );
    3812 \end{verbatim}
    3813 
    3814 \begin{verbatim}
     3822psPlaneCoord *
     3823psCoordFPAToTP(psPlaneCoord *out,               ///< Coordinates to return, or NULL
     3824               const psPlaneCoord *coord ///< input FPA coordinate
     3825               const psFPA *fpa,        ///< FPA description
     3826               );
     3827
    38153828/** Convert tangent plane coords to (RA,Dec) */
    3816 psCoord *
    3817 psCoordTPtoSky(psCoord *out,            ///< Coordinates to return, or NULL
    3818                const psExposure *exp,   ///< Exposure description
    3819                const psCoord *coord     ///< input TP coordinate
    3820                );
    3821 \end{verbatim}
    3822 
    3823 \begin{verbatim}
     3829psSphereCoord *
     3830psCoordTPtoSky(psSphereCoord *out,      ///< Coordinates to return, or NULL
     3831               const psPlaneCoord *coord ///< input TP coordinate
     3832               const psGrommit *grommit, ///< Grommit for fast conversion
     3833               );
     3834
    38243835/** Convert Cell coords to FPA coordinates */
    3825 psCoord *
    3826 psCoordCellToFPA(psCoord *out,          ///< Coordinates to return, or NULL
    3827                  const psCell *cell,    ///< Cell description
    3828                  const psCoord *coord   ///< Input cell coordinates
    3829                 );
     3836psPlaneCoord *
     3837psCoordCellToFPA(psPlaneCoord *out,     ///< Coordinates to return, or NULL
     3838                 const psPlaneCoord *coord ///< Input cell coordinates
     3839                 const psCell *cell,    ///< Cell description
     3840                );
    38303841\end{verbatim}
    38313842
     
    38403851/** Get the airmass for a given position and sidereal time */
    38413852float
    3842 psGetAirmass(const psCoord *coord,      ///< Position on the sky
    3843              double siderealTime,       ///< Sidereal time
    3844              float height               ///< Height above sea level
     3853psGetAirmass(const psSphereCoord *coord, ///< Position on the sky
     3854             double siderealTime,       ///< Sidereal time
     3855             float height               ///< Height above sea level
    38453856             );
    38463857\end{verbatim}
     
    38493860/** Get the parallactic angle for a given position and sidereal time */
    38503861float
    3851 psGetParallactic(const psCoord *coord, ///< Position on the sky
     3862psGetParallactic(const psSphereCoord *coord, ///< Position on the sky
    38523863                 double siderealTime    ///< Sidereal time
    38533864                 );
     
    38933904\begin{verbatim}
    38943905typedef struct {
    3895     int ID;                             ///< ID number for this photometric system
    3896     char *name;                         ///< Name of photometric system
    3897     char *camera;                       ///< Camera for photometric system
    3898     char *filter;                       ///< Filter used for photometric system
    3899     char *detector;                     ///< Detector used for photometric system
     3906    const int ID;                       ///< ID number for this photometric system
     3907    const char *name;                   ///< Name of photometric system
     3908    const char *camera;                 ///< Camera for photometric system
     3909    const char *filter;                 ///< Filter used for photometric system
     3910    const char *detector;               ///< Detector used for photometric system
    39003911} psPhotSystem;
    39013912\end{verbatim}
     
    39393950M_{\rm pM} - pA, M_{\rm sP} - M_{\rm sM} - sA)$.
    39403951
     3952\TBD{Really want a set of polynomials defined for specific colour
     3953ranges.}
     3954
    39413955%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    39423956%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    39523966\begin{verbatim}
    39533967/** Get Sun Position */
    3954 psCoord *
    3955 psGetSunPos(float mjd                   ///< MJD to get position for
    3956     );
    3957 \end{verbatim}
    3958 
    3959 \begin{verbatim}
     3968psSphereCoord *
     3969psGetSunPos(float mjd                   ///< MJD to get position for
     3970    );
     3971
    39603972/** Get Moon position */
    3961 psCoord *
    3962 psGetMoonPos(float mjd,                 ///< MJD to get position for
    3963              double latitude,           ///< Latitude for apparent position
    3964              double longitude           ///< Longitude for apparent position
    3965     );
    3966 \end{verbatim}
    3967 
    3968 \begin{verbatim}
     3973psSphereCoord *
     3974psGetMoonPos(float mjd,                 ///< MJD to get position for
     3975             double latitude,           ///< Latitude for apparent position
     3976             double longitude           ///< Longitude for apparent position
     3977    );
     3978
    39693979/** Get Moon phase */
    39703980float
    39713981psGetMoonPhase(float mjd                ///< MJD to get phase for
    39723982    );
    3973 \end{verbatim}
    3974 
    3975 \begin{verbatim}
     3983
    39763984/** Get Planet positions */
    3977 psCoord *
     3985psSphereCoord *
    39783986psGetSolarSystemPos(const char *solarSystemObject, ///< Named S.S. object
    39793987                    float mjd           ///< MJD to get position for
     
    39944002%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    39954003
    3996 \appendix
    3997 
    3998 \pagebreak
    3999 \section{API Summary: all functions}
    4000 
    4001 \subsection{System Utilities}
    4002 \input{psSystemGroup.tex}
    4003 
    4004 \subsection{Data Containers}
    4005 \input{psDataGroup.tex}
    4006 
    4007 \subsection{Math Utilities}
    4008 \input{psMathGroup.tex}
    4009 
    4010 \subsection{Astronomy Functions}
    4011 \input{psAstroGroup.tex}
    4012 
    4013 \pagebreak
    4014 \section{API Summary: all structures}
    4015 \input{psStructures.tex}
     4004%\appendix
     4005%
     4006%\pagebreak
     4007%\section{API Summary: all functions}
     4008%
     4009%\subsection{System Utilities}
     4010%\input{psSystemGroup.tex}
     4011%
     4012%\subsection{Data Containers}
     4013%\input{psDataGroup.tex}
     4014%
     4015%\subsection{Math Utilities}
     4016%\input{psMathGroup.tex}
     4017%
     4018%\subsection{Astronomy Functions}
     4019%\input{psAstroGroup.tex}
     4020%
     4021%\pagebreak
     4022%\section{API Summary: all structures}
     4023%\input{psStructures.tex}
    40164024
    40174025\bibliographystyle{plain} \bibliography{panstarrs}
Note: See TracChangeset for help on using the changeset viewer.