Changeset 31451 for trunk/psModules/src/objects/pmSourceMoments.c
- Timestamp:
- May 5, 2011, 11:02:53 AM (15 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/objects/pmSourceMoments.c (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/objects/pmSourceMoments.c
r31153 r31451 66 66 // if mode & EXTERNAL or mode2 & MATCHED, do not re-calculate the centroid (use peak as centroid) 67 67 68 bool pmSourceMoments(pmSource *source, psF32 radius, psF32 sigma, psF32 minSN, psImageMaskType maskVal)68 bool pmSourceMoments(pmSource *source, float radius, float sigma, float minSN, float minKronRadius, psImageMaskType maskVal) 69 69 { 70 70 PS_ASSERT_PTR_NON_NULL(source, false); … … 74 74 75 75 // this function assumes the sky has been well-subtracted for the image 76 psF32sky = 0.0;76 float sky = 0.0; 77 77 78 78 if (source->moments == NULL) { … … 80 80 } 81 81 82 psF32Sum = 0.0;83 psF32Var = 0.0;84 psF32SumCore = 0.0;85 psF32VarCore = 0.0;86 psF32R2 = PS_SQR(radius);87 psF32minSN2 = PS_SQR(minSN);88 psF32rsigma2 = 0.5 / PS_SQR(sigma);82 float Sum = 0.0; 83 float Var = 0.0; 84 float SumCore = 0.0; 85 float VarCore = 0.0; 86 float R2 = PS_SQR(radius); 87 float minSN2 = PS_SQR(minSN); 88 float rsigma2 = 0.5 / PS_SQR(sigma); 89 89 90 90 // a note about coordinates: coordinates of objects throughout psphot refer to the primary … … 109 109 // Xn = SUM (x - xc)^n * (z - sky) 110 110 111 psF32 RF = 0.0; 112 psF32 RH = 0.0; 113 psF32 RS = 0.0; 114 psF32 XX = 0.0; 115 psF32 XY = 0.0; 116 psF32 YY = 0.0; 117 psF32 XXX = 0.0; 118 psF32 XXY = 0.0; 119 psF32 XYY = 0.0; 120 psF32 YYY = 0.0; 121 psF32 XXXX = 0.0; 122 psF32 XXXY = 0.0; 123 psF32 XXYY = 0.0; 124 psF32 XYYY = 0.0; 125 psF32 YYYY = 0.0; 111 float RFW = 0.0; 112 float RHW = 0.0; 113 114 float RF = 0.0; 115 float RH = 0.0; 116 float RS = 0.0; 117 float XX = 0.0; 118 float XY = 0.0; 119 float YY = 0.0; 120 float XXX = 0.0; 121 float XXY = 0.0; 122 float XYY = 0.0; 123 float YYY = 0.0; 124 float XXXX = 0.0; 125 float XXXY = 0.0; 126 float XXYY = 0.0; 127 float XYYY = 0.0; 128 float YYYY = 0.0; 126 129 127 130 Sum = 0.0; // the second pass may include slightly different pixels, re-determine Sum 131 132 // float dX = source->moments->Mx - source->peak->xf; 133 // float dY = source->moments->My - source->peak->yf; 134 // float dR = hypot(dX, dY); 135 // float Xo = (dR < 2.0) ? source->moments->Mx : source->peak->xf; 136 // float Yo = (dR < 2.0) ? source->moments->My : source->peak->yf; 137 float Xo = source->moments->Mx; 138 float Yo = source->moments->My; 128 139 129 140 // center of mass in subimage. Note: the calculation below uses pixel index, so we correct 130 141 // xCM, yCM from pixel coords to pixel index here. 131 psF32 xCM = source->moments->Mx- 0.5 - source->pixels->col0; // coord of peak in subimage132 psF32 yCM = source->moments->My- 0.5 - source->pixels->row0; // coord of peak in subimage142 float xCM = Xo - 0.5 - source->pixels->col0; // coord of peak in subimage 143 float yCM = Yo - 0.5 - source->pixels->row0; // coord of peak in subimage 133 144 134 145 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 135 146 136 psF32yDiff = row - yCM;147 float yDiff = row - yCM; 137 148 if (fabs(yDiff) > radius) continue; 138 149 139 psF32 *vPix = source->pixels->data.F32[row]; 140 psF32 *vWgt = source->variance->data.F32[row]; 150 float *vPix = source->pixels->data.F32[row]; 151 float *vWgt = source->variance->data.F32[row]; 152 141 153 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row]; 154 // psImageMaskType *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row]; 142 155 143 156 for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) { … … 151 164 if (isnan(*vPix)) continue; 152 165 153 psF32xDiff = col - xCM;166 float xDiff = col - xCM; 154 167 if (fabs(xDiff) > radius) continue; 155 168 156 169 // radius is just a function of (xDiff, yDiff) 157 psF32r2 = PS_SQR(xDiff) + PS_SQR(yDiff);170 float r2 = PS_SQR(xDiff) + PS_SQR(yDiff); 158 171 if (r2 > R2) continue; 159 172 160 psF32fDiff = *vPix - sky;161 psF32pDiff = fDiff;162 psF32wDiff = *vWgt;173 float fDiff = *vPix - sky; 174 float pDiff = fDiff; 175 float wDiff = *vWgt; 163 176 164 177 // skip pixels below specified significance level. this is allowed, but should be … … 171 184 // weighting over weights the sky for faint sources 172 185 if (sigma > 0.0) { 173 psF32z = r2 * rsigma2;186 float z = r2 * rsigma2; 174 187 assert (z >= 0.0); 175 psF32weight = exp(-z);188 float weight = exp(-z); 176 189 177 190 wDiff *= weight; … … 182 195 183 196 // Kron Flux uses the 1st radial moment (NOT Gaussian windowed?) 184 psF32 r = sqrt(r2); 185 psF32 rf = r * fDiff; 186 psF32 rh = sqrt(r) * fDiff; 187 psF32 rs = fDiff; 188 189 psF32 x = xDiff * pDiff; 190 psF32 y = yDiff * pDiff; 191 192 psF32 xx = xDiff * x; 193 psF32 xy = xDiff * y; 194 psF32 yy = yDiff * y; 195 196 psF32 xxx = xDiff * xx / r; 197 psF32 xxy = xDiff * xy / r; 198 psF32 xyy = xDiff * yy / r; 199 psF32 yyy = yDiff * yy / r; 200 201 psF32 xxxx = xDiff * xxx / r2; 202 psF32 xxxy = xDiff * xxy / r2; 203 psF32 xxyy = xDiff * xyy / r2; 204 psF32 xyyy = xDiff * yyy / r2; 205 psF32 yyyy = yDiff * yyy / r2; 197 float r = sqrt(r2); 198 float rf = r * fDiff; 199 float rh = sqrt(r) * fDiff; 200 float rs = fDiff; 201 202 float rfw = r * pDiff; 203 float rhw = sqrt(r) * pDiff; 204 205 float x = xDiff * pDiff; 206 float y = yDiff * pDiff; 207 208 float xx = xDiff * x; 209 float xy = xDiff * y; 210 float yy = yDiff * y; 211 212 float xxx = xDiff * xx / r; 213 float xxy = xDiff * xy / r; 214 float xyy = xDiff * yy / r; 215 float yyy = yDiff * yy / r; 216 217 float xxxx = xDiff * xxx / r2; 218 float xxxy = xDiff * xxy / r2; 219 float xxyy = xDiff * xyy / r2; 220 float xyyy = xDiff * yyy / r2; 221 float yyyy = yDiff * yyy / r2; 206 222 207 223 RF += rf; 208 224 RH += rh; 209 225 RS += rs; 226 227 RFW += rfw; 228 RHW += rhw; 210 229 211 230 XX += xx; … … 244 263 source->moments->Myyyy = YYYY/Sum; 245 264 246 // Calculate the Kron magnitude (make this block optional?) 247 float radKinner = 1.0*source->moments->Mrf; 248 float radKron = 2.5*source->moments->Mrf; 249 float radKouter = 4.0*source->moments->Mrf; 265 // if Mrf (first radial moment) is very small, we are getting into low-significance 266 // territory. saturate at minKronRadius. conversely, if Mrf is > radius, we are clearly 267 // making an error. saturate at radius. 268 float kronRefRadius = MIN(radius, MAX(minKronRadius, source->moments->Mrf)); 269 270 float radKinner = 1.0*kronRefRadius; 271 float radKron = 2.5*kronRefRadius; 272 float radKouter = 4.0*kronRefRadius; 250 273 251 274 int nKronPix = 0; … … 259 282 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 260 283 261 psF32yDiff = row - yCM;284 float yDiff = row - yCM; 262 285 if (fabs(yDiff) > radKouter) continue; 263 286 264 psF32 *vPix = source->pixels->data.F32[row]; 265 psF32 *vWgt = source->variance->data.F32[row]; 287 float *vPix = source->pixels->data.F32[row]; 288 float *vWgt = source->variance->data.F32[row]; 289 266 290 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row]; 291 // psImageMaskType *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row]; 267 292 268 293 for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) { … … 276 301 if (isnan(*vPix)) continue; 277 302 278 psF32xDiff = col - xCM;303 float xDiff = col - xCM; 279 304 if (fabs(xDiff) > radKouter) continue; 280 305 281 306 // radKron is just a function of (xDiff, yDiff) 282 psF32r2 = PS_SQR(xDiff) + PS_SQR(yDiff);283 284 psF32pDiff = *vPix - sky;285 psF32wDiff = *vWgt;307 float r2 = PS_SQR(xDiff) + PS_SQR(yDiff); 308 309 float pDiff = *vPix - sky; 310 float wDiff = *vWgt; 286 311 287 312 // skip pixels below specified significance level. this is allowed, but should be … … 290 315 if (PS_SQR(pDiff) < minSN2*wDiff) continue; 291 316 292 psF32r = sqrt(r2);317 float r = sqrt(r2); 293 318 if (r < radKron) { 294 319 Sum += pDiff; … … 335 360 } 336 361 337 bool pmSourceMomentsGetCentroid(pmSource *source, psF32 radius, psF32 sigma, psF32minSN, psImageMaskType maskVal, float xGuess, float yGuess) {362 bool pmSourceMomentsGetCentroid(pmSource *source, float radius, float sigma, float minSN, psImageMaskType maskVal, float xGuess, float yGuess) { 338 363 339 364 // First Pass: calculate the first moments (these are subtracted from the coordinates below) … … 342 367 // .. etc 343 368 344 psF32sky = 0.0;345 346 psF32peakPixel = -PS_MAX_F32;369 float sky = 0.0; 370 371 float peakPixel = -PS_MAX_F32; 347 372 psS32 numPixels = 0; 348 psF32Sum = 0.0;349 psF32Var = 0.0;350 psF32X1 = 0.0;351 psF32Y1 = 0.0;352 psF32R2 = PS_SQR(radius);353 psF32minSN2 = PS_SQR(minSN);354 psF32rsigma2 = 0.5 / PS_SQR(sigma);373 float Sum = 0.0; 374 float Var = 0.0; 375 float X1 = 0.0; 376 float Y1 = 0.0; 377 float R2 = PS_SQR(radius); 378 float minSN2 = PS_SQR(minSN); 379 float rsigma2 = 0.5 / PS_SQR(sigma); 355 380 356 381 float xPeak = xGuess - source->pixels->col0; // coord of peak in subimage … … 358 383 359 384 // we are guaranteed to have a valid pixel and variance at this location (right? right?) 360 // psF32weightNorm = source->pixels->data.F32[yPeak][xPeak] / sqrt (source->variance->data.F32[yPeak][xPeak]);385 // float weightNorm = source->pixels->data.F32[yPeak][xPeak] / sqrt (source->variance->data.F32[yPeak][xPeak]); 361 386 // psAssert (isfinite(source->pixels->data.F32[yPeak][xPeak]), "peak must be on valid pixel"); 362 387 // psAssert (isfinite(source->variance->data.F32[yPeak][xPeak]), "peak must be on valid pixel"); … … 370 395 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 371 396 372 psF32yDiff = row + 0.5 - yPeak;397 float yDiff = row + 0.5 - yPeak; 373 398 if (fabs(yDiff) > radius) continue; 374 399 375 psF32 *vPix = source->pixels->data.F32[row]; 376 psF32 *vWgt = source->variance->data.F32[row]; 400 float *vPix = source->pixels->data.F32[row]; 401 float *vWgt = source->variance->data.F32[row]; 402 377 403 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row]; 404 // psImageMaskType *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row]; 378 405 379 406 for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) { … … 387 414 if (isnan(*vPix)) continue; 388 415 389 psF32xDiff = col + 0.5 - xPeak;416 float xDiff = col + 0.5 - xPeak; 390 417 if (fabs(xDiff) > radius) continue; 391 418 392 419 // radius is just a function of (xDiff, yDiff) 393 psF32r2 = PS_SQR(xDiff) + PS_SQR(yDiff);420 float r2 = PS_SQR(xDiff) + PS_SQR(yDiff); 394 421 if (r2 > R2) continue; 395 422 396 psF32pDiff = *vPix - sky;397 psF32wDiff = *vWgt;423 float pDiff = *vPix - sky; 424 float wDiff = *vWgt; 398 425 399 426 // skip pixels below specified significance level. for a PSFs, this … … 408 435 // weighting over weights the sky for faint sources 409 436 if (sigma > 0.0) { 410 psF32z = r2*rsigma2;437 float z = r2*rsigma2; 411 438 assert (z >= 0.0); 412 psF32weight = exp(-z);439 float weight = exp(-z); 413 440 414 441 wDiff *= weight; … … 419 446 Sum += pDiff; 420 447 421 psF32xWght = xDiff * pDiff;422 psF32yWght = yDiff * pDiff;448 float xWght = xDiff * pDiff; 449 float yWght = yDiff * pDiff; 423 450 424 451 X1 += xWght; … … 477 504 return true; 478 505 } 506 507 float pmSourceMinKronRadius(psArray *sources, float PSF_SN_LIM) { 508 509 psVector *radii = psVectorAllocEmpty(100, PS_TYPE_F32); 510 511 for (int i = 0; i < sources->n; i++) { 512 pmSource *src = sources->data[i]; // Source of interest 513 if (!src || !src->moments) { 514 continue; 515 } 516 517 if (src->mode & PM_SOURCE_MODE_BLEND) { 518 continue; 519 } 520 521 if (!src->moments->nPixels) continue; 522 523 if (src->moments->SN < PSF_SN_LIM) continue; 524 525 // XXX put in Mxx,Myy cut based on clump location 526 527 psVectorAppend(radii, src->moments->Mrf); 528 } 529 530 // find the peak in this image 531 psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN); 532 533 if (!psVectorStats (stats, radii, NULL, NULL, 0)) { 534 psError(PS_ERR_UNKNOWN, false, "Unable to get image statistics.\n"); 535 psFree(stats); 536 return NAN; 537 } 538 539 float minRadius = stats->sampleMedian; 540 541 psFree(radii); 542 psFree(stats); 543 return minRadius; 544 } 545
Note:
See TracChangeset
for help on using the changeset viewer.
