IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Apr 8, 2008, 8:36:06 AM (18 years ago)
Author:
eugene
Message:

merging from eam_branch_20080324 : psphot work on extended source fitting and related I/O functions

File:
1 edited

Legend:

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

    r17113 r17396  
    11# include "psphotInternal.h"
    22# include <gsl/gsl_sf_gamma.h>
     3
     4float psphotModelContour (psImage *image, psImage *weight, psImage *mask, pmModel *model, float Ro);
    35
    46// we need to call this function after sources have been fitted to the PSF model and
     
    1416    psTimerStart ("psphot");
    1517
    16     float CR_NSIGMA_LIMIT = psMetadataLookupF32 (&status, recipe, "PSPHOT.CRNSIGMA.LIMIT");
     18    float CR_NSIGMA_LIMIT = psMetadataLookupF32 (&status, recipe, "PSPHOT.CR.NSIGMA.LIMIT");
     19    assert (status);
     20
     21    float EXT_NSIGMA_LIMIT = psMetadataLookupF32 (&status, recipe, "PSPHOT.EXT.NSIGMA.LIMIT");
    1722    assert (status);
    1823
     
    2429        if (isfinite(source->crNsigma)) continue;
    2530
    26         source->crNsigma  = -1.0;
    27         source->extNsigma = -1.0;
    28 
    2931        // source must have been subtracted
    30         source->crNsigma  = -3.0;
    3132        if (!(source->mode & PM_SOURCE_MODE_SUBTRACTED)) continue;
    3233
    33         psF32 **resid = source->pixels->data.F32;
     34        psF32 **resid  = source->pixels->data.F32;
    3435        psF32 **weight = source->weight->data.F32;
    35         psU8 **mask = source->maskObj->data.U8;
     36        psU8 **mask    = source->maskObj->data.U8;
     37
     38        // check for extendedness: measure the delta flux significance at the 1 sigma contour
     39        source->extNsigma = psphotModelContour (source->pixels, source->weight, source->maskObj, source->modelPSF, 1.0);
     40
     41        // XXX prevent a source from being both CR and EXT?
     42        if (source->extNsigma > EXT_NSIGMA_LIMIT) {
     43          source->mode |= PM_SOURCE_MODE_EXT_LIMIT;
     44        }
    3645
    3746        int xPeak = source->peak->xf - source->pixels->col0 + 0.5;
    3847        int yPeak = source->peak->yf - source->pixels->row0 + 0.5;
    3948
    40         // skip sources which are too close to a boundary
    41         source->crNsigma  = -4.0;
     49        // XXX for now, skip sources which are too close to a boundary
     50        // XXX raise a flag?
    4251        if (xPeak < 1) continue;
    4352        if (xPeak > source->pixels->numCols - 2) continue;
     
    4655
    4756        // XXX for now, just skip any sources with masked pixels
    48         source->crNsigma  = -5.0;
     57        // XXX raise a flag?
    4958        bool keep = true;
    5059        for (int iy = -1; (iy <= +1) && keep; iy++) {
     
    113122        }
    114123        source->crNsigma  = (nCR > 0)  ? fCR / nCR : 0.0;
    115         source->extNsigma = (nEXT > 0) ? fabs(fEXT) / nEXT : 0.0;
    116124        // NOTE: abs needed to make the Nsigma value positive
    117125
     
    122130
    123131        if (source->crNsigma > CR_NSIGMA_LIMIT) {
    124           source->mode |= PM_SOURCE_MODE_CRLIMIT;
     132          source->mode |= PM_SOURCE_MODE_CR_LIMIT;
    125133        }
    126134    }
     
    169177 */
    170178
     179
     180// given the PSF ellipse parameters, navigate around the 1sigma contour, return the total
     181// deviation in sigmas.  This is measure on the residual image - should we ignore negative
     182// deviations?
     183float psphotModelContour (psImage *image, psImage *weight, psImage *mask, pmModel *model, float Ro) {
     184
     185    psF32 *PAR = model->params->data.F32;
     186
     187    // Ro = (x / SXX)^2 + (y / SYY)^2 + x y SXY;
     188    // y^2 (1/SYY^2) + y (x SXY) + (x / SXX)^2 - Ro = 0;
     189    // y = [-(x SXY) +/- sqrt ((x SXY)^2 - 4 (1/SYY^2) ((x/SXX)^2 - Ro))] * [SYY^2 / 2];
     190    // y = [-B +/- sqrt (B^2 - 4 A C)] / [2 A];
     191
     192    // min/max value of x is where T -> 0
     193    // solve this for x2:
     194    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);
     195    if (Q < 0.0) return NAN; // ellipse is imaginary
     196
     197    int xMax = sqrt(Q);
     198    int xMin = -1.0*xMax;
     199
     200    int nPts = 0;
     201    float nSigma = 0.0;
     202
     203    for (int x = xMin; x <= xMax; x++) {
     204        float A = PS_SQR (1.0 / PAR[PM_PAR_SYY]);
     205        float B = x * PAR[PM_PAR_SXY];
     206        float C = PS_SQR (x / PAR[PM_PAR_SXX]) - Ro;
     207
     208        float T = PS_SQR(B) - 4*A*C;
     209        if (T < 0.0) continue;
     210   
     211        float yP = (-B + sqrt (T)) / (2.0 * A);
     212        float yM = (-B - sqrt (T)) / (2.0 * A);
     213
     214        int xPix  = x  + PAR[PM_PAR_XPOS] - image->col0 + 0.5;
     215        int yPixM = yM + PAR[PM_PAR_YPOS] - image->row0 + 0.5;
     216        int yPixP = yP + PAR[PM_PAR_YPOS] - image->row0 + 0.5;
     217
     218        if (xPix < 0) continue;
     219        if (xPix >= image->numCols) continue;
     220
     221        if ((yPixM >= 0) && (yPixM < image->numRows)) {
     222            if (!mask || !mask->data.U8[yPixM][xPix]) {
     223                float dSigma = image->data.F32[yPixM][xPix] / sqrt (weight->data.F32[yPixM][xPix]);
     224                nSigma += dSigma;
     225                nPts ++;
     226            }
     227        }
     228       
     229        if (yPixM == yPixP) continue;
     230
     231        if ((yPixP >= 0) && (yPixP < image->numRows)) {
     232            if (!mask || !mask->data.U8[yPixP][xPix]) {
     233                float dSigma = image->data.F32[yPixP][xPix] / sqrt (weight->data.F32[yPixP][xPix]);
     234                nSigma += dSigma;
     235                nPts ++;
     236            }
     237        }
     238    }   
     239    nSigma /= nPts;
     240    return nSigma;
     241}
Note: See TracChangeset for help on using the changeset viewer.