Changeset 13900 for trunk/psphot/src/psphotFindPeaks.c
- Timestamp:
- Jun 19, 2007, 4:40:44 PM (19 years ago)
- File:
-
- 1 edited
-
trunk/psphot/src/psphotFindPeaks.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot/src/psphotFindPeaks.c
r13430 r13900 1 1 # include "psphotInternal.h" 2 2 3 // In this function, we smooth the image, then search for the peaks 3 // In this function, we smooth the image, then search for the peaks 4 4 psArray *psphotFindPeaks (pmReadout *readout, psMetadata *recipe, 5 bool returnFootprints,6 const int pass) {5 bool returnFootprints, 6 const int pass, psMaskType maskVal) { 7 7 8 8 float SIGMA_SMTH, NSIGMA_SMTH, NSIGMA_PEAK; … … 13 13 14 14 if (pass == 1) { 15 SIGMA_SMTH = psMetadataLookupF32 (&status, recipe, "PEAKS_SMOOTH_SIGMA");16 NSIGMA_SMTH = psMetadataLookupF32 (&status, recipe, "PEAKS_SMOOTH_NSIGMA");15 SIGMA_SMTH = psMetadataLookupF32 (&status, recipe, "PEAKS_SMOOTH_SIGMA"); 16 NSIGMA_SMTH = psMetadataLookupF32 (&status, recipe, "PEAKS_SMOOTH_NSIGMA"); 17 17 } else { 18 bool status_x, status_y;19 float FWHM_X = psMetadataLookupF32 (&status_x, recipe, "FWHM_X");20 float FWHM_Y = psMetadataLookupF32 (&status_y, recipe, "FWHM_Y");21 if (!status_x | !status_y) {22 psError(PSPHOT_ERR_CONFIG, false, "FWHM_X or FWHM_Y not defined");23 return false;24 }25 SIGMA_SMTH = 0.5*(FWHM_X + FWHM_Y) / (2.0*sqrt(2.0*log(2.0)));26 NSIGMA_SMTH = psMetadataLookupF32 (&status, recipe, "PEAKS_SMOOTH_NSIGMA");18 bool status_x, status_y; 19 float FWHM_X = psMetadataLookupF32 (&status_x, recipe, "FWHM_X"); 20 float FWHM_Y = psMetadataLookupF32 (&status_y, recipe, "FWHM_Y"); 21 if (!status_x | !status_y) { 22 psError(PSPHOT_ERR_CONFIG, false, "FWHM_X or FWHM_Y not defined"); 23 return false; 24 } 25 SIGMA_SMTH = 0.5*(FWHM_X + FWHM_Y) / (2.0*sqrt(2.0*log(2.0))); 26 NSIGMA_SMTH = psMetadataLookupF32 (&status, recipe, "PEAKS_SMOOTH_NSIGMA"); 27 27 } 28 28 29 29 // smooth the image, applying the mask as we go 30 30 psImage *smooth_im = psImageCopy (NULL, readout->image, PS_TYPE_F32); 31 psImageSmoothMaskF32 (smooth_im, readout->mask, 0xff, SIGMA_SMTH, NSIGMA_SMTH);31 psImageSmoothMaskF32 (smooth_im, readout->mask, maskVal, SIGMA_SMTH, NSIGMA_SMTH); 32 32 psLogMsg ("psphot", PS_LOG_MINUTIA, "smooth image: %f sec\n", psTimerMark ("psphot")); 33 33 34 34 // smooth the weight, applying the mask as we go 35 35 psImage *smooth_wt = psImageCopy (NULL, readout->weight, PS_TYPE_F32); 36 psImageSmoothMaskF32 (smooth_wt, readout->mask, 0xff, SIGMA_SMTH/sqrt(2), NSIGMA_SMTH);36 psImageSmoothMaskF32 (smooth_wt, readout->mask, maskVal, SIGMA_SMTH/sqrt(2), NSIGMA_SMTH); 37 37 psLogMsg ("psphot", PS_LOG_MINUTIA, "smooth weight: %f sec\n", psTimerMark ("psphot")); 38 38 39 39 psImage *mask = readout->mask; 40 40 41 // optionally save example images under trace 41 // optionally save example images under trace 42 42 if (psTraceGetLevel("psphot") > 5) { 43 char name[64];44 sprintf (name, "imsmooth.v%d.fits", pass);45 psphotSaveImage (NULL, smooth_im, name);46 sprintf (name, "wtsmooth.v%d.fits", pass);47 psphotSaveImage (NULL, smooth_wt, name);43 char name[64]; 44 sprintf (name, "imsmooth.v%d.fits", pass); 45 psphotSaveImage (NULL, smooth_im, name); 46 sprintf (name, "wtsmooth.v%d.fits", pass); 47 psphotSaveImage (NULL, smooth_wt, name); 48 48 } 49 49 50 50 // build the significance image on top of smooth_im 51 51 for (int j = 0; j < smooth_im->numRows; j++) { 52 for (int i = 0; i < smooth_im->numCols; i++) {53 float value = smooth_im->data.F32[j][i];54 if (value < 0 || smooth_wt->data.F32[j][i] <= 0 || mask->data.U8[j][i]) {55 smooth_im->data.F32[j][i] = 0.0;56 } else {57 smooth_im->data.F32[j][i] = PS_SQR(value) / smooth_wt->data.F32[j][i];58 }59 }52 for (int i = 0; i < smooth_im->numCols; i++) { 53 float value = smooth_im->data.F32[j][i]; 54 if (value < 0 || smooth_wt->data.F32[j][i] <= 0 || (mask->data.U8[j][i] & maskVal)) { 55 smooth_im->data.F32[j][i] = 0.0; 56 } else { 57 smooth_im->data.F32[j][i] = PS_SQR(value) / smooth_wt->data.F32[j][i]; 58 } 59 } 60 60 } 61 61 psLogMsg ("psphot", PS_LOG_INFO, "built smoothed signficance image: %f sec\n", psTimerMark ("psphot")); 62 62 63 // optionally save example images under trace 63 // optionally save example images under trace 64 64 if (psTraceGetLevel("psphot") > 5) { 65 char name[64];66 sprintf (name, "snsmooth.v%d.fits", pass);67 psphotSaveImage (NULL, smooth_im, name);65 char name[64]; 66 sprintf (name, "snsmooth.v%d.fits", pass); 67 psphotSaveImage (NULL, smooth_im, name); 68 68 } 69 69 … … 73 73 // signal/noise limit for the detected peaks 74 74 if (pass == 1) { 75 NSIGMA_PEAK = psMetadataLookupF32 (&status, recipe, "PEAKS_NSIGMA_LIMIT");75 NSIGMA_PEAK = psMetadataLookupF32 (&status, recipe, "PEAKS_NSIGMA_LIMIT"); 76 76 } else { 77 NSIGMA_PEAK = psMetadataLookupF32 (&status, recipe, "PEAKS_NSIGMA_LIMIT_2");78 } 79 77 NSIGMA_PEAK = psMetadataLookupF32 (&status, recipe, "PEAKS_NSIGMA_LIMIT_2"); 78 } 79 80 80 // we need to define the threshold based on the value of NSIGMA_PEAK and the applied smoothing 81 81 // gaussian SIGMA. a peak in the significance image has an effective S/N for faint sources … … 87 87 // terms of smooth_im peak counts Io, for a desired S/N limit corresponds to 88 88 // S/N = sqrt(Io)*4*pi*sigma_sm^2 89 // thus, the threshold is: 89 // thus, the threshold is: 90 90 float effArea = 4.0*M_PI*PS_SQR(SIGMA_SMTH); 91 91 if (effArea < 1) { 92 effArea = 1;// never less than a pixel92 effArea = 1; // never less than a pixel 93 93 } 94 94 float threshold = PS_SQR(NSIGMA_PEAK) / effArea; … … 97 97 psArray *peaks = pmFindImagePeaks (smooth_im, threshold); 98 98 if (peaks == NULL) { 99 // XXX this may also be due to a programming or config error100 // XXX do we need to set something in the readout->analysis to indicate that 101 // we tried and failed to find peaks (something in the header data)102 psError(PSPHOT_ERR_DATA, false, "no peaks found in this image");103 return false;99 // XXX this may also be due to a programming or config error 100 // XXX do we need to set something in the readout->analysis to indicate that 101 // we tried and failed to find peaks (something in the header data) 102 psError(PSPHOT_ERR_DATA, false, "no peaks found in this image"); 103 return false; 104 104 } 105 105 106 106 // correct the peak values to S/N = sqrt(value*effArea) 107 107 // get the peak flux from the unsmoothed image … … 110 110 int col0 = readout->image->col0; 111 111 for (int i = 0; i < peaks->n; i++) { 112 pmPeak *peak = peaks->data[i];113 peak->SN = sqrt(peak->value*effArea);114 peak->flux = readout->image->data.F32[peak->y-row0][peak->x-col0];112 pmPeak *peak = peaks->data[i]; 113 peak->SN = sqrt(peak->value*effArea); 114 peak->flux = readout->image->data.F32[peak->y-row0][peak->x-col0]; 115 115 } 116 116 117 117 // limit the total number of returned peak as specified 118 118 if (pass == 1) { 119 psArraySort (peaks, pmPeakSortBySN);120 int NMAX = psMetadataLookupS32 (&status, recipe, "PEAKS_NMAX");121 if (NMAX && (peaks->n > NMAX)) {122 psArray *tmpPeaks = psArrayAllocEmpty (NMAX);123 for (int i = 0; i < NMAX; i++) {124 psArrayAdd (tmpPeaks, 100, peaks->data[i]);125 }126 psFree (peaks);127 peaks = tmpPeaks;128 }129 } 119 psArraySort (peaks, pmPeakSortBySN); 120 int NMAX = psMetadataLookupS32 (&status, recipe, "PEAKS_NMAX"); 121 if (NMAX && (peaks->n > NMAX)) { 122 psArray *tmpPeaks = psArrayAllocEmpty (NMAX); 123 for (int i = 0; i < NMAX; i++) { 124 psArrayAdd (tmpPeaks, 100, peaks->data[i]); 125 } 126 psFree (peaks); 127 peaks = tmpPeaks; 128 } 129 } 130 130 131 131 // optional dump of all peak data 132 132 char *output = psMetadataLookupStr (&status, recipe, "PEAKS_OUTPUT_FILE"); 133 133 if (status && (output != NULL) && (output[0])) { 134 pmPeaksWriteText (peaks, output);134 pmPeaksWriteText (peaks, output); 135 135 } 136 136 psLogMsg ("psphot", PS_LOG_INFO, "%ld peaks: %f sec\n", peaks->n, psTimerMark ("psphot")); … … 142 142 // want to do that 143 143 // 144 if (returnFootprints) { // We want an array of pmFootprint, not pmPeak145 int npixMin = psMetadataLookupS32(&status, recipe, "FOOTPRINT_NPIXMIN");146 if (!status) {147 npixMin = 1;148 }149 float FOOTPRINT_NSIGMA_LIMIT =150 psMetadataLookupS32(&status, recipe,151 (pass == 1) ? "FOOTPRINT_NSIGMA_LIMIT" : "FOOTPRINT_NSIGMA_LIMIT_2");152 if (!status) {153 FOOTPRINT_NSIGMA_LIMIT = NSIGMA_PEAK;154 }155 threshold = PS_SQR(FOOTPRINT_NSIGMA_LIMIT)/effArea;144 if (returnFootprints) { // We want an array of pmFootprint, not pmPeak 145 int npixMin = psMetadataLookupS32(&status, recipe, "FOOTPRINT_NPIXMIN"); 146 if (!status) { 147 npixMin = 1; 148 } 149 float FOOTPRINT_NSIGMA_LIMIT = 150 psMetadataLookupS32(&status, recipe, 151 (pass == 1) ? "FOOTPRINT_NSIGMA_LIMIT" : "FOOTPRINT_NSIGMA_LIMIT_2"); 152 if (!status) { 153 FOOTPRINT_NSIGMA_LIMIT = NSIGMA_PEAK; 154 } 155 threshold = PS_SQR(FOOTPRINT_NSIGMA_LIMIT)/effArea; 156 156 157 psArray *footprints = pmFindFootprints(smooth_im, threshold, npixMin);158 pmPeaksAssignToFootprints(footprints, peaks);157 psArray *footprints = pmFindFootprints(smooth_im, threshold, npixMin); 158 pmPeaksAssignToFootprints(footprints, peaks); 159 159 160 psFree(peaks);161 peaks = footprints;// well, you know what I mean160 psFree(peaks); 161 peaks = footprints; // well, you know what I mean 162 162 } 163 163 … … 174 174 */ 175 175 psErrorCode 176 psphotCullPeaks(const psImage *image, // the image wherein lives the footprint177 const psImage *weight,// corresponding variance image178 const psMetadata *recipe,179 psArray *footprints) {// array of pmFootprints176 psphotCullPeaks(const psImage *image, // the image wherein lives the footprint 177 const psImage *weight, // corresponding variance image 178 const psMetadata *recipe, 179 psArray *footprints) { // array of pmFootprints 180 180 bool status = false; 181 181 float nsigma_delta = psMetadataLookupF32(&status, recipe, "FOOTPRINT_CULL_NSIGMA_DELTA"); 182 182 if (!status) { 183 nsigma_delta = 0; // min. 183 nsigma_delta = 0; // min. 184 184 } 185 185 float nsigma_min = psMetadataLookupF32(&status, recipe, "FOOTPRINT_CULL_NSIGMA_MIN"); 186 186 if (!status) { 187 nsigma_min = 0;187 nsigma_min = 0; 188 188 } 189 189 const float skyStdev = psMetadataLookupF32(NULL, recipe, "SKY_STDEV"); 190 190 191 191 return pmFootprintArrayCullPeaks(image, weight, footprints, 192 nsigma_delta, nsigma_min*skyStdev);192 nsigma_delta, nsigma_min*skyStdev); 193 193 }
Note:
See TracChangeset
for help on using the changeset viewer.
