IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Apr 24, 2011, 10:09:38 PM (15 years ago)
Author:
eugene
Message:

determine the min kron radius = radius for bright PSF stars; mask interpolation used index instead of pixel coordinates in psImageInterpolate; add minKronRadius to pmSource; change errMag to psfMagErr; in growth curve, avoid perfect int radii (they can be inconsistent on + and - due to float precision; add pmGrowthCurveForSources; psfMagErr is always calculated from psfModel; apply ApTrend to all source psf mags and fluxes (not just psf sources); always use the psfModel for PSF_QF,_PERFECT; use BILINEAR to interpolate for aperture mags (BIQUAD implementation is wrong; apply growth curve to apMag & apFlux for all sources; save GrowthCurve with PSF model and read from PSF model

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20110404/psModules/src/objects/pmGrowthCurveGenerate.c

    r31327 r31361  
    5050
    5151#include "pmSourcePhotometry.h"
    52 
    53 pmGrowthCurve *pmGrowthCurveForPosition (psImage *image, pmPSF *psf, bool ignore, psImageMaskType maskVal, psImageMaskType markVal, float xc, float yc);
     52#include "pmGrowthCurveGenerate.h"
    5453
    5554/*****************************************************************************/
     
    226225    return growth;
    227226}
     227
     228// we generate the growth curve for the center of the image with the specified psf model
     229bool pmGrowthCurveGenerateFromSources (pmReadout *readout, pmPSF *psf, psArray *sources, bool INTERPOLATE_AP, psImageMaskType maskVal, psImageMaskType markVal)
     230{
     231    PS_ASSERT_PTR_NON_NULL(readout, false);
     232    PS_ASSERT_PTR_NON_NULL(readout->image, false);
     233
     234    // maskVal is used to test for rejected pixels, and must include markVal
     235    maskVal |= markVal;
     236
     237    pmSourcePhotometryMode photMode = INTERPOLATE_AP ? PM_SOURCE_PHOT_INTERP : 0;
     238   
     239    // measure the growth curve for each PSF source and average them together
     240    psArray *growths = psArrayAllocEmpty (100);
     241
     242    for (int i = 0; i < sources->n; i++) {
     243
     244        pmSource *source = sources->data[i];
     245
     246        if (!(source->mode & PM_SOURCE_MODE_PSFSTAR)) continue;
     247
     248        pmGrowthCurve *growth = pmGrowthCurveForSource (source, psf, photMode, maskVal, markVal);
     249        if (!growth) continue;
     250       
     251        psArrayAdd (growths, 100, growth);
     252        psFree (growth);
     253    }
     254    psAssert (growths->n, "cannot build growth curve (no valid PSF stars?)");
     255
     256# if (0)
     257    FILE *f = fopen ("growth.dat", "w");
     258    assert (f);
     259
     260    for (int j = 0; j < psf->growth->radius->n; j++) {
     261
     262        fprintf (f, "%f : ", psf->growth->radius->data.F32[j]);
     263
     264        // XXX dump the growth curves:
     265        for (int i = 0; i < growths->n; i++) {
     266           
     267            pmGrowthCurve *growth = growths->data[i];
     268            if (!growth) continue;
     269
     270            fprintf (f, "%8.4f ", growth->apMag->data.F32[j]);
     271        }
     272        fprintf (f, "\n");
     273    }
     274    fclose (f);
     275# endif
     276
     277    // just use a simple sample median to get the 'best' value from each growth curve...
     278    psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN);
     279
     280    psVector *values = psVectorAlloc (growths->n, PS_DATA_F32);
     281
     282    // loop over a range of source fluxes
     283    // no need to interpolate since we have forced the object center
     284    // to 0.5, 0.5 above
     285    for (int i = 0; i < psf->growth->radius->n; i++) {
     286
     287        // median the values for each radial bin
     288        values->n = 0;
     289        for (int j = 0; j < growths->n; j++) {
     290            pmGrowthCurve *growth = growths->data[j];
     291            if (!isfinite(growth->apMag->data.F32[i])) continue;
     292            psVectorAppend (values, growth->apMag->data.F32[i] - growth->fitMag);
     293        }
     294        if (values->n == 0) {
     295            psf->growth->apMag->data.F32[i] = NAN;
     296        } else {
     297            if (!psVectorStats (stats, values, NULL, NULL, 0)) {
     298                psError(PS_ERR_UNKNOWN, false, "failure to measure stats");
     299                return false;
     300            }
     301            psf->growth->apMag->data.F32[i] = stats->sampleMedian;
     302        }
     303    }
     304
     305    psf->growth->fitMag = psf->growth->apMag->data.F32[psf->growth->radius->n-1];
     306    psf->growth->apRef = psVectorInterpolate (psf->growth->radius, psf->growth->apMag, psf->growth->refRadius);
     307    psf->growth->apLoss = psf->growth->fitMag - psf->growth->apRef;
     308
     309    psLogMsg ("psphot.growth", 4, "GrowthCurve : apLoss : %f (fitMag - apMag @ ref : %f - %f)\n", psf->growth->apLoss, psf->growth->fitMag, psf->growth->apRef);
     310
     311    psFree (growths);
     312    psFree (stats);
     313    psFree (values);
     314
     315    return true;
     316}
     317
     318pmGrowthCurve *pmGrowthCurveForSource (pmSource *source, pmPSF *psf, pmSourcePhotometryMode photMode, psImageMaskType maskVal, psImageMaskType markVal) {
     319
     320    float radius;
     321
     322    assert (psf->growth);
     323
     324    float minRadius = psf->growth->radius->data.F32[0];
     325    pmGrowthCurve *growth = pmGrowthCurveAlloc (minRadius, psf->growth->maxRadius, psf->growth->refRadius);
     326
     327    // measure the fitMag for this source (for normalization)
     328    // pmSourcePhotometryModel (&fitMag, NULL, source->psfModel);
     329    growth->fitMag = source->psfMag;
     330
     331    float xc = source->peak->xf;
     332    float yc = source->peak->yf;
     333
     334    // Loop over the range of radii
     335    for (int i = 0; i < growth->radius->n; i++) {
     336
     337        radius = growth->radius->data.F32[i];
     338
     339        // mask the given aperture and measure the apMag
     340        psImageKeepCircle (source->maskObj, xc, yc, radius, "OR", markVal);
     341
     342        if (!pmSourceMagnitudes (source, psf, photMode, maskVal, markVal, radius)) {
     343            psFree (growth);
     344            return NULL;
     345        }
     346
     347        // if (!pmSourcePhotometryAper (NULL, &apMag, NULL, NULL, NULL, source->pixels, NULL, source->maskObj, maskVal)) {
     348        //     psFree (growth);
     349        //     return NULL;
     350        // }
     351
     352        psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); // clear the circular mask
     353
     354        growth->apMag->data.F32[i] = source->apMag;
     355    }
     356    return growth;
     357}
     358
     359# if (0)
     360    // solve for the best growth and the offsets per star to minimize the scatter
     361
     362    // generate the per-star and per-radius sums
     363    int Nradius = psf->growth->radius->n;
     364    int Nstar = growths->n;
     365
     366    psVector *Mstar   = psVectorAlloc (Nstar, PS_DATA_F32);
     367    psVector *Mradius = psVectorAlloc (Nradius, PS_DATA_F32);
     368
     369    psVectorInit (Mstar, 0.0);
     370    psVectorInit (Mradius, 0.0);
     371
     372    for (int i = 0; i < Nstar; i++) {
     373        pmGrowthCurve *growth = growths->data[i];
     374        for (int j = 0; j < Nradius; j++) {
     375            Mstar->data.F32[i] += growth->apMag->data.F32[j];
     376            Mradius->data.F32[j] += growth->apMag->data.F32[j];
     377        }
     378    }
     379
     380    psImage *A = psImageAlloc(Nstar + Nradius, Nstar + Nradius, PS_DATA_F32);
     381    psVector *B = psVectorAlloc(Nstar + Nradius, PS_DATA_F32);
     382
     383    psImageInit (A, 0.0);
     384    psVectorInit (B, 0.0);
     385
     386    for (int i = 0; i < Nstar; i++) {
     387        A->data.F32[i][i] = Nradius;
     388        B->data.F32[i] = Mstar->data.F32[i];
     389    }
     390    for (int i = 0; i < Nradius; i++) {
     391        int j = i + Nstar;
     392        A->data.F32[j][j] = Nstar;
     393        B->data.F32[j] = Mradius->data.F32[i];
     394    }
     395   
     396    if (!psMatrixGJSolve(A, B)) {
     397        psAbort("GJ failure");
     398    }
     399
     400    for (int i = 0; i < Nradius; i++) {
     401        psf->growth->apMag->data.F32[i] = B->data.F32[Nstar+i];
     402    }
     403
     404    // XXX this analysis produces a biased growth curve: points with small radius are more
     405    // likely to err on the side of being too faint (bacause of mis-aligned aperture), while on
     406    // the bright side the tend to be too bright (because of contaminating neighbors).  Bright
     407    // stars are less likely to be biased,
     408
     409    // XXX at this point, we could iterate and exclude some of the stars with low data quality
     410    // XXX we could also weight the above by flux or something
     411
     412# endif
Note: See TracChangeset for help on using the changeset viewer.