IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

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

updates for cycle 5

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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}
Note: See TracChangeset for help on using the changeset viewer.