IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 25302


Ignore:
Timestamp:
Sep 8, 2009, 6:24:00 PM (17 years ago)
Author:
Paul Price
Message:

Photometer fake sources to measure magnitude biases near limiting magnitude. Had to change a few prototypes to include 'const'.

Location:
branches/pap/psphot/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • branches/pap/psphot/src/psphot.h

    r25260 r25302  
    4949bool            psphotPSFstats (pmReadout *readout, psMetadata *recipe, pmPSF *psf);
    5050bool            psphotMomentsStats (pmReadout *readout, psMetadata *recipe, psArray *sources);
    51 bool            psphotFitSourcesLinear (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, bool final);
     51bool            psphotFitSourcesLinear (pmReadout *readout, psArray *sources, const psMetadata *recipe, const pmPSF *psf, bool final);
    5252bool            psphotReplaceUnfitSources (psArray *sources, psImageMaskType maskVal);
    5353
     
    6464bool            psphotGuessModel_Threaded (psThreadJob *job);
    6565
    66 bool            psphotMagnitudes (pmConfig *config, pmReadout *readout, const pmFPAview *view, psArray *sources, pmPSF *psf);
     66bool            psphotMagnitudes (pmConfig *config, pmReadout *readout, const pmFPAview *view, psArray *sources, const pmPSF *psf);
    6767bool            psphotMagnitudes_Threaded (psThreadJob *job);
    6868
     
    7676bool            psphotExtendedSourceAnalysis (pmReadout *readout, psArray *sources, psMetadata *recipe);
    7777bool            psphotExtendedSourceFits (pmReadout *readout, psArray *sources, psMetadata *recipe);
    78 bool            psphotFake(pmReadout *readout, const pmPSF *psf, psMetadata *recipe, const psArray *realSources);
     78bool            psphotFake(pmConfig *config, pmReadout *readout, const pmFPAview *view, const pmPSF *psf, psMetadata *recipe, const psArray *realSources);
    7979
    8080// thread-related:
  • branches/pap/psphot/src/psphotFake.c

    r25278 r25302  
    2121    PM_ASSERT_READOUT_NON_NULL(ro, false);
    2222    PM_ASSERT_READOUT_VARIANCE(ro, false);
     23    assert(magLim);
     24    assert(radius);
    2325
    2426    psKernel *kernel = psImageSmoothKernel(smoothSigma, smoothNsigma); // Kernel used for smoothing
     
    5254    psFree(normModel);
    5355
    54     if (magLim) {
    55         // The signal-to-noise of the smoothed image is: S/N ~ I_smooth / sqrt(variance * factor)
    56 
    57         // since the variance factor tells us the variance in the smoothed image.  Now, the trick is working
    58         // out what the intensity in the smoothed image is, and how it is related to the flux.  We are
    59         // convolving Io G_* with G_PSF/2pi.w^2, where G_* is the approximately-Gaussian PSF of the star,
    60         // G_PSF is the pretty-close-matching Gaussian of the convolution kernel, Io is the peak flux in the
    61         // unsmoothed image, and w is the width of the Gaussian.  Now, a normalised 2D Gaussian convolved
    62         // with itself has a normalisation of 1/2pi(w^2+w^2) = 1/4pi.w^2.  Therefore:
    63         // I_smooth = Flux / 2*norm.
    64         float peakLim = thresh * sqrtf(meanVar * factor); // Limiting peak value in smoothed image
    65         float fluxLim = 2.0 * norm * peakLim; // Limiting flux in original
    66         *magLim = -2.5 * log10f(fluxLim);
    67         psTrace("psphot.fake", 1, "Limiting peak: %f\n", peakLim);
    68         psTrace("psphot.fake", 1, "Limiting flux: %f\n", fluxLim);
    69         psTrace("psphot.fake", 1, "Limiting mag: %f\n", *magLim);
    70     }
    71     if (radius) {
    72         *radius = smoothSigma * smoothNsigma;
    73     }
     56    // The signal-to-noise of the smoothed image is: S/N ~ I_smooth / sqrt(variance * factor)
     57    // since the variance factor tells us the variance in the smoothed image.  Now, the trick is working
     58    // out what the intensity in the smoothed image is, and how it is related to the flux.  We are
     59    // convolving Io G_* with G_PSF/2pi.w^2, where G_* is the approximately-Gaussian PSF of the star,
     60    // G_PSF is the pretty-close-matching Gaussian of the convolution kernel, Io is the peak flux in the
     61    // unsmoothed image, and w is the width of the Gaussian.  Now, a normalised 2D Gaussian convolved
     62    // with itself has a normalisation of 1/2pi(w^2+w^2) = 1/4pi.w^2.  Therefore:
     63    // I_smooth = Flux / 2*norm.
     64    float peakLim = thresh * sqrtf(meanVar * factor); // Limiting peak value in smoothed image
     65    float fluxLim = 2.0 * norm * peakLim; // Limiting flux in original
     66    *magLim = -2.5 * log10f(fluxLim);
     67    psTrace("psphot.fake", 1, "Limiting peak: %f\n", peakLim);
     68    psTrace("psphot.fake", 1, "Limiting flux: %f\n", fluxLim);
     69    psTrace("psphot.fake", 1, "Limiting mag: %f\n", *magLim);
     70
     71    *radius = smoothSigma * smoothNsigma;
    7472
    7573    return true;
     
    9088    PS_ASSERT_VECTOR_NON_NULL(magOffsets, false);
    9189    PS_ASSERT_VECTOR_TYPE(magOffsets, PS_TYPE_F32, false);
     90    assert(xSrc);
     91    assert(ySrc);
    9292
    9393    int numBins = magOffsets->n;                                    // Number of bins
     
    140140
    141141// *** in this section, perform the photometry for fake sources ***
    142 bool psphotFake(pmReadout *readout, const pmPSF *psf, psMetadata *recipe, const psArray *realSources)
     142bool psphotFake(pmConfig *config, pmReadout *readout, const pmFPAview *view, const pmPSF *psf,
     143                psMetadata *recipe, const psArray *realSources)
    143144{
    144145    PM_ASSERT_READOUT_NON_NULL(readout, false);
     
    201202    }
    202203
     204    // XXX Could speed this up significantly by only convolving the central pixels of each fake source
    203205    psImage *significance = psphotSignificanceImage(readout, recipe, 2, maskVal);
    204206    if (!significance) {
     
    213215    int numBins = magOffsets->n;                          // Number of bins
    214216    int numCols = readout->image->numCols, numRows = readout->image->numRows; // Size of image
    215     psVector *frac = psVectorAlloc(numBins, PS_TYPE_F32); // Fraction of sources in each bin
     217    psVector *count = psVectorAlloc(numBins, PS_TYPE_S32); // Number of sources found in each bin
     218    psArray *fakeSources = psArrayAllocEmpty(numSources * numBins); // Fake sources
     219    psVector *fakeEnd = psVectorAllocEmpty(numSources * numBins, PS_TYPE_S32); // End index of each bin
     220    long numFound = 0;                                                           // Number of sources found
    216221    for (int i = 0; i < numBins; i++) {
    217         int numFound = 0;               // Number found
     222        int num = 0;               // Number found
    218223        for (int j = 0; j < numSources; j++) {
    219224            // Coordinates of interest
     
    221226            float y = PS_MIN(yFake->data.F32[i][j] + 0.5, numRows - 1);
    222227            int xPix = x, yPix = y;     // Pixel coordinates
    223             if (significance->data.F32[yPix][xPix] > thresh) {
     228            float sig = significance->data.F32[yPix][xPix]; // Significance of pixel
     229            if (sig > thresh) {
     230                pmSource *source = pmSourceAlloc(); // Fake source
     231                source->peak = pmPeakAlloc(x, y, NAN, PM_PEAK_LONE);
     232                if (!pmSourceDefinePixels(source, readout, x, y, radius)) {
     233                    psErrorClear();
     234                    continue;
     235                }
     236                source->modelPSF = pmModelFromPSFforXY(psf, x, y, 2.0 * sqrtf(sig));
     237                source->type = PM_SOURCE_TYPE_STAR;
     238
     239                num++;
     240
     241                fakeSources->data[numFound] = source;
    224242                numFound++;
    225243            }
    226244        }
    227         frac->data.F32[i] = (float)numFound / (float)numSources;
    228     }
     245        count->data.S32[i] = num;
     246        fakeEnd->data.S32[i] = numFound;
     247    }
     248    fakeSources->n = numFound;
    229249
    230250    psFree(xFake);
     
    232252    psFree(significance);
    233253
     254    if (!psphotFitSourcesLinear(readout, fakeSources, recipe, psf, true)) {
     255        psError(PS_ERR_UNKNOWN, false, "Unable to perform linear fit on fake sources.");
     256        psFree(fakeSources);
     257        psFree(fakeEnd);
     258        psFree(count);
     259        return false;
     260    }
     261    if (!psphotMagnitudes(config, readout, view, fakeSources, psf)) {
     262        psError(PS_ERR_UNKNOWN, false, "Unable to measure magnitudes of fake sources.");
     263        psFree(fakeSources);
     264        psFree(fakeEnd);
     265        psFree(count);
     266        return false;
     267    }
     268
     269    psVector *magErrMean = psVectorAlloc(numBins, PS_TYPE_F32); // Mean error in magnitude for each bin
     270    psVector *magErrStdev = psVectorAlloc(numBins, PS_TYPE_F32); // Stdev of error in magnitude for each bin
     271    psVector *magErr = psVectorAlloc(numSources, PS_TYPE_F32);   // Magnitude errors
     272    psVector *magMask = psVectorAlloc(numSources, PS_TYPE_VECTOR_MASK); // Mask for magnitude errors
     273    psStats *magStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV); // Statistics
     274    for (int i = 0, index = 0; i < numBins; i++) {
     275        psStatsInit(magStats);
     276        psVectorInit(magMask, 0);
     277
     278        float magRef = magLim + magOffsets->data.F32[i]; // Reference magnitude
     279        for (int j = 0; index < fakeEnd->data.S32[i]; j++, index++) {
     280            pmSource *source = fakeSources->data[index]; // Source of interest
     281            if (!source || !isfinite(source->psfMag)) {
     282                magMask->data.PS_TYPE_VECTOR_MASK_DATA[j] = 0xFF;
     283                continue;
     284            }
     285            magErr->data.F32[j] = source->psfMag - magRef;
     286        }
     287        if (!psVectorStats(magStats, magErr, NULL, magMask, 0xFF)) {
     288            // Probably because we don't have enough sources
     289            psErrorClear();
     290        }
     291        magErrMean->data.F32[i] = magStats->sampleMean;
     292        magErrStdev->data.F32[i] = magStats->sampleStdev;
     293    }
     294    psFree(magStats);
     295    psFree(magMask);
     296    psFree(magErr);
     297
     298    psFree(fakeSources);
     299    psFree(fakeEnd);
     300
    234301    // XXX How do we get the results out?
    235302    psMetadata *stats = psMetadataAlloc();
    236     psMetadataAddVector(stats, PS_LIST_TAIL, "FAKE.EFF", PS_META_REPLACE,
    237                         "Efficiency fractions", frac);
     303    psMetadataAddS32(stats, PS_LIST_TAIL, "FAKE.NUM", PS_META_REPLACE,
     304                     "Number of sources per bin", numSources);
     305    psMetadataAddF32(stats, PS_LIST_TAIL, "FAKE.REF", PS_META_REPLACE,
     306                     "Efficiency reference magnitude", magLim);
    238307    psMetadataAddVector(stats, PS_LIST_TAIL, "FAKE.MAG", PS_META_REPLACE,
    239308                        "Efficiency magnitudes", magOffsets);
    240     psMetadataAddF32(stats, PS_LIST_TAIL, "FAKE.REF", PS_META_REPLACE,
    241                      "Efficiency reference magnitude", magLim);
     309    psMetadataAddVector(stats, PS_LIST_TAIL, "FAKE.COUNTS", PS_META_REPLACE,
     310                        "Number of sources retrieved", count);
     311    psMetadataAddVector(stats, PS_LIST_TAIL, "FAKE.ERR", PS_META_REPLACE,
     312                        "Mean magnitude differences", magErrMean);
     313    psMetadataAddVector(stats, PS_LIST_TAIL, "FAKE.RMS", PS_META_REPLACE,
     314                        "Stdev in magnitude differences", magErrStdev);
    242315    psMetadataConfigWrite(stats, "fake.stats");
    243316    psFree(stats);
    244317
    245     psFree(frac);
     318    psFree(count);
     319    psFree(magErrMean);
     320    psFree(magErrStdev);
    246321
    247322    return true;
  • branches/pap/psphot/src/psphotFitSourcesLinear.c

    r23445 r25302  
    1212static bool SetBorderMatrixElements (psSparseBorder *border, pmReadout *readout, psArray *sources, bool constant_weights, int SKY_FIT_ORDER, psImageMaskType markVal);
    1313
    14 bool psphotFitSourcesLinear (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, bool final) {
     14bool psphotFitSourcesLinear (pmReadout *readout, psArray *sources, const psMetadata *recipe, const pmPSF *psf, bool final) {
    1515
    1616    bool status;
  • branches/pap/psphot/src/psphotMagnitudes.c

    r23349 r25302  
    11# include "psphotInternal.h"
    22
    3 bool psphotMagnitudes(pmConfig *config, pmReadout *readout, const pmFPAview *view, psArray *sources, pmPSF *psf) {
     3bool psphotMagnitudes(pmConfig *config, pmReadout *readout, const pmFPAview *view, psArray *sources, const pmPSF *psf) {
    44
    55    bool status = false;
     
    6464
    6565            psArrayAdd(job->args, 1, cells->data[j]); // sources
    66             psArrayAdd(job->args, 1, psf);
     66            psArrayAdd(job->args, 1, (pmPSF*)psf);    // Casting away const
    6767            psArrayAdd(job->args, 1, binning);
    6868            psArrayAdd(job->args, 1, backModel);
  • branches/pap/psphot/src/psphotReadout.c

    r25246 r25302  
    224224    psphotMagnitudes(config, readout, view, sources, psf);
    225225
    226     if (!psphotFake(readout, psf, recipe, sources)) {
     226    if (!psphotFake(config, readout, view, psf, recipe, sources)) {
    227227        psErrorStackPrint(stderr, "Unable to determine detection efficiencies from fake sources");
    228228        psErrorClear();
Note: See TracChangeset for help on using the changeset viewer.