Changeset 25755 for trunk/psphot/src/psphotSourceStats.c
- Timestamp:
- Oct 2, 2009, 3:12:47 PM (17 years ago)
- Location:
- trunk/psphot/src
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
psphotSourceStats.c (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot/src
- Property svn:ignore
-
old new 18 18 psphotVersionDefinitions.h 19 19 psphotMomentsStudy 20 psphotPetrosianStudy
-
- Property svn:ignore
-
trunk/psphot/src/psphotSourceStats.c
r24589 r25755 1 1 # include "psphotInternal.h" 2 2 3 psArray *psphotSourceStats (pmConfig *config, pmReadout *readout, pmDetections *detections) { 3 bool psphotSetMomentsWindow (psMetadata *recipe, psArray *sources); 4 5 psArray *psphotSourceStats (pmConfig *config, pmReadout *readout, pmDetections *detections, bool setWindow) { 4 6 5 7 bool status = false; … … 21 23 float OUTER = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS"); 22 24 if (!status) return NULL; 25 26 OUTER = PS_MAX(OUTER, 20.0); // XXX Guarantee that we can encompass the max moments radius 27 23 28 char *breakPt = psMetadataLookupStr (&status, recipe, "BREAK_POINT"); 24 29 if (!status) return NULL; … … 60 65 psphotVisualShowMoments (sources); 61 66 return sources; 67 } 68 69 if (setWindow) { 70 if (!psphotSetMomentsWindow(recipe, sources)) { 71 psError(PS_ERR_UNEXPECTED_NULL, false, "Failed to determine Moments Window!"); 72 return NULL; 73 } 62 74 } 63 75 … … 144 156 float RADIUS = psMetadataLookupF32 (&status, recipe, "PSF_MOMENTS_RADIUS"); 145 157 if (!status) return false; 146 float MIN_PIXEL_SN = psMetadataLookupF32 (&status, recipe, "MOMENTS_MIN_PIXEL_SN");147 if (!status) return false;148 158 float SIGMA = psMetadataLookupF32 (&status, recipe, "MOMENTS_GAUSS_SIGMA"); 149 159 if (!status) return false; … … 194 204 } 195 205 196 // measure basic source moments 197 status = pmSourceMoments (source, RADIUS, SIGMA, MIN_PIXEL_SN);206 // measure basic source moments (no S/N clipping on input pixels) 207 status = pmSourceMoments (source, RADIUS, SIGMA, 0.0); 198 208 if (status) { 199 209 Nmoments ++; … … 205 215 BIG_RADIUS = PS_MIN (INNER, 3*RADIUS); 206 216 psTrace ("psphot", 4, "retrying moments for %d, %d\n", source->peak->x, source->peak->y); 207 status = pmSourceMoments (source, BIG_RADIUS, 3.0*SIGMA, MIN_PIXEL_SN);217 status = pmSourceMoments (source, BIG_RADIUS, 3.0*SIGMA, 0.0); 208 218 if (status) { 209 219 source->mode |= PM_SOURCE_MODE_BIG_RADIUS; … … 231 241 } 232 242 233 # if (0) 234 bool psphotSourceStats_Unthreaded (int *nfail, int *nmoments, psArray *sources, psMetadata *recipe) { 235 236 bool status = false; 237 float BIG_RADIUS; 238 239 float INNER = psMetadataLookupF32 (&status, recipe, "SKY_INNER_RADIUS"); 240 if (!status) return false; 241 float MIN_SN = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN"); 242 if (!status) return false; 243 float RADIUS = psMetadataLookupF32 (&status, recipe, "PSF_MOMENTS_RADIUS"); 244 if (!status) return false; 245 246 // bit-masks to test for good/bad pixels 247 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); 248 assert (maskVal); 249 250 // bit-mask to mark pixels not used in analysis 251 psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT"); 252 assert (markVal); 253 254 // maskVal is used to test for rejected pixels, and must include markVal 255 maskVal |= markVal; 256 257 // threaded measurement of the sources moments 258 int Nfail = 0; 259 int Nmoments = 0; 260 for (int i = 0; i < sources->n; i++) { 261 pmSource *source = sources->data[i]; 262 263 // skip faint sources for moments measurement 264 if (source->peak->SN < MIN_SN) { 265 continue; 266 } 267 268 // measure a local sky value 269 // the local sky is now ignored; kept here for reference only 270 status = pmSourceLocalSky (source, PS_STAT_SAMPLE_MEDIAN, INNER, maskVal, markVal); 271 if (!status) { 272 psErrorClear(); // XXX re-consider the errors raised here 273 Nfail ++; 274 continue; 275 } 276 277 // measure the local sky variance (needed if noise is not sqrt(signal)) 278 // XXX EAM : this should use ROBUST not SAMPLE median, but it is broken 279 status = pmSourceLocalSkyVariance (source, PS_STAT_SAMPLE_MEDIAN, INNER, maskVal, markVal); 280 if (!status) { 281 Nfail ++; 282 psErrorClear(); 283 continue; 284 } 285 286 // measure basic source moments 287 status = pmSourceMoments (source, RADIUS, SIGMA, MIN_PIXEL_SN); 288 if (status) { 289 Nmoments ++; 290 continue; 291 } 292 293 // if no valid pixels, or massive swing, likely saturated source, 294 // try a much larger box 295 BIG_RADIUS = PS_MIN (INNER, 3*RADIUS); 296 psTrace ("psphot", 4, "retrying moments for %d, %d\n", source->peak->x, source->peak->y); 297 status = pmSourceMoments (source, BIG_RADIUS, 3.0*SIGMA, MIN_PIXEL_SN); 298 if (status) { 299 Nmoments ++; 300 continue; 301 } 302 303 Nfail ++; 304 psErrorClear(); 305 continue; 306 } 307 308 // change the value of a scalar on the array (wrap this and put it in psArray.h) 309 *nmoments = Nmoments; 310 *nfail = Nfail; 311 243 // this function attempts to iteratively determine the best value for sigma of the moments weighting Gaussian 244 bool psphotSetMomentsWindow (psMetadata *recipe, psArray *sources) { 245 246 bool status; 247 248 float MIN_SN = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN"); 249 if (!status) return false; 250 251 // XXX move this to a config file? 252 float sigma[4] = {1.0, 2.0, 3.0, 4.5}; 253 float Sout[4]; 254 255 // this sorts by peak->SN 256 sources = psArraySort (sources, pmSourceSortBySN); 257 258 // loop over radii: 259 for (int i = 0; i < 4; i++) { 260 261 // XXX move max source number to config 262 for (int j = 0; (j < sources->n) && (j < 400); j++) { 263 264 pmSource *source = sources->data[j]; 265 psAssert (source->moments, "force moments to exist"); 266 source->moments->nPixels = 0; 267 268 // skip faint sources for moments measurement 269 if (source->peak->SN < MIN_SN) { 270 continue; 271 } 272 273 // measure basic source moments (no S/N clipping on input pixels) 274 status = pmSourceMoments (source, 4*sigma[i], sigma[i], 0.0); 275 } 276 277 // choose a grid scale that is a fixed fraction of the psf sigma^2 278 psMetadataAddF32(recipe, PS_LIST_TAIL, "PSF_CLUMP_GRID_SCALE", PS_META_REPLACE, "clump grid", 0.1*PS_SQR(sigma[i])); 279 psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_SX_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(sigma[i])); 280 psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_SY_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(sigma[i])); 281 282 // determine the PSF parameters from the source moment values 283 pmPSFClump psfClump = pmSourcePSFClump (NULL, sources, recipe); 284 psLogMsg ("psphot", 3, "radius %.1f, nStars: %d, nSigma: %5.2f, X, Y: %f, %f (%f, %f)\n", sigma[i], psfClump.nStars, psfClump.nSigma, psfClump.X, psfClump.Y, sqrt(psfClump.X) / sigma[i], sqrt(psfClump.Y) / sigma[i]); 285 286 psMetadataAddS32 (recipe, PS_LIST_TAIL, "PSF.CLUMP.NREGIONS", PS_META_REPLACE, "psf clump regions", 1); 287 psMetadata *regionMD = psMetadataLookupPtr (&status, recipe, "PSF.CLUMP.REGION.000"); 288 if (!regionMD) { 289 regionMD = psMetadataAlloc(); 290 psMetadataAddMetadata (recipe, PS_LIST_TAIL, "PSF.CLUMP.REGION.000", PS_META_REPLACE, "psf clump region", regionMD); 291 psFree (regionMD); 292 } 293 psMetadataAddF32 (regionMD, PS_LIST_TAIL, "PSF.CLUMP.X", PS_META_REPLACE, "psf clump center", psfClump.X); 294 psMetadataAddF32 (regionMD, PS_LIST_TAIL, "PSF.CLUMP.Y", PS_META_REPLACE, "psf clump center", psfClump.Y); 295 psMetadataAddF32 (regionMD, PS_LIST_TAIL, "PSF.CLUMP.DX", PS_META_REPLACE, "psf clump center", psfClump.dX); 296 psMetadataAddF32 (regionMD, PS_LIST_TAIL, "PSF.CLUMP.DY", PS_META_REPLACE, "psf clump center", psfClump.dY); 297 298 // psphotVisualPlotMoments (recipe, sources); 299 300 Sout[i] = sqrt(0.5*(psfClump.X + psfClump.Y)) / sigma[i]; 301 } 302 303 // we are looking for sigma for which Sout = 0.65 (or some other value) 304 305 float Sigma = NAN; 306 float minS = Sout[0]; 307 float maxS = Sout[0]; 308 for (int i = 0; i < 4; i++) { 309 minS = PS_MIN(Sout[i], minS); 310 maxS = PS_MAX(Sout[i], maxS); 311 } 312 if (minS > 0.65) Sigma = sigma[3]; 313 if (maxS < 0.65) Sigma = sigma[0]; 314 315 for (int i = 0; i < 3; i++) { 316 if ((Sout[i] > 0.65) && (Sout[i+1] > 0.65)) continue; 317 if ((Sout[i] < 0.65) && (Sout[i+1] < 0.65)) continue; 318 Sigma = sigma[i] + (0.65 - Sout[i])*(sigma[i+1] - sigma[i])/(Sout[i+1] - Sout[i]); 319 } 320 psAssert (isfinite(Sigma), "did we miss a case?"); 321 322 // choose a grid scale that is a fixed fraction of the psf sigma^2 323 psMetadataAddF32(recipe, PS_LIST_TAIL, "PSF_CLUMP_GRID_SCALE", PS_META_REPLACE, "clump grid", 0.1*PS_SQR(Sigma)); 324 psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_SX_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(Sigma)); 325 psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_SY_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(Sigma)); 326 psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_GAUSS_SIGMA", PS_META_REPLACE, "moments limit", Sigma); 327 psMetadataAddF32(recipe, PS_LIST_TAIL, "PSF_MOMENTS_RADIUS", PS_META_REPLACE, "moments limit", 4.0*Sigma); 328 329 psLogMsg ("psphot", 3, "using window function with sigma = %f\n", Sigma); 312 330 return true; 313 331 } 314 # endif
Note:
See TracChangeset
for help on using the changeset viewer.
