IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Oct 2, 2009, 3:12:47 PM (17 years ago)
Author:
eugene
Message:

check in changes from gene@development branch : extensive changes to moments calculation, psf model generation, aperture residuals; improvements to extended source analysis

Location:
trunk/psphot/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/psphot/src

    • Property svn:ignore
      •  

        old new  
        1818psphotVersionDefinitions.h
        1919psphotMomentsStudy
         20psphotPetrosianStudy
  • trunk/psphot/src/psphotSourceStats.c

    r24589 r25755  
    11# include "psphotInternal.h"
    22
    3 psArray *psphotSourceStats (pmConfig *config, pmReadout *readout, pmDetections *detections) {
     3bool psphotSetMomentsWindow (psMetadata *recipe, psArray *sources);
     4
     5psArray *psphotSourceStats (pmConfig *config, pmReadout *readout, pmDetections *detections, bool setWindow) {
    46
    57    bool status = false;
     
    2123    float OUTER    = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS");
    2224    if (!status) return NULL;
     25
     26    OUTER = PS_MAX(OUTER, 20.0); // XXX Guarantee that we can encompass the max moments radius
     27
    2328    char *breakPt  = psMetadataLookupStr (&status, recipe, "BREAK_POINT");
    2429    if (!status) return NULL;
     
    6065        psphotVisualShowMoments (sources);
    6166        return sources;
     67    }
     68
     69    if (setWindow) {
     70        if (!psphotSetMomentsWindow(recipe, sources)) {
     71            psError(PS_ERR_UNEXPECTED_NULL, false, "Failed to determine Moments Window!");
     72            return NULL;
     73        }
    6274    }
    6375
     
    144156    float RADIUS       = psMetadataLookupF32 (&status, recipe, "PSF_MOMENTS_RADIUS");
    145157    if (!status) return false;
    146     float MIN_PIXEL_SN = psMetadataLookupF32 (&status, recipe, "MOMENTS_MIN_PIXEL_SN");
    147     if (!status) return false;
    148158    float SIGMA        = psMetadataLookupF32 (&status, recipe, "MOMENTS_GAUSS_SIGMA");
    149159    if (!status) return false;
     
    194204        }
    195205
    196         // measure basic source moments
    197         status = pmSourceMoments (source, RADIUS, SIGMA, MIN_PIXEL_SN);
     206        // measure basic source moments (no S/N clipping on input pixels)
     207        status = pmSourceMoments (source, RADIUS, SIGMA, 0.0);
    198208        if (status) {
    199209            Nmoments ++;
     
    205215        BIG_RADIUS = PS_MIN (INNER, 3*RADIUS);
    206216        psTrace ("psphot", 4, "retrying moments for %d, %d\n", source->peak->x, source->peak->y);
    207         status = pmSourceMoments (source, BIG_RADIUS, 3.0*SIGMA, MIN_PIXEL_SN);
     217        status = pmSourceMoments (source, BIG_RADIUS, 3.0*SIGMA, 0.0);
    208218        if (status) {
    209219            source->mode |= PM_SOURCE_MODE_BIG_RADIUS;
     
    231241}
    232242
    233 # if (0)
    234 bool psphotSourceStats_Unthreaded (int *nfail, int *nmoments, psArray *sources, psMetadata *recipe) {
    235 
    236     bool status = false;
    237     float BIG_RADIUS;
    238 
    239     float INNER    = psMetadataLookupF32 (&status, recipe, "SKY_INNER_RADIUS");
    240     if (!status) return false;
    241     float MIN_SN   = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN");
    242     if (!status) return false;
    243     float RADIUS   = psMetadataLookupF32 (&status, recipe, "PSF_MOMENTS_RADIUS");
    244     if (!status) return false;
    245 
    246     // bit-masks to test for good/bad pixels
    247     psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT");
    248     assert (maskVal);
    249 
    250     // bit-mask to mark pixels not used in analysis
    251     psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT");
    252     assert (markVal);
    253 
    254     // maskVal is used to test for rejected pixels, and must include markVal
    255     maskVal |= markVal;
    256 
    257     // threaded measurement of the sources moments
    258     int Nfail = 0;
    259     int Nmoments = 0;
    260     for (int i = 0; i < sources->n; i++) {
    261         pmSource *source = sources->data[i];
    262 
    263         // skip faint sources for moments measurement
    264         if (source->peak->SN < MIN_SN) {
    265             continue;
    266         }
    267 
    268         // measure a local sky value
    269         // the local sky is now ignored; kept here for reference only
    270         status = pmSourceLocalSky (source, PS_STAT_SAMPLE_MEDIAN, INNER, maskVal, markVal);
    271         if (!status) {
    272             psErrorClear(); // XXX re-consider the errors raised here
    273             Nfail ++;
    274             continue;
    275         }
    276 
    277         // measure the local sky variance (needed if noise is not sqrt(signal))
    278         // XXX EAM : this should use ROBUST not SAMPLE median, but it is broken
    279         status = pmSourceLocalSkyVariance (source, PS_STAT_SAMPLE_MEDIAN, INNER, maskVal, markVal);
    280         if (!status) {
    281             Nfail ++;
    282             psErrorClear();
    283             continue;
    284         }
    285 
    286         // measure basic source moments
    287         status = pmSourceMoments (source, RADIUS, SIGMA, MIN_PIXEL_SN);
    288         if (status) {
    289             Nmoments ++;
    290             continue;
    291         }
    292 
    293         // if no valid pixels, or massive swing, likely saturated source,
    294         // try a much larger box
    295         BIG_RADIUS = PS_MIN (INNER, 3*RADIUS);
    296         psTrace ("psphot", 4, "retrying moments for %d, %d\n", source->peak->x, source->peak->y);
    297         status = pmSourceMoments (source, BIG_RADIUS, 3.0*SIGMA, MIN_PIXEL_SN);
    298         if (status) {
    299             Nmoments ++;
    300             continue;
    301         }
    302 
    303         Nfail ++;
    304         psErrorClear();
    305         continue;
    306     }
    307 
    308     // change the value of a scalar on the array (wrap this and put it in psArray.h)
    309     *nmoments = Nmoments;
    310     *nfail = Nfail;
    311 
     243// this function attempts to iteratively determine the best value for sigma of the moments weighting Gaussian
     244bool psphotSetMomentsWindow (psMetadata *recipe, psArray *sources) {
     245
     246    bool status;
     247
     248    float MIN_SN = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN");
     249    if (!status) return false;
     250
     251    // XXX move this to a config file?
     252    float sigma[4] = {1.0, 2.0, 3.0, 4.5};
     253    float Sout[4];
     254
     255    // this sorts by peak->SN
     256    sources = psArraySort (sources, pmSourceSortBySN);
     257
     258    // loop over radii:
     259    for (int i = 0; i < 4; i++) {
     260
     261        // XXX move max source number to config
     262        for (int j = 0; (j < sources->n) && (j < 400); j++) {
     263 
     264            pmSource *source = sources->data[j];
     265            psAssert (source->moments, "force moments to exist");
     266            source->moments->nPixels = 0;
     267
     268            // skip faint sources for moments measurement
     269            if (source->peak->SN < MIN_SN) {
     270                continue;
     271            }
     272
     273            // measure basic source moments (no S/N clipping on input pixels)
     274            status = pmSourceMoments (source, 4*sigma[i], sigma[i], 0.0);
     275        }
     276
     277        // choose a grid scale that is a fixed fraction of the psf sigma^2
     278        psMetadataAddF32(recipe, PS_LIST_TAIL, "PSF_CLUMP_GRID_SCALE", PS_META_REPLACE, "clump grid", 0.1*PS_SQR(sigma[i]));
     279        psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_SX_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(sigma[i]));
     280        psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_SY_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(sigma[i]));
     281
     282        // determine the PSF parameters from the source moment values
     283        pmPSFClump psfClump = pmSourcePSFClump (NULL, sources, recipe);
     284        psLogMsg ("psphot", 3, "radius %.1f, nStars: %d, nSigma: %5.2f, X,  Y: %f, %f (%f, %f)\n", sigma[i], psfClump.nStars, psfClump.nSigma, psfClump.X, psfClump.Y, sqrt(psfClump.X) / sigma[i], sqrt(psfClump.Y) / sigma[i]);
     285
     286        psMetadataAddS32 (recipe, PS_LIST_TAIL, "PSF.CLUMP.NREGIONS",  PS_META_REPLACE, "psf clump regions", 1);
     287        psMetadata *regionMD = psMetadataLookupPtr (&status, recipe, "PSF.CLUMP.REGION.000");
     288        if (!regionMD) {
     289            regionMD = psMetadataAlloc();
     290            psMetadataAddMetadata (recipe, PS_LIST_TAIL, "PSF.CLUMP.REGION.000", PS_META_REPLACE, "psf clump region", regionMD);
     291            psFree (regionMD);
     292        }
     293        psMetadataAddF32 (regionMD, PS_LIST_TAIL, "PSF.CLUMP.X",  PS_META_REPLACE, "psf clump center", psfClump.X);
     294        psMetadataAddF32 (regionMD, PS_LIST_TAIL, "PSF.CLUMP.Y",  PS_META_REPLACE, "psf clump center", psfClump.Y);
     295        psMetadataAddF32 (regionMD, PS_LIST_TAIL, "PSF.CLUMP.DX", PS_META_REPLACE, "psf clump center", psfClump.dX);
     296        psMetadataAddF32 (regionMD, PS_LIST_TAIL, "PSF.CLUMP.DY", PS_META_REPLACE, "psf clump center", psfClump.dY);
     297           
     298        // psphotVisualPlotMoments (recipe, sources);
     299
     300        Sout[i] = sqrt(0.5*(psfClump.X + psfClump.Y)) / sigma[i];
     301    }
     302
     303    // we are looking for sigma for which Sout = 0.65 (or some other value)
     304
     305    float Sigma = NAN;
     306    float minS = Sout[0];
     307    float maxS = Sout[0];
     308    for (int i = 0; i < 4; i++) {
     309        minS = PS_MIN(Sout[i], minS);
     310        maxS = PS_MAX(Sout[i], maxS);
     311    }
     312    if (minS > 0.65) Sigma = sigma[3];
     313    if (maxS < 0.65) Sigma = sigma[0];
     314
     315    for (int i = 0; i < 3; i++) {
     316        if ((Sout[i] > 0.65) && (Sout[i+1] > 0.65)) continue;
     317        if ((Sout[i] < 0.65) && (Sout[i+1] < 0.65)) continue;
     318        Sigma = sigma[i] + (0.65 - Sout[i])*(sigma[i+1] - sigma[i])/(Sout[i+1] - Sout[i]);
     319    }
     320    psAssert (isfinite(Sigma), "did we miss a case?");
     321       
     322    // choose a grid scale that is a fixed fraction of the psf sigma^2
     323    psMetadataAddF32(recipe, PS_LIST_TAIL, "PSF_CLUMP_GRID_SCALE", PS_META_REPLACE, "clump grid", 0.1*PS_SQR(Sigma));
     324    psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_SX_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(Sigma));
     325    psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_SY_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(Sigma));
     326    psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_GAUSS_SIGMA", PS_META_REPLACE, "moments limit", Sigma);
     327    psMetadataAddF32(recipe, PS_LIST_TAIL, "PSF_MOMENTS_RADIUS", PS_META_REPLACE, "moments limit", 4.0*Sigma);
     328
     329    psLogMsg ("psphot", 3, "using window function with sigma = %f\n", Sigma);
    312330    return true;
    313331}
    314 # endif
Note: See TracChangeset for help on using the changeset viewer.