Changeset 17870 for trunk/psphot/src/psphotFindPeaks.c
- Timestamp:
- May 30, 2008, 4:09:46 PM (18 years ago)
- File:
-
- 1 edited
-
trunk/psphot/src/psphotFindPeaks.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot/src/psphotFindPeaks.c
r17444 r17870 1 1 # include "psphotInternal.h" 2 2 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 6 psArray *psphotFindPeaks (psImage *significance, pmReadout *readout, psMetadata *recipe, const float threshold, const int nMax) { 5 7 6 psArray *psphotFindPeaks (psImage *significance, pmReadout *readout, psMetadata *recipe, const int pass, psMaskType maskVal) {7 8 float NSIGMA_PEAK;9 8 bool status = false; 10 9 11 // smooth the image and weight map12 10 psTimerStart ("peaks"); 13 14 // signal/noise limit for the detected peaks15 // 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 smoothing27 // gaussian SIGMA. a peak in the significance image has an effective S/N for faint sources28 // 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 noise30 // 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 in33 // terms of significance peak counts Io, for a desired S/N limit corresponds to34 // S/N = sqrt(Io)*4*pi*sigma_sm^235 // 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 pixel39 }40 if (pass == 1) {41 effArea = 4.0*M_PI; // XXX better than nothing but still fairly poor42 }43 44 float threshold = PS_SQR(NSIGMA_PEAK) / effArea;45 46 // record the actual effective area and peak threshold47 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);49 11 50 12 // find the peaks in the smoothed image … … 59 21 } 60 22 61 // correct the peak values to S/N = sqrt( value*effArea)23 // correct the peak values to S/N = sqrt(significance) 62 24 // get the peak flux from the unsmoothed image 63 25 // the peak pixel coords are guaranteed to be on the image … … 66 28 for (int i = 0; i < peaks->n; i++) { 67 29 pmPeak *peak = peaks->data[i]; 68 peak->SN = sqrt(peak->value *effArea);30 peak->SN = sqrt(peak->value); 69 31 peak->flux = readout->image->data.F32[peak->y-row0][peak->x-col0]; 70 32 } 71 33 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; 84 43 } 85 44 86 45 // optional dump of all peak data 87 // XXX need a better check for this option88 46 char *output = psMetadataLookupStr (&status, recipe, "PEAKS_OUTPUT_FILE"); 89 if ( status && (output != NULL) && (output[0])) {47 if (output && strcasecmp (output, "NONE")) { 90 48 pmPeaksWriteText (peaks, output); 91 49 } … … 95 53 96 54 } 97
Note:
See TracChangeset
for help on using the changeset viewer.
