IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Apr 4, 2011, 1:12:39 PM (15 years ago)
Author:
eugene
Message:

use the smoothed image for footprint culling; use a more stringent culling for saturated stars; more tweaks to get sat stars to be fitted; various updates to psphotStack; unify psphotImageLoop varients; be a bit careful about number of stars in a PSF clump

Location:
trunk/psphot
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/psphot

  • trunk/psphot/src/psphotSourceStats.c

    r29936 r31154  
    122122        // allocate space for moments
    123123        source->moments = pmMomentsAlloc();
     124
     125        if (source->mode & PM_SOURCE_MODE_MOMENTS_FAILURE) {
     126            fprintf (stderr, "moment failure\n");
     127        }
    124128
    125129        // allocate image, weight, mask arrays for each peak (square of radius OUTER)
     
    361365
    362366    bool status = false;
    363     float BIG_RADIUS;
    364367    psScalar *scalar = NULL;
    365368
     
    373376    psImageMaskType maskVal         = PS_SCALAR_VALUE(job->args->data[5],PS_TYPE_IMAGE_MASK_DATA);
    374377    psImageMaskType markVal         = PS_SCALAR_VALUE(job->args->data[6],PS_TYPE_IMAGE_MASK_DATA);
     378
     379    // if no valid pixels, massive swing or very large Mrf, likely saturated source,
     380    // try a much larger box
     381    float BIG_RADIUS = 3.0*RADIUS;
     382    float BIG_SIGMA  = 3.0*SIGMA;
    375383
    376384    // maskVal is used to test for rejected pixels, and must include markVal
     
    390398
    391399        // skip faint sources for moments measurement
    392         if (source->peak->SN < MIN_SN) {
     400        if (sqrt(source->peak->detValue) < MIN_SN) {
    393401            source->mode |= PM_SOURCE_MODE_BELOW_MOMENTS_SN;
    394402            Nfaint++;
     
    416424        }
    417425
    418         // measure basic source moments (no S/N clipping on input pixels)
    419         status = pmSourceMoments (source, RADIUS, SIGMA, 0.0, maskVal);
    420         // XXX moments / aperture test:
    421         if (0) {
    422             // clear the mask bit and set the circular mask pixels
    423             psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
    424             psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, 4.0*source->moments->Mrf, "OR", markVal);
    425            
    426             float apMag = NAN;
    427             pmSourcePhotometryAper (&apMag, NULL, NULL, NULL, source->pixels, source->variance, source->maskObj, maskVal);
    428             fprintf (stderr, "apMag: %f, kronMag: %f\n", apMag, -2.5*log10(source->moments->KronFlux));
    429 
    430             // clear the mask bit
    431             psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal));
    432         }           
    433         if (status) {
    434             Nmoments ++;
    435             continue;
    436         }
    437 
    438         // if no valid pixels, or massive swing, likely saturated source,
    439         // try a much larger box
    440         BIG_RADIUS = PS_MIN (INNER, 3*RADIUS);
    441         psTrace ("psphot", 4, "retrying moments for %d, %d\n", source->peak->x, source->peak->y);
    442         status = pmSourceMoments (source, BIG_RADIUS, 3.0*SIGMA, 0.0, maskVal);
    443         if (status) {
    444             source->mode |= PM_SOURCE_MODE_BIG_RADIUS;
    445             Nmoments ++;
    446             continue;
    447         }
    448 
    449         source->mode |= PM_SOURCE_MODE_MOMENTS_FAILURE;
    450         Nfail ++;
    451         psErrorClear();
    452         continue;
     426        // XXX how can this be set: this is raised in pmSourceRoughClass, called after this function?
     427        if (source->mode & PM_SOURCE_MODE_SATSTAR) {
     428            fprintf (stderr, "satstar: %f,%f\n", source->peak->xf, source->peak->yf);
     429        }
     430
     431        if (!(source->peak->type == PM_PEAK_SUSPECT_SATURATION)) {
     432            // measure basic source moments (no S/N clipping on input pixels)
     433            status = pmSourceMoments (source, RADIUS, SIGMA, 0.0, maskVal);
     434        } else {
     435            // For saturated stars, choose a much larger box NOTE this is slightly sleazy, but
     436            // only slightly: pmSourceRedefinePixels uses the readout to pass the pointers to
     437            // the parent image data.  I guess the API could be simplified: we could recover
     438            // this from the source in the function
     439
     440            pmReadout tmpReadout;
     441            tmpReadout.image    = (psImage *)source->pixels->parent;
     442            tmpReadout.mask     = (psImage *)source->maskView->parent;
     443            tmpReadout.variance = (psImage *)source->variance->parent;
     444
     445            // re-allocate image, weight, mask arrays for each peak with box big enough to fit BIG_RADIUS
     446            pmSourceRedefinePixels (source, &tmpReadout, source->peak->x, source->peak->y, BIG_RADIUS + 2);
     447
     448            psTrace ("psphot", 4, "retrying moments for %d, %d\n", source->peak->x, source->peak->y);
     449            status = pmSourceMoments (source, BIG_RADIUS, BIG_SIGMA, 0.0, maskVal);
     450            source->mode |= PM_SOURCE_MODE_BIG_RADIUS;
     451        }
     452        if (!status) {
     453            source->mode |= PM_SOURCE_MODE_MOMENTS_FAILURE;
     454            Nfail ++;
     455            psErrorClear();
     456            continue;
     457        }
     458        Nmoments ++;
     459
     460        // re-try big sources or not??
     461        // if (source->moments->Mrf < 2.0*SIGMA)
    453462    }
    454463
     
    473482
    474483    float MIN_SN = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN"); psAssert (status, "missing MOMENTS_SN_MIN");
    475     float PSF_SN_LIM = psMetadataLookupF32(&status, recipe, "PSF_SN_LIM"); psAssert (status, "missing PSF_SN_LIM");
    476484    psF32 MOMENTS_AR_MAX = psMetadataLookupF32(&status, recipe, "MOMENTS_AR_MAX"); psAssert (status, "missing MOMENTS_AR_MAX");
     485
     486    // when we set the window, we are not attempting to measure spatial variations; we can use a somewhat higher S/N limit
     487    // since we are using all sources (true?)
     488    float PSF_SN_LIM = 2.0*psMetadataLookupF32(&status, recipe, "PSF_SN_LIM"); psAssert (status, "missing PSF_SN_LIM");
    477489
    478490    // XXX move this to a config file?
     
    480492    float sigma[NSIGMA] = {1.0, 2.0, 3.0, 4.5, 6.0, 9.0, 12.0, 18.0};
    481493    float Sout[NSIGMA];
    482 
    483     // this sorts by peak->SN
    484     sources = psArraySort (sources, pmSourceSortBySN);
     494    int   Nout[NSIGMA]; // number of stars found in clump : use this to control the number of regions measured by psphotRoughClass
     495
     496    // this sorts by peak->rawFlux
     497    sources = psArraySort (sources, pmSourceSortByFlux);
    485498
    486499    // loop over radii:
     
    495508
    496509            // skip faint sources for moments measurement
    497             if (source->peak->SN < MIN_SN) {
     510            if (sqrt(source->peak->detValue) < MIN_SN) {
    498511                continue;
    499512            }
     
    510523        // determine the PSF parameters from the source moment values
    511524        pmPSFClump psfClump = pmSourcePSFClump (NULL, NULL, sources, PSF_SN_LIM, PSF_CLUMP_GRID_SCALE, MOMENTS_SX_MAX, MOMENTS_SY_MAX, MOMENTS_AR_MAX);
    512         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]);
     525        psLogMsg ("psphot", 3, "radius %.1f, nStars: %d of %d in clump, nSigma: %5.2f, X,  Y: %f, %f (%f, %f)\n", sigma[i], psfClump.nStars, psfClump.nTotal, psfClump.nSigma, psfClump.X, psfClump.Y, sqrt(psfClump.X) / sigma[i], sqrt(psfClump.Y) / sigma[i]);
    513526
    514527#if 0
     
    531544
    532545        Sout[i] = sqrt(0.5*(psfClump.X + psfClump.Y)) / sigma[i];
     546        Nout[i] = psfClump.nStars;
    533547    }
    534548
    535549    // we are looking for sigma for which Sout = 0.65 (or some other value)
     550    int Nstars = 0;
    536551    float Sigma = NAN;
    537552    float minS = Sout[0];
     
    549564        if ((Sout[i] < 0.65) && (Sout[i+1] < 0.65)) continue;
    550565        Sigma = sigma[i] + (0.65 - Sout[i])*(sigma[i+1] - sigma[i])/(Sout[i+1] - Sout[i]);
     566        Nstars = 0.5*(Nout[i] + Nout[i+1]);
    551567    }
    552568    psAssert (isfinite(Sigma), "did we miss a case?");
     
    558574    psMetadataAddF32(analysis, PS_LIST_TAIL, "MOMENTS_GAUSS_SIGMA", PS_META_REPLACE, "moments limit", Sigma);
    559575    psMetadataAddF32(analysis, PS_LIST_TAIL, "PSF_MOMENTS_RADIUS", PS_META_REPLACE, "moments limit", 4.0*Sigma);
     576    psMetadataAddF32(analysis, PS_LIST_TAIL, "PSF_CLUMP_NSTARS", PS_META_REPLACE, "number of stars in clump", Nstars);
    560577
    561578    psLogMsg ("psphot", 3, "using window function with sigma = %f\n", Sigma);
Note: See TracChangeset for help on using the changeset viewer.