- Timestamp:
- Apr 24, 2011, 10:09:38 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20110404/psModules/src/objects/pmSourceMoments.c
r31327 r31361 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 psF32RFW = 0.0;112 psF32RHW = 0.0;113 114 psF32RF = 0.0;115 psF32RH = 0.0;116 psF32RS = 0.0;117 psF32XX = 0.0;118 psF32XY = 0.0;119 psF32YY = 0.0;120 psF32XXX = 0.0;121 psF32XXY = 0.0;122 psF32XYY = 0.0;123 psF32YYY = 0.0;124 psF32XXXX = 0.0;125 psF32XXXY = 0.0;126 psF32XXYY = 0.0;127 psF32XYYY = 0.0;128 psF32YYYY = 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; 129 129 130 130 Sum = 0.0; // the second pass may include slightly different pixels, re-determine Sum … … 140 140 // center of mass in subimage. Note: the calculation below uses pixel index, so we correct 141 141 // xCM, yCM from pixel coords to pixel index here. 142 psF32xCM = Xo - 0.5 - source->pixels->col0; // coord of peak in subimage143 psF32yCM = Yo - 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 144 144 145 145 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 146 146 147 psF32yDiff = row - yCM;147 float yDiff = row - yCM; 148 148 if (fabs(yDiff) > radius) continue; 149 149 150 psF32*vPix = source->pixels->data.F32[row];151 psF32*vWgt = source->variance->data.F32[row];150 float *vPix = source->pixels->data.F32[row]; 151 float *vWgt = source->variance->data.F32[row]; 152 152 153 153 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row]; … … 164 164 if (isnan(*vPix)) continue; 165 165 166 psF32xDiff = col - xCM;166 float xDiff = col - xCM; 167 167 if (fabs(xDiff) > radius) continue; 168 168 169 169 // radius is just a function of (xDiff, yDiff) 170 psF32r2 = PS_SQR(xDiff) + PS_SQR(yDiff);170 float r2 = PS_SQR(xDiff) + PS_SQR(yDiff); 171 171 if (r2 > R2) continue; 172 172 173 psF32fDiff = *vPix - sky;174 psF32pDiff = fDiff;175 psF32wDiff = *vWgt;173 float fDiff = *vPix - sky; 174 float pDiff = fDiff; 175 float wDiff = *vWgt; 176 176 177 177 // skip pixels below specified significance level. this is allowed, but should be … … 184 184 // weighting over weights the sky for faint sources 185 185 if (sigma > 0.0) { 186 psF32z = r2 * rsigma2;186 float z = r2 * rsigma2; 187 187 assert (z >= 0.0); 188 psF32weight = exp(-z);188 float weight = exp(-z); 189 189 190 190 wDiff *= weight; … … 195 195 196 196 // Kron Flux uses the 1st radial moment (NOT Gaussian windowed?) 197 psF32r = sqrt(r2);198 psF32rf = r * fDiff;199 psF32rh = sqrt(r) * fDiff;200 psF32rs = fDiff;201 202 psF32rfw = r * pDiff;203 psF32rhw = sqrt(r) * pDiff;204 205 psF32x = xDiff * pDiff;206 psF32y = yDiff * pDiff;207 208 psF32xx = xDiff * x;209 psF32xy = xDiff * y;210 psF32yy = yDiff * y;211 212 psF32xxx = xDiff * xx / r;213 psF32xxy = xDiff * xy / r;214 psF32xyy = xDiff * yy / r;215 psF32yyy = yDiff * yy / r;216 217 psF32xxxx = xDiff * xxx / r2;218 psF32xxxy = xDiff * xxy / r2;219 psF32xxyy = xDiff * xyy / r2;220 psF32xyyy = xDiff * yyy / r2;221 psF32yyyy = 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; 222 222 223 223 RF += rf; … … 245 245 } 246 246 247 // if Mrf (first radial moment) is << sigma, we are getting into low-significance 248 // territory. saturate at 0.75*sigma. conversely, if Mrf is > radius, we are clearly 249 // making an error. saturate at radius. 250 source->moments->Mrf = MIN(radius, MAX(0.75*sigma, RF/RS)); 251 source->moments->Mrh = MIN(radius, MAX(0.75*sigma, RH/RS)); 247 source->moments->Mrf = RF/RS; 248 source->moments->Mrh = RH/RS; 252 249 253 250 source->moments->Mxx = XX/Sum; … … 266 263 source->moments->Myyyy = YYYY/Sum; 267 264 268 // XXX TEST:269 // source->moments->KronFinner = RFW/Sum;270 // source->moments->KronFouter = sigma;271 272 // Calculate the Kron magnitude (make this block optional?) 273 float radKinner = 1.0* source->moments->Mrf;274 float radKron = 2.5* source->moments->Mrf;275 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; 276 273 277 274 int nKronPix = 0; … … 285 282 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 286 283 287 psF32yDiff = row - yCM;284 float yDiff = row - yCM; 288 285 if (fabs(yDiff) > radKouter) continue; 289 286 290 psF32*vPix = source->pixels->data.F32[row];291 psF32*vWgt = source->variance->data.F32[row];287 float *vPix = source->pixels->data.F32[row]; 288 float *vWgt = source->variance->data.F32[row]; 292 289 293 290 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row]; … … 304 301 if (isnan(*vPix)) continue; 305 302 306 psF32xDiff = col - xCM;303 float xDiff = col - xCM; 307 304 if (fabs(xDiff) > radKouter) continue; 308 305 309 306 // radKron is just a function of (xDiff, yDiff) 310 psF32r2 = PS_SQR(xDiff) + PS_SQR(yDiff);311 312 psF32pDiff = *vPix - sky;313 psF32wDiff = *vWgt;307 float r2 = PS_SQR(xDiff) + PS_SQR(yDiff); 308 309 float pDiff = *vPix - sky; 310 float wDiff = *vWgt; 314 311 315 312 // skip pixels below specified significance level. this is allowed, but should be … … 318 315 if (PS_SQR(pDiff) < minSN2*wDiff) continue; 319 316 320 psF32r = sqrt(r2);317 float r = sqrt(r2); 321 318 if (r < radKron) { 322 319 Sum += pDiff; … … 363 360 } 364 361 365 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) { 366 363 367 364 // First Pass: calculate the first moments (these are subtracted from the coordinates below) … … 370 367 // .. etc 371 368 372 psF32sky = 0.0;373 374 psF32peakPixel = -PS_MAX_F32;369 float sky = 0.0; 370 371 float peakPixel = -PS_MAX_F32; 375 372 psS32 numPixels = 0; 376 psF32Sum = 0.0;377 psF32Var = 0.0;378 psF32X1 = 0.0;379 psF32Y1 = 0.0;380 psF32R2 = PS_SQR(radius);381 psF32minSN2 = PS_SQR(minSN);382 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); 383 380 384 381 float xPeak = xGuess - source->pixels->col0; // coord of peak in subimage … … 386 383 387 384 // we are guaranteed to have a valid pixel and variance at this location (right? right?) 388 // 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]); 389 386 // psAssert (isfinite(source->pixels->data.F32[yPeak][xPeak]), "peak must be on valid pixel"); 390 387 // psAssert (isfinite(source->variance->data.F32[yPeak][xPeak]), "peak must be on valid pixel"); … … 398 395 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 399 396 400 psF32yDiff = row + 0.5 - yPeak;397 float yDiff = row + 0.5 - yPeak; 401 398 if (fabs(yDiff) > radius) continue; 402 399 403 psF32*vPix = source->pixels->data.F32[row];404 psF32*vWgt = source->variance->data.F32[row];400 float *vPix = source->pixels->data.F32[row]; 401 float *vWgt = source->variance->data.F32[row]; 405 402 406 403 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row]; … … 417 414 if (isnan(*vPix)) continue; 418 415 419 psF32xDiff = col + 0.5 - xPeak;416 float xDiff = col + 0.5 - xPeak; 420 417 if (fabs(xDiff) > radius) continue; 421 418 422 419 // radius is just a function of (xDiff, yDiff) 423 psF32r2 = PS_SQR(xDiff) + PS_SQR(yDiff);420 float r2 = PS_SQR(xDiff) + PS_SQR(yDiff); 424 421 if (r2 > R2) continue; 425 422 426 psF32pDiff = *vPix - sky;427 psF32wDiff = *vWgt;423 float pDiff = *vPix - sky; 424 float wDiff = *vWgt; 428 425 429 426 // skip pixels below specified significance level. for a PSFs, this … … 438 435 // weighting over weights the sky for faint sources 439 436 if (sigma > 0.0) { 440 psF32z = r2*rsigma2;437 float z = r2*rsigma2; 441 438 assert (z >= 0.0); 442 psF32weight = exp(-z);439 float weight = exp(-z); 443 440 444 441 wDiff *= weight; … … 449 446 Sum += pDiff; 450 447 451 psF32xWght = xDiff * pDiff;452 psF32yWght = yDiff * pDiff;448 float xWght = xDiff * pDiff; 449 float yWght = yDiff * pDiff; 453 450 454 451 X1 += xWght; … … 507 504 return true; 508 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.
