IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 20144


Ignore:
Timestamp:
Oct 14, 2008, 10:14:51 AM (18 years ago)
Author:
Paul Price
Message:

Cleaning up, adding comments.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psphot/src/psphotSourceSize.c

    r19915 r20144  
    22# include <gsl/gsl_sf_gamma.h>
    33
    4 float psphotModelContour (psImage *image, psImage *weight, psImage *mask, psMaskType maskVal, pmModel *model, float Ro);
     4static float psphotModelContour(const psImage *image, const psImage *weight, const psImage *mask,
     5                                psMaskType maskVal, const pmModel *model, float Ro);
    56
    67// we need to call this function after sources have been fitted to the PSF model and
     
    1011// deviation from the psf model at the r = FWHM/2 position
    1112
    12 bool psphotSourceSize (pmConfig *config, pmReadout *readout, psArray *sources, psMetadata *recipe, long first)
     13bool psphotSourceSize(pmConfig *config, pmReadout *readout, psArray *sources, psMetadata *recipe, long first)
    1314{
    14 
    1515    bool status;
    1616
     
    4141
    4242        // skip source if it was already measured
    43         if (isfinite(source->crNsigma)) continue;
     43        if (isfinite(source->crNsigma)) {
     44            psTrace("psphot", 7, "Not calculating extNsigma,crNsigma since already measured\n");
     45            continue;
     46        }
    4447
    4548        // source must have been subtracted
    46         if (!(source->mode & PM_SOURCE_MODE_SUBTRACTED)) continue;
     49        if (!(source->mode & PM_SOURCE_MODE_SUBTRACTED)) {
     50            psTrace("psphot", 7, "Not calculating extNsigma,crNsigma since source is not subtracted\n");
     51            continue;
     52        }
    4753
    4854        psF32 **resid  = source->pixels->data.F32;
     
    5157
    5258        // check for extendedness: measure the delta flux significance at the 1 sigma contour
    53         source->extNsigma = psphotModelContour (source->pixels, source->weight, source->maskObj, maskVal, source->modelPSF, 1.0);
     59        source->extNsigma = psphotModelContour(source->pixels, source->weight, source->maskObj, maskVal,
     60                                               source->modelPSF, 1.0);
    5461
    5562        // XXX prevent a source from being both CR and EXT?
    5663        if (source->extNsigma > EXT_NSIGMA_LIMIT) {
    57           source->mode |= PM_SOURCE_MODE_EXT_LIMIT;
    58         }
    59 
     64            source->mode |= PM_SOURCE_MODE_EXT_LIMIT;
     65        }
     66
     67        // Integer position of peak
    6068        int xPeak = source->peak->xf - source->pixels->col0 + 0.5;
    6169        int yPeak = source->peak->yf - source->pixels->row0 + 0.5;
     
    6371        // XXX for now, skip sources which are too close to a boundary
    6472        // XXX raise a flag?
    65         if (xPeak < 1) continue;
    66         if (xPeak > source->pixels->numCols - 2) continue;
    67         if (yPeak < 1) continue;
    68         if (yPeak > source->pixels->numRows - 2) continue;
     73        if (xPeak < 1 || xPeak > source->pixels->numCols - 2 ||
     74            yPeak < 1 || yPeak > source->pixels->numRows - 2) {
     75            psTrace("psphot", 7, "Not calculating crNsigma due to edge\n");
     76            continue;
     77        }
    6978
    7079        // XXX for now, just skip any sources with masked pixels
     
    7382        for (int iy = -1; (iy <= +1) && keep; iy++) {
    7483            for (int ix = -1; (ix <= +1) && keep; ix++) {
    75                 if (mask[yPeak+iy][xPeak+ix]) { keep &= false; }
    76             }
    77         }
    78         if (!keep) continue;
    79 
    80         if (mask[yPeak][xPeak] & maskVal) continue;
    81 
    82         // XXX need to deal with edge peaks... and mask
    83         float nX = 0;
    84         float nY = 0;
    85         float nL = 0;
    86         float nR = 0;
    87 
    88         if (!(mask[yPeak+0][xPeak-1] & maskVal) && !(mask[yPeak+0][xPeak+1] & maskVal)) {
    89             float cX = 2*resid[yPeak][xPeak] - resid[yPeak+0][xPeak-1] - resid[yPeak+0][xPeak+1];
    90             float dcX = 4*weight[yPeak][xPeak] + weight[yPeak+0][xPeak-1] + weight[yPeak+0][xPeak+1];
    91             nX = cX / sqrt(dcX);
    92         }
    93 
    94         if (!(mask[yPeak-1][xPeak+0] & maskVal) && !(mask[yPeak+1][xPeak+0] & maskVal)) {
    95             float cY = 2*resid[yPeak][xPeak] - resid[yPeak-1][xPeak+0] - resid[yPeak+1][xPeak+0];
    96             float dcY = 4*weight[yPeak][xPeak] + weight[yPeak-1][xPeak+0] + weight[yPeak+1][xPeak+0];
    97             nY = cY / sqrt(dcY);
    98         }
    99 
    100         if (!(mask[yPeak-1][xPeak-1] & maskVal) && !(mask[yPeak+1][xPeak+1] & maskVal)) {
    101             float dcL = 4*weight[yPeak][xPeak] + weight[yPeak-1][xPeak-1] + weight[yPeak+1][xPeak+1];
    102             float cL = 2*resid[yPeak][xPeak] - resid[yPeak-1][xPeak-1] - resid[yPeak+1][xPeak+1];
    103             nL = cL / sqrt(dcL);
    104         }
    105 
    106         if (!(mask[yPeak+1][xPeak-1] & maskVal) && !(mask[yPeak-1][xPeak+1] & maskVal)) {
    107             float dcR = 4*weight[yPeak][xPeak] + weight[yPeak+1][xPeak-1] + weight[yPeak-1][xPeak+1];
    108             float cR = 2*resid[yPeak][xPeak] - resid[yPeak+1][xPeak-1] - resid[yPeak-1][xPeak+1];
    109             nR = cR / sqrt(dcR);
    110         }
     84                if (mask[yPeak+iy][xPeak+ix] & maskVal) {
     85                    keep = false;
     86                }
     87            }
     88        }
     89        if (!keep) {
     90            psTrace("psphot", 7, "Not calculating crNsigma due to masked pixels\n");
     91            continue;
     92        }
     93
     94        // Compare the central pixel with those on either side, for the four possible lines through it.
     95
     96        // Across the middle: y = 0
     97        float cX = 2*resid[yPeak][xPeak]   - resid[yPeak+0][xPeak-1]  - resid[yPeak+0][xPeak+1];
     98        float dcX = 4*weight[yPeak][xPeak] + weight[yPeak+0][xPeak-1] + weight[yPeak+0][xPeak+1];
     99        float nX = cX / sqrtf(dcX);
     100
     101        // Up the centre: x = 0
     102        float cY = 2*resid[yPeak][xPeak]   - resid[yPeak-1][xPeak+0]  - resid[yPeak+1][xPeak+0];
     103        float dcY = 4*weight[yPeak][xPeak] + weight[yPeak-1][xPeak+0] + weight[yPeak+1][xPeak+0];
     104        float nY = cY / sqrtf(dcY);
     105
     106        // Diagonal: x = y
     107        float cL = 2*resid[yPeak][xPeak]   - resid[yPeak-1][xPeak-1]  - resid[yPeak+1][xPeak+1];
     108        float dcL = 4*weight[yPeak][xPeak] + weight[yPeak-1][xPeak-1] + weight[yPeak+1][xPeak+1];
     109        float nL = cL / sqrtf(dcL);
     110
     111        // Diagonal: x = - y
     112        float cR = 2*resid[yPeak][xPeak]   - resid[yPeak+1][xPeak-1]  - resid[yPeak-1][xPeak+1];
     113        float dcR = 4*weight[yPeak][xPeak] + weight[yPeak+1][xPeak-1] + weight[yPeak-1][xPeak+1];
     114        float nR = cR / sqrtf(dcR);
    111115
    112116        // P(chisq > chisq_obs; Ndof) = gamma_Q (Ndof/2, chisq/2)
     
    118122        // not strictly accurate: overcounts the chisq contribution from the center pixel (by
    119123        // factor of 4); also biases a bit low if any pixels are masked
    120         // XXX I am not sure I want to keep this value...
    121         source->psfChisq = PS_SQR (nX) + PS_SQR (nY) + PS_SQR (nX) + PS_SQR (nR);
     124        // XXX I am not sure I want to keep this value...
     125        source->psfChisq = PS_SQR(nX) + PS_SQR(nY) + PS_SQR(nX) + PS_SQR(nR);
    122126
    123127        float fCR = 0.0;
     
    156160            psImage *weight = source->weight;
    157161
     162            // XXX This should be a recipe variable
    158163            # define SN_LIMIT 5.0
    159164
     
    232237
    233238// given the PSF ellipse parameters, navigate around the 1sigma contour, return the total
    234 // deviation in sigmas.  This is measure on the residual image - should we ignore negative
     239// deviation in sigmas.  This is measured on the residual image - should we ignore negative
    235240// deviations?
    236     float psphotModelContour (psImage *image, psImage *weight, psImage *mask, psMaskType maskVal, pmModel *model, float Ro) {
    237 
    238     psF32 *PAR = model->params->data.F32;
    239 
    240     // Ro = (x / SXX)^2 + (y / SYY)^2 + x y SXY;
     241static float psphotModelContour(const psImage *image, const psImage *weight, const psImage *mask,
     242                                psMaskType maskVal, const pmModel *model, float Ro)
     243{
     244    psF32 *PAR = model->params->data.F32; // Model parameters
     245    float sxx = PAR[PM_PAR_SXX], sxy = PAR[PM_PAR_SXY], syy = PAR[PM_PAR_SYY]; // Ellipse parameters
     246
     247    // We treat the contour as an ellipse:
     248    // Ro = (x / SXX)^2 + (y / SYY)^2 + x y SXY
    241249    // y^2 (1/SYY^2) + y (x SXY) + (x / SXX)^2 - Ro = 0;
    242     // y = [-(x SXY) +/- sqrt ((x SXY)^2 - 4 (1/SYY^2) ((x/SXX)^2 - Ro))] * [SYY^2 / 2];
    243     // y = [-B +/- sqrt (B^2 - 4 A C)] / [2 A];
    244 
    245     // min/max value of x is where T -> 0
    246     // solve this for x2:
    247     float Q = Ro * PS_SQR(PAR[PM_PAR_SXX]) / (1.0 - PS_SQR(PAR[PM_PAR_SXX]*PAR[PM_PAR_SYY]*PAR[PM_PAR_SXY]) / 4.0);
    248     if (Q < 0.0) return NAN; // ellipse is imaginary
    249 
    250     int xMax = sqrt(Q);
    251     int xMin = -1.0*xMax;
    252 
    253     int nPts = 0;
    254     float nSigma = 0.0;
    255 
    256     for (int x = xMin; x <= xMax; x++) {
    257         float A = PS_SQR (1.0 / PAR[PM_PAR_SYY]);
    258         float B = x * PAR[PM_PAR_SXY];
    259         float C = PS_SQR (x / PAR[PM_PAR_SXX]) - Ro;
    260 
     250    // This is a quadratic, Ay^2 + By + C with A = 1/SYY^2, B = x*SXY, C = (x / SXX)^2 - Ro
     251    // The solution is y = [-B +/- sqrt (B^2 - 4 A C)] / [2 A], so:
     252    // y = [-(x SXY) +/- sqrt ((x SXY)^2 - 4 (1/SYY^2) ((x/SXX)^2 - Ro))] * [SYY^2 / 2]
     253
     254    // min/max value of x is where B^2 - 4AC = 0; solve this for x
     255    float Q = Ro * PS_SQR(sxx) / (1.0 - PS_SQR(sxx * syy * sxy) / 4.0);
     256    if (Q < 0.0) {
     257        // ellipse is imaginary
     258        return NAN;
     259    }
     260
     261    int radius = sqrtf(Q) + 0.5;        // Radius of ellipse
     262    int nPts = 0;                       // Number of points in ellipse
     263    float nSigma = 0.0;                 //
     264
     265    for (int x = -radius; x <= radius; x++) {
     266        // Polynomial coefficients
     267        float A = PS_SQR (1.0 / syy);
     268        float B = x * sxy;
     269        float C = PS_SQR (x / sxx) - Ro;
    261270        float T = PS_SQR(B) - 4*A*C;
    262         if (T < 0.0) continue;
    263 
     271        if (T < 0.0) {
     272            continue;
     273        }
     274
     275        // y position in source frame
    264276        float yP = (-B + sqrt (T)) / (2.0 * A);
    265277        float yM = (-B - sqrt (T)) / (2.0 * A);
    266278
     279        // Get the closest pixel positions (image frame)
    267280        int xPix  = x  + PAR[PM_PAR_XPOS] - image->col0 + 0.5;
    268281        int yPixM = yM + PAR[PM_PAR_YPOS] - image->row0 + 0.5;
    269282        int yPixP = yP + PAR[PM_PAR_YPOS] - image->row0 + 0.5;
    270283
    271         if (xPix < 0) continue;
    272         if (xPix >= image->numCols) continue;
    273 
    274         if ((yPixM >= 0) && (yPixM < image->numRows)) {
    275             if (!mask || !(mask->data.U8[yPixM][xPix] & maskVal)) {
    276                 float dSigma = image->data.F32[yPixM][xPix] / sqrt (weight->data.F32[yPixM][xPix]);
    277                 nSigma += dSigma;
    278                 nPts ++;
    279             }
    280         }
    281 
    282         if (yPixM == yPixP) continue;
    283 
    284         if ((yPixP >= 0) && (yPixP < image->numRows)) {
    285             if (!mask || !(mask->data.U8[yPixP][xPix] & maskVal)) {
    286                 float dSigma = image->data.F32[yPixP][xPix] / sqrt (weight->data.F32[yPixP][xPix]);
    287                 nSigma += dSigma;
    288                 nPts ++;
    289             }
     284        if (xPix < 0 || xPix >= image->numCols) {
     285            continue;
     286        }
     287
     288        if (yPixM >= 0 && yPixM < image->numRows &&
     289            !(mask && (mask->data.PS_TYPE_MASK_DATA[yPixM][xPix] & maskVal))) {
     290            float dSigma = image->data.F32[yPixM][xPix] / sqrtf(weight->data.F32[yPixM][xPix]);
     291            nSigma += dSigma;
     292            nPts++;
     293        }
     294
     295        if (yPixM == yPixP) {
     296            continue;
     297        }
     298
     299        if (yPixP >= 0 && yPixP < image->numRows &&
     300            !(mask && (mask->data.PS_TYPE_MASK_DATA[yPixP][xPix] & maskVal))) {
     301            float dSigma = image->data.F32[yPixP][xPix] / sqrtf(weight->data.F32[yPixP][xPix]);
     302            nSigma += dSigma;
     303            nPts++;
    290304        }
    291305    }
Note: See TracChangeset for help on using the changeset viewer.