IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 3070


Ignore:
Timestamp:
Jan 21, 2005, 3:59:10 PM (21 years ago)
Author:
eugene
Message:

updates for cycle 5

Location:
trunk/doc
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/modules/ChangeLogSDRS.tex

    r2818 r3070  
    1 %%% $Id: ChangeLogSDRS.tex,v 1.10 2004-12-24 02:30:46 price Exp $
     1%%% $Id: ChangeLogSDRS.tex,v 1.11 2005-01-22 01:59:10 eugene Exp $
    22
    33\subsection{Changes from version 00 to version 01}
     
    3535\item Added a \code{mask} to \code{pmSubtractSky}, and specified that binned pixels which are clipped may be interpolated over, or simply ignored.
    3636\item Added further explanation for \code{pmReadoutCombine}.
     37\item Added Object Detection section
     38\item Added PSPhot pseudo-C example
    3739\end{itemize}
  • trunk/doc/modules/ModulesSDRS.tex

    r3068 r3070  
    1 %%% $Id: ModulesSDRS.tex,v 1.27 2005-01-20 07:46:41 eugene Exp $
     1%%% $Id: ModulesSDRS.tex,v 1.28 2005-01-22 01:59:10 eugene Exp $
    22\documentclass[panstarrs]{panstarrs}
    33
     
    1111\project{Pan-STARRS Image Processing Pipeline}
    1212\organization{Institute for Astronomy}
    13 \version{02}
     13\version{03}
    1414\docnumber{PSDC-430-012}
    1515
     
    2727% version  Date            Description
    2828DR & 2004 Jun 7 & Draft \\ \hline
    29 00 & 2004 Aug 16 & release for cycle 3 \\ \hline
     2900 & 2004 Aug 16 & final for cycle 3 \\ \hline
    303001 & 2004 Oct 12 & draft for cycle 4 \\ \hline
     3102 & 2004 Nov 30 & final for cycle 4 \\ \hline
     3203 & 2005 Jan 21 & draft for cycle 5 \\ \hline
    3133\RevisionsEnd
    3234
     
    10401042\subsection{Overview}
    10411043
    1042 The process of finding, measurering, and classifying astronomical
     1044The process of finding, measuring, and classifying astronomical
    10431045sources on images is one of the critical tasks of the IPP or any
    10441046astronomical software system.  In this section, we define structures
     
    10471049components which can be connected together to construct a complete
    10481050object measurement suite.  An example pseudo-C program using these
    1049 functions is provided in Appendix~\ref{psphot}. 
     1051functions is provided in Appendix~\ref{psphot}.
    10501052
    10511053We first define the collection of structures needed to carry
     
    10531055define what we mean by an astronomical object in the context of image
    10541056source detection.  An astronomical object may be as simple as a
    1055 stellar point source, or it may consist of a more complex galaxy which
    1056 has smooth extended structure, or it may consist of an irregular
    1057 galaxy or galaxy group with substantial and complex sub-structure, or
    1058 it may consist of complex non-stellar structures such as planetary
    1059 nebular, reflection nebular, outflows and jets. 
    1060 
    1061 The simplest objects (ie, stars) can be sufficiently modelled by the
     1057stellar point source, or it may consist of a galaxy which has smooth
     1058extended structure; it may consist of an irregular galaxy or galaxy
     1059group with substantial and complex sub-structure, or it may consist of
     1060complex non-stellar structures such as planetary nebulae, reflection
     1061nebulae, outflows and jets.
     1062
     1063The simplest objects (ie, stars) can be sufficiently modeled by the
    10621064point-source function (PSF).  More complex objects (such as simple,
    10631065smooth galaxies), may have approximate analytical models which
    10641066represent their morphology with more-or-less accuracy.  In the extreme
    1065 cases, the objects are not well modelled at all and must be
    1066 represented in other ways.  Thus, one aspect of our data structures
    1067 must be elements to specify if an object has been represented by a
    1068 model, what the model parameters are, and how well it is represented
    1069 by the model.  Another aspect of the data structures must be a
    1070 representation of the pixels associated with the object so complex
    1071 structures may be reference without attempting to supply an analytical
    1072 model.  Finally, it is often useful to allow a single complex model to
    1073 be represented as a collection of simpler contained structures which
    1074 may be modelled.  Thus, the representation of an object must be
    1075 capable of identifying children, or substructures, of that object.
     1067cases, the objects are not well modeled at all and must be represented
     1068in other ways.  Thus, one aspect of our data structures must be
     1069elements to specify if an object has been represented by a model, what
     1070the model parameters are, and how well it is represented by the model.
     1071Another aspect of the data structures must be a representation of the
     1072pixels associated with the object so complex structures may be
     1073referenced without attempting to supply an analytical model.  Finally,
     1074it is often useful to allow a single complex model to be represented
     1075as a collection of simpler contained structures which may be modelled.
     1076Thus, the representation of an object must be capable of identifying
     1077children, or substructures, of that object.
    10761078
    10771079Two additional aspects must be considered.  First, source detection
    1078 need no be performed on a single image in isolation: it is necessary
     1080need not be performed on a single image in isolation: it is necessary
    10791081for multiple realizations of the same source in multiple images to be
    10801082measured together (whether or not through simultaneous fitting in
    10811083multiple bands or via application of the results from one image to
    1082 another image).  Second, it may be necessary for object measurements
    1083 to be performed on pixels in which no source is actually detectable.
    1084 For example, this is a convenient way to provide flux upper limits at
    1085 the locations of known objects.
    1086 
    1087 \subsection{Source Structures}
     1084another image).  Second, it will be necessary to performed object
     1085measurements on pixels in which no source is actually detected.  For
     1086example, this is a convenient way to provide flux upper limits at the
     1087locations of known objects.
     1088
     1089\subsection{Structures to Describe Sources}
    10881090
    10891091We start by defining a single source detected in a single band:
    10901092\begin{verbatim}
    10911093typedef struct {
    1092   psPeak *peak;
    1093   psPixels *pixels;
    1094   psMoments *moments;
    1095   psModel *models;
    1096   psSourceType type;
     1094  psPeak *peak;            // description of peak pixel
     1095  psImage *pixels;         // rectangular region including object pixels
     1096  psImage *mask;           // mask to mark pixels associated with object in region
     1097  psMoments *moments;      // basic moments measure for the object
     1098  psModel *models;         // model parameters and type
     1099  psSourceType type;       // best identification of object
    10971100} psSource;
    10981101\end{verbatim}
    10991102
    11001103This source has the capacity for several types of measurements.  The
    1101 simplest measurement of a source is the location of the peak pixel
    1102 associated with the source:
     1104simplest measurement of a source is the location and flux of the peak
     1105pixel associated with the source:
    11031106\begin{verbatim}
    11041107typedef struct {
    1105   int x;
    1106   int y;
    1107   float counts;
    1108   psPeakType class;
     1108  int x;                   // x-coordinate of peak pixel
     1109  int y;                   // y-coordinate of peak pixel
     1110  float counts;            // value of peak pixel (above sky?)
     1111  psPeakType class;        // description of peak
    11091112} psPeak;
    11101113\end{verbatim}
    11111114
    11121115A peak pixel may have several features which may be determined when
    1113 the peak is found or measured.  These are carried by the
    1114 \code{psPeakType} structure.  The \code{PS_PEAK_LONE} represents a
    1115 single pixel which is higher than its 8 immediate neighbors.  The
     1116the peak is found or measured.  These are specified by the
     1117\code{psPeakType} enum.  \code{PS_PEAK_LONE} represents a single pixel
     1118which is higher than its 8 immediate neighbors.  The
    11161119\code{PS_PEAK_EDGE} represents a peak pixel which touching the image
    11171120edge.  The \code{PS_PEAK_FLAT} represents a peak pixel which has more
     
    11201123\begin{verbatim}
    11211124typedef enum {
    1122   PS_PEAK_LONE;
    1123   PS_PEAK_EDGE;
    1124   PS_PEAK_FLAT;
     1125  PS_PEAK_LONE;             // isolated peak
     1126  PS_PEAK_EDGE;             // peak on edge
     1127  PS_PEAK_FLAT;             // peak has equal-value neighbors
    11251128} psPeakType;
    11261129\end{verbatim}
    11271130
    1128 In addition, the pixels which contain the source may be specified with
    1129 the \code{psPixels} element.  A \code{psPixels} collection identifies
    1130 a group of pixels by specifying sets of pixel spans:
    1131 \begin{verbatim}
    1132 typedef struct {
    1133   int nspan;
    1134   int rmin, rmax;
    1135   int cmin, cmax;
    1136   psSpan *s;
    1137 } psPixels;
    1138 \end{verbatim}
    1139 %
    1140 \begin{verbatim}
    1141 typedef struct {
    1142   short row;
    1143   short col0;
    1144   short col1;
    1145 } psSpan;
    1146 \end{verbatim}
     1131The pixels which contain the source may be specified with the
     1132\code{psImage *pixels} element, and the mask image may be used to
     1133exclude any pixels which are not considered part of the source.  Note
     1134that the source image may be simply a subimage of the main image or a
     1135separate copy if the pixels are modified (eg, by subtracting flux from
     1136other sources, etc).
    11471137
    11481138One of the simplest measurements which can be made quickly for an
     
    11521142\begin{verbatim}
    11531143typedef struct {
    1154   float x;
    1155   float y;
    1156   float Sx;
    1157   float Sy;
    1158   float Sxy;
    1159   float Sum;
    1160   float Peak;
    1161   float Sky;
    1162   int   nPixels;
     1144  float x;                  // x-coord of centroid
     1145  float y;                  // y-coord of centroid
     1146  float Sx;                 // x-second moment
     1147  float Sy;                 // y-second moment
     1148  float Sxy;                // xy cross moment
     1149  float Sum;                // pixel sum above sky (background)
     1150  float Peak;               // peak counts above sky
     1151  float Sky;                // sky level (background)
     1152  int   nPixels;            // number of pixels used
    11631153} psMoments;
    11641154\end{verbatim}
    11651155
    1166 An object may be modelled with some analytical function.  The result
    1167 of the model includes the model parameters and their errors, along
    1168 with the fit $\Chi^2$.
     1156An object's flux distribution may be modelled with some analytical
     1157function.  The description of the model includes the model parameters
     1158and their errors, along with the fit $\chi^2$.  The model type is
     1159specified by the enum \code{psObjectModel}, specified below.  We
     1160discuss the details of these models in section~\ref{ObjectModels}.
    11691161
    11701162\begin{verbatim}
    11711163typedef struct {
    1172   psObjectModel type;
    1173   int Nparams;
    1174   float *params;
    1175   float *dparams;
    1176   float chisq;
     1164  psObjectModel type;       // model to be used
     1165  int Nparams;              // number of parameters
     1166  float *params;            // parameter values
     1167  float *dparams;           // parameter errors
     1168  float chisq;              // fit chisq
    11771169} psModel;
    11781170\end{verbatim}
     
    11851177  PS_MODEL_WAUSS;
    11861178  PS_MODEL_SERSIC;
    1187   PS_MODEL_SERSIC_BULGE;
     1179  PS_MODEL_SERSIC_CORE;
    11881180} psModelType;
    11891181\end{verbatim}
     
    11911183\subsection{Basic Object Detection APIs}
    11921184
    1193 \begin{verbatim}
    1194 psVector *pmFindVectorPeaks (psVector vector, float threshold);
     1185In this section, we specify a collection of basic functions which
     1186operate on images and sources.  We define them roughly in order in
     1187which we expect to use them in a basic object detection process.
     1188
     1189\begin{verbatim}
     1190psVector *pmFindVectorPeaks(const psVector vector, float threshold);
    11951191\end{verbatim}
    11961192
    11971193Find all local peaks in the given vector above the given threshold.  A
    11981194peak is defined as any element with a value greater than its two
    1199 neighbors with a value above the threshold.  Two types of special
    1200 cases have to be addressed.  If an element has the same value as the
    1201 following element, it is not considered a peak.  If an element has the
    1202 same value as the preceeding element (but not the following), then it
    1203 is considered a peak.  Note that this rule (arbitrarily) identifies
    1204 flat regions by their trailing edge.  At the edges, the element must
    1205 be higher than its neighbor, or equal for the end edge.  This rule
    1206 again places the peak associated with a flat region which touches the
    1207 image edge at the image edge.  The result fo this function is a vector
    1208 containing the coordinates of the detected peaks.
    1209 
    1210 \begin{verbatim}
    1211 psList *pmFindImagePeaks (psImage image, float threshold);
     1195neighbors and with a value above the threshold.  Two types of special
     1196cases must be addressed.  Equal value elements: If an element has the
     1197same value as the following element, it is not considered a peak.  If
     1198an element has the same value as the preceeding element (but not the
     1199following), then it is considered a peak.  Note that this rule
     1200(arbitrarily) identifies flat regions by their trailing edge.  Edge
     1201cases: At start of the vector, the element must be higher than its
     1202neighbor.  At the end of the vector, the element must be higher or
     1203equal to its neighbor.  These two rules again places the peak
     1204associated with a flat region which touches the image edge at the
     1205image edge.  The result of this function is a vector containing the
     1206coordinates (element number) of the detected peaks (type
     1207\code{psU32}).
     1208
     1209\begin{verbatim}
     1210psList *pmFindImagePeaks(const psImage *image, float threshold);
    12121211\end{verbatim}
    12131212
     
    12151214This function should find all row peaks using
    12161215\code{pmFindVectorPeaks}, then test each row peak and exclude peaks
    1217 which are not local peaks.  A peak is a local peak if it is higher
    1218 than all 8 neighbors.  \tbd{flat region?}  The result of this function
    1219 is a list of \code{psPeak} entries.
    1220 
    1221 \begin{verbatim}
    1222 psList *pmCullPeaks (psList peaks, float maxvalue, psRegion valid);
     1216which are not local peaks.  A peak is a local peak if it has a higher value
     1217than all 8 neighbors.  If the peak has the same value as its +y
     1218neighbor or +x neighbor, it is NOT a local peak.  If any other
     1219neighbors have an equal value, the peak is considered a valid peak.
     1220Note two points: first, the +x neighbor condition is already enforced
     1221by \code{pmFindVectorPeaks}.  Second, these rules have the effect of
     1222making flat-topped regions have single peaks at the (+x,+y) corner.
     1223When selecting the peaks, their type must also be set.  The result of
     1224this function is a list of \code{psPeak} entries.
     1225
     1226\tbd{do we need a function psVector *psImageRowVector (psImage *image, int row);}
     1227
     1228\begin{verbatim}
     1229psList *pmCullPeaks(psList *peaks, float maxvalue, const psRegion *valid);
    12231230\end{verbatim}
    12241231
     
    12261233criteria.  Peaks should be eliminated if they have a peak value above
    12271234the given maximum value limit or if the fall outside the valid
    1228 region. 
    1229 
    1230 \begin{verbatim}
    1231 psSource *pmSourceLocalSky (psImage *image, psPeak *peak, float inner_radius, float outer_radius),
     1235region.  The result of the function is to reduce the number of peaks
     1236in the input peaks list, and return the resulting list.
     1237
     1238\begin{verbatim}
     1239psSource *pmSourceLocalSky(const psImage *image, const psPeak *peak, float inner_radius, float outer_radius),
    12321240\end{verbatim}
    12331241
    12341242Measure the local sky in the vicinity of the given \code{peak}.  The
    12351243image pixels in the square annulus with inner and outer radii as
    1236 specified are used to measure the median (clipped mean?)  (statistic
    1237 from \code{psStats}?) in the vicinity of the the specified peak
     1244specified are used to measure the median \tbd{(clipped mean?)
     1245(statistic from psStats?)} in the vicinity of the the specified peak
    12381246coordinates.  The resulting sky is applied to the \code{psMoments}
    12391247element of the allocated \code{psSource} structure.  The input
     
    12421250
    12431251\begin{verbatim}
    1244 psSource *pmSourceMoments (psImage *image, psSource *source, float radius),
     1252psSource *pmSourceMoments(psSource *source, const psImage *image, float radius),
    12451253\end{verbatim}
    12461254
    12471255Measure source moments for the given \code{source}, using the value of
    1248 \code{source.moments.sky} provided.  The resulting moment values are
    1249 applied to the \code{source.moments} entry, and the source is
    1250 retained.  The moments are measured within the given radius of the
    1251 \code{source.peak} coordinates.
    1252 
    1253 \begin{verbatim}
    1254 psSource *pmSourceRoughClass (psSource *source, float saturate, float SNlim, psRegion valid);
    1255 \end{verbatim}
    1256 
    1257 \begin{verbatim}
    1258 pmSourceFitModel (psImage *image, psSource *source, psModelType model);
    1259 \end{verbatim}
    1260 
    1261 \begin{verbatim}
    1262 pmSourceFitModel (psImage *image, psSource *source, psModelType model);
    1263 \end{verbatim}
     1256\code{source.moments.sky} provided as the local background value.  The
     1257resulting moment values are applied to the \code{source.moments}
     1258entry, and the source is returned.  The moments are measured within
     1259the given radius of the \code{source.peak} coordinates.
     1260
     1261\begin{verbatim}
     1262psSource *pmSourceRoughClass(psSource *source, float saturate, float SNlim, const psRegion *valid);
     1263\end{verbatim}
     1264
     1265Based on the specified data values, make a guess at the source
     1266classification. 
     1267
     1268\subsection{Object Fitting}
     1269
     1270We need a way to fit a particular functional model to an object.
     1271PSLib includes the \code{psMinimizeLMChi2} and \code{psMinimizePowell}
     1272functions, which form the core of this processes.  However, additional
     1273support functions and wrapping functions are necessary for the
     1274specific case of source fitting.  The operations can be broken down
     1275into discrete steps:
     1276
     1277\begin{enumerate}
     1278\item Identify the pixels of interest
     1279
     1280\item Make a guess at the model parameters.  For some models, the
     1281parameters may be guessed based on only the moments.  For others,
     1282additional measurements must be made.
     1283
     1284\item Construct the input vectors from the pixels of interest.
     1285
     1286\item Apply fitting function \code{psMinimizeLMChi2()}
     1287
     1288\item Construct model image.
     1289
     1290\item Subtract model from image.
     1291\end{enumerate}
     1292
     1293\begin{verbatim}
     1294bool pmSourceSetPixelsCircle(psSource *source, const psImage *image, float radius);
     1295\end{verbatim}
     1296
     1297Define pixels associated with a source based on a circular aperture.
     1298This operation creates the \code{source.pixels} and \code{source.mask}
     1299entries for the source based on a circular aperture centered on the
     1300source centroid (or peak?).  The \code{source.pixels} is a subimage of
     1301the input image.  The function returns \code{TRUE} on success or
     1302\code{FALSE} on failure.
     1303
     1304\begin{verbatim}
     1305bool pmSourceModelGuess(psSource *source, const psImage *image);
     1306\end{verbatim}
     1307
     1308Convert available data to an initial guess for the given model.  The
     1309method of defining the model parameter guesses are specified for each
     1310model below.  The guess values are placed in the model parameters.  The
     1311function returns \code{TRUE} on success or \code{FALSE} on failure.
     1312
     1313\begin{verbatim}
     1314psArray *pmSourceContour(const psSource *source, const psImage *image, float level, int mode);
     1315\end{verbatim}
     1316
     1317Find points in a contour for the given source at the given level.  If
     1318mode is \code{PS_CONTOUR_CRUDE}, the contour is found by starting at
     1319the source peak, running along each pixel row until the level is
     1320crossed, then interpolating to the level coordinate for that row.
     1321This is done for each row, with the starting point determined by the
     1322midpoint of the previous row, until the starting point has a value
     1323below the contour level.  The resulting contour consists of two
     1324vectors giving the x and y coordinates of the contour levels.  This
     1325function may be used as part of the model guess inputs.
     1326
     1327\tbd{Other modes may be specified in the future for more refined contours}
     1328
     1329\begin{verbatim}
     1330bool pmSourceFitModel(psSource *source, psImage *image);
     1331\end{verbatim}
     1332
     1333Fit the requested model to the specified source.  The starting guess
     1334for the model is given by the input \code{source.model} parameter
     1335values.  The pixels of interest are specified by the
     1336\code{source.pixels} and \code{source.mask} entries.  This function
     1337calls \code{psMinimizeLMChi2()} on the image data.  The function
     1338returns \code{TRUE} on success or \code{FALSE} on failure.
     1339
     1340\begin{verbatim}
     1341bool pmSourceAddModel(psImage *image, psSource *source, bool center);
     1342\end{verbatim}
     1343
     1344Add the given source model flux to the provided image.  The boolean
     1345option center selects if the source is recentered to the image center
     1346or if it is placed at its centroid location.  The pixel range in the
     1347target image is at most the pixel range specified by the
     1348\code{source.pixels} image.  The success status is returned. 
     1349
     1350\begin{verbatim}
     1351bool pmSourceSubModel(psSource *source);
     1352\end{verbatim}
     1353
     1354Subtract the model from its image pixels given by
     1355\code{source.pixels}.  The success status is returned. 
    12641356
    12651357\subsection{Basic Object Models}
    1266 
    1267 float PGaussian (psVector *deriv, psVector *params, psVector *x);
    1268 
    1269   X = x[0] - param[2];
    1270   Y = x[1] - param[3];
     1358\label{ObjectModels}
     1359
     1360We specify a variety of basic object models which are required.
     1361Details of the model functional forms, parameters, and the derivatives
     1362are specified in the ADD.
     1363
     1364\subsubsection{Real 2D Gaussian}
     1365
     1366\begin{verbatim}
     1367float psMinLM_Gauss2D(psVector *deriv, psVector *params, psVector *x);
     1368\end{verbatim}
     1369
     1370This function is a two-dimensional Gaussian with an elliptical
     1371cross-section and a constant local background. 
     1372
     1373The intial guess for the Gaussian parameters may be taken from the
     1374moments, peak value, and local sky.
     1375
     1376\subsubsection{Pseudo-Gaussian}
     1377
     1378\begin{verbatim}
     1379float psMinLM_PseudoGauss2D(psVector *deriv, psVector *params, psVector *x);
     1380\end{verbatim}
     1381
     1382This function is a polynomial approximation of a 2D Gaussian otherwise
     1383very similar to the real Gaussian.  It is used in place of a real
     1384Gaussian for speed.
     1385
     1386The intial guess for the Gaussian parameters may be taken from the
     1387moments, peak value, and local sky.
     1388
     1389\subsubsection{Waussian}
     1390
     1391\begin{verbatim}
     1392float psMinLM_Wauss2D(psVector *deriv, psVector *params, psVector *x);
     1393\end{verbatim}
     1394
     1395The Waussian is a modified polynomial approximation of a 2D Gaussian,
     1396with non-linear polynomial terms having variable coefficients, rather
     1397than the Taylor series values of 1/2 and 1/6. 
     1398
     1399\subsubsection{Twisted Gaussian}
     1400
     1401\begin{verbatim}
     1402float psMinLM_TwistGauss2D(psVector *deriv, psVector *params, psVector *x);
     1403\end{verbatim}
     1404
     1405This function describes an object with power-law wings and a flattened
     1406core, where the core has a different contour from the wings. 
     1407
     1408The intial guess for the Gaussian parameters may be taken from the
     1409moments, peak value, and local sky.
     1410
     1411\tbd{future galaxy models to be implemented}
     1412
     1413\subsubsection{Sersic Galaxy Model}
     1414
     1415\begin{verbatim}
     1416float psMinLM_Sersic(psVector *deriv, psVector *params, psVector *x);
     1417\end{verbatim}
     1418
     1419\subsubsection{Sersic with Core Galaxy Model}
     1420
     1421\begin{verbatim}
     1422float psMinLM_SersicCore(psVector *deriv, psVector *params, psVector *x);
     1423\end{verbatim}
     1424
     1425\subsubsection{Pseudo Sersic Galaxy Model}
     1426
     1427\begin{verbatim}
     1428float psMinLM_PseudoSersic(psVector *deriv, psVector *params, psVector *x);
     1429\end{verbatim}
     1430
     1431\appendix
     1432
     1433\section{Pseudo-C PSPhot}
     1434\label{psphot}
     1435
     1436\begin{verbatim}
     1437# include <pslib.h>
     1438# include <psmodule.h>
     1439
     1440main () {
     1441
     1442  psMetadata *header;
     1443  psImage *image;
     1444
     1445  fd = psFitsOpen (argv[1]);
     1446  md = psFitsReadHeader (fd);
     1447  image = psFitsReadImage (fd, md);
     1448
     1449  stats = psImageStats (NULL, image);
     1450
     1451  RDNOISE  = psMetadataLookup (md, "RDNOISE");
     1452  GAIN     = psMetadataLookup (md, "GAIN");
     1453  INNER    = psMetadataLookup (config, "INNER_RADIUS");
     1454  OUTER    = psMetadataLookup (config, "OUTER_RADIUS");
     1455  SATURATE = psMetadataLookup (config, "SATURATE");
     1456  NSIGMA   = psMetadataLookup (config, "PSF_PEAK_THRESHOLD");
     1457  RADIUS   = psMetadataLookup (config, "PSF_MOMENTS_RADIUS");
     1458  XBORDER  = psMetadataLookup (config, "XBORDER");
     1459  YBORDER  = psMetadataLookup (config, "YBORDER");
     1460
     1461  keep = psRegionAlloc (XBORDER, image->nCol - YBORDER,
     1462                        YBORDER, image->nRow - YBORDER);
    12711463 
    1272   px = param[4]*X;
    1273   py = param[5]*Y;
    1274 
    1275   z = 0.5*SQ(px) + 0.5*SQ(py) + param[6]*X*Y;
    1276   r = 1.0 / (1 + z + 0.5*z*z*(1 + z/3)); /* ~ exp (-Z) */
    1277   f = param[1]*r + param[0];
    1278   q = param[1]*r*r*(1 + z + 0.5*z*z);
    1279   /* note difference from gaussian: q = param[1]*r */
    1280 
    1281   deriv[0] = +1;
    1282   deriv[1] = +r;
    1283   deriv[2] = q*(2*px*param[4] + param[6]*Y);
    1284   deriv[3] = q*(2*py*param[5] + param[6]*X);
    1285   deriv[4] = -2*q*px*X;
    1286   deriv[5] = -2*q*py*Y;
    1287   deriv[6] = -q*X*Y;
    1288 
    1289 float Waussian (psVector *deriv, psVector *params, psVector *x);
    1290 
    1291   X = x - param[2];
    1292   Y = y - param[2];
     1464  Sky = stats->median;
     1465  Sig = sqrt(Sky/GAIN + SQ(RDNOISE));
     1466
     1467  kernel = psKernelParts ();
     1468  smooth = psImageConvolve (NULL, image, kernel, PS_PARTS);
     1469
     1470  peaks = pmFindImagePeaks (smooth, NSIGMA*Sig + Sky);
     1471
     1472  peaks = pmCullImagePeaks (peaks, SATURATE, keep);
    12931473 
    1294   px = param[4]*X;
    1295   py = param[5]*Y;
    1296 
    1297   z = 0.5*SQ(px) + 0.5*SQ(py) + param[6]*X*Y;
    1298   k = 0.5*z*z*(1 + param[8]*z/3);
    1299   r = 1.0 / (1 + z + param[7]*k); /* ~ exp (-Z) */
    1300   f = param[1]*r + param[0];
    1301   q = param[1]*r*r*(1 + param[7]*z*(1 + param[8]*z/2));
    1302   /* note difference from gaussian: q = param[1]*r */
    1303 
    1304   deriv[0] = +1;
    1305   deriv[1] = +r;
    1306   deriv[2] = q*(2*px*param[4] + param[6]*Y);
    1307   deriv[3] = q*(2*py*param[5] + param[6]*X);
    1308   deriv[4] = -2*q*px*X;
    1309   deriv[5] = -2*q*py*Y;
    1310   deriv[6] = -q*X*Y;
    1311   deriv[7] = -100*param[1]*r*r*k;
    1312   deriv[8] = -100*param[1]*r*r*param[7]*(z*z*z)/6;
    1313   /* the values of 100 dampen the swing of param[7,8] */
    1314 
    1315 float TwistGaussian ()
    1316 
    1317   X = x - param[2];
    1318   Y = y - param[3];
     1474  sources = pmSourceLocalSky (image, peaks, INNER, OUTER);
     1475
     1476  sources = pmSourceMoments (image, sources, RADIUS);
    13191477 
    1320   px1 = param[4]*X;
    1321   py1 = param[5]*Y;
    1322   px2 = param[7]*X;
    1323   py2 = param[8]*Y;
    1324 
    1325   z1 = 0.5*SQ(px1) + 0.5*SQ(py1) + param[4]*X*Y;
    1326   z2 = 0.5*SQ(px2) + 0.5*SQ(py2) + param[9]*X*Y;
    1327 
    1328   r = 1.0 / (1 + z1 + pow(z2,Npow));
    1329   f = param[5]*r + param[6];
    1330 
    1331   q1 = param[5]*SQ(r);
    1332   q2 = param[5]*SQ(r)*Npow*pow(z2,(Npow-1));
    1333 
    1334   deriv[0] = +1;
    1335   deriv[1] = +r;
    1336   deriv[2] = q1*(2*px1*param[4] + param[6]*Y) + q2*(2*px2*param[7] + param[9]*Y);
    1337   deriv[3] = q1*(2*py1*param[5] + param[6]*X) + q2*(2*py2*param[8] + param[9]*X);
    1338 
    1339   /* these fudge factors impede the growth of param[4] beyond param[7] */
    1340   f1 = fabs(param[7]) / fabs(param[4]);
    1341   f2 = (f1 < FSCALE) ? 1 : FFACTOR*(f1 - FSCALE) + 1;
    1342   deriv[4] = -2*q1*px1*X*f2;
    1343 
    1344   /* these fudge factors impede the growth of param[5] beyond param[8] */
    1345   f1 = fabs(param[8]) / fabs(param[5]);
    1346   f2 = (f1 < FSCALE) ? 1 : FFACTOR*(f1 - FSCALE) + 1;
    1347   deriv[5] = -2*q1*py1*Y*f2;
    1348 
    1349   deriv[6] = -q1*X*Y;
    1350 
    1351   deriv[7] = -2*q2*px2*X;
    1352   deriv[8] = -2*q2*py2*Y;
    1353   deriv[9] = -q2*X*Y;
    1354 
    1355 
     1478  sources = pmSourceRoughClassify (sources, SATURATE, MIN_SN_LIM, keep);
     1479
     1480  stars = pmSourceSelectBrightStars (sources);
     1481
     1482  stars = pmSourceFitModel (
     1483}
     1484
     1485
     1486
     1487psArray *pmFindImagePeaks (psImage *image, float threshold) {
     1488
     1489  psVector *row;
     1490
     1491  row = psVectorAlloc (image[0].Ncol);
     1492
     1493  /* find peaks in each row */
     1494  for (i = 0; i < image[0].Nrow; i++) {
     1495    rowpeaks = pmFindVectorPeaks (row, threshold);
     1496    peaks.x = rowpeaks;
     1497    peaks.y = i;
     1498    peaks.z = image (i, x);
     1499  }
     1500
     1501  /* drop non-local peaks (peaks with neighbors) */
     1502  for (n = 0; n < peaks.n; n++) {
     1503    if (!local_peak) {
     1504      drop_peak;
     1505    }
     1506  }
     1507  return (peaks);
     1508}
     1509\end{verbatim}
    13561510
    13571511\section{Revision Change Log}
  • trunk/doc/pslib/ChangeLogADD.tex

    r2640 r3070  
    1717\item Added short section on histograms in the presence of errors.
    1818\item Added short note on inverse spherical transformations.
     19\item Added section on astronomical object models
    1920\end{itemize}
  • trunk/doc/pslib/ChangeLogSDRS.tex

    r3069 r3070  
    1 %%% $Id: ChangeLogSDRS.tex,v 1.57 2005-01-20 08:25:45 price Exp $
     1%%% $Id: ChangeLogSDRS.tex,v 1.58 2005-01-22 01:57:42 eugene Exp $
    22
    33\subsection{Changes from version 00 to version 01}
     
    390390\end{itemize}
    391391
    392 \subsection{Changes from Revision 10 (30 November 2004) to present}
     392\subsection{Changes from Revision 10 (30 November 2004) to Revision 11 (21 January 2005)}
    393393
    394394\begin{itemize}
     
    399399\item fixed error of psHash to psMetadata in psFitsReadHeaderSet
    400400\item added psFitsWriteImage
    401 \item changed psFitsWriteImageSection to psFitsUpdateImage {\bf verify}
    402 \item changed psFitsWriteHeader to psFitsUpdateHeader {\bf verify}
     401\item changed psFitsWriteImageSection to psFitsUpdateImage
    403402\item added header entry to psFitsWriteTable
    404403\item added psFitsUpdateTable
     
    434433  PS_INTERPOLATE_BICUBIC_VARIANCE, PS_INTERPOLATE_SINC_VARIANCE}.
    435434\item Added \code{psImageTransform}.
    436 \end{itemize}
     435\item Added section of Database Functions
     436\end{itemize}
  • trunk/doc/pslib/psLibADD.tex

    r2779 r3070  
    1 %%% $Id: psLibADD.tex,v 1.56 2004-12-21 21:37:08 price Exp $
     1%%% $Id: psLibADD.tex,v 1.57 2005-01-22 01:57:42 eugene Exp $
    22\documentclass[panstarrs]{panstarrs}
    33
     
    16461646%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    16471647
    1648 \subsubsection{Missing and Todo}
     1648\subsection{Missing and Todo}
    16491649
    16501650\tbd{define SINC, LAGRANGE interpolation}
     
    16591659
    16601660\tbd{define Brent's method \& minimization bracketing}
     1661
     1662\section{Pan-STARRS Modules}
     1663
     1664\subsection{Object Models}
     1665
     1666\subsubsection{Real 2D Gaussian}
     1667
     1668This function is a two-dimensional Gaussian with an elliptical
     1669cross-section and a constant local background:
     1670\[
     1671f(x,y) = Z_o e^{-z} + S_o
     1672\]
     1673where
     1674\[
     1675z = \frac{(x - x_o)^2}{2\sigma_x^2} + \frac{(y-y_o)^2}{2\sigma_y^2} + (x-x_o) (y - y_o) \sigma_{xy}
     1676\]
     1677
     1678Below is the relationship between the \code{psModel} parameters and
     1679the function parameters, sample C-code implementing the function
     1680efficiently, and the value of the derivatives:
     1681
     1682\begin{verbatim}
     1683  param[0] = So;
     1684  param[1] = Zo;
     1685  param[2] = Xo;
     1686  param[3] = Yo;
     1687  param[4] = sqrt(2) / SigmaX;
     1688  param[5] = sqrt(2) / SigmaY;
     1689  param[6] = Sxy;
     1690
     1691  X = x[0] - param[2];
     1692  Y = x[1] - param[3];
     1693 
     1694  px = param[4]*X;
     1695  py = param[5]*Y;
     1696
     1697  z = 0.5*SQ(px) + 0.5*SQ(py) + param[6]*X*Y;
     1698  r = exp(-z);
     1699  f = param[1]*r + param[0];
     1700  /* f is the function value */
     1701
     1702  q = param[1]*r;
     1703  deriv[0] = +1;
     1704  deriv[1] = +r;
     1705  deriv[2] = q*(2*px*param[4] + param[6]*Y);
     1706  deriv[3] = q*(2*py*param[5] + param[6]*X);
     1707  deriv[4] = -2*q*px*X;
     1708  deriv[5] = -2*q*py*Y;
     1709  deriv[6] = -q*X*Y;
     1710\end{verbatim}
     1711
     1712The intial guess for the Gaussian parameters may be taken from the
     1713moments, peak value, and local sky.
     1714
     1715\subsubsection{Pseudo-Gaussian}
     1716
     1717This function is a polynomial approximation of a 2D Gaussian.  The
     1718function is very similar to the real Gaussian:
     1719\[
     1720f(x,y) = Z_o (1 + z + z^2/2 + z^3/6)^{-1} + S_o
     1721\]
     1722where
     1723\[
     1724z = \frac{(x - x_o)^2}{2\sigma_x^2} + \frac{(y-y_o)^2}{2\sigma_y^2} + (x-x_o) (y - y_o) \sigma_{xy}
     1725\]
     1726
     1727Below is the relationship between the \code{psModel} parameters and
     1728the function parameters, sample C-code implementing the function
     1729efficiently, and the value of the derivatives:
     1730
     1731\begin{verbatim}
     1732  param[0] = So;
     1733  param[1] = Zo;
     1734  param[2] = Xo;
     1735  param[3] = Yo;
     1736  param[4] = sqrt(2) / SigmaX;
     1737  param[5] = sqrt(2) / SigmaY;
     1738  param[6] = Sxy;
     1739
     1740  X = x[0] - param[2];
     1741  Y = x[1] - param[3];
     1742 
     1743  px = param[4]*X;
     1744  py = param[5]*Y;
     1745
     1746  z = 0.5*SQ(px) + 0.5*SQ(py) + param[6]*X*Y;
     1747  t = 1 + z + 0.5*z*z;
     1748  r = 1.0 / (t*(1 + z/3)); /* ~ exp (-Z) */
     1749  f = param[1]*r + param[0];
     1750  /* f is the function value */
     1751
     1752  /* note difference from a pure gaussian: q = param[1]*r */
     1753  q = param[1]*r*r*t;
     1754  deriv[0] = +1;
     1755  deriv[1] = +r;
     1756  deriv[2] = q*(2*px*param[4] + param[6]*Y);
     1757  deriv[3] = q*(2*py*param[5] + param[6]*X);
     1758  deriv[4] = -2*q*px*X;
     1759  deriv[5] = -2*q*py*Y;
     1760  deriv[6] = -q*X*Y;
     1761\end{verbatim}
     1762
     1763The intial guess for the Gaussian parameters may be taken from the
     1764moments, peak value, and local sky.
     1765
     1766\subsubsection{Waussian}
     1767
     1768The Waussian is a modified polynomial approximation of a 2D Gaussian,
     1769with non-linear polynomial terms having variable coefficients, rather
     1770than the Taylor series values of 1/2 and 1/6.  The
     1771function is very similar to the pseudo-Gaussian:
     1772\[
     1773f(x,y) = Z_o (1 + z + B_2 (z^2/2 + B_3 z^3/6))^{-1} + S_o
     1774\]
     1775where
     1776\[
     1777z = \frac{(x - x_o)^2}{2\sigma_x^2} + \frac{(y-y_o)^2}{2\sigma_y^2} + (x-x_o) (y - y_o) \sigma_{xy}
     1778\]
     1779
     1780Below is the relationship between the \code{psModel} parameters and
     1781the function parameters, sample C-code implementing the function
     1782efficiently, and the value of the derivatives.  Note the fudge factors
     1783of 100 in the derivatives of $B_2$ and $B_3$: these are included to
     1784slow the variation of these parameters, which are otherwise very
     1785sensitive to small errors.
     1786
     1787\begin{verbatim}
     1788  param[0] = So;
     1789  param[1] = Zo;
     1790  param[2] = Xo;
     1791  param[3] = Yo;
     1792  param[4] = Sx;
     1793  param[5] = Sy;
     1794  param[6] = Sxy;
     1795  param[7] = B2;
     1796  param[8] = B3;
     1797
     1798  X = x - param[2];
     1799  Y = y - param[2];
     1800 
     1801  px = param[4]*X;
     1802  py = param[5]*Y;
     1803
     1804  z = 0.5*SQ(px) + 0.5*SQ(py) + param[6]*X*Y;
     1805  t = 0.5*z*z*(1 + param[8]*z/3);
     1806  r = 1.0 / (1 + z + param[7]*t); /* ~ exp (-Z) */
     1807  f = param[1]*r + param[0];
     1808
     1809  /* note difference from gaussian: q = param[1]*r */
     1810  q = param[1]*r*r*(1 + param[7]*z*(1 + param[8]*z/2));
     1811  deriv[0] = +1;
     1812  deriv[1] = +r;
     1813  deriv[2] = q*(2*px*param[4] + param[6]*Y);
     1814  deriv[3] = q*(2*py*param[5] + param[6]*X);
     1815  deriv[4] = -2*q*px*X;
     1816  deriv[5] = -2*q*py*Y;
     1817  deriv[6] = -q*X*Y;
     1818  deriv[7] = -100*param[1]*r*r*t;
     1819  deriv[8] = -100*param[1]*r*r*param[7]*(z*z*z)/6;
     1820  /* the values of 100 dampen the swing of param[7,8] */
     1821\end{verbatim}
     1822
     1823\subsubsection{Twisted Gaussian}
     1824
     1825This function describes an object with power-law wings and a flattened
     1826core, where the core has a different contour from the wings. 
     1827
     1828\[
     1829f(x,y) = Z_{\rm pk} (1 + z_1 + z_2^M)^{-1} + Sky
     1830\]
     1831where
     1832\[
     1833z_1 = \frac{x^2}{2\sigma_{x,in}^2} + \frac{y^2}{2\sigma_{y,in}^2} + x y \sigma_{xy,in}
     1834z_2 = \frac{x^2}{2\sigma_{x,out}^2} + \frac{y^2}{2\sigma_{y,out}^2} + x y \sigma_{xy,out}
     1835\]
     1836
     1837\begin{verbatim}
     1838  param[0]  = So;
     1839  param[1]  = Zo;
     1840  param[2]  = Xo;
     1841  param[3]  = Yo;
     1842  param[4]  = SxInner;
     1843  param[5]  = SyInner;
     1844  param[6]  = SxyInner;
     1845  param[7]  = SxOuter;
     1846  param[8]  = SyOuter;
     1847  param[9]  = SxyOuter;
     1848  param[10] = N;
     1849
     1850  X = x - param[2];
     1851  Y = y - param[3];
     1852 
     1853  px1 = param[4]*X;
     1854  py1 = param[5]*Y;
     1855  px2 = param[7]*X;
     1856  py2 = param[8]*Y;
     1857
     1858  z1 = 0.5*SQ(px1) + 0.5*SQ(py1) + param[4]*X*Y;
     1859  z2 = 0.5*SQ(px2) + 0.5*SQ(py2) + param[9]*X*Y;
     1860
     1861  r  = 1.0 / (1 + z1 + pow(z2,param[10]));
     1862  f  = param[5]*r + param[6];
     1863
     1864  q1 = param[5]*SQ(r);
     1865  q2 = param[5]*SQ(r)*param[10]*pow(z2,(param[10]-1));
     1866
     1867  deriv[0] = +1;
     1868  deriv[1] = +r;
     1869  deriv[2] = q1*(2*px1*param[4] + param[6]*Y) + q2*(2*px2*param[7] + param[9]*Y);
     1870  deriv[3] = q1*(2*py1*param[5] + param[6]*X) + q2*(2*py2*param[8] + param[9]*X);
     1871
     1872  /* these fudge factors impede the growth of param[4] beyond param[7] */
     1873  f1 = fabs(param[7]) / fabs(param[4]);
     1874  f2 = (f1 < FSCALE) ? 1 : FFACTOR*(f1 - FSCALE) + 1;
     1875  deriv[4] = -2*q1*px1*X*f2;
     1876
     1877  /* these fudge factors impede the growth of param[5] beyond param[8] */
     1878  f1 = fabs(param[8]) / fabs(param[5]);
     1879  f2 = (f1 < FSCALE) ? 1 : FFACTOR*(f1 - FSCALE) + 1;
     1880  deriv[5] = -2*q1*py1*Y*f2;
     1881
     1882  deriv[6] = -q1*X*Y;
     1883
     1884  deriv[7] = -2*q2*px2*X;
     1885  deriv[8] = -2*q2*py2*Y;
     1886  deriv[9] = -q2*X*Y;
     1887  deriv[10] = -q1*ln(z2);
     1888\end{verbatim}
     1889
     1890The intial guess for the Gaussian parameters may be taken from the
     1891moments, peak value, and local sky.
     1892
     1893\tbd{future galaxy models to be implemented}
     1894
     1895\begin{verbatim}
     1896float Sersic()
     1897  param[0] = So;
     1898  param[1] = Zo;
     1899  param[2] = Xo;
     1900  param[3] = Yo;
     1901  param[4] = Sx;
     1902  param[5] = Sy;
     1903  param[6] = Sxy;
     1904  param[7] = Nexp;
     1905
     1906float SersicBulge()
     1907  param[0]  So;
     1908  param[1]  Zo;
     1909  param[2]  Xo;
     1910  param[3]  Yo;
     1911  param[4]  SxInner;
     1912  param[5]  SyInner;
     1913  param[6]  SxyInner;
     1914  param[7]  Zd;
     1915  param[8]  SxOuter;
     1916  param[9]  SyOuter;
     1917  param[10] = SxyOuter;
     1918  param[11] = Nexp;
     1919\end{verbatim}
    16611920
    16621921%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  • trunk/doc/pslib/psLibSDRS.tex

    r3069 r3070  
    1 %%% $Id: psLibSDRS.tex,v 1.168 2005-01-20 08:25:55 price Exp $
     1%%% $Id: psLibSDRS.tex,v 1.169 2005-01-22 01:57:42 eugene Exp $
    22\documentclass[panstarrs,spec]{panstarrs}
    33
     
    1111\project{Pan-STARRS Image Processing Pipeline}
    1212\organization{Institute for Astronomy}
    13 \version{10}
     13\version{11}
    1414\docnumber{PSDC-430-007}
    1515
     
    414109 & 2004 Nov 15 & final for cycle 4 \\ \hline
    424210 & 2004 Nov 30 & update for cycle 4 \\
     4311 & 2005 Jan 21 & draft for cycle 5 \\
    4344\RevisionsEnd
    4445
     
    9798search path, PSLib may be used within a program by including the line
    9899\code{#include <pslib.h>} into the C code and linking with
    99 \code{-lpslib}.
     100\code{-lpslib.}
    100101
    101102This document describes the data structures and details the functions
     
    109110principle relevance and VerbPhase describes the operation applied to
    110111that data type.  For example, the function which copies an image (of
    111 type \code{psImage}) is called \code{psImageCopy()}.
     112type \code{psImage}) is called \code{psImageCopy().}
    112113
    113114%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    41934194typedef xmlDocPtr psXMLDoc;
    41944195void psXMLDocFree(psXMLDoc *doc);
    4195 \end{verbatim}.
     4196\end{verbatim}
    41964197
    41974198The next pair of functions convert a \code{psMetadata} data structure
     
    42004201psXMLDoc *psMetadataToXMLDoc(const psMetadata *metadata);
    42014202psMetadata *psXMLDocToMetadata(const psXMLDoc *doc);
    4202 \end{verbatim}.
     4203\end{verbatim}
    42034204
    42044205The next pair of functions loads the data in a named file into a
     
    42084209psXMLDoc *psXMLParseFile(const char *filename);
    42094210int psXMLDocToFile(const psXMLDoc *doc, const char *filename);
    4210 \end{verbatim}.
     4211\end{verbatim}
    42114212
    42124213The next pair of functions accepts a block of memory and parses it
     
    42154216psXMLDoc *psXMLParseMemory(const char *buffer, const int size);
    42164217int psXMLDocToMemory(const psXMLDoc *doc, char *buffer);
    4217 \end{verbatim}.
     4218\end{verbatim}
    42184219
    42194220The next pair of functions read from and write to a file descriptor.
     
    42244225psXMLDoc *psXMLParseFD(int fd);
    42254226int psXMLDocToFD(const psXMLDoc *doc, int fd);
    4226 \end{verbatim}.
     4227\end{verbatim}
     4228
     4229\subsection{Database Functions}
     4230
     4231Many of the applications that PSLib will be used for will require
     4232access to a simple relational database.  PSLib includes generic
     4233database-independent interface mechanisms as part of its API set.  The
     4234most important aspect of PSLib's database support is to abstract as
     4235much database specific complexity as is feasible.  As almost all RDBMS
     4236provide at least a simple transactional model, commit and rollback
     4237support should be provided.
     4238
     4239Currently, only support for MySQL 4.1.x is required but other backends
     4240may be added as options in the future.  As a particular example which
     4241has implications for the database interaction model, support for
     4242SQLite may be required in the future.  Currently, the choice of
     4243backend database interface may be made as a compile option.  Details
     4244of the specified APIs in the discussion below refer to the relevant
     4245MySQL functions.
     4246
     4247Database errors must be trapped and placed onto the psError stack.
     4248The complete error message should be retrieved with the database's
     4249error function.
     4250
     4251\subsubsection{Managing the Database Connection}
     4252
     4253We specify a database handle which carries the information about the
     4254database connection:
     4255
     4256\begin{verbatim}
     4257    typedef struct {
     4258        MYSQL mysql;
     4259    } psDB;
     4260\end{verbatim}
     4261
     4262The following collection of functions provides basic database functionality:
     4263
     4264\begin{verbatim}
     4265    // wraps mysql_init() & mysql_real_connect()
     4266    psDB *psDBInit(const char *host, const char *user, const char *passwd, const char *dbname);
     4267
     4268    // wraps mysql_close()
     4269    void psDBCleanup(psDB *dbh);
     4270
     4271    // wraps mysql_create_db()
     4272    bool psDBCreate(psDB *dbh, const char *dbname);
     4273
     4274    // wraps mysql_select_db()
     4275    bool psDBChange(psDB *dbh, const char *dbname);
     4276
     4277    // wraps mysql_drop_db()
     4278    bool psDBDrop(psDB *dbh, const char *dbname);
     4279\end{verbatim}
     4280
     4281For MySQL support, \code{psDBInit()} wraps \code{mysql_init()} and
     4282\code{mysql_real_connect()} in order to initialize a psDB structure and
     4283establish a database connection.  A null pointer should be returned on
     4284failure.
     4285
     4286When implementing support for SQLite, or other DB which is purely
     4287file-based, the \code{host}, \code{user}, and \code{passwd} arguments
     4288would be ignored while \code{dbname} would specify the path to the
     4289SQLite db file.
     4290
     4291\subsubsection{Interacting with Database Tables}
     4292
     4293The functions in this section perform high level interactions with the
     4294database tables.  All of them should behave ``atomically'' with
     4295respect to the state of the database.  Specifically, all interactions
     4296with the database should be done as a part of a transaction that is
     4297rolled-back on failure and committed only after all queries used by
     4298the API have been run.  In general, this API set attempts to treat a
     4299database table as a 2D matrix where columns can be represented by a
     4300\code{psVector} and rows as a \code{psMetadata} type.  A
     4301\code{psMetadata} collection is also used to define the columns of a
     4302table and as part of the query restrictions.
     4303
     4304\begin{verbatim}
     4305    bool psDBCreateTable(psDB *dbh, const char *tableName, psMetadata *md);
     4306\end{verbatim}
     4307
     4308This function generates and executes the SQL needed to create a table
     4309named \code{tableName}, with the column names and datatypes as
     4310described in \code{md}.  Each data item in the \code{psMetadata}
     4311collection represents a single table field.  The name of the field is
     4312given by the name of the \code{psMetadataItem} and the data type is
     4313give by the \code{psMetadataItem.type} and \code{psMetadataItem.ptype}
     4314entries.  A lookup table should be used to convert from PSLib types
     4315into MySQL compatible SQL data types.  For example, a
     4316\code{PS_META_STR} would map to an SQL99 varchar.  If value of
     4317\code{type} is \code{PS_META_STR} then the \code{psMetadataItem.data}
     4318element is set to a string with the length for the field written as a
     4319text string.  The value of the \code{psMetadataItem.data} element is
     4320unused for the \code{PS_META_PRIMITIVE} types.  Other metadata types
     4321beyond \code{PS_META_STR} and \code{PS_META_PRIMITIVE} are not allowed
     4322in a table definition metadata collection.
     4323
     4324Database indexes can be specified setting the \code{comment} field to
     4325``\code{Primary Key}'' or ``\code{Key}''.  Comment are otherwise
     4326ignored.
     4327
     4328\begin{verbatim}
     4329    bool psDBDropTable(psDB *dbh, const char *tableName);
     4330\end{verbatim}
     4331
     4332This function deletes the specified table.
     4333
     4334\begin{verbatim}
     4335    psArray *psDBSelectColumn(psDB *dbh, const char *tableName, const char *col, const psU64 limit);
     4336    psVector *psDBSelectColumnNum(psDB *dbh, const char *tableName, const char *col, const psU64 limit);
     4337\end{verbatim}
     4338
     4339These functions generates and executes the SQL needed to select an
     4340entire column from a table or up to \code{limit} rows from it.  If
     4341\code{limit} is 0, the entire range is returned.  The database
     4342response is processed and a \code{psArray} of elements of the native
     4343type is returned.  The Num version of the function returns the data in
     4344a \code{psVector}.  It returns an error (NULL) if the requested field
     4345is not a numerical type.
     4346
     4347\begin{verbatim}
     4348    psArray *psDBSelectRows(psDB *dbh, const char *tableName, psMetadata *where);
     4349\end{verbatim}
     4350
     4351This function returns rows from the specified table which match
     4352the restrictions given by \code{where}.  The restrictions are
     4353specified as field / value pairs.  The \code{psMetadata} collection
     4354where must consist of valid database fields, though the database query
     4355checking functions may be used to validate the fields as part of the
     4356query.  If \code{where} is \code{NULL}, then there are no restrictions
     4357on the rows selected.  The selected rows are returned as a
     4358\code{psArray} of \code{psMetadata} values, one per row.
     4359
     4360\begin{verbatim}
     4361    bool psDBInsertRow(psDB *dbh, const char *tableName, psMetadata *row);
     4362\end{verbatim}
     4363
     4364Insert the data from \code{row} into \code{tableName}.  It should be noted in
     4365the API reference that if fields are specified in \code{row} that do not exist
     4366in \code{tablename}, the insert will fail.
     4367
     4368\begin{verbatim}
     4369    psArray *psDBDumpRows(psDB *dbh, const char *tableName);
     4370\end{verbatim}
     4371
     4372Fetch all rows as an psArray of psMetadata.
     4373
     4374\begin{verbatim}
     4375    psArray *psDBDumpCols(psDB *dbh, const char *tableName);
     4376\end{verbatim}
     4377
     4378Fetch all columns as an psArray of psVector
     4379
     4380\begin{verbatim}
     4381    psU64 psDBUpdateRow(psDB *dbh, const char *tableName, psMetadata *where, psMetadata *values);
     4382\end{verbatim}
     4383
     4384Update the columns contained in \code{values} in the row(s) that have a field
     4385with the value indicated by \code{where} (note that this is only allows very
     4386limited use of SQL99's ``where'' semantics).  The number of rows modified is
     4387returned.  If there are multiple psMetadataItems in \code{where} then each item
     4388should be considered as an additional constraint.  e.g.  ``where foo = x and
     4389where bar = y''
     4390
     4391\begin{verbatim}
     4392    psU64 psDBDeleteRow(psDB *dbh, const char *tableName, psMetadata *where);
     4393\end{verbatim}
     4394
     4395Delete the rows that are matched by \code{where} using the same semantics for
     4396\code{where} as in psDBUpdateRow().
    42274397
    42284398\subsection{FITS I/O Functions}
     
    45984768
    45994769\begin{verbatim}
    4600 psPlaneTransform *psPlaneTransformInvert(psPlaneTransform *out, const psPlaneTransform *in, float xMin,
    4601                                          float xMax, float yMin, float yMax, int nSamples);
    4602 psPlaneTransform *psPlaneTransformCombine(psPlaneTransform *out, const psPlaneTransform *trans1,
    4603                                           const psPlaneTransform *trans2);
    4604 bool psPlaneTranformFit(psPlaneTransform *trans, const psArray *source, const psArray *dest, int nRejIter,
    4605                         float sigmaClip);
     4770psPlaneTransform *psPlaneTransformInvert(psPlaneTransform *out, const psPlaneTransform *in, psRegion *region, int nSamples);
     4771psPlaneTransform *psPlaneTransformCombine(psPlaneTransform *out, const psPlaneTransform *trans1, const psPlaneTransform *trans2);
     4772bool psPlaneTranformFit(psPlaneTransform *trans, const psArray *source, const psArray *dest, int nRejIter, float sigmaClip);
    46064773\end{verbatim}
    46074774
     
    46124779the forward transformation.  In the event that the input
    46134780transformation is linear, an exact solution may be calculated;
    4614 otherwise \code{nSamples} samples in each axis, ranging from
    4615 \code{xMin} to \code{xMax} and \code{yMin} to \code{yMax} shall be
    4616 used as a grid to fit the best inverse transformation.  The function
    4617 shall return \code{NULL} if it was unable to generate the inverse
    4618 transformation; otherwise it shall return the inverse transformation.
    4619 In the event that \code{out} is \code{NULL}, a new
    4620 \code{psPlaneTransform} shall be allocated and returned.
    4621 
    4622 \code{psPlaneTransformSubsume} takes two transformations
     4781otherwise \code{nSamples} samples in each axis, covering the region
     4782specified by \code{region} shall be used as a grid to fit the best
     4783inverse transformation.  The function shall return \code{NULL} if it
     4784was unable to generate the inverse transformation; otherwise it shall
     4785return the inverse transformation.  In the event that \code{out} is
     4786\code{NULL}, a new \code{psPlaneTransform} shall be allocated and
     4787returned.
     4788
     4789\code{psPlaneTransformCombine} takes two transformations
    46234790(\code{trans1} and \code{trans2}) and returns a single transformation
    46244791that has the effect of performing \code{trans1} followed by
    46254792\code{trans2}.  The function shall return \code{NULL} if it was unable
    46264793to generate the transformation; otherwise it shall return the
    4627 transformation.  \tbd{Not sure on the algorithm yet --- it may be the
    4628 same as for \code{psPlaneTransformInvert}, in which case we will need
    4629 the ranges and number of samples as well.}
    4630 
    4631 \code{psPlaneTransform} takes two arrays containing matched
    4632 coordinates (i.e., coordinates the \code{source} correspond to the
    4633 appropriate coordinates in the \code{dest}) and returns the
     4794transformation.
     4795
     4796\code{psPlaneTransformFit} takes two arrays containing matched
     4797coordinates (i.e., coordinates in the \code{source} array correspond
     4798to the coordinates in the \code{dest} array) and returns the
    46344799best-fitting transformation.  The \code{source} and \code{dest} will
    46354800contain \code{psCoord}s.  In the event that the number of coordinates
Note: See TracChangeset for help on using the changeset viewer.