IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 25312


Ignore:
Timestamp:
Sep 9, 2009, 5:50:03 PM (17 years ago)
Author:
Paul Price
Message:

Got the magnitude measurements working properly now.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/pap/psphot/src/psphotFake.c

    r25309 r25312  
    44                    PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_LIMITS) // Mask to apply to models
    55
    6 #define TESTING
     6//#define TESTING
    77
    88
     
    1212// non-Gaussian PSF) to the limiting flux in the un-smoothed original image.
    1313static bool fakeLimit(float *magLim,           // Limiting magntiude, to return
    14                       int *radius,             // Radius for fake sources
     14                      int *radius,             // Radius for fake sources, to return
     15                      float *minFlux,          // Minimum flux for fake sources, to return
     16                      float *norm,             // Normalisation of PSF (conversion: peak --> integrated flux)
    1517                      const pmReadout *ro,     // Readout of interest
    1618                      const pmPSF *psf,        // Point-spread function
     
    2527    assert(magLim);
    2628    assert(radius);
     29    assert(minFlux);
     30    assert(norm);
    2731
    2832    psKernel *kernel = psImageSmoothKernel(smoothSigma, smoothNsigma); // Kernel used for smoothing
     
    5357        return false;
    5458    }
    55     float norm = normModel->modelFlux(normModel->params); // Total flux for peak of 1.0
     59    *norm = normModel->modelFlux(normModel->params); // Total flux for peak of 1.0
    5660    psFree(normModel);
    5761
     
    6569    // I_smooth = Flux / 2*norm.
    6670    float peakLim = thresh * sqrtf(meanVar * factor); // Limiting peak value in smoothed image
    67     float fluxLim = 2.0 * norm * peakLim; // Limiting flux in original
     71    float fluxLim = 2.0 * *norm * peakLim; // Limiting flux in original
    6872    *magLim = -2.5 * log10f(fluxLim);
    6973    psTrace("psphot.fake", 1, "Limiting peak: %f\n", peakLim);
     
    7276
    7377    *radius = smoothSigma * smoothNsigma;
     78
     79    *minFlux = 0.1 * sqrtf(meanVar);
    7480
    7581    return true;
     
    8389                         int numSources,                 // Number of fake sources for each bin
    8490                         float refMag,                   // Reference magnitude
    85                          int radius                      // Radius for fake sources
     91                         int radius,                     // Radius for fake sources
     92                         float minFlux                   // Minimum flux for fake sources
    8693                         )
    8794{
     
    122129    pmReadout *fakeRO = pmReadoutAlloc(NULL); // Fake readout
    123130    if (!pmReadoutFakeFromVectors(fakeRO, numCols, numRows, xAll, yAll, magAll,
    124                                   NULL, NULL, psf, NAN, radius, false, true)) {
     131                                  NULL, NULL, psf, minFlux, radius, false, true)) {
    125132        psError(PS_ERR_UNKNOWN, false, "Unable to generate fake image");
    126133        psFree(fakeRO);
     
    191198
    192199
    193 
     200#if defined(TESTING) && 0
    194201    {
    195202        psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS);
     
    205212        psFree(rng);
    206213    }
    207 
     214#endif
    208215
    209216
     
    211218    float magLim;                       // Guess at limiting magnitude
    212219    int radius;                         // Radius for fake sources
    213     if (!fakeLimit(&magLim, &radius, readout, psf, thresh, smoothSigma, smoothNsigma, maskVal)) {
     220    float minFlux;                      // Minimum flux for fake sources
     221    float norm;                         // Normalisation of PSF
     222    if (!fakeLimit(&magLim, &radius, &minFlux, &norm, readout,
     223                   psf, thresh, smoothSigma, smoothNsigma, maskVal)) {
    214224        psError(PS_ERR_UNKNOWN, false, "Unable to determine limits for image");
    215225        return false;
     
    223233
    224234    psImage *xFake = NULL, *yFake = NULL; // Coordinates of sources, each bin in a row
    225     if (!fakeGenerate(&xFake, &yFake, readout, psf, magOffsets, numSources, magLim, radius)) {
     235    if (!fakeGenerate(&xFake, &yFake, readout, psf, magOffsets, numSources, magLim, radius, minFlux)) {
    226236        psError(PS_ERR_UNKNOWN, false, "Unable to generate fake sources");
    227237        psFree(xFake);
     
    246256
    247257#ifdef TESTING
    248     psphotSaveImage(NULL, readout->mask, "fake_sig.fits");
     258    psphotSaveImage(NULL, significance, "fake_sig.fits");
    249259#endif
    250260
     
    253263    int numBins = magOffsets->n;                          // Number of bins
    254264    psVector *count = psVectorAlloc(numBins, PS_TYPE_S32); // Number of sources found in each bin
    255     psArray *fakeSources = psArrayAllocEmpty(numSources * numBins); // Fake sources
    256     psVector *fakeEnd = psVectorAllocEmpty(numSources * numBins, PS_TYPE_S32); // End index of each bin
    257     long numFound = 0;                                                           // Number of sources found
     265    psArray *fakeSources = psArrayAlloc(numSources);            // Fake sources in each bin
     266    psArray *fakeSourcesAll = psArrayAllocEmpty(numSources * numBins); // All fake sources
    258267    for (int i = 0; i < numBins; i++) {
    259         int num = 0;               // Number found
    260 
     268        int numFound = 0;               // Number found
     269
     270        // Determine extraction size
     271        float mag = magLim + magOffsets->data.F32[i]; // Magnitude for bin
     272        float peak = powf(10.0, -0.4 * mag) / norm;   // Peak flux
     273        pmModel *model = pmModelFromPSFforXY(psf, numCols / 2.0, numRows / 2.0, peak); // Model for source
     274        if (!model || (model->flags & MODEL_MASK)) {
     275            psError(PS_ERR_UNKNOWN, true, "Unable to generate model for bin %d", i);
     276            psFree(model);
     277            return false;
     278        }
     279        float sourceRadius = PS_MAX(radius, model->modelRadius(model->params, minFlux)); // Radius for source
     280        psFree(model);
     281
     282        psArray *sources = psArrayAllocEmpty(numSources); // Sources in this bin
    261283        for (int j = 0; j < numSources; j++) {
    262284            // Coordinates of interest
    263             float x = PS_MIN(xFake->data.F32[i][j] + 0.5, numCols - 1);
    264             float y = PS_MIN(yFake->data.F32[i][j] + 0.5, numRows - 1);
    265             int xPix = x, yPix = y;    // Pixel coordinates
     285            float x = xFake->data.F32[i][j];
     286            float y = yFake->data.F32[i][j];
     287            int xPix = PS_MIN(x + 0.5, numCols - 1), yPix = PS_MIN(y + 0.5, numRows - 1); // Pixel coordinates
    266288            float sig = significance->data.F32[yPix][xPix]; // Significance of pixel
    267289            if (sig > thresh) {
    268290                pmSource *source = pmSourceAlloc(); // Fake source
    269                 source->peak = pmPeakAlloc(x, y, NAN, PM_PEAK_LONE);
    270                 if (!pmSourceDefinePixels(source, readout, x, y, radius)) {
     291                source->peak = pmPeakAlloc(x, y, sig, PM_PEAK_LONE);
     292                if (!pmSourceDefinePixels(source, readout, x, y, sourceRadius)) {
    271293                    psErrorClear();
    272294                    continue;
    273295                }
     296                source->peak->xf = x;
     297                source->peak->yf = y;
    274298                source->modelPSF = pmModelFromPSFforXY(psf, x, y, 2.0 * sqrtf(sig));
    275299                source->type = PM_SOURCE_TYPE_STAR;
    276300
    277                 num++;
    278 
    279                 fakeSources->data[numFound] = source;
    280301                numFound++;
     302                psArrayAdd(sources, sources->n, source);
     303                psArrayAdd(fakeSourcesAll, fakeSourcesAll->n, source);
     304                psFree(source);
    281305            }
    282306        }
    283         count->data.S32[i] = num;
    284         fakeEnd->data.S32[i] = numFound;
    285     }
    286     fakeSources->n = numFound;
    287 
     307        fakeSources->data[i] = sources;
     308        count->data.S32[i] = numFound;
     309    }
    288310    psFree(xFake);
    289311    psFree(yFake);
    290312    psFree(significance);
    291313
    292     if (!psphotFitSourcesLinear(readout, fakeSources, recipe, psf, true)) {
     314    if (!psphotFitSourcesLinear(readout, fakeSourcesAll, recipe, psf, true)) {
    293315        psError(PS_ERR_UNKNOWN, false, "Unable to perform linear fit on fake sources.");
    294316        psFree(fakeSources);
    295         psFree(fakeEnd);
    296317        psFree(count);
    297318        return false;
    298319    }
    299     if (!psphotMagnitudes(config, readout, view, fakeSources, psf)) {
     320
     321    // Disable aperture corrections; casting away const!
     322    pmTrend2D *apTrend = psf->ApTrend;  // Aperture trend
     323    ((pmPSF*)psf)->ApTrend = NULL;
     324
     325    if (!psphotMagnitudes(config, readout, view, fakeSourcesAll, psf)) {
    300326        psError(PS_ERR_UNKNOWN, false, "Unable to measure magnitudes of fake sources.");
    301327        psFree(fakeSources);
    302         psFree(fakeEnd);
    303328        psFree(count);
    304         return false;
    305     }
    306 
     329        ((pmPSF*)psf)->ApTrend = apTrend; // Casting away const!
     330        return false;
     331    }
     332    psFree(fakeSourcesAll);
     333
     334    // Re-enable aperture corrections; casting away const!
     335    ((pmPSF*)psf)->ApTrend = apTrend;
     336
     337    psVector *magDiffMean = psVectorAlloc(numBins, PS_TYPE_F32); // Mean difference in magnitude for each bin
     338    psVector *magDiffStdev = psVectorAlloc(numBins, PS_TYPE_F32); // Stdev of diff in magnitude for each bin
    307339    psVector *magErrMean = psVectorAlloc(numBins, PS_TYPE_F32); // Mean error in magnitude for each bin
    308     psVector *magErrStdev = psVectorAlloc(numBins, PS_TYPE_F32); // Stdev of error in magnitude for each bin
    309     psVector *magErrErrMean = psVectorAlloc(numBins, PS_TYPE_F32); // Mean error in magnitude for each bin
     340    psVector *magDiff = psVectorAlloc(numSources, PS_TYPE_F32);   // Magnitude differences
    310341    psVector *magErr = psVectorAlloc(numSources, PS_TYPE_F32);   // Magnitude errors
    311     psVector *magErrErr = psVectorAlloc(numSources, PS_TYPE_F32); // Error in magnitude error
    312342    psVector *magMask = psVectorAlloc(numSources, PS_TYPE_VECTOR_MASK); // Mask for magnitude errors
    313     psStats *magStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV | PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics
    314     psVector *robustMedian = psVectorAlloc(numBins, PS_TYPE_F32);
    315     psVector *robustStdev = psVectorAlloc(numBins, PS_TYPE_F32);
    316     for (int i = 0, index = 0; i < numBins; i++) {
     343    psStats *magStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV |
     344                                     PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics
     345    for (int i = 0; i < numBins; i++) {
    317346        psStatsInit(magStats);
    318347        psVectorInit(magMask, 0);
    319348
     349#ifdef TESTING
    320350        psString name = NULL;
    321351        psStringAppend(&name, "fake_%d.dat", i);
    322352        FILE *file = fopen(name, "w");
     353        psFree(name);
     354#endif
    323355
    324356        float magRef = magLim + magOffsets->data.F32[i]; // Reference magnitude
    325         int j;                          // Index
    326         for (j = 0; index < fakeEnd->data.S32[i]; j++, index++) {
    327             pmSource *source = fakeSources->data[index]; // Source of interest
     357        psArray *sources = fakeSources->data[i];         // Sources in bin
     358        for (int j = 0; j < sources->n; j++) {
     359            pmSource *source = sources->data[j]; // Source of interest
    328360            if (!source || !isfinite(source->psfMag)) {
    329361                magMask->data.PS_TYPE_VECTOR_MASK_DATA[j] = 0xFF;
     
    331363            }
    332364
    333             fprintf(file, "%f %f %f %f %f\n", source->peak->xf, source->peak->yf,
     365#ifdef TESTING
     366            fprintf(file, "%f %f %f %f %f %f %f\n", source->peak->xf, source->peak->yf,
     367                    source->modelPSF->params->data.F32[PM_PAR_XPOS],
     368                    source->modelPSF->params->data.F32[PM_PAR_YPOS],
    334369                    magRef, source->psfMag, source->errMag);
    335             magErr->data.F32[j] = source->psfMag - magRef;
    336             magErrErr->data.F32[j] = source->errMag;
    337         }
    338         magErr->n = j;
    339         magMask->n = j;
     370#endif
     371            magDiff->data.F32[j] = source->psfMag - magRef;
     372            magErr->data.F32[j] = source->errMag;
     373        }
     374        magDiff->n = sources->n;
     375        magMask->n = sources->n;
     376        magErr->n = sources->n;
     377        if (!psVectorStats(magStats, magDiff, NULL, magMask, 0xFF)) {
     378            // Probably because we don't have enough sources
     379            psErrorClear();
     380        }
     381
     382        if (isfinite(magStats->robustMedian) && isfinite(magStats->robustStdev)) {
     383            magDiffMean->data.F32[i] = magStats->robustMedian;
     384            magDiffStdev->data.F32[i] = magStats->robustStdev;
     385        } else {
     386            magDiffMean->data.F32[i] = magStats->sampleMean;
     387            magDiffStdev->data.F32[i] = magStats->sampleStdev;
     388        }
     389
    340390        if (!psVectorStats(magStats, magErr, NULL, magMask, 0xFF)) {
    341391            // Probably because we don't have enough sources
    342392            psErrorClear();
    343393        }
    344         magErrMean->data.F32[i] = magStats->sampleMean;
    345         magErrStdev->data.F32[i] = magStats->sampleStdev;
    346         robustMedian->data.F32[i] = magStats->robustMedian;
    347         robustStdev->data.F32[i] = magStats->robustStdev;
    348         if (!psVectorStats(magStats, magErrErr, NULL, magMask, 0xFF)) {
    349             // Probably because we don't have enough sources
    350             psErrorClear();
    351         }
    352         magErrErrMean->data.F32[i] = magStats->sampleMean;
     394
     395        if (isfinite(magStats->robustMedian)) {
     396            magErrMean->data.F32[i] = magStats->robustMedian;
     397        } else {
     398            magErrMean->data.F32[i] = magStats->sampleMean;
     399        }
     400
     401#ifdef TESTING
    353402        fclose(file);
    354     }
    355 
     403#endif
     404    }
    356405
    357406    psFree(magStats);
     407    psFree(magDiff);
    358408    psFree(magMask);
    359409    psFree(magErr);
    360410
    361411    psFree(fakeSources);
    362     psFree(fakeEnd);
    363412
    364413    // XXX How do we get the results out?
     
    372421    psMetadataAddVector(stats, PS_LIST_TAIL, "FAKE.COUNTS", PS_META_REPLACE,
    373422                        "Number of sources retrieved", count);
    374     psMetadataAddVector(stats, PS_LIST_TAIL, "FAKE.ERR", PS_META_REPLACE,
    375                         "Mean magnitude differences", magErrMean);
    376     psMetadataAddVector(stats, PS_LIST_TAIL, "FAKE.RMS", PS_META_REPLACE,
    377                         "Stdev in magnitude differences", magErrStdev);
    378     psMetadataAddVector(stats, PS_LIST_TAIL, "FAKE.RM", PS_META_REPLACE,
    379                         "Robust median magnitude differences", robustMedian);
    380     psMetadataAddVector(stats, PS_LIST_TAIL, "FAKE.RS", PS_META_REPLACE,
    381                         "Robust stdev in magnitude differences", robustStdev);
    382     psMetadataAddVector(stats, PS_LIST_TAIL, "FAKE.MEANERR", PS_META_REPLACE,
    383                         "Mean error in magnitude differences", magErrErrMean);
     423    psMetadataAddVector(stats, PS_LIST_TAIL, "FAKE.DIFF.MEAN", PS_META_REPLACE,
     424                        "Mean magnitude differences", magDiffMean);
     425    psMetadataAddVector(stats, PS_LIST_TAIL, "FAKE.DIFF.STDEV", PS_META_REPLACE,
     426                        "Stdev of magnitude differences", magDiffStdev);
     427    psMetadataAddVector(stats, PS_LIST_TAIL, "FAKE.ERR.MEAN", PS_META_REPLACE,
     428                        "Mean error in magnitude differences", magErrMean);
    384429    psMetadataConfigWrite(stats, "fake.stats");
    385430    psFree(stats);
    386431
    387432    psFree(count);
     433    psFree(magDiffMean);
     434    psFree(magDiffStdev);
    388435    psFree(magErrMean);
    389     psFree(magErrStdev);
    390 
    391     psFree(robustMedian);
    392     psFree(robustStdev);
    393436
    394437    return true;
Note: See TracChangeset for help on using the changeset viewer.