Changeset 20486
- Timestamp:
- Oct 31, 2008, 11:50:16 AM (18 years ago)
- Location:
- trunk/psModules/src/camera
- Files:
-
- 2 edited
-
pmFPAMaskWeight.c (modified) (2 diffs)
-
pmFPAMaskWeight.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/camera/pmFPAMaskWeight.c
r20307 r20486 14 14 15 15 #define PIXELS_BUFFER 100 // Size of buffer for allocating pixel lists 16 #define RENORM_NUM_SIGMA 3.0 // Number of standard deviations for Gaussian kernel 17 #define RENORM_PEAK 4.0 // Number of standard deviations of noise for fake source peak flux 18 16 19 17 20 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// … … 315 318 316 319 return success; 320 } 321 322 323 bool pmReadoutWeightRenormPixels(const pmReadout *readout, psMaskType maskVal, 324 psStatsOptions meanStat, psStatsOptions stdevStat, psRandom *rng) 325 { 326 PM_ASSERT_READOUT_NON_NULL(readout, false); 327 PM_ASSERT_READOUT_IMAGE(readout, false); 328 PM_ASSERT_READOUT_WEIGHT(readout, false); 329 330 psImage *image = readout->image, *mask = readout->mask, *weight = readout->weight; // Readout parts 331 332 if (!psMemIncrRefCounter(rng)) { 333 rng = psRandomAlloc(PS_RANDOM_TAUS, 0); 334 } 335 336 psStats *weightStats = psStatsAlloc(meanStat);// Statistics for mean 337 if (!psImageBackground(weightStats, NULL, weight, mask, maskVal, rng)) { 338 psError(PS_ERR_UNKNOWN, false, "Unable to measure mean weight for image"); 339 psFree(weightStats); 340 psFree(rng); 341 return false; 342 } 343 float meanVariance = weightStats->robustMedian; // Mean variance 344 psFree(weightStats); 345 346 psStats *imageStats = psStatsAlloc(stdevStat);// Statistics for mean 347 if (!psImageBackground(imageStats, NULL, image, mask, maskVal, rng)) { 348 psError(PS_ERR_UNKNOWN, false, "Unable to measure stdev of image"); 349 psFree(imageStats); 350 psFree(rng); 351 return false; 352 } 353 float stdevImage = imageStats->robustStdev; // Standard deviation of image 354 psFree(imageStats); 355 psFree(rng); 356 357 float correction = PS_SQR(stdevImage) / meanVariance; // Correction to take variance to what it should be 358 psLogMsg("psModules.camera", PS_LOG_INFO, "Renormalising weight map by %f", correction); 359 psBinaryOp(weight, weight, "*", psScalarAlloc(correction, PS_TYPE_F32)); 360 361 return true; 362 } 363 364 365 bool pmReadoutWeightRenormPhot(const pmReadout *readout, psMaskType maskVal, int num, float width, 366 psStatsOptions meanStat, psStatsOptions stdevStat, psRandom *rng) 367 { 368 PM_ASSERT_READOUT_NON_NULL(readout, false); 369 PM_ASSERT_READOUT_IMAGE(readout, false); 370 PM_ASSERT_READOUT_WEIGHT(readout, false); 371 372 if (!psMemIncrRefCounter(rng)) { 373 rng = psRandomAlloc(PS_RANDOM_TAUS, 0); 374 } 375 376 psImage *image = readout->image, *mask = readout->mask, *weight = readout->weight; // Readout images 377 378 // Measure background 379 psStats *bgStats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);// Statistics for background 380 if (!psImageBackground(bgStats, NULL, image, mask, maskVal, rng)) { 381 psError(PS_ERR_UNKNOWN, false, "Unable to measure background for image"); 382 psFree(bgStats); 383 psFree(rng); 384 return false; 385 } 386 float bgMean = bgStats->robustMedian; // Background level 387 float bgNoise = bgStats->robustStdev; // Background standard deviation 388 psFree(bgStats); 389 psTrace("psModules.camera", 5, "Background is %f +/- %f\n", bgMean, bgNoise); 390 391 392 // Construct kernels for flux measurement 393 // We use N(0,width) and N(0,width/sqrt(2)) kernels, following psphotSignificanceImage. 394 float sigFactor = 4.0 * M_PI * PS_SQR(width); // Factor for conversion from im/wt ratio to significance 395 int size = RENORM_NUM_SIGMA, fullSize = 2 * size + 1; // Half-size and full size of Gaussian 396 psVector *gauss = psVectorAlloc(fullSize, PS_TYPE_F32); // Gaussian for weighting 397 psVector *gauss2 = psVectorAlloc(fullSize, PS_TYPE_F32); // Gaussian squared 398 for (int i = 0, x = -size; i < fullSize; i++, x++) { 399 gauss->data.F32[i] = expf(-0.5 * PS_SQR(x) / PS_SQR(width)); 400 gauss2->data.F32[i] = expf(-PS_SQR(x) / PS_SQR(width)); 401 } 402 403 // Size of image 404 int numCols = image->numCols, numRows = image->numRows; // Size of images 405 int xSize = numCols - fullSize, ySize = numRows - fullSize; // Size of consideration 406 int xOffset = size, yOffset = size; // Offset to region of consideration 407 408 // Measure fluxes 409 float peakFlux = RENORM_PEAK * bgNoise; // Peak flux for fake sources 410 psVector *noise = psVectorAlloc(num, PS_TYPE_F32); // Measurements of the noise 411 psVector *source = psVectorAlloc(num, PS_TYPE_F32); // Measurements of fake sources 412 psVector *guess = psVectorAlloc(num, PS_TYPE_F32); // Guess at significance 413 psVector *photMask = psVectorAlloc(num, PS_TYPE_MASK); // Mask for fluxes 414 for (int i = 0; i < num; i++) { 415 // Coordinates of interest 416 int xPix = psRandomUniform(rng) * xSize + xOffset; 417 int yPix = psRandomUniform(rng) * ySize + yOffset; 418 psAssert(xPix - size >= 0 && xPix + size < numCols && 419 yPix - size >= 0 && yPix + size > numRows, 420 "Bad pixel position"); 421 422 // Weighted aperture photometry 423 // This has the same effect as smoothing the image by the window function 424 float sumNoise = 0.0; // Sum for noise measurement 425 float sumSource = 0.0; // Sum for source measurement 426 float sumWeight = 0.0; // Sum for weight measurement 427 float sumGauss = 0.0, sumGauss2 = 0.0; // Sums of Gaussian kernels 428 for (int v = 0, y = yPix - size; v < fullSize; v++, y++) { 429 float xSumNoise = 0.0; // Sum for noise measurement in x 430 float xSumSource = 0.0; // Sum for source measurement in x 431 float xSumWeight = 0.0; // Sum for weight measurement in x 432 float xSumGauss = 0.0, xSumGauss2 = 0.0; // Sums of Gaussian kernels in x 433 float yGauss = peakFlux * gauss->data.F32[v]; // Value of Gaussian in y 434 for (int u = 0, x = xPix - size; u < fullSize; u++, x++) { 435 if (mask && mask->data.PS_TYPE_MASK_DATA[y][x] & maskVal) { 436 continue; 437 } 438 float value = image->data.F32[y][x] - bgMean; // Value of image 439 float xGauss = gauss->data.F32[u]; // Value of Gaussian in x 440 float xGauss2 = gauss2->data.F32[u]; // Value of Gaussian^2 in x 441 xSumNoise += value * xGauss; 442 xSumSource += (value + xGauss * yGauss) * xGauss; 443 xSumWeight += weight->data.F32[y][x] * xGauss2; 444 xSumGauss += xGauss; 445 xSumGauss2 += xGauss2; 446 } 447 float yGauss2 = gauss2->data.F32[v]; // Value of Gaussian^2 in y 448 sumNoise += xSumNoise * yGauss; 449 sumSource += xSumSource * yGauss; 450 sumWeight += xSumWeight * yGauss2; 451 sumGauss += xSumGauss * yGauss; 452 sumGauss2 += xSumGauss2 * yGauss2; 453 } 454 455 float weightValue = sumWeight / sumGauss2; // Value of convolved weight 456 photMask->data.PS_TYPE_MASK_DATA[i] = ((isfinite(sumNoise) && isfinite(sumSource) && 457 isfinite(weightValue) && sumGauss > 0 && sumGauss2 > 0) ? 458 0 : 0xFF); 459 460 noise->data.F32[i] = sumNoise / sumGauss; 461 source->data.F32[i] = sumSource / sumGauss; 462 guess->data.F32[i] = (sumSource > 0) ? sigFactor * PS_SQR(sumSource) / sumWeight * sumGauss2 : 0.0; 463 psTrace("psModules.camera", 10, "Flux %d (%d,%d): %f, %f, %f\n", 464 i, xPix, yPix, source->data.F32[i], noise->data.F32[i], guess->data.F32[i]); 465 } 466 psFree(gauss); 467 psFree(gauss2); 468 psFree(rng); 469 470 // Standard deviation of fluxes gives us the real significance 471 psStats *stdevStats = psStatsAlloc(stdevStat); // Statistics 472 if (!psVectorStats(stdevStats, noise, NULL, photMask, 0xFF)) { 473 psError(PS_ERR_UNKNOWN, false, "Unable to measure standard deviation of fluxes"); 474 psFree(stdevStats); 475 psFree(noise); 476 psFree(source); 477 psFree(guess); 478 psFree(photMask); 479 return false; 480 } 481 float stdev = psStatsGetValue(stdevStats, stdevStat); // Stadard deviation of fluxes 482 psFree(stdevStats); 483 psFree(noise); 484 psTrace("psModules.camera", 5, "Standard deviation of fluxes is %f\n", stdev); 485 486 // Ratio of measured significance to guessed significance 487 psVector *ratio = psVectorAlloc(num, PS_TYPE_F32); // Ratio of measured to guess 488 for (int i = 0; i < num; i++) { 489 float measuredSig = PS_SQR(source->data.F32[i] / stdev); // Measured significance 490 if (source->data.F32[i] <= 0.0) { 491 photMask->data.PS_TYPE_MASK_DATA[i] = 0xFF; 492 } 493 ratio->data.F32[i] = measuredSig / guess->data.F32[i]; 494 } 495 psFree(source); 496 psFree(guess); 497 498 psStats *meanStats = psStatsAlloc(meanStat | stdevStat); // Statistics 499 if (!psVectorStats(meanStats, ratio, NULL, photMask, 0xFF)) { 500 psError(PS_ERR_UNKNOWN, false, "Unable to measure mean ratio"); 501 psFree(meanStats); 502 psFree(ratio); 503 psFree(photMask); 504 return false; 505 } 506 float meanRatio = psStatsGetValue(meanStats, meanStat); // Mean ratio 507 psTrace("psModules.camera", 5, "Mean significance ratio is %f +/- %f\n", 508 meanRatio, psStatsGetValue(meanStats, stdevStat)); 509 psFree(meanStats); 510 psFree(ratio); 511 psFree(photMask); 512 513 psLogMsg("psModules.camera", PS_LOG_INFO, "Renormalising weight map by %f", meanRatio); 514 psBinaryOp(weight, weight, "*", psScalarAlloc(meanRatio, PS_TYPE_F32)); 515 516 return true; 317 517 } 318 518 -
trunk/psModules/src/camera/pmFPAMaskWeight.h
r19163 r20486 5 5 * @author Eugene Magnier, IfA 6 6 * 7 * @version $Revision: 1.1 5$ $Name: not supported by cvs2svn $8 * @date $Date: 2008- 08-22 22:25:22$7 * @version $Revision: 1.16 $ $Name: not supported by cvs2svn $ 8 * @date $Date: 2008-10-31 21:50:16 $ 9 9 * Copyright 2005-2006 Institute for Astronomy, University of Hawaii 10 10 */ … … 93 93 ); 94 94 95 /// Renormalise the weight map to match the actual pixel variance 96 /// 97 /// The weight (variance) map is adjusted so that the mean matches the actual pixel variance in the image 98 bool pmReadoutWeightRenormPixels( 99 const pmReadout *readout, ///< Readout to normalise 100 psMaskType maskVal, ///< Value to mask 101 psStatsOptions meanStat, ///< Statistic to measure the mean (of the variance map) 102 psStatsOptions stdevStat, ///< Statistic to measure the stdev (of the image) 103 psRandom *rng ///< Random number generator 104 ); 105 106 /// Renormalise the weight map to match the actual photometry variance 107 /// 108 /// The weight (variance) map is adjusted so that the actual significance of fake sources matches the 109 /// guestimated significance 110 bool pmReadoutWeightRenormPhot( 111 const pmReadout *readout, ///< Readout to normalise 112 psMaskType maskVal, ///< Value to mask 113 int num, ///< Number of instances to measure over the image 114 float width, ///< Photometry width 115 psStatsOptions meanStat, ///< Statistic to measure the mean 116 psStatsOptions stdevStat, ///< Statistic to measure the stdev 117 psRandom *rng ///< Random number generator 118 ); 119 95 120 /// Renormalise the weight map to match the actual variance 96 121 ///
Note:
See TracChangeset
for help on using the changeset viewer.
