IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 25278


Ignore:
Timestamp:
Sep 4, 2009, 6:08:08 PM (17 years ago)
Author:
Paul Price
Message:

Fixed determination of rough limiting magnitude.

File:
1 edited

Legend:

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

    r25265 r25278  
    11# include "psphotInternal.h"
    22
    3 #define TESTING
    4 
    5 
    6 #ifdef TESTING
    7 #define MIN_FLUX 0.1                    // Minimum flux for faint sources
    8 #endif
     3#define MODEL_MASK (PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE | \
     4                    PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_LIMITS) // Mask to apply to models
    95
    106
     
    1410// non-Gaussian PSF) to the limiting flux in the un-smoothed original image.
    1511static bool fakeLimit(float *magLim,           // Limiting magntiude, to return
    16                       float *minFlux,          // Minimum flux, to return
     12                      int *radius,             // Radius for fake sources
    1713                      const pmReadout *ro,     // Readout of interest
     14                      const pmPSF *psf,        // Point-spread function
    1815                      float thresh,            // Threshold for source identification
    19                       float fwhmMajor, float fwhmMinor, // Size of PSF
    20                       float smoothNsigma,       // Smoothing limit
    21                       psImageMaskType maskVal   // Value to mask
     16                      float smoothSigma,       // Gaussian smoothing sigma
     17                      float smoothNsigma,      // Smoothing limit
     18                      psImageMaskType maskVal  // Value to mask
    2219                      )
    2320{
     
    2522    PM_ASSERT_READOUT_VARIANCE(ro, false);
    2623
    27     float smoothSigma  = 0.5*(fwhmMajor + fwhmMinor) / (2.0*sqrtf(2.0*log(2.0)));
    2824    psKernel *kernel = psImageSmoothKernel(smoothSigma, smoothNsigma); // Kernel used for smoothing
    2925    psKernel *newCovar = psImageCovarianceCalculate(kernel, ro->covariance); // Covariance matrix
     
    4541    psFree(stats);
    4642
     43    // Need to normalise out difference between Gaussian and real PSF
     44    pmModel *normModel = pmModelFromPSFforXY(psf, 0.5 * ro->variance->numCols,
     45                                             0.5 * ro->variance->numRows, 1.0); // Model for normalisation
     46    if (!normModel || (normModel->flags & MODEL_MASK)) {
     47        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate PSF model.");
     48        psFree(normModel);
     49        return false;
     50    }
     51    float norm = normModel->modelFlux(normModel->params); // Total flux for peak of 1.0
     52    psFree(normModel);
     53
    4754    if (magLim) {
    48         *magLim = -2.5 * log10(thresh * sqrtf(meanVar * factor));
    49     }
    50     if (minFlux) {
    51         *minFlux = sqrtf(meanVar);
     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;
    5273    }
    5374
     
    6283                         int numSources,                 // Number of fake sources for each bin
    6384                         float refMag,                   // Reference magnitude
    64                          float minFlux                   // Minimum flux level for fake image
     85                         int radius                      // Radius for fake sources
    6586                         )
    6687{
     
    99120    pmReadout *fakeRO = pmReadoutAlloc(NULL); // Fake readout
    100121    if (!pmReadoutFakeFromVectors(fakeRO, numCols, numRows, xAll, yAll, magAll,
    101                                   NULL, NULL, psf, minFlux, 0, false, false)) {
     122                                  NULL, NULL, psf, NAN, radius, false, true)) {
    102123        psError(PS_ERR_UNKNOWN, false, "Unable to generate fake image");
    103124        psFree(fakeRO);
     
    130151
    131152    // Collect recipe information
    132     bool mdok;                                                 // Status of MD lookup
    133153    float fwhmMajor = psMetadataLookupF32(NULL, recipe, "FWHM_MAJ"); // PSF size in x
    134154    float fwhmMinor = psMetadataLookupF32(NULL, recipe, "FWHM_MIN"); // PSF size in y
     
    157177        return NULL;
    158178    }
    159     float minFluxFudge = psMetadataLookupF32(&mdok, recipe, "FAKE.MINFLUX"); // Fudge factor for minimum flux
    160     if (!mdok) {
    161         minFluxFudge = 1.0;
    162     }
     179
     180    float smoothSigma = 0.5*(fwhmMajor + fwhmMinor) / (2.0*sqrtf(2.0*log(2.0))); // Gaussian smoothing sigma
    163181
    164182    psImageMaskType maskVal = psMetadataLookupImageMask(NULL, recipe, "MASK.PSPHOT"); // Value to mask
     
    166184    // remove all sources, adding noise for subtracted sources
    167185    psphotRemoveAllSources(realSources, recipe);
    168     psphotAddNoise(readout, realSources, recipe);
     186    //    psphotAddNoise(readout, realSources, recipe);
    169187
    170188    float magLim;                       // Guess at limiting magnitude
    171     float minFlux;                      // Minimum flux for fake image
    172     if (!fakeLimit(&magLim, &minFlux, readout, thresh, fwhmMajor, fwhmMinor, smoothNsigma, maskVal)) {
     189    int radius;                         // Radius for fake sources
     190    if (!fakeLimit(&magLim, &radius, readout, psf, thresh, smoothSigma, smoothNsigma, maskVal)) {
    173191        psError(PS_ERR_UNKNOWN, false, "Unable to determine limits for image");
    174192        return false;
    175193    }
    176     minFlux *= minFluxFudge;
    177194
    178195    psImage *xFake = NULL, *yFake = NULL; // Coordinates of sources, each bin in a row
    179     if (!fakeGenerate(&xFake, &yFake, readout, psf, magOffsets, numSources, magLim, minFlux)) {
     196    if (!fakeGenerate(&xFake, &yFake, readout, psf, magOffsets, numSources, magLim, radius)) {
    180197        psError(PS_ERR_UNKNOWN, false, "Unable to generate fake sources");
    181198        psFree(xFake);
     
    195212
    196213    int numBins = magOffsets->n;                          // Number of bins
     214    int numCols = readout->image->numCols, numRows = readout->image->numRows; // Size of image
    197215    psVector *frac = psVectorAlloc(numBins, PS_TYPE_F32); // Fraction of sources in each bin
    198216    for (int i = 0; i < numBins; i++) {
    199217        int numFound = 0;               // Number found
    200218        for (int j = 0; j < numSources; j++) {
    201             float x = xFake->data.F32[i][j], y = yFake->data.F32[i][j]; // Coordinates of interest
    202             int xPix = x, yPix = y;                                     // Pixel coordinates
     219            // Coordinates of interest
     220            float x = PS_MIN(xFake->data.F32[i][j] + 0.5, numCols - 1);
     221            float y = PS_MIN(yFake->data.F32[i][j] + 0.5, numRows - 1);
     222            int xPix = x, yPix = y;     // Pixel coordinates
    203223            if (significance->data.F32[yPix][xPix] > thresh) {
    204224                numFound++;
Note: See TracChangeset for help on using the changeset viewer.