- Timestamp:
- Aug 29, 2011, 1:26:12 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20110710/psModules/src/objects/pmSourceMoments.c
r32202 r32216 80 80 } 81 81 82 if (source->moments->nPixels != 0) {83 fprintf (stderr, "remeasure moments: %f,%f\n", source->peak->xf, source->peak->yf);84 }85 86 82 float Sum = 0.0; 87 83 float Var = 0.0; … … 120 116 // Xn = SUM (x - xc)^n * (z - sky) 121 117 122 float RF W= 0.0;123 float R HW= 0.0;118 float RFa = 0.0; 119 float RSa = 0.0; 124 120 125 121 float RF = 0.0; … … 154 150 float yCM = Yo - 0.5 - source->pixels->row0; // coord of peak in subimage 155 151 152 // calculate the higher-order moments using Xo,Yo 156 153 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 157 154 … … 205 202 Sum += pDiff; 206 203 207 // Kron Flux uses the 1st radial moment (NOT Gaussian windowed?)208 204 float r = sqrt(r2); 209 float rf = r * fDiff;210 float rh = sqrt(r) * fDiff;211 float rs = fDiff;212 213 float rfw = r * pDiff;214 float rhw = sqrt(r) * pDiff;215 205 216 206 float x = xDiff * pDiff; … … 232 222 float yyyy = yDiff * yyy / r2; 233 223 234 RF += rf;235 RH += rh;236 RS += rs;237 238 RFW += rfw;239 RHW += rhw;240 241 224 XX += xx; 242 225 XY += xy; … … 253 236 XYYY += xyyy; 254 237 YYYY += yyyy; 238 239 // Kron Flux uses the 1st radial moment (NOT Gaussian windowed?) 240 // XXX float r = sqrt(r2); 241 // XXX float rf = r * fDiff; 242 // XXX float rh = sqrt(r) * fDiff; 243 // XXX float rs = fDiff; 244 // XXX 245 // XXX float rfw = r * pDiff; 246 // XXX float rhw = sqrt(r) * pDiff; 247 // XXX 248 // XXX RF += rf; 249 // XXX RH += rh; 250 // XXX RS += rs; 251 // XXX 252 // XXX RFW += rfw; 253 // XXX RHW += rhw; 255 254 } 256 255 } 257 258 source->moments->Mrf = RF/RS;259 source->moments->Mrh = RH/RS;260 261 256 source->moments->Mxx = XX/Sum; 262 257 source->moments->Mxy = XY/Sum; … … 273 268 source->moments->Mxyyy = XYYY/Sum; 274 269 source->moments->Myyyy = YYYY/Sum; 270 271 # define TEST_X1 167 272 # define TEST_Y1 299 273 # define TEST_X2 180 274 # define TEST_Y2 300 275 if ((fabs(Xo - TEST_X1) < 3) && (fabs(Yo - TEST_Y1) < 3)) { 276 fprintf (stderr, "test obj 1\n"); 277 } 278 if ((fabs(Xo - TEST_X2) < 3) && (fabs(Yo - TEST_Y2) < 3)) { 279 fprintf (stderr, "test obj 2\n"); 280 } 281 282 float **vPix = source->pixels->data.F32; 283 float **vWgt = source->variance->data.F32; 284 psImageMaskType **vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA; 285 286 // calculate the 1st radial moment (for kron flux) -- symmetrical averaging 287 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 288 289 float yDiff = row - yCM; 290 if (fabs(yDiff) > radius) continue; 291 292 // coordinate of mirror pixel 293 int yFlip = yCM - yDiff; 294 if (yFlip < 0) continue; 295 if (yFlip >= source->pixels->numRows) continue; 296 297 for (psS32 col = 0; col < source->pixels->numCols ; col++) { 298 // check mask and value for this pixel 299 if (vMsk && (vMsk[row][col] & maskVal)) continue; 300 if (isnan(vPix[row][col])) continue; 301 302 float xDiff = col - xCM; 303 if (fabs(xDiff) > radius) continue; 304 305 // coordinate of mirror pixel 306 int xFlip = xCM - xDiff; 307 if (xFlip < 0) continue; 308 if (xFlip >= source->pixels->numCols) continue; 309 310 // check mask and value for mirror pixel 311 if (vMsk && (vMsk[yFlip][xFlip] & maskVal)) continue; 312 if (isnan(vPix[yFlip][xFlip])) continue; 313 314 // radius is just a function of (xDiff, yDiff) 315 float r2 = PS_SQR(xDiff) + PS_SQR(yDiff); 316 if (r2 > R2) continue; 317 318 float fDiff1 = vPix[row][col] - sky; 319 float fDiff2 = vPix[yFlip][xFlip] - sky; 320 float pDiff = (fDiff1 > 0.0) ? sqrt(fabs(fDiff1*fDiff2)) : -sqrt(fabs(fDiff1*fDiff2)); 321 322 // Kron Flux uses the 1st radial moment (NOT Gaussian windowed?) 323 float r = sqrt(r2); 324 float rf = r * pDiff; 325 float rh = sqrt(r) * pDiff; 326 float rs = 0.5 * (fDiff1 + fDiff2); 327 328 float rfa = r * fDiff1; 329 float rsa = fDiff1; 330 331 RF += rf; 332 RH += rh; 333 RS += rs; 334 335 RFa += rfa; 336 RSa += rsa; 337 } 338 } 339 340 source->moments->Mrf = RF/RS; 341 source->moments->Mrh = RH/RS; 342 343 float R1 = RFa / RSa; 344 if ((fabs(Xo - TEST_X1) < 3) && (fabs(Yo - TEST_Y1) < 3)) { 345 fprintf (stderr, "R1: %f vs %f\n", R1, source->moments->Mrf); 346 } 347 if ((fabs(Xo - TEST_X2) < 3) && (fabs(Yo - TEST_Y2) < 3)) { 348 fprintf (stderr, "R2: %f vs %f\n", R1, source->moments->Mrf); 349 } 350 351 // fprintf (stderr, "Rad: %f vs %f\n", R1, source->moments->Mrf); 275 352 276 353 // if Mrf (first radial moment) is very small, we are getting into low-significance … … 294 371 float SumOuter = 0.0; 295 372 373 // calculate the Kron flux, and related fluxes (symmetrical averaging) 296 374 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 297 375 298 376 float yDiff = row - yCM; 299 377 if (fabs(yDiff) > radKouter) continue; 378 379 // coordinate of mirror pixel 380 int yFlip = yCM - yDiff; 381 if (yFlip < 0) continue; 382 if (yFlip >= source->pixels->numRows) continue; 383 384 for (psS32 col = 0; col < source->pixels->numCols ; col++) { 385 // check mask and value for this pixel 386 if (vMsk && (vMsk[row][col] & maskVal)) continue; 387 if (isnan(vPix[row][col])) continue; 388 389 float xDiff = col - xCM; 390 if (fabs(xDiff) > radKouter) continue; 391 392 // coordinate of mirror pixel 393 int xFlip = xCM - xDiff; 394 if (xFlip < 0) continue; 395 if (xFlip >= source->pixels->numCols) continue; 396 397 // check mask and value for mirror pixel 398 if (vMsk && (vMsk[yFlip][xFlip] & maskVal)) continue; 399 if (isnan(vPix[yFlip][xFlip])) continue; 400 401 // radKron is just a function of (xDiff, yDiff) 402 float r2 = PS_SQR(xDiff) + PS_SQR(yDiff); 403 404 float fDiff1 = vPix[row][col] - sky; 405 float fDiff2 = vPix[yFlip][xFlip] - sky; 406 float pDiff = (fDiff1 > 0.0) ? sqrt(fabs(fDiff1*fDiff2)) : -sqrt(fabs(fDiff1*fDiff2)); 407 // float pDiff = vPix[row][col] - sky; 408 float wDiff = vWgt[row][col]; 409 410 // skip pixels below specified significance level. this is allowed, but should be 411 // avoided -- the over-weights the wings of bright stars compared to those of faint 412 // stars. 413 if (PS_SQR(pDiff) < minSN2*wDiff) continue; 414 415 # define WEIGHTED 0 416 # if (WEIGHTED) 417 float z = r2 * rsigma2 / 4.0; 418 assert (z >= 0.0); 419 float weight = exp(-z); 420 # else 421 float weight = 1.0; 422 # endif 423 424 float r = sqrt(r2); 425 if (r < radKron) { 426 Sum += pDiff*weight; 427 Var += wDiff*weight; 428 nKronPix ++; 429 // if (beVerbose) fprintf (stderr, "mome: %d %d %f %f %f\n", col, row, sky, *vPix, Sum); 430 } 431 432 // use sigma (fixed by psf) not a radKron based value 433 if (r < sigma) { 434 SumCore += pDiff; 435 VarCore += wDiff; 436 nCorePix ++; 437 } 438 439 if ((r > radKinner) && (r < radKron)) { 440 SumInner += pDiff; 441 nInner ++; 442 } 443 if ((r > radKron) && (r < radKouter)) { 444 SumOuter += pDiff; 445 nOuter ++; 446 } 447 } 448 } 449 // *** should I rescale these fluxes by pi R^2 / nNpix? 450 // XXX source->moments->KronCore = SumCore * M_PI * PS_SQR(sigma) / nCorePix; 451 // XXX source->moments->KronCoreErr = sqrt(VarCore) * M_PI * PS_SQR(sigma) / nCorePix; 452 // XXX source->moments->KronFlux = Sum * M_PI * PS_SQR(radKron) / nKronPix; 453 // XXX source->moments->KronFluxErr = sqrt(Var) * M_PI * PS_SQR(radKron) / nKronPix; 454 // XXX source->moments->KronFinner = SumInner * M_PI * (PS_SQR(radKron) - PS_SQR(radKinner)) / nInner; 455 // XXX source->moments->KronFouter = SumOuter * M_PI * (PS_SQR(radKouter) - PS_SQR(radKron)) / nOuter; 456 457 source->moments->KronCore = SumCore; 458 source->moments->KronCoreErr = sqrt(VarCore); 459 source->moments->KronFlux = Sum; 460 source->moments->KronFluxErr = sqrt(Var); 461 source->moments->KronFinner = SumInner; 462 source->moments->KronFouter = SumOuter; 463 464 // XXX not sure I should save this here... 465 source->moments->KronFluxPSF = source->moments->KronFlux; 466 source->moments->KronFluxPSFErr = source->moments->KronFluxErr; 467 source->moments->KronRadiusPSF = source->moments->Mrf; 468 469 psTrace ("psModules.objects", 4, "Mrf: %f KronFlux: %f Mxx: %f Mxy: %f Myy: %f Mxxx: %f Mxxy: %f Mxyy: %f Myyy: %f Mxxxx: %f Mxxxy: %f Mxxyy: %f Mxyyy: %f Mxyyy: %f\n", 470 source->moments->Mrf, source->moments->KronFlux, 471 source->moments->Mxx, source->moments->Mxy, source->moments->Myy, 472 source->moments->Mxxx, source->moments->Mxxy, source->moments->Mxyy, source->moments->Myyy, 473 source->moments->Mxxxx, source->moments->Mxxxy, source->moments->Mxxyy, source->moments->Mxyyy, source->moments->Myyyy); 474 475 psTrace ("psModules.objects", 3, "peak %f %f (%f = %f) Mx: %f My: %f Sum: %f Mxx: %f Mxy: %f Myy: %f sky: %f Npix: %d\n", 476 source->peak->xf, source->peak->yf, source->peak->rawFlux, sqrt(source->peak->detValue), source->moments->Mx, source->moments->My, Sum, source->moments->Mxx, source->moments->Mxy, source->moments->Myy, sky, source->moments->nPixels); 477 478 return(true); 479 } 480 481 bool pmSourceMomentsGetCentroid(pmSource *source, float radius, float sigma, float minSN, psImageMaskType maskVal, float xGuess, float yGuess) { 482 483 // First Pass: calculate the first moments (these are subtracted from the coordinates below) 484 // Sum = SUM (z - sky) 485 // X1 = SUM (x - xc)*(z - sky) 486 // .. etc 487 488 float sky = 0.0; 489 490 float peakPixel = -PS_MAX_F32; 491 psS32 numPixels = 0; 492 float Sum = 0.0; 493 float Var = 0.0; 494 float X1 = 0.0; 495 float Y1 = 0.0; 496 float R2 = PS_SQR(radius); 497 float minSN2 = PS_SQR(minSN); 498 float rsigma2 = 0.5 / PS_SQR(sigma); 499 500 float xPeak = xGuess - source->pixels->col0; // coord of peak in subimage 501 float yPeak = yGuess - source->pixels->row0; // coord of peak in subimage 502 503 // we are guaranteed to have a valid pixel and variance at this location (right? right?) 504 // float weightNorm = source->pixels->data.F32[yPeak][xPeak] / sqrt (source->variance->data.F32[yPeak][xPeak]); 505 // psAssert (isfinite(source->pixels->data.F32[yPeak][xPeak]), "peak must be on valid pixel"); 506 // psAssert (isfinite(source->variance->data.F32[yPeak][xPeak]), "peak must be on valid pixel"); 507 // psAssert (source->variance->data.F32[yPeak][xPeak] > 0, "peak must be on valid pixel"); 508 509 // the moments [Sum(x*f) / Sum(f)] are calculated in pixel index values, and should 510 // not depend on the fractional pixel location of the source. However, the aperture 511 // (radius) and the Gaussian window (sigma) depend subtly on the fractional pixel 512 // position of the expected centroid 513 514 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 515 516 float yDiff = row + 0.5 - yPeak; 517 if (fabs(yDiff) > radius) continue; 300 518 301 519 float *vPix = source->pixels->data.F32[row]; 302 520 float *vWgt = source->variance->data.F32[row]; 303 521 304 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];305 // psImageMaskType *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row];522 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row]; 523 // psImageMaskType *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row]; 306 524 307 525 for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) { … … 315 533 if (isnan(*vPix)) continue; 316 534 317 float xDiff = col - xCM;318 if (fabs(xDiff) > radKouter) continue;319 320 // radKron is just a function of (xDiff, yDiff)321 float r2 = PS_SQR(xDiff) + PS_SQR(yDiff);322 323 float pDiff = *vPix - sky;324 float wDiff = *vWgt;325 326 // skip pixels below specified significance level. this is allowed, but should be327 // avoided -- the over-weights the wings of bright stars compared to those of faint328 // stars.329 if (PS_SQR(pDiff) < minSN2*wDiff) continue;330 331 # define WEIGHTED 1332 # if (WEIGHTED)333 float z = r2 * rsigma2 / 4.0;334 assert (z >= 0.0);335 float weight = exp(-z);336 # endif337 338 float r = sqrt(r2);339 if (r < radKron) {340 # if (WEIGHTED)341 Sum += pDiff*weight;342 Var += wDiff*weight;343 # else344 Sum += pDiff;345 Var += wDiff;346 # endif347 nKronPix ++;348 // if (beVerbose) fprintf (stderr, "mome: %d %d %f %f %f\n", col, row, sky, *vPix, Sum);349 }350 351 // use sigma (fixed by psf) not a radKron based value352 if (r < sigma) {353 SumCore += pDiff;354 VarCore += wDiff;355 nCorePix ++;356 }357 358 if ((r > radKinner) && (r < radKron)) {359 SumInner += pDiff;360 nInner ++;361 }362 if ((r > radKron) && (r < radKouter)) {363 SumOuter += pDiff;364 nOuter ++;365 }366 }367 }368 // *** should I rescale these fluxes by pi R^2 / nNpix?369 source->moments->KronCore = SumCore * M_PI * PS_SQR(sigma) / nCorePix;370 source->moments->KronCoreErr = sqrt(VarCore) * M_PI * PS_SQR(sigma) / nCorePix;371 source->moments->KronFlux = Sum * M_PI * PS_SQR(radKron) / nKronPix;372 source->moments->KronFluxErr = sqrt(Var) * M_PI * PS_SQR(radKron) / nKronPix;373 source->moments->KronFinner = SumInner * M_PI * (PS_SQR(radKron) - PS_SQR(radKinner)) / nInner;374 source->moments->KronFouter = SumOuter * M_PI * (PS_SQR(radKouter) - PS_SQR(radKron)) / nOuter;375 376 // XXX not sure I should save this here...377 source->moments->KronFluxPSF = source->moments->KronFlux;378 source->moments->KronFluxPSFErr = source->moments->KronFluxErr;379 source->moments->KronRadiusPSF = source->moments->Mrf;380 381 psTrace ("psModules.objects", 4, "Mrf: %f KronFlux: %f Mxx: %f Mxy: %f Myy: %f Mxxx: %f Mxxy: %f Mxyy: %f Myyy: %f Mxxxx: %f Mxxxy: %f Mxxyy: %f Mxyyy: %f Mxyyy: %f\n",382 source->moments->Mrf, source->moments->KronFlux,383 source->moments->Mxx, source->moments->Mxy, source->moments->Myy,384 source->moments->Mxxx, source->moments->Mxxy, source->moments->Mxyy, source->moments->Myyy,385 source->moments->Mxxxx, source->moments->Mxxxy, source->moments->Mxxyy, source->moments->Mxyyy, source->moments->Myyyy);386 387 psTrace ("psModules.objects", 3, "peak %f %f (%f = %f) Mx: %f My: %f Sum: %f Mxx: %f Mxy: %f Myy: %f sky: %f Npix: %d\n",388 source->peak->xf, source->peak->yf, source->peak->rawFlux, sqrt(source->peak->detValue), source->moments->Mx, source->moments->My, Sum, source->moments->Mxx, source->moments->Mxy, source->moments->Myy, sky, source->moments->nPixels);389 390 return(true);391 }392 393 bool pmSourceMomentsGetCentroid(pmSource *source, float radius, float sigma, float minSN, psImageMaskType maskVal, float xGuess, float yGuess) {394 395 // First Pass: calculate the first moments (these are subtracted from the coordinates below)396 // Sum = SUM (z - sky)397 // X1 = SUM (x - xc)*(z - sky)398 // .. etc399 400 float sky = 0.0;401 402 float peakPixel = -PS_MAX_F32;403 psS32 numPixels = 0;404 float Sum = 0.0;405 float Var = 0.0;406 float X1 = 0.0;407 float Y1 = 0.0;408 float R2 = PS_SQR(radius);409 float minSN2 = PS_SQR(minSN);410 float rsigma2 = 0.5 / PS_SQR(sigma);411 412 float xPeak = xGuess - source->pixels->col0; // coord of peak in subimage413 float yPeak = yGuess - source->pixels->row0; // coord of peak in subimage414 415 // we are guaranteed to have a valid pixel and variance at this location (right? right?)416 // float weightNorm = source->pixels->data.F32[yPeak][xPeak] / sqrt (source->variance->data.F32[yPeak][xPeak]);417 // psAssert (isfinite(source->pixels->data.F32[yPeak][xPeak]), "peak must be on valid pixel");418 // psAssert (isfinite(source->variance->data.F32[yPeak][xPeak]), "peak must be on valid pixel");419 // psAssert (source->variance->data.F32[yPeak][xPeak] > 0, "peak must be on valid pixel");420 421 // the moments [Sum(x*f) / Sum(f)] are calculated in pixel index values, and should422 // not depend on the fractional pixel location of the source. However, the aperture423 // (radius) and the Gaussian window (sigma) depend subtly on the fractional pixel424 // position of the expected centroid425 426 for (psS32 row = 0; row < source->pixels->numRows ; row++) {427 428 float yDiff = row + 0.5 - yPeak;429 if (fabs(yDiff) > radius) continue;430 431 float *vPix = source->pixels->data.F32[row];432 float *vWgt = source->variance->data.F32[row];433 434 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];435 // psImageMaskType *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row];436 437 for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) {438 if (vMsk) {439 if (*vMsk & maskVal) {440 vMsk++;441 continue;442 }443 vMsk++;444 }445 if (isnan(*vPix)) continue;446 447 535 float xDiff = col + 0.5 - xPeak; 448 536 if (fabs(xDiff) > radius) continue;
Note:
See TracChangeset
for help on using the changeset viewer.
