Changeset 627
- Timestamp:
- May 7, 2004, 5:15:51 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/doc/pslib/psLibSDRS.tex (modified) (94 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/doc/pslib/psLibSDRS.tex
r573 r627 1 %%% $Id: psLibSDRS.tex,v 1.4 0 2004-05-04 04:13:29price Exp $1 %%% $Id: psLibSDRS.tex,v 1.41 2004-05-08 03:15:51 price Exp $ 2 2 \documentclass[panstarrs]{panstarrs} 3 3 … … 82 82 The installed base of code for PSLib consists of header files, the 83 83 binary 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}. 84 equivalent, \code{libpslib.so} (or \code{libpslib.dylib} in the case 85 of OS/X). Assuming these components have been installed into the 86 library and search path, PSLib may be used within a program by 87 including the line \code{#include <pslib.h>} into the C code and 88 linking with \code{-lpslib}. 88 89 89 90 This document describes the data structures and details the functions … … 113 114 (\href{heasarc.gsfc.nasa.gov/docs/software/fitsio/}{\tt 114 115 heasarc.gsfc.nasa.gov/docs/software/fitsio/}); and 115 \item Many of the astronomy routines will wrap the StarLink Astronomy116 libraries (SLALib;116 \item Many of the astronomy routines will wrap the StarLink Positional 117 Astronomy libraries (SLALib; 117 118 \href{star-www.rl.ac.uk/star/docs/sun67.htx/sun67.html}{\tt 118 119 star-www.rl.ac.uk/star/docs/sun67.htx/sun67.html}. 120 \item \tbd{Some graphics library, possibly the SM library.} 119 121 \end{itemize} 120 122 … … 486 488 management routines respect the use of the \code{refCounter} field: 487 489 \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 do490 and \code{psAlloc} will initialize the field to 1. \code{psFree} 491 must generate an error if \code{refCounter != 1}. However, they do 490 492 not (and cannot practically) enforce the use of the counters; this is 491 493 a requirement of external APIs which intend to use the feature. … … 512 514 (\S\ref{sec:psDlist}). 513 515 516 \paragraph{Destructors} 517 514 518 \subsubsection{Relation of Memory Management to Structures} 515 519 \label{sec:free} … … 517 521 In this document, we specify several C \code{struct}s. It is expected 518 522 that instances of, for example, \code{struct psMyType} will be 519 constructed using \code{psMyTypeAlloc()} calls, and destr ucted using523 constructed using \code{psMyTypeAlloc()} calls, and destroyed using 520 524 \code{psMyTypeFree()} calls. The allocator will allocate the required 521 525 memory 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 528 The existence of complicated structures which include pointers to 529 other 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 533 reference counter and returns.} An example destructor is shown below: 534 535 \begin{verbatim} 536 void 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 553 This allows, for example, the \code{psMyType} to be imported into the 554 metadata (\S\ref{sec:metadata}) without the user worrying about the 555 details of the memory allocation/deallocation: 529 556 530 557 \begin{verbatim} … … 596 623 relationship is seen in two ways. First, a facility inherits the 597 624 trace 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. 625 hierarchy is used to format the listing of the trace facilities so 626 that they are easy to read. The first of these rules provides a 627 mechanism to define the default trace levels for any facility even if 628 it has not been registered explicitly since all named facilities are 629 implicitly children of the top level facility (\code{.}). The second 630 rule is simply an organizational technique to make the listing of 631 facility information clear. 604 632 605 633 The API to place a trace message in the code, and simultaneously set … … 621 649 % 622 650 \begin{verbatim} 623 int ps SetTraceLevel(char *facil, int level);651 int psTraceSetLevel(char *facil, int level); 624 652 \end{verbatim} 625 653 % … … 629 657 % 630 658 \begin{verbatim} 631 int ps GetTraceLevel(char *facil);659 int psTraceGetLevel(char *facil); 632 660 \end{verbatim} 633 661 % … … 635 663 rules specified above. A specified trace message (identified by 636 664 \code{psTrace}) shall be printed if and only if 637 \code{ps GetTraceLevel(facil)} returns a value greater than or equal to665 \code{psTraceGetLevel(facil)} returns a value greater than or equal to 638 666 the value of \code{myLevel} for that message. That is, a larger 639 667 number for the trace level corresponds to lower-level statements, and … … 641 669 642 670 PSLib will include a utility function for examining the current 643 tracing levels of all facilities: \code{void ps PrintTraceLevels(void);}.671 tracing levels of all facilities: \code{void psTracePrintLevels(void);}. 644 672 This function will print the hierarchy of trace facilities along with 645 673 the current trace level for each facility. For example, a particular 646 674 program may have a few facilities defined, along with their trace 647 levels. A call to \code{ps PrintTraceLevels} may produce a listing675 levels. A call to \code{psTracePrintLevels} may produce a listing 648 676 which appears as: 649 677 \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 656 685 \end{verbatim} 657 686 … … 661 690 % 662 691 \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");692 psTrace("IPP.flatten", 2, "starting flatten function\n"); 693 psTrace("IPP.flatten", 0, "flat-field image is \%s\n", filename); 694 psTrace("IPP.flatten.divide", 2, "doing the divide\n"); 695 psTrace("IPP.flatten.divide", 3, "trying the loop, i = \%d\n", i); 696 psTrace("IPP.flatten.divide", 1, "got an invalid pixel value (NaN) at \%d,\%d\n"); 697 psTrace("IPP.flatten.divide", 2, "divide is done\n"); 669 698 \end{verbatim} 670 699 % … … 673 702 % 674 703 \begin{verbatim} 675 ERROR: flat-field image foo.fits is invalid 676 doing the divide677 got an invalid pixel value (NaN) at 500,20678 divide is done704 flat-field image is foo.fits 705 doing the divide 706 got an invalid pixel value (NaN) at 500,20 707 divide is done 679 708 \end{verbatim} 680 709 % … … 683 712 % 684 713 \begin{verbatim} 685 starting flatten function686 trying the loop, i = 0687 trying the loop, i = 1688 trying the loop, i = 2714 starting flatten function 715 trying the loop, i = 0 716 trying the loop, i = 1 717 trying the loop, i = 2 689 718 ... 690 719 \end{verbatim} … … 698 727 \code{void psTraceReset(void)} will set all trace levels to 0. 699 728 700 \tbd{ability to send trace messages to output locations other than stdout?} 729 730 The trace may optionally be written to a file on specifying a filename 731 with \code{psTraceSetDestination}: 732 \begin{verbatim} 733 void psTraceSetDestination(const char *filename // File to write to 734 ); 735 \end{verbatim} 736 If the \code{filename} is \code{NULL}, then the trace is sent to 737 standard output. 701 738 702 739 \subsubsection{Message Logging} … … 722 759 \begin{verbatim} 723 760 void psLogMsg(char *name, int myLevel, char *fmt, ...); 724 void ps VLogMsg(char *name, int myLevel, char *fmt, va_list ap);761 void psLogVMsg(char *name, int myLevel, char *fmt, va_list ap); 725 762 \end{verbatim} 726 763 where \code{name} is a word to describe the source of the message, … … 728 765 is a printf-style formatting statement defining the actual message, 729 766 and is followed by the arguments to the formatting code. The second 730 form, \code{ps VLogMsg} is an equivalent command which takes a767 form, \code{psLogVMsg} is an equivalent command which takes a 731 768 \code{va_list} argument. 732 769 … … 744 781 % 745 782 \begin{verbatim} 746 int ps SetLogLevel(int level);783 int psLogSetLevel(int level); 747 784 \end{verbatim} 748 785 % … … 750 787 invoked with \code{psLogMsg} is only printed if its value of 751 788 \code{myLevel} is less than the current value set by 752 \code{ps SetLogLevel}.789 \code{psLogSetLevel}. 753 790 754 791 Log messages are sent to the destination most recently set using: 755 792 % 756 793 \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?}. 794 int psLogSetDestination(int dest); 795 \end{verbatim} 796 % 797 The only values that are initially defined are \code{PS_LOG_TO_STDERR} 798 and \code{PS_LOG_TO_STDOUT} to write to \code{stderr} and 799 \code{stdout} respectively, and \code{PS_LOG_TO_NONE} to turn off 800 logging. \tbd{Log to a server via TCP/IP; will possibly set these 801 values to negative integers and allow psLogSetDestination to take 802 a positive-integer file descriptor.}. 764 803 765 804 The output format is controlled with the function: 766 805 % 767 806 \begin{verbatim} 768 void ps SetLogFormat(const char *fmt);807 void psLogSetFormat(const char *fmt); 769 808 \end{verbatim} 770 809 % … … 795 834 % 796 835 The possible order of the format entries is fixed and not determined 797 by the order of the letters used in \code{ps SetLogFormat}. Selecting836 by the order of the letters used in \code{psLogSetFormat}. Selecting 798 837 an output format with fewer than the complete set of 5 entries simply 799 838 removes those entries from the output messages. 839 840 Specifying a \code{fmt} of \code{NULL} turns off logging (equivalent 841 to calling \code{psLogSetDestination(PS_LOG_TO_NONE)}, whereas if the 842 \code{fmt} is \code{""}, then the format reverts to the default. 800 843 801 844 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% … … 833 876 error that has already resulted in a call to \code{psError}. The 834 877 final required argument, \code{fmt}, is a \code{printf}-style format 835 that is passed to \code{psLog Msg} with code \code{PS_LOG_ERROR}.878 that is passed to \code{psLogVMsg} with code \code{PS_LOG_ERROR}. 836 879 837 880 The result of a call to \code{psError} shall be to push an error onto … … 855 898 856 899 \begin{verbatim} 857 const psErr *ps GetError(int which); ///< return specified error (or an "error" with code PS_ERR_NONE)858 const psErr *ps LastError(void); ///< return last error (or an "error" with code PS_ERR_NONE)900 const psErr *psErrorGet(int which); ///< return specified error (or an "error" with code PS_ERR_NONE) 901 const psErr *psErrorLast(void); ///< return last error (or an "error" with code PS_ERR_NONE) 859 902 \end{verbatim} 860 903 … … 866 909 867 910 The entire error stack may be printed to an open file descriptor by 868 calling \code{psErrorStackPrint} (or \code{ps VErrorStackPrint}); if911 calling \code{psErrorStackPrint} (or \code{psErrorVStackPrint}); if 869 912 and only if there are current errors, the printf-style string 870 913 \code{fmt} is first printed to the file descriptor \code{fd}. In this … … 872 915 defined in the next section. Note that these are also available in 873 916 the \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}.917 should be indented by an additional space (see example). 918 \code{psErrorVStackPrint} shall not invoke \code{va_end}. 876 919 877 920 \begin{verbatim} 878 921 void psErrorStackPrint(FILE *fd, const char *fmt, ...); ///< print the errorstack to this file descriptor 879 void ps VErrorStackPrint(FILE *fd, const char *fmt, va_list va); ///< print the errorstack to this file922 void psErrorVStackPrint(FILE *fd, const char *fmt, va_list va); ///< print the errorstack to this file 880 923 ///< descriptor 881 924 \end{verbatim} … … 916 959 \begin{verbatim} 917 960 typedef struct { 918 psErrorCode code; // An error code919 c har *descrip; //the associated description961 psErrorCode code; ///< An error code 962 const char *descrip; ///< the associated description 920 963 } psErrorDescription; 921 964 \end{verbatim} … … 998 1041 to be valid values of \code{errno}. 999 1042 1000 The implementation may add extra fields (e.g., \code{PS_ERR_N_ERR_CLASSES}).1001 1002 1043 \file{psErrorCodes.c} shall define the necessary function to register 1003 1044 the error codes. … … 1042 1083 psErrorStackPrint(stdout, "Traceback:\n"); 1043 1084 1044 if (ps LastError()->code == PS_ERR_UNKNOWN) {1085 if (psErrorLast()->code == PS_ERR_UNKNOWN) { 1045 1086 fprintf(stderr, "Last error is of unknown type\n"); 1046 1087 } 1047 if (ps GetError(2)->code == PS_ERR_IO) {1088 if (psErrorGet(2)->code == PS_ERR_IO) { 1048 1089 fprintf(stderr, "Third oldest error is of type IO\n"); 1049 1090 } … … 1053 1094 psErrorStackPrint(stdout, "Traceback:\n"); 1054 1095 1055 if (ps LastError()->code == PS_ERR_NONE) {1096 if (psErrorLast()->code == PS_ERR_NONE) { 1056 1097 fprintf(stderr, "No errors. Hurrah\n"); 1057 1098 } … … 1178 1219 \end{verbatim} 1179 1220 We discuss the application of \code{psType} in more detail in 1180 section~\ref{ arithmetic}.1221 section~\ref{sec:arithmetic}. 1181 1222 1182 1223 \subsection{Arrays of Simple Types} … … 1269 1310 array.\footnote{\eg{} \code{va->arr[i] = psMemIncrRefCounter(ptr);}} 1270 1311 If \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). 1312 list should be deleted, but not the elements on it (an error should be 1313 raised if the \code{refCounter} is 1; otherwise their 1314 \code{refCounter}'s should be decremented) --- this is to account for 1315 an array of heterogeneous types. 1273 1316 1274 1317 \subsection{Doubly-linked lists} … … 1379 1422 \code{iter} is provided by the functions: 1380 1423 \begin{verbatim} 1381 void psDlistSetIterator(psDlist *list, int where );1382 void *psDlistGetNext(psDlist *list );1383 void *psDlistGetPrev(psDlist *list );1424 void psDlistSetIterator(psDlist *list, int where, int which); 1425 void *psDlistGetNext(psDlist *list, int which); 1426 void *psDlistGetPrev(psDlist *list, int which); 1384 1427 \end{verbatim} 1385 1428 The first of these functions uses the value of \code{where} to set the 1386 1429 iteration 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 1431 specified by \code{which}. The next two functions move the iteration 1432 cursor forward or backwards, returning the data item from the 1433 resulting list entry, or returning \code{NULL} at the end of the list. 1434 Explicit traversal of the list using the \code{psDlistElem}s 1435 \code{prev} and \code{next} pointers is also supported. 1436 1437 A list may be sorted using \code{psDlistSort}, which requires the 1438 specification of a comparison function to specify how the objects on 1439 the list should be sorted. The motivation is primarily to be able to 1440 iterate on a sorted list of keys from a hash. 1441 \begin{verbatim} 1442 psDlist *psDlistSort(psDlist *list, int (*compare)(const void *a, const void *b) ); 1443 \end{verbatim} 1393 1444 1394 1445 \subsection{Hash Tables} … … 1411 1462 1412 1463 For PSLib, we define a hash table and hash buckets as follows: 1413 \footnote{ We choose not to use the posixfunction \code{hcreate},1464 \footnote{ We choose not to use the POSIX function \code{hcreate}, 1414 1465 \code{hdestroy}, and \code{hsearch} as they only support a single hash 1415 1466 table at any one time.} … … 1550 1601 psBitset * 1551 1602 psBitsetSet(psBitset *restrict myBits, ///< Input bitset 1552 int bit///< Bit to set1603 int bit ///< Bit to set 1553 1604 ); 1554 1605 \end{verbatim} … … 1582 1633 performing the specified \code{operator} (one of \code{"AND"}, 1583 1634 \code{"OR"}, or \code{"XOR"}) on \code{inBits1} and \code{inBits2}. 1635 1636 Finally, \code{psBitsetNot} applies a unary \code{NOT} to a bitset: 1637 1638 \begin{verbatim} 1639 /** Apply unary NOT to a bitset */ 1640 psBitset * 1641 psBitsetNot(psBitset *out, ///< Output bitset, or NULL 1642 psBitset *in ///< Input bitset to be NOT-ed 1643 ); 1644 \end{verbatim} 1584 1645 1585 1646 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% … … 1749 1810 1750 1811 \subsubsection{Histograms} 1812 \label{sec:histograms} 1751 1813 1752 1814 We also require to be able to generate histograms, given a list of … … 1754 1816 1755 1817 \begin{verbatim} 1756 /** Histograms */1818 /** Histograms */ 1757 1819 typedef struct { 1758 const psFloatArray *restrict lower; ///< Lower bounds for the bins1759 const psFloatArray *restrict upper; ///< Upper bounds forthe bins1760 psIntArray *nums; ///< Number in each of the bins1761 const float minVal, maxVal; ///< Minimum and maximum values1762 int minNum, maxNum; ///< Number below the minimum and above the maximum1820 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? 1763 1825 } psHistogram; 1764 1826 \end{verbatim} … … 1772 1834 /** Constructor */ 1773 1835 psHistogram * 1774 psHistogramAlloc(float lower, ///< Lower limit for the bins1775 float upper,///< Upper limit for the bins1776 float size ///< Sizeof the bins1836 psHistogramAlloc(float lower, ///< Lower limit for the bins 1837 float upper, ///< Upper limit for the bins 1838 int n ///< Number of the bins 1777 1839 ); 1778 1840 \end{verbatim} … … 1781 1843 /** Generic constructor */ 1782 1844 psHistogram * 1783 psHistogramAllocGeneric(const psFloatArray *restrict lower, ///< Lower bounds for the bins 1784 const psFloatArray *restrict upper, ///< Upper bounds for the bins 1845 psHistogramAllocGeneric(const psFloatArray *restrict bounds, ///< Bounds for the bins 1785 1846 float minVal, ///< Minimum value 1786 1847 float maxVal ///< Maximum value … … 1825 1886 \item Calculate a matrix determinant; 1826 1887 \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 1828 1890 \item Convert a matrix to a vector. 1829 1891 \end{itemize} … … 1905 1967 \end{verbatim} 1906 1968 1969 Eigenvectors of a matrix are calculated by \code{psMatrixEigenvectors}: 1970 1971 \begin{verbatim} 1972 /** Eigenvectors of a matrix */ 1973 psVector * 1974 psMatrixEigenvectors(psImage *myMatrix ///< Matrix to get eigenvectors for 1975 ); 1976 \end{verbatim} 1977 1907 1978 Finally, we specify two functions to convert between matrices and 1908 1979 vectors. This allows the use of vectors in matrix arithmetic, since … … 1930 2001 1931 2002 We 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. */ 2003 floating-point two-dimensional images and one-dimensional arrays. We 2004 expect that these will be implemented through wrapping an external 2005 library. 2006 2007 The forward and reverse Fourier transforms may be calculated using the 2008 following APIs: 2009 2010 \begin{verbatim} 2011 /** Forward FFT an image. Returns a complex float image. */ 1978 2012 psImage * 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 */ 2013 psImageFFT(const psImage *image ///< Image to transform 2014 ); 2015 2016 /** Forward FFT an array of floating-point numbers. */ 2053 2017 psFloatArray * 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 */ 2018 psFloatArrayFFT(const psFloatArray *arr ///< Array to transform 2019 ); 2020 2021 /** Inverse FFT an image. */ 2066 2022 psImage * 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 */ 2023 psImageInverseFFT(const psImage *fftImage ///< FFT-ed image to inverse-transform 2024 ); 2025 2026 /** Inverse FFT an array of complex floating-point numbers */ 2027 psComplexArray * 2028 psComplexArrayInverseFFT(const psComplexArray *fftArray ///< FFT-ed array to inverse-transform 2029 ); 2030 \end{verbatim} 2031 2032 Neither 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 2034 multiply an image that has been forward- and reverse-transformed by 2035 $1/N$. 2036 2037 The \code{psImage}s output by \code{psImageFFT} and 2038 \code{psImageInverseFFT} should be of complex floating-point type. Following 2039 an inverse transform, therefore, the user will likely want to extract the 2040 real parts: 2041 2042 \begin{verbatim} 2043 /** Get the real part of an image */ 2072 2044 psImage * 2073 psFFTGetFT(psImage *out, //!< Image to write to (or NULL) 2074 const psFFT *fft //!< FFT to get Fourier transform from 2075 ); 2045 psImageReal(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 */ 2050 psFloatArray * 2051 psComplexArrayReal(psFloatArray *out, ///< Array for output (or NULL) 2052 const psComplexArray *in ///< Array to get the real part of 2053 ); 2054 \end{verbatim} 2055 2056 To aid operations on FFT-ed images or arrays, we also specify 2057 functions to return the complex conjugate of an image or array: 2058 2059 \begin{verbatim} 2060 /** Get the complex conjugate of an image */ 2061 psImage * 2062 psImageConjugate(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 */ 2067 psComplexArray * 2068 psComplexArrayConjugate(psComplexArray *out, ///< Array for output (or NULL) 2069 const psComplexArray *in ///< Array to get the complex conjugate of 2070 ); 2071 \end{verbatim} 2072 2073 Finally, the power spectrum may be calculated directly from the 2074 original image or array: 2075 2076 \begin{verbatim} 2077 /** Calculate power spectrum of an image */ 2078 psImage * 2079 psImagePowerSpectrum(const psImage *image ///< Image to obtain power spectrum of 2080 ); 2081 2082 /** Calculate power spectrum of an array of floating-point numbers */ 2083 psFloatArray * 2084 psFloatArrayPowerSpectrum(const psFloatArray *arr ///< Array to obtain power spectrum of 2085 ); 2076 2086 \end{verbatim} 2077 2087 … … 2085 2095 \begin{verbatim} 2086 2096 /** 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 */ 2088 2100 float 2089 2101 psGaussian(float x, ///< Value at which to evaluate … … 2180 2192 2181 2193 \begin{verbatim} 2182 /** Minimizea particular non-linear function */2194 /** Find the minimum of a particular non-linear function */ 2183 2195 psFloatArray * 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 ); 2196 psMinimize(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 ); 2188 2201 \end{verbatim} 2189 2202 … … 2191 2204 the specified function. It takes as input a function, 2192 2205 \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}. 2206 the function, \code{initialGuess} which is returned with the best-fit 2207 parameters, and an optional mask for the parameters to minimize, 2208 \code{paramMask} (all parameters are fit if \code{NULL}). 2195 2209 2196 2210 \begin{verbatim} 2197 2211 /** Minimize chi^2 for input data */ 2198 2212 psFloatArray * 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 constant2213 psMinimizeChi2(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 2206 2220 ); 2207 2221 \end{verbatim} … … 2212 2226 parameters, \code{evalModel}; a list of observations, (\code{domain}, 2213 2227 \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}. 2228 parameters, \code{initialGuess} which is returned with the best-fit 2229 parameters, and an optional mask specifying which parameters are to be 2230 fit, \code{paramMask} (all parameters are fit if \code{NULL}). 2216 2231 2217 2232 \begin{verbatim} … … 2243 2258 \begin{verbatim} 2244 2259 typedef struct psImage { 2245 psType type; ///< image data type and dimension2246 int nx, ny;///< size of image2247 int x0, y0;///< data region relative to parent2260 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 2248 2263 union { 2249 float **rows;///< Pointers to floating-point data (default)2250 short int **rows_si;///< Pointers to short-integer data2251 int **rows_i;///< Pointers to integer data2252 long int **rows_li;///< Pointers to long-integer data2253 unsigned short int **rows_usi;///< Pointers to unsigned-short-integer data2254 unsigned int **rows_ui;///< Pointers to unsigned-integer data2255 unsigned long int **rows_uli;///< Pointers to unsigned-long-integer data2256 float **rows_f;///< Pointers to floating-point data2257 double **rows_d;///< Pointers to double-precision data2258 complex float **rows_complex;///< Pointers to complex floating-point data2264 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 2259 2274 } rows; 2260 struct psImage *parent;///< parent, if a subimage2261 int Nchildren; ///< number of subimages2262 struct psImage *children; ///< children of this region; array of Nchildren pointers2275 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 2263 2278 } psImage; 2264 2279 \end{verbatim} … … 2266 2281 This structure represents an image consisting of a 2-D array of 2267 2282 pixels. The size of this array is given by the elements \code{(nx, 2268 ny)}. The data type of the pixel is defined bythe \code{psType type}2269 entry (s ee \ref{arithmetic}). (n.b. that for FITS images, these2270 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.2283 ny)}. The data type of the pixel is defined in the \code{psType type} 2284 entry (specifically, the \code{psElemType} member, \code{type}; see 2285 \ref{sec:arithmetic}). (n.b. that for FITS images, these values are 2286 restricted to the datatypes equivalent to the valid BITPIX values 8, 2287 16, 32, -32, -64). The image represented in the data structure may 2288 represent a subset of the pixels in a complete array, in which case 2289 the image is considered to be the child of that parent array. The 2290 offset of the \code{(0,0)} pixel in this array relative to the parent 2291 array is given by the elements \code{(x0,y0)}. The structure may 2292 include references to subrasters (\code{children, Nchildren}) and/or 2293 to a containing array (\code{parent}). Unless this is image is a 2294 child of another image (represents a subset of the pixels of another 2295 image), the image data is allocated in a contiguous block. 2281 2296 2282 2297 We require a variety of functions to manipulate these image … … 2291 2306 to the valid FITS BITPIX types. 2292 2307 \begin{verbatim} 2293 psImage *psImageAlloc (int nx, int ny, ps Type type);2308 psImage *psImageAlloc (int nx, int ny, psElemType type); 2294 2309 \end{verbatim} 2295 2310 where \code{nx} and \code{ny} specify the size of the image and … … 2301 2316 outside of the parent image. 2302 2317 \begin{verbatim} 2303 psImage *psImageSubset( psImage *out,psImage *image, int nx, int ny, int x0, int y0);2318 psImage *psImageSubset(const psImage *image, int nx, int ny, int x0, int y0); 2304 2319 \end{verbatim} 2305 2320 where \code{image} is the parent image, \code{nx,ny} specify the 2306 2321 dimensions of the desired subraster, and \code{x0, y0} specify the 2307 2322 starting 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. 2323 contained within the raster of the parent image. Note that the 2324 \code{refCounter} for the parent should be incremented. 2311 2325 2312 2326 Free the memory associated with a specific image, including the pixel … … 2321 2335 \end{verbatim} 2322 2336 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); 2337 Create a copy of the specified image, converting the type in the 2338 process. If the output target pointer is not NULL, place the result 2339 in the specified structure. The output image data must be allocated 2340 as a single, contiguous block of memory. The output image may not be 2341 the input image. 2342 \begin{verbatim} 2343 psImage *psImageCopy(psImage *output, const psImage *input, psElemType type); 2335 2344 \end{verbatim} 2336 2345 … … 2346 2355 specified by \code{stats}. 2347 2356 \begin{verbatim} 2348 psFloatArray *psImageSlice(psFloatArray *out, psImage *input, int x, int y, int nx, int ny,2357 psFloatArray *psImageSlice(psFloatArray *out, const psImage *input, int x, int y, int nx, int ny, 2349 2358 int direction, const psStats *stats); 2350 2359 \end{verbatim} 2351 2360 2352 2361 Extract 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 of2362 floats). The vector \code{(xs,ys)} - \code{(xe,ye)} forms the basis of 2354 2363 the output vector. Pixels are considered in a rectangular region of 2355 2364 width \code{dw} about this vector. The input region is collapsed in … … 2360 2369 specified by \code{stats}. 2361 2370 \begin{verbatim} 2362 psFloatArray *psImageCut(psFloatArray *out, psImage *input, float xs, float ys, float xe, float ye,2363 float dw, psStats *stats);2371 psFloatArray *psImageCut(psFloatArray *out, const psImage *input, float xs, float ys, float xe, float ye, 2372 float dw, const psStats *stats); 2364 2373 \end{verbatim} 2365 2374 … … 2371 2380 output vector value is specified by \code{stats} 2372 2381 \begin{verbatim} 2373 psFloatArray *psImageRadialCut(psFloatArray *out, psImage *input, float x, float y, float radius, float dr,2374 psStats *stats);2382 psFloatArray *psImageRadialCut(psFloatArray *out, const psImage *input, float x, float y, 2383 const psFloatArray *radii, const psStats *stats); 2375 2384 \end{verbatim} 2376 2385 … … 2379 2388 Rebin image to new scale. A new image is constructed in which the 2380 2389 dimensions 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); 2390 error for \code{scale} $> 1$). The \code{scale} is equal in each 2391 dimension. The output image is generated from all input image pixels. 2392 Each pixel in the output image is derived from the statistics of the 2393 corresponding set of input image pixels based on the statistics 2394 specified by \code{stats}. 2395 \begin{verbatim} 2396 psImage *psImageRebin(psImage *out, const psImage *input, float scale, const psStats *stats); 2387 2397 \end{verbatim} 2388 2398 … … 2394 2404 that a positive angle is an anti-clockwise rotation. 2395 2405 \begin{verbatim} 2396 psImage *psImageRotate(psImage *out, psImage *input, float angle);2406 psImage *psImageRotate(psImage *out, const psImage *input, float angle); 2397 2407 \end{verbatim} 2398 2408 … … 2404 2414 set to the value given by \code{exposed}. 2405 2415 \begin{verbatim} 2406 psImage *psImageShift(psImage *out, psImage *input, float dx, float dy, float exposed);2416 psImage *psImageShift(psImage *out, const psImage *input, float dx, float dy, float exposed); 2407 2417 \end{verbatim} 2408 2418 … … 2411 2421 image. Edge pixels wrap to the other side (no values are lost). 2412 2422 \begin{verbatim} 2413 psImage *psImageRoll(psImage *out, psImage *input, int dx, int dy);2423 psImage *psImageRoll(psImage *out, const psImage *input, int dx, int dy); 2414 2424 \end{verbatim} 2415 2425 … … 2419 2429 determined are specified by \code{stats}. 2420 2430 \begin{verbatim} 2421 psStats *psImageGetStats(ps Image *input, psStats *stats);2431 psStats *psImageGetStats(psStats *stats, const psImage *input); 2422 2432 \end{verbatim} 2423 2433 2424 2434 Construct a histogram from an image (or subimage). The histogram to 2425 2435 generate is specified by \code{psHistogram hist} (see 2426 section~\ref{ histogram}).2427 \begin{verbatim} 2428 psHistogram *psImageHistogram(psHistogram *hist, psImage *input);2436 section~\ref{sec:histograms}). 2437 \begin{verbatim} 2438 psHistogram *psImageHistogram(psHistogram *hist, const psImage *input); 2429 2439 \end{verbatim} 2430 2440 … … 2433 2443 interest. 2434 2444 \begin{verbatim} 2435 psPolynomial2D *psImageFitPolynomial(ps Image *input, psPolynomial2D *coeffs);2445 psPolynomial2D *psImageFitPolynomial(psPolynomial2D *coeffs, const psImage *input); 2436 2446 \end{verbatim} 2437 2447 2438 2448 Evaluate a 2-D polynomial surface for the image pixels. Given the 2439 2449 input 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);2450 of the polynomial function. 2451 \begin{verbatim} 2452 psImage *psImageEvalPolynomial(psImage *input, const psPolynomial2D *coeffs); 2443 2453 \end{verbatim} 2444 2454 … … 2449 2459 full image or a subimage to be read. The starting pixel of the region 2450 2460 is 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 two2452 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 specified2458 parameters are out of range for the data in the image file, if the2459 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 c har *extname, int extnum,char *filename);2461 region are specified by \code{nx,ny}. A negative value of -1 for 2462 these two parameters specifies the full array of the requested image, 2463 less absolute value of the variable. If the native image is a cube, 2464 the value of z specifies the requested slice of the image. The data 2465 is read from the extension specified by extname (matching the EXTNAME 2466 keyword) or by the extnum value (with 0 representing the PHU, 1 the 2467 first extension, etc). This function must call \code{psError} and 2468 return \code{NULL} if any of the specified parameters are out of range 2469 for the data in the image file, if the specified image file does not 2470 exist, or the image on disk is zero- or one-dimensional. 2471 \begin{verbatim} 2472 psImage *psImageReadSection(psImage *output, int x0, int y0, int nx, int ny, int z, 2473 const char *extname, int extnum, const char *filename); 2464 2474 \end{verbatim} 2465 2475 … … 2469 2479 \begin{verbatim} 2470 2480 psImage *psImageFReadSection(psImage *output, int x, int y, int nx, int ny, int z, 2471 c har *extname, int extnum, FILE *f);2481 const char *extname, int extnum, FILE *f); 2472 2482 \end{verbatim} 2473 2483 \tbd{The use of \code{FILE*} to carry around the file descriptor is to be reviewed.} … … 2480 2490 created. 2481 2491 \begin{verbatim} 2482 psImage *psImageWriteSection( psImage *input, int x, int y, int z,2483 c har *extname, int extnum,char *filename);2492 psImage *psImageWriteSection(const psImage *input, int x, int y, int z, 2493 const char *extname, int extnum, const char *filename); 2484 2494 \end{verbatim} 2485 2495 2486 2496 Write an image section to file descriptor as above: 2487 2497 \begin{verbatim} 2488 psImage *psImageFWriteSection( psImage *input, int x, int y, int z,2489 c har *extname, int extnum, FILE *f);2498 psImage *psImageFWriteSection(const psImage *input, int x, int y, int z, 2499 const char *extname, int extnum, FILE *f); 2490 2500 \end{verbatim} 2491 2501 \tbd{The use of \code{FILE*} to carry around the file descriptor is to be reviewed.} 2492 2502 2493 2503 Read header data from a FITS image file into a \code{psMetaData} 2494 structure (see section~\ref{ metadata}. The \code{extname} and2504 structure (see section~\ref{sec:metadata}. The \code{extname} and 2495 2505 \code{extnum} parameters specify the extension of interest as above. 2496 2506 If the named extension does not exist, the function should return an 2497 2507 error. 2498 2508 \begin{verbatim} 2499 psMetadata *psImageReadHeader(psMetadata *output, c har *extname, int extnum,char *filename);2509 psMetadata *psImageReadHeader(psMetadata *output, const char *extname, int extnum, const char *filename); 2500 2510 \end{verbatim} 2501 2511 … … 2503 2513 structure. 2504 2514 \begin{verbatim} 2505 psMetadata *psImageFReadHeader(psMetadata *output, c har *extname, int extnum, FILE *f);2515 psMetadata *psImageFReadHeader(psMetadata *output, const char *extname, int extnum, FILE *f); 2506 2516 \end{verbatim} 2507 2517 … … 2531 2541 (multiply overlay times image), \code{/} (divide image by overlay). 2532 2542 \begin{verbatim} 2533 int psImageOverlaySection(psImage *image, psImage *overlay, int x0, int y0,char *op);2543 int psImageOverlaySection(psImage *image, const psImage *overlay, int x0, int y0, const char *op); 2534 2544 \end{verbatim} 2535 2545 … … 2928 2938 appropriate destructor for the \code{val} (recall that it is the duty 2929 2939 of 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}).2940 free the memory if and only if the \code{refCounter == 1} --- see 2941 \S\ref{sec:free}). 2932 2942 2933 2943 \begin{verbatim} … … 3010 3020 key, e.g., if the user only wants to iterate through 3011 3021 \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 3023 item of metadata --- even those that are non-unique. 3013 3024 3014 3025 \begin{verbatim} … … 3017 3028 ); 3018 3029 3019 /// get the next entryin the sequence3030 /// get the next item in the sequence 3020 3031 psMetadataItem *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 3022 3034 ); 3023 3035 \end{verbatim} … … 3046 3058 \subsection{Detector and sky positions} 3047 3059 3048 \tbd{the definition of psCoord must be review: split into psSphere and psPlane?}3049 3050 3060 Both detector and sky positions will be used extensively in the IPP. 3051 3061 The first are linear coordinates which conform to Euclidean geometry 3052 3062 while 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; 3063 must often be taken. We put these into two structures, 3064 \code{psPlaneCoord} and \code{psSphereCoord}, respectively. 3065 Partitioning these two will enable error-checking. 3066 3067 \begin{verbatim} 3068 /** A point in 2-D space, with errors. */ 3069 typedef 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 */ 3077 typedef struct { 3078 double r; ///< RA 3079 double d; ///< Dec 3080 double rErr; ///< Error in RA 3081 double dErr; ///< Error in Dec 3082 } psSphereCoord; 3078 3083 \end{verbatim} 3079 3084 … … 3120 3125 psDPolynomial2D *x; 3121 3126 psDPolynomial2D *y; 3122 } ps CoordXform;3127 } psPlaneCoordXform; 3123 3128 \end{verbatim} 3124 3129 … … 3129 3134 frame \code{x,y} (say a single CCD) to a second frame \code{p,q} (say, 3130 3135 a second CCD image). If we have only first order terms in the 3131 transformation \code{ps CoordXform T}, the new coordinates would be3136 transformation \code{psPlaneCoordXform T}, the new coordinates would be 3132 3137 represented by the terms: 3133 3138 % … … 3147 3152 psDPolynomial4D *x; 3148 3153 psDPolynomial4D *y; 3149 } ps Distortion;3150 \end{verbatim} 3151 3152 Like \code{ps CoordXform}, \code{psDistortion} contains two3154 } psPlaneDistortion; 3155 \end{verbatim} 3156 3157 Like \code{psPlaneCoordXform}, \code{psPlaneDistortion} contains two 3153 3158 \code{psDPolynomial4D} structures representing polynomials of 3154 3159 arbitrary order as a function of four, rather than two dimensions. … … 3159 3164 single CCD) of an object with magnitude and color \code{m,c} to a 3160 3165 second frame \code{p,q} (say, a second CCD image). If we have only 3161 first order terms in the transformation \code{ps CoordXform T}, the new3166 first order terms in the transformation \code{psPlaneCoordXform T}, the new 3162 3167 coordinates would be represented by the terms: 3163 3168 % … … 3176 3181 \begin{verbatim} 3177 3182 /** 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} 3183 psPlaneCoord *psPlaneCoordXformApply (psPlaneCoord *out, ///< Output coordinates, or NULL 3184 const psPlaneCoordXform *frame, ///< coordinate transformation 3185 const psPlaneCoord *coords ///< input coordiate 3186 ); 3187 3185 3188 /** apply the optical distortion to the given coordinate, magnitude, color */ 3186 ps Coord *psDistortionApply (psCoord *out, ///< Output coordinates, or NULL3187 const psdistortion *pattern, ///< optical distortion pattern3188 const psCoord *coords, ///< input coordinate3189 float mag,///< magnitude of object3190 float color ///< color of object3189 psPlaneCoord *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 3191 3194 ); 3192 3195 \end{verbatim} … … 3199 3202 systems. All of these basic spherical transformations represent 3200 3203 rotations 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 ); 3204 transformation function which takes a structure, 3205 \code{psSphereCoordTransformation}, defining the transformation 3206 between two spherical coordinate systems (the structure contains the 3207 sines and cosines of the angles involved so as to minimize computation 3208 time for repeated transformations). We also define a function to 3209 generate \code{psSphereCoordTransformation}, based on the three angles 3210 describing the location of the pole and the relative equatorial 3211 rotations of the two systems. We also specify special functions to 3212 return the \code{psSphereCoordTransformation} for transformations 3213 between standard coordinate systems. 3214 3215 \begin{verbatim} 3216 /** General spherical transformation */ 3217 typedef struct { 3218 double sin1, sin2, sin3, cos1, cos2, cos3; ///< Sines and cosines for transformation 3219 } psSphereCoordTransformation; 3220 \end{verbatim} 3221 3222 The constructor and destructor are defined as follows: 3223 3224 \begin{verbatim} 3225 /** Constructor */ 3226 psSphereCoordTransformation * 3227 psSphereCoordTransformationAlloc(double pole1, ///< First location of pole 3228 double pole2, ///< Second location of pole 3229 double rotation ///< Rotation between systems 3230 ); 3231 3232 /** Destructor */ 3233 void psSphereCoordTranformationFree(psSphereCoordTransformation *trans ///< Transformation to destroy 3234 ); 3235 \end{verbatim} 3236 3237 Spherical coordinates may be transformed by providing the transformation to 3238 \code{psSphereCoordTransform}: 3239 3240 \begin{verbatim} 3241 /** Apply general spherical transformation */ 3242 psSphereCoord * 3243 psSphereCoordTransform(const psSphereCoord *coord, ///< Coordinates to convert 3244 psSphereCoordSystem *sys ///< System to use to convert 3245 ); 3246 \end{verbatim} 3247 3248 The following functions simply return the appropriate 3249 \code{psSphereCoordTransformation} to convert between predefined 3250 spherical coordinate systems (i.e., ICRS, Ecliptic and Galactic). 3251 3252 \begin{verbatim} 3253 /** Return transformation structure to convert ICRS to Ecliptic */ 3254 psSphereCoordTransformation *psSphereCoordTransformationItoE(void); 3255 3256 /** Return transformation structure to convert Ecliptic to ICRS */ 3257 psSphereCoordTransformation *psSphereCoordTransformationEtoI(void); 3258 3259 /** Return transformation structure to convert ICRS to Galactic */ 3260 psSphereCoordTransformation *psSphereCoordTransformationItoG(void); 3261 3262 /** Return transformation structure to convert Galactic to ICRS */ 3263 psSphereCoordTransformation *psSphereCoordTransformationGtoI(void); 3250 3264 \end{verbatim} 3251 3265 … … 3264 3278 \end{itemize} 3265 3279 3266 \begin{verbatim} 3267 psCoord *psCoordProject (psCoord *coord, char *projection); 3280 The following functions will project and deproject (respectively) 3281 spherical coordinates: 3282 3283 \begin{verbatim} 3284 /** Project spherical system onto a plane */ 3285 psPlaneCoord * 3286 psCoordProject(const psSphereCoord *coord, ///< Spherical coordinates to project 3287 const char *projection ///< Projection to use 3288 ); 3289 3290 /** Deproject plane onto spherical system */ 3291 psSphereCoord * 3292 psCoordDeproject(const psPlaneCoord *coord, ///< Plane coordinates to deproject 3293 const char *projection ///< Projection to use 3294 ); 3268 3295 \end{verbatim} 3269 3296 … … 3275 3302 \begin{verbatim} 3276 3303 /** 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} 3304 psSphereCoord * 3305 psSphereCoordGetOffset(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 3285 3311 /** 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} 3312 psSphereCoord * 3313 psSphereCoordApplyOffset(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 3320 Note that these should propagate the errors appropriately. 3292 3321 3293 3322 … … 3318 3347 single readout of the detector, along with metadata needed to define 3319 3348 that 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. 3349 original detector pixels explicitly in the structure, and pointers to 3350 the general metadata and derived objects, if any. 3323 3351 3324 3352 A single detector may produce more than one read which is associated. … … 3382 3410 3383 3411 A 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. 3412 thereof). It contains a pointer to the pixel data, and additional 3413 pointers to the objects found in the readout, and the readout 3414 metadata. It also contains the offset from the lower-left corner of 3415 the chip, in the case that the CCD was windowed. 3389 3416 3390 3417 \begin{verbatim} 3391 3418 /** a Readout: a collection of pixels */ 3392 3419 typedef 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 3398 3424 psMetadata *md; ///< Readout-level metadata 3399 3425 } psReadout; … … 3421 3447 */ 3422 3448 typedef struct { 3423 int nReadouts; ///< number of readouts in this cell realization; each may have its own3424 ///<image, objects and overscan.3425 struct psReadout *readouts; ///< Readouts from the cell3426 psMetadata *md; ///< Cell-level metadata3427 3428 ps CoordXform *cellToChip;///< Transformations from cell coordinates to chip coordinates3429 ps CoordXform *cellToFPA;///< Transformations from cell coordinates to FPA coordinates3430 ps CoordXform *cellToSky;///< Quick and Dirty transformations from cell coordinates to sky3431 3432 struct psChip *parentChip; ///< chip which contains this cell3449 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 3433 3459 } psCell; 3434 3460 \end{verbatim} … … 3442 3468 a coordinate transform from the chip to the focal plane. It is 3443 3469 expected that this transforms will consist of two second-order 2D 3444 polynomials; hence we expectthat it is prudent to include a reverse3470 polynomials; hence we think that it is prudent to include a reverse 3445 3471 transformation which will be derived from numerically inverting the 3446 3472 forward transformation. … … 3452 3478 typedef struct { 3453 3479 int nCells; ///< Number of Cells assigned 3454 psCell *cells;///< Cells in the Chip3455 3456 psMetadata *md; ///< Chip-level metadata3457 ps CoordXform *chipToFPA;///< Transformations from chip coordinates to FPA coordinates3458 ps CoordXform *FPAtoChip;///< Transformations from FPA coordinates to chip3459 3460 struct psFPA *parentFPA; ///< FPA which contains this chip3480 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 3461 3487 } psChip; 3462 3488 \end{verbatim} … … 3472 3498 two coordinates in position, the magnitude of the object, and the 3473 3499 color of the object) in order to correct for optical distortions and 3474 the effects of the atmosphere; hence we expectthat it is prudent to3500 the effects of the atmosphere; hence we think that it is prudent to 3475 3501 include a reverse transformation which will be derived from 3476 3502 numerically inverting the forward transformation. Since colors are … … 3488 3514 int nChips; ///< Number of Cells assigned 3489 3515 int nAlloc; ///< Number of Cells available 3490 psChip *chips;///< Chips in the Focal Plane Array3491 3492 psMetadata *md; ///< FPA-level metadata3493 ps Distortion *TPtoFP;///< Transformation term from3494 ps Distortion *FPtoTP;///< Transformation term from3495 psFixedPattern *pattern; ///< Fixed pattern residual offsets3496 psExposure *exp;///< information about this exposure3516 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 3497 3523 psPhotSystem colorPlus, colorMinus; ///< Colour reference 3498 3524 float rmsX, rmsY; ///< Dispersion in astrometric solution … … 3511 3537 typedef struct { 3512 3538 // Telescope longitude, latitude and height are stored separately, since they don't change with pointing 3513 double ra, dec;///< Telescope boresight3514 double ha;///< Hour angle3515 double zd;///< Zenith distance3516 double az;///< Azimuth3517 double lst;///< Local Sidereal Time3518 float mjd;///< MJD of observation3519 float rotAngle;///< Rotator position angle3520 float temp;///< Air temperature, for estimating refraction3521 float pressure;///< Air pressure, for calculating refraction3522 float humidity;///< Relative humidity, for calculating refraction3523 float exptime;///< Exposure time3539 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 3524 3550 /* 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 3532 3557 } psExposure; 3533 3558 \end{verbatim} … … 3583 3608 3584 3609 The following steps are required to convert from the cell coordinates to 3585 the sky \tbd{convert Cell- >Chip and Chip->FP to psDistortion}:3610 the sky \tbd{convert Cell-$>$Chip and Chip-$>$FP to psDistortion}: 3586 3611 \begin{itemize} 3587 3612 \item Cell $\longleftrightarrow$ Chip: two 2D polynomials, $(X,Y) = f(x,y)$; … … 3613 3638 3614 3639 \begin{verbatim} 3615 /** Information needed (by SLAL ib) to convert Apparent to Observed Position */3640 /** Information needed (by SLALIB) to convert Apparent to Observed Position */ 3616 3641 typedef struct { 3617 double latitude;///< geodetic latitude (radians)3618 double sinLat, cosLat;///< sine and cosine of geodetic latitude3619 double abberationMag;///< magnitude of diurnal aberration vector3620 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) 3629 3654 } psGrommit; 3655 \end{verbatim} 3656 3657 The \code{psGrommit} is calculated from telescope information for the 3658 particular exposure: 3659 3660 \begin{verbatim} 3661 /** Constructor */ 3662 psGrommit * 3663 psGrommitAlloc(const psExposure *exp ///< Relevant exposure 3664 ); 3665 3666 /** Destructor */ 3667 void 3668 psGrommitFree(psGrommit *grommit ///< Grommit to destroy 3669 ); 3630 3670 \end{verbatim} 3631 3671 … … 3664 3704 /** returns Chip in FPA which contains the given FPA coordinate */ 3665 3705 psChip * 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} 3706 psChipInFPA (psChip *out, ///< Chip to return, or NULL 3707 const psPlaneCoord *coord ///< coordinate in FPA 3708 const psFPA *fpa, ///< FPA description 3709 ); 3710 3673 3711 /** returns Cell in Chip which contains the given chip coordinate */ 3674 3712 psCell * 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} 3713 psCellInChip(psCell *out, ///< Cell to return, or NULL 3714 const psPlaneCoord *coord ///< coordinate in chip 3715 const psChip *chip, ///< chip description 3716 ); 3717 3686 3718 /** Return the cell in FPA which contains the given FPA coordinates */ 3687 3719 psCell * 3688 psCellInFPA(psCell *out, ///< Cell to return, or NULL3689 const psFPA *fpa, ///< FPA description 3690 const psCoord *coord ///< Coordinate in FPA 3691 );3720 psCellInFPA(psCell *out, ///< Cell to return, or NULL 3721 const psPlaneCoord *coord ///< Coordinate in FPA 3722 const psFPA *fpa, ///< FPA description 3723 ); 3692 3724 \end{verbatim} 3693 3725 … … 3724 3756 \begin{verbatim} 3725 3757 /** 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} 3758 psPlaneCoord * 3759 psCoordSkyToCell(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 3734 3765 /** 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} 3766 psSphereCoord * 3767 psCoordCellToSky(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 3743 3772 /** 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} 3773 psSphereCoord * 3774 psCoordCellToSkyQuick(psSphereCoord *out, ///< Coordinates to return, or NULL 3775 const psPlaneCoord *coord ///< cell coordinates to transform 3776 const psCell *cell, ///< Cell description 3777 ); 3778 3752 3779 /** 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} 3780 psPlaneCoord * 3781 psCoordSkyToTP(psPlaneCoord *out, ///< Coordinates to return, or NULL 3782 const psSphereCoord *coord ///< input Sky coordinate 3783 const psGrommit *grommit, ///< Grommit for fast conversion 3784 ); 3785 3761 3786 /** 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} 3787 psPlaneCoord * 3788 psCoordTPtoFPA(psPlaneCoord *out, ///< Coordinates to return, or NULL 3789 const psPlaneCoord *coord ///< input TP coordinate 3790 const psFPA *fpa, ///< FPA description 3791 ); 3792 3770 3793 /** 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} 3794 psPlaneCoord * 3795 psCoordFPAtoChip (psPlaneCoord *out, ///< Coordinates to return, or NULL 3796 const psPlaneCoord *coord ///< input FPA coordinate 3797 const psChip *chip, ///< Chip of interest 3798 ); 3799 3779 3800 /** 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} 3801 psPlaneCoord * 3802 psCoordChiptoCell (psPlaneCoord *out, ///< Coordinates to return, or NULL 3803 const psPlaneCoord *coord ///< input Chip coordinate 3804 const psCell *cell, ///< Cell of interest 3805 ); 3806 3788 3807 /** 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} 3808 psPlaneCoord * 3809 psCoordCelltoChip (psPlaneCoord *out, ///< Coordinates to return, or NULL 3810 const psPlaneCoord *coord ///< input Cell coordinate 3811 const psCell *cell, ///< Cell description 3812 ); 3813 3797 3814 /** 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} 3815 psPlaneCoord * 3816 psCoordChiptoFPA (psPlaneCoord *out, ///< Coordinates to return, or NULL 3817 const psPlaneCoord *coord ///< input Chip coordinate 3818 const psChip *chip, ///< Chip description 3819 ); 3820 3806 3821 /** 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} 3822 psPlaneCoord * 3823 psCoordFPAToTP(psPlaneCoord *out, ///< Coordinates to return, or NULL 3824 const psPlaneCoord *coord ///< input FPA coordinate 3825 const psFPA *fpa, ///< FPA description 3826 ); 3827 3815 3828 /** 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} 3829 psSphereCoord * 3830 psCoordTPtoSky(psSphereCoord *out, ///< Coordinates to return, or NULL 3831 const psPlaneCoord *coord ///< input TP coordinate 3832 const psGrommit *grommit, ///< Grommit for fast conversion 3833 ); 3834 3824 3835 /** Convert Cell coords to FPA coordinates */ 3825 ps Coord *3826 psCoordCellToFPA(ps Coord *out,///< Coordinates to return, or NULL3827 const psCell *cell, ///< Cell description 3828 const psCoord *coord ///< Input cell coordinates 3829 );3836 psPlaneCoord * 3837 psCoordCellToFPA(psPlaneCoord *out, ///< Coordinates to return, or NULL 3838 const psPlaneCoord *coord ///< Input cell coordinates 3839 const psCell *cell, ///< Cell description 3840 ); 3830 3841 \end{verbatim} 3831 3842 … … 3840 3851 /** Get the airmass for a given position and sidereal time */ 3841 3852 float 3842 psGetAirmass(const ps Coord *coord,///< Position on the sky3843 double siderealTime, ///< Sidereal time3844 float height///< Height above sea level3853 psGetAirmass(const psSphereCoord *coord, ///< Position on the sky 3854 double siderealTime, ///< Sidereal time 3855 float height ///< Height above sea level 3845 3856 ); 3846 3857 \end{verbatim} … … 3849 3860 /** Get the parallactic angle for a given position and sidereal time */ 3850 3861 float 3851 psGetParallactic(const ps Coord *coord,///< Position on the sky3862 psGetParallactic(const psSphereCoord *coord, ///< Position on the sky 3852 3863 double siderealTime ///< Sidereal time 3853 3864 ); … … 3893 3904 \begin{verbatim} 3894 3905 typedef struct { 3895 int ID;///< ID number for this photometric system3896 c har *name;///< Name of photometric system3897 c har *camera;///< Camera for photometric system3898 c har *filter;///< Filter used for photometric system3899 c har *detector;///< Detector used for photometric system3906 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 3900 3911 } psPhotSystem; 3901 3912 \end{verbatim} … … 3939 3950 M_{\rm pM} - pA, M_{\rm sP} - M_{\rm sM} - sA)$. 3940 3951 3952 \TBD{Really want a set of polynomials defined for specific colour 3953 ranges.} 3954 3941 3955 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3942 3956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% … … 3952 3966 \begin{verbatim} 3953 3967 /** Get Sun Position */ 3954 psCoord * 3955 psGetSunPos(float mjd ///< MJD to get position for 3956 ); 3957 \end{verbatim} 3958 3959 \begin{verbatim} 3968 psSphereCoord * 3969 psGetSunPos(float mjd ///< MJD to get position for 3970 ); 3971 3960 3972 /** 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} 3973 psSphereCoord * 3974 psGetMoonPos(float mjd, ///< MJD to get position for 3975 double latitude, ///< Latitude for apparent position 3976 double longitude ///< Longitude for apparent position 3977 ); 3978 3969 3979 /** Get Moon phase */ 3970 3980 float 3971 3981 psGetMoonPhase(float mjd ///< MJD to get phase for 3972 3982 ); 3973 \end{verbatim} 3974 3975 \begin{verbatim} 3983 3976 3984 /** Get Planet positions */ 3977 ps Coord *3985 psSphereCoord * 3978 3986 psGetSolarSystemPos(const char *solarSystemObject, ///< Named S.S. object 3979 3987 float mjd ///< MJD to get position for … … 3994 4002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3995 4003 3996 \appendix3997 3998 \pagebreak3999 \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 \pagebreak4014 \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} 4016 4024 4017 4025 \bibliographystyle{plain} \bibliography{panstarrs}
Note:
See TracChangeset
for help on using the changeset viewer.
