IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 30, 2008, 4:09:46 PM (18 years ago)
Author:
eugene
Message:

fix errors in calculation of sig image; API change: sig image is now actual S/N2

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psphot/src/psphotFindPeaks.c

    r17444 r17870  
    11# include "psphotInternal.h"
    22
    3 // XXX let's make a better distinction between 'pass' and needing/having a PSF.
    4 // In this function, we smooth the image, then search for the peaks
     3// Find peaks in the significance image above a threshold significance level.  The significance
     4// image must be constructed to represent (S/N)^2.  If nMax is non-zero, only return a maximum
     5// of nMax peaks
     6psArray *psphotFindPeaks (psImage *significance, pmReadout *readout, psMetadata *recipe, const float threshold, const int nMax) {
    57
    6 psArray *psphotFindPeaks (psImage *significance, pmReadout *readout, psMetadata *recipe, const int pass, psMaskType maskVal) {
    7 
    8     float NSIGMA_PEAK;
    98    bool status = false;
    109
    11     // smooth the image and weight map
    1210    psTimerStart ("peaks");
    13 
    14     // signal/noise limit for the detected peaks
    15     // XXX this is a little lame: can we do something better than 'pass'?
    16     if (pass == 1) {
    17         NSIGMA_PEAK = psMetadataLookupF32 (&status, recipe, "PEAKS_NSIGMA_LIMIT");
    18     } else {
    19         NSIGMA_PEAK = psMetadataLookupF32 (&status, recipe, "PEAKS_NSIGMA_LIMIT_2");
    20     }
    21     PS_ASSERT (status, NULL);
    22 
    23     float SIGMA_SMTH  = psMetadataLookupF32 (&status, recipe, "SIGMA_SMOOTH");
    24     psAssert (status, "SIGMA_SMOOTH missing: call psphotSignificanceImage first");
    25 
    26     // we need to define the threshold based on the value of NSIGMA_PEAK and the applied smoothing
    27     // gaussian SIGMA.  a peak in the significance image has an effective S/N for faint sources
    28     // of (S = Io*2pi*sigma_eff^2) / sqrt(Var), where sigma_eff^2 = sigma_obs^2 + sigma_sm^2.
    29     // the smoothing of the varience map does not affect the faint-source S/N since the noise
    30     // is constant under a faint source.
    31 
    32     // if sigma_sm = sigma_obs, then sigma_eff^2 = 2 sigma_sm^2. in this case, the threshold in
    33     // terms of significance peak counts Io, for a desired S/N limit corresponds to
    34     // S/N = sqrt(Io)*4*pi*sigma_sm^2
    35     // thus, the threshold is:
    36     float effArea = 4.0*M_PI*PS_SQR(SIGMA_SMTH);
    37     if (effArea < 1) {
    38         effArea = 1;                    // never less than a pixel
    39     }
    40     if (pass == 1) {
    41         effArea = 4.0*M_PI; // XXX better than nothing but still fairly poor
    42     }
    43 
    44     float threshold = PS_SQR(NSIGMA_PEAK) / effArea;
    45 
    46     // record the actual effective area and peak threshold
    47     psMetadataAddF32  (recipe, PS_LIST_TAIL, "EFFECTIVE_AREA", PS_META_REPLACE, "Effective Area", effArea);
    48     psMetadataAddF32  (recipe, PS_LIST_TAIL, "PEAK_THRESHOLD", PS_META_REPLACE, "Peak Detection Threshold", threshold);
    4911
    5012    // find the peaks in the smoothed image
     
    5921    }
    6022
    61     // correct the peak values to S/N = sqrt(value*effArea)
     23    // correct the peak values to S/N = sqrt(significance)
    6224    // get the peak flux from the unsmoothed image
    6325    // the peak pixel coords are guaranteed to be on the image
     
    6628    for (int i = 0; i < peaks->n; i++) {
    6729        pmPeak *peak = peaks->data[i];
    68         peak->SN = sqrt(peak->value*effArea);
     30        peak->SN = sqrt(peak->value);
    6931        peak->flux = readout->image->data.F32[peak->y-row0][peak->x-col0];
    7032    }
    7133
    72     // limit the total number of returned peak as specified
    73     if (pass == 1) {
    74         psArraySort (peaks, pmPeakSortBySN);
    75         int NMAX = psMetadataLookupS32 (&status, recipe, "PEAKS_NMAX");
    76         if (NMAX && (peaks->n > NMAX)) {
    77             psArray *tmpPeaks = psArrayAllocEmpty (NMAX);
    78             for (int i = 0; i < NMAX; i++) {
    79                 psArrayAdd (tmpPeaks, 100, peaks->data[i]);
    80             }
    81             psFree (peaks);
    82             peaks = tmpPeaks;
    83         }
     34    // limit the total number of returned peaks as specified
     35    psArraySort (peaks, pmPeakSortBySN);
     36    if (nMax && (peaks->n > nMax)) {
     37        psArray *tmpPeaks = psArrayAllocEmpty (nMax);
     38        for (int i = 0; i < nMax; i++) {
     39            psArrayAdd (tmpPeaks, 100, peaks->data[i]);
     40        }
     41        psFree (peaks);
     42        peaks = tmpPeaks;
    8443    }
    8544
    8645    // optional dump of all peak data
    87     // XXX need a better check for this option
    8846    char *output = psMetadataLookupStr (&status, recipe, "PEAKS_OUTPUT_FILE");
    89     if (status && (output != NULL) && (output[0])) {
     47    if (output && strcasecmp (output, "NONE")) {
    9048        pmPeaksWriteText (peaks, output);
    9149    }
     
    9553
    9654}
    97 
Note: See TracChangeset for help on using the changeset viewer.