IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 25338


Ignore:
Timestamp:
Sep 10, 2009, 7:11:55 PM (17 years ago)
Author:
Paul Price
Message:

Only convolving the pixels of interest, rather than the entire image. On the plus side, this runs a LOT faster. On the minus side, the code has to be kept in sync with psphotSignificanceImage.c.

File:
1 edited

Legend:

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

    r25334 r25338  
    1515                     float *minFlux,          // Minimum flux for fake sources, to return
    1616                     float *norm,             // Normalisation of PSF (conversion: peak --> integrated flux)
     17                     float *covarFactor,// Covariance factor
    1718                     const pmReadout *ro,     // Readout of interest
    1819                     const pmPSF *psf,        // Point-spread function
     
    2930    assert(minFlux);
    3031    assert(norm);
     32    assert(covarFactor);
    3133
    3234    psKernel *kernel = psImageSmoothKernel(smoothSigma, smoothNsigma); // Kernel used for smoothing
    3335    psKernel *newCovar = psImageCovarianceCalculate(kernel, ro->covariance); // Covariance matrix
    3436    psFree(kernel);
    35     float factor = psImageCovarianceFactor(newCovar); // Variance factor
     37    *covarFactor = psImageCovarianceFactor(newCovar); // Variance factor
    3638    psFree(newCovar);
    3739
     
    6870    // with itself has a normalisation of 1/2pi(w^2+w^2) = 1/4pi.w^2.  Therefore:
    6971    // I_smooth = Flux / 2*norm.
    70     float peakLim = thresh * sqrtf(meanVar * factor); // Limiting peak value in smoothed image
     72    float peakLim = thresh * sqrtf(meanVar * *covarFactor); // Limiting peak value in smoothed image
    7173    float fluxLim = 2.0 * *norm * peakLim; // Limiting flux in original
    7274    *magLim = -2.5 * log10f(fluxLim);
     
    106108    *ySrc = psImageRecycle(*ySrc, numSources, numBins, PS_TYPE_F32);
    107109
    108     // Master list, for image creation
    109110    psVector *xAll = psVectorAlloc(numBins * numSources, PS_TYPE_F32);
    110111    psVector *yAll = psVectorAlloc(numBins * numSources, PS_TYPE_F32);
     
    132133        psError(PS_ERR_UNKNOWN, false, "Unable to generate fake image");
    133134        psFree(fakeRO);
    134         psFree(xAll);
    135         psFree(yAll);
    136135        psFree(magAll);
    137136        return false;
    138137    }
    139     psFree(xAll);
    140     psFree(yAll);
    141138    psFree(magAll);
    142139
     
    187184        return NULL;
    188185    }
     186    float minGauss = psMetadataLookupF32(NULL, recipe, "PEAKS_MIN_GAUSS"); // Minimum valid fraction of kernel
     187    if (!isfinite(minGauss)) {
     188        psWarning("PEAKS_MIN_GAUSS is not set in recipe; using default value");
     189        minGauss = 0.5;
     190    }
    189191
    190192    float smoothSigma = 0.5*(fwhmMajor + fwhmMinor) / (2.0*sqrtf(2.0*log(2.0))); // Gaussian smoothing sigma
    191193    int numCols = readout->image->numCols, numRows = readout->image->numRows; // Size of image
     194    int numBins = magOffsets->n;                          // Number of bins
    192195
    193196    psImageMaskType maskVal = psMetadataLookupImageMask(NULL, recipe, "MASK.PSPHOT"); // Value to mask
     
    220223    float minFlux;                      // Minimum flux for fake sources
    221224    float norm;                         // Normalisation of PSF
    222     if (!effLimit(&magLim, &radius, &minFlux, &norm, readout,
    223                    psf, thresh, smoothSigma, smoothNsigma, maskVal)) {
     225    float covarFactor;                  // Covariance factor
     226    if (!effLimit(&magLim, &radius, &minFlux, &norm, &covarFactor, readout,
     227                  psf, thresh, smoothSigma, smoothNsigma, maskVal)) {
    224228        psError(PS_ERR_UNKNOWN, false, "Unable to determine limits for image");
    225229        return false;
     
    233237
    234238    psImage *xFake = NULL, *yFake = NULL; // Coordinates of sources, each bin in a row
    235     if (!effGenerate(&xFake, &yFake, readout, psf, magOffsets, numSources, magLim, radius, minFlux)) {
     239    if (!effGenerate(&xFake, &yFake, readout, psf, magOffsets,
     240                     numSources, magLim, radius, minFlux)) {
    236241        psError(PS_ERR_UNKNOWN, false, "Unable to generate fake sources");
    237242        psFree(xFake);
     
    247252
    248253    // XXX Could speed this up significantly by only convolving the central pixels of each fake source
    249     psImage *significance = psphotSignificanceImage(readout, recipe, 2, maskVal);
    250     if (!significance) {
    251         psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate significance image");
    252         psFree(xFake);
    253         psFree(yFake);
    254         return false;
    255     }
    256 
    257 #ifdef TESTING
    258     psphotSaveImage(NULL, significance, "fake_sig.fits");
    259 #endif
    260 
    261     thresh *= thresh;                   // Significance image is actually significance-squared
    262 
    263     int numBins = magOffsets->n;                          // Number of bins
     254    psVector *significance = NULL;       // Significance image
     255    {
     256        int num = numSources * numBins; // Total number of sources
     257        // Pixel coordinates of sources
     258        psVector *xPix = psVectorAlloc(num, PS_TYPE_S32);
     259        psVector *yPix = psVectorAlloc(num, PS_TYPE_S32);
     260        for (int i = 0, index = 0; i < numBins; i++) {
     261            for (int j = 0; j < numSources; j++, index++) {
     262                float x = xFake->data.F32[i][j];
     263                float y = yFake->data.F32[i][j];
     264                xPix->data.S32[index] = PS_MIN(x + 0.5, numCols - 1);
     265                yPix->data.S32[index] = PS_MIN(y + 0.5, numRows - 1);
     266            }
     267        }
     268
     269        psVector *convImage = psImageSmoothMaskPixels(readout->image, readout->mask, maskVal, xPix, yPix,
     270                                                      smoothSigma, smoothNsigma, minGauss); // Convolved image
     271        if (!convImage) {
     272            psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to smooth image pixels");
     273            psFree(xPix);
     274            psFree(yPix);
     275            psFree(xFake);
     276            psFree(yFake);
     277            return false;
     278        }
     279        psVector *convVar = psImageSmoothMaskPixels(readout->variance, readout->mask, maskVal, xPix, yPix,
     280                                                    smoothSigma, smoothNsigma, minGauss); // Convolved varianc
     281        if (!convVar) {
     282            psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to smooth variance pixels");
     283            psFree(xPix);
     284            psFree(yPix);
     285            psFree(xFake);
     286            psFree(yFake);
     287            return false;
     288        }
     289
     290        float factor = 1.0 / covarFactor; // Correction for covariance
     291
     292        const psImage *mask = readout->mask;  // Mask for readout
     293        for (int i = 0; i < num; i++) {
     294            float imageVal = convImage->data.F32[i]; // Image value
     295            float varVal = convVar->data.F32[i]; // Variance value
     296            int x = xPix->data.S32[i], y = yPix->data.S32[i]; // Coordinates
     297            if (imageVal < 0 || varVal <= 0 || (mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal)) {
     298                convImage->data.F32[i] = 0.0;
     299            } else {
     300                convImage->data.F32[i] = factor * PS_SQR(imageVal) / varVal;
     301            }
     302        }
     303
     304        psFree(xPix);
     305        psFree(yPix);
     306
     307        significance = convImage;
     308        psFree(convVar);
     309    }
     310
     311    thresh *= thresh;                   // "Significance" is actually significance-squared
     312
    264313    psVector *count = psVectorAlloc(numBins, PS_TYPE_S32); // Number of sources found in each bin
    265314    psArray *fakeSources = psArrayAlloc(numSources);            // Fake sources in each bin
    266315    psArray *fakeSourcesAll = psArrayAllocEmpty(numSources * numBins); // All fake sources
    267     for (int i = 0; i < numBins; i++) {
     316    for (int i = 0, index = 0; i < numBins; i++) {
    268317        int numFound = 0;               // Number found
    269318
     
    281330
    282331        psArray *sources = psArrayAllocEmpty(numSources); // Sources in this bin
    283         for (int j = 0; j < numSources; j++) {
     332        for (int j = 0; j < numSources; j++, index++) {
    284333            // Coordinates of interest
    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
    288             float sig = significance->data.F32[yPix][xPix]; // Significance of pixel
     334            float sig = significance->data.F32[index]; // Significance of pixel
    289335            if (sig > thresh) {
    290336                pmSource *source = pmSourceAlloc(); // Fake source
     337                float x = xFake->data.F32[i][j];
     338                float y = yFake->data.F32[i][j];
    291339                source->peak = pmPeakAlloc(x, y, sig, PM_PEAK_LONE);
    292340                if (!pmSourceDefinePixels(source, readout, x, y, sourceRadius)) {
Note: See TracChangeset for help on using the changeset viewer.