- Timestamp:
- May 3, 2010, 8:45:22 AM (16 years ago)
- Location:
- branches/simmosaic_branches
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/simmosaic_branches
- Property svn:mergeinfo changed
-
branches/simmosaic_branches/psModules
-
Property svn:mergeinfo
set to (toggle deleted branches)
/trunk/psModules merged eligible /branches/eam_branches/stackphot.20100406/psModules 27623-27653 /branches/pap_delete/psModules 27530-27595
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
branches/simmosaic_branches/psModules/src/camera/pmFPAMaskWeight.c
r24767 r27839 111 111 // psError(PS_ERR_IO, true, "CELL.SATURATION is not set --- unable to set mask.\n"); 112 112 // return false; 113 psWarning("CELL.SATURATION is not set --- completely masking cell.\n");114 saturation = NAN;113 psWarning("CELL.SATURATION is not set --- completely masking cell.\n"); 114 saturation = NAN; 115 115 } 116 116 float bad = psMetadataLookupF32(&mdok, cell->concepts, "CELL.BAD"); // Bad level … … 118 118 // psError(PS_ERR_IO, true, "CELL.BAD is not set --- unable to set mask.\n"); 119 119 // return false; 120 psWarning("CELL.BAD is not set --- completely masking cell.\n");121 bad = NAN;120 psWarning("CELL.BAD is not set --- completely masking cell.\n"); 121 bad = NAN; 122 122 } 123 123 psTrace("psModules.camera", 5, "Saturation: %f, bad: %f\n", saturation, bad); 124 124 125 // if CELL.GAIN or CELL.READNOISE are not set, then the variance will be set to NAN; 125 // if CELL.GAIN or CELL.READNOISE are not set, then the variance will be set to NAN; 126 126 // in this case, we have to set the mask as well 127 127 float gain = psMetadataLookupF32(&mdok, cell->concepts, "CELL.GAIN"); // Cell gain … … 140 140 // completely mask if SATURATION or BAD are invalid 141 141 if (isnan(saturation) || isnan(bad) || isnan(gain) || isnan(readnoise)) { 142 psImageInit(mask, badMask);143 return true;142 psImageInit(mask, badMask); 143 return true; 144 144 } 145 145 … … 230 230 // return false; 231 231 psWarning("CELL.GAIN is not set --- setting variance to NAN\n"); 232 gain = NAN;232 gain = NAN; 233 233 } 234 234 float readnoise = psMetadataLookupF32(&mdok, cell->concepts, "CELL.READNOISE"); // Cell read noise … … 237 237 // return false; 238 238 psWarning("CELL.READNOISE is not set --- setting variance to NAN\n"); 239 readnoise = NAN;239 readnoise = NAN; 240 240 } 241 241 // if we have a non-NAN readnoise, then we need to ensure it has been updated (not necessary if NAN) … … 248 248 if (isnan(gain) || isnan(readnoise)) { 249 249 if (!readout->variance) { 250 // generate the image if needed250 // generate the image if needed 251 251 readout->variance = psImageAlloc(readout->image->numCols, readout->image->numRows, PS_TYPE_F32); 252 252 } 253 // XXX need to set the mask, if defined253 // XXX need to set the mask, if defined 254 254 psImageInit(readout->variance, NAN); 255 return true;255 return true; 256 256 } 257 257 … … 262 262 263 263 // a negative variance is non-sensical. if the image value drops below 1, the variance must be 1. 264 // XXX this calculation is wrong: limit is 1 e-, but this is in DN264 // XXX this calculation is wrong: limit is 1 e-, but this is in DN 265 265 readout->variance = (psImage*)psUnaryOp(readout->variance, readout->variance, "abs"); 266 266 readout->variance = (psImage*)psBinaryOp(readout->variance, readout->variance, "max", … … 276 276 // apply a supplied readnoise map (NOTE: in DN, not electrons): 277 277 if (noiseMap) { 278 psImage *rdVar = (psImage*)psBinaryOp(NULL, (const psPtr) noiseMap, "*", (const psPtr) noiseMap);279 readout->variance = (psImage*)psBinaryOp(readout->variance, readout->variance, "+", rdVar);280 psFree (rdVar);278 psImage *rdVar = (psImage*)psBinaryOp(NULL, (const psPtr) noiseMap, "*", (const psPtr) noiseMap); 279 readout->variance = (psImage*)psBinaryOp(readout->variance, readout->variance, "+", rdVar); 280 psFree (rdVar); 281 281 } else { 282 readout->variance = (psImage*)psBinaryOp(readout->variance, readout->variance, "+", psScalarAlloc(readnoise*readnoise/gain/gain, PS_TYPE_F32));282 readout->variance = (psImage*)psBinaryOp(readout->variance, readout->variance, "+", psScalarAlloc(readnoise*readnoise/gain/gain, PS_TYPE_F32)); 283 283 } 284 284 … … 362 362 363 363 364 bool pmReadoutVarianceRenorm Pixels(const pmReadout *readout, psImageMaskType maskVal,365 psStatsOptions meanStat, psStatsOptions stdevStat, psRandom *rng)364 bool pmReadoutVarianceRenormalise(const pmReadout *readout, psImageMaskType maskVal, 365 int sample, float minValid, float maxValid) 366 366 { 367 367 PM_ASSERT_READOUT_NON_NULL(readout, false); … … 370 370 371 371 psImage *image = readout->image, *mask = readout->mask, *variance = readout->variance; // Readout parts 372 373 if (!psMemIncrRefCounter(rng)) { 374 rng = psRandomAlloc(PS_RANDOM_TAUS); 375 } 376 377 psStats *varianceStats = psStatsAlloc(meanStat);// Statistics for mean 378 if (!psImageBackground(varianceStats, NULL, variance, mask, maskVal, rng)) { 379 psError(PS_ERR_UNKNOWN, false, "Unable to measure mean variance for image"); 380 psFree(varianceStats); 381 psFree(rng); 382 return false; 383 } 384 float meanVariance = varianceStats->robustMedian; // Mean variance 385 psFree(varianceStats); 386 387 psStats *imageStats = psStatsAlloc(stdevStat);// Statistics for mean 388 if (!psImageBackground(imageStats, NULL, image, mask, maskVal, rng)) { 389 psError(PS_ERR_UNKNOWN, false, "Unable to measure stdev of image"); 390 psFree(imageStats); 391 psFree(rng); 392 return false; 393 } 394 float stdevImage = imageStats->robustStdev; // Standard deviation of image 395 psFree(imageStats); 396 psFree(rng); 397 398 float correction = PS_SQR(stdevImage) / meanVariance; // Correction to take variance to what it should be 399 psLogMsg("psModules.camera", PS_LOG_INFO, "Renormalising variance map by %f", correction); 400 psBinaryOp(variance, variance, "*", psScalarAlloc(correction, PS_TYPE_F32)); 401 402 return true; 403 } 404 405 406 bool pmReadoutVarianceRenormPhot(const pmReadout *readout, psImageMaskType maskVal, int num, float width, 407 psStatsOptions meanStat, psStatsOptions stdevStat, psRandom *rng) 408 { 409 PM_ASSERT_READOUT_NON_NULL(readout, false); 410 PM_ASSERT_READOUT_IMAGE(readout, false); 411 PM_ASSERT_READOUT_VARIANCE(readout, false); 412 413 if (!psMemIncrRefCounter(rng)) { 414 rng = psRandomAlloc(PS_RANDOM_TAUS); 415 } 416 417 psImage *image = readout->image, *mask = readout->mask, *variance = readout->variance; // Readout images 418 419 // Measure background 420 psStats *bgStats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);// Statistics for background 421 if (!psImageBackground(bgStats, NULL, image, mask, maskVal, rng)) { 422 psError(PS_ERR_UNKNOWN, false, "Unable to measure background for image"); 423 psFree(bgStats); 424 psFree(rng); 425 return false; 426 } 427 float bgMean = bgStats->robustMedian; // Background level 428 float bgNoise = bgStats->robustStdev; // Background standard deviation 429 psFree(bgStats); 430 psTrace("psModules.camera", 5, "Background is %f +/- %f\n", bgMean, bgNoise); 431 432 433 // Construct kernels for flux measurement 434 // We use N(0,width) and N(0,width/sqrt(2)) kernels, following psphotSignificanceImage. 435 float sigFactor = 4.0 * M_PI * PS_SQR(width); // Factor for conversion from im/wt ratio to significance 436 int size = RENORM_NUM_SIGMA, fullSize = 2 * size + 1; // Half-size and full size of Gaussian 437 psVector *gauss = psVectorAlloc(fullSize, PS_TYPE_F32); // Gaussian for weighting 438 psVector *gauss2 = psVectorAlloc(fullSize, PS_TYPE_F32); // Gaussian squared 439 for (int i = 0, x = -size; i < fullSize; i++, x++) { 440 gauss->data.F32[i] = expf(-0.5 * PS_SQR(x) / PS_SQR(width)); 441 gauss2->data.F32[i] = expf(-PS_SQR(x) / PS_SQR(width)); 442 } 443 444 // Size of image 445 int numCols = image->numCols, numRows = image->numRows; // Size of images 446 int xSize = numCols - fullSize, ySize = numRows - fullSize; // Size of consideration 447 int xOffset = size, yOffset = size; // Offset to region of consideration 448 449 // Measure fluxes 450 float peakFlux = RENORM_PEAK * bgNoise; // Peak flux for fake sources 451 psVector *noise = psVectorAlloc(num, PS_TYPE_F32); // Measurements of the noise 452 psVector *source = psVectorAlloc(num, PS_TYPE_F32); // Measurements of fake sources 453 psVector *guess = psVectorAlloc(num, PS_TYPE_F32); // Guess at significance 454 psVector *photMask = psVectorAlloc(num, PS_TYPE_VECTOR_MASK); // Mask for fluxes 455 for (int i = 0; i < num; i++) { 456 // Coordinates of interest 457 int xPix = psRandomUniform(rng) * xSize + xOffset + 0.5; 458 int yPix = psRandomUniform(rng) * ySize + yOffset + 0.5; 459 psAssert(xPix - size >= 0 && xPix + size < numCols && 460 yPix - size >= 0 && yPix + size < numRows, 461 "Bad pixel position: %d,%d", xPix, yPix); 462 463 // Weighted aperture photometry 464 // This has the same effect as smoothing the image by the window function 465 float sumNoise = 0.0; // Sum for noise measurement 466 float sumSource = 0.0; // Sum for source measurement 467 float sumVariance = 0.0; // Sum for variance measurement 468 float sumGauss = 0.0, sumGauss2 = 0.0; // Sums of Gaussian kernels 469 for (int v = 0, y = yPix - size; v < fullSize; v++, y++) { 470 float xSumNoise = 0.0; // Sum for noise measurement in x 471 float xSumSource = 0.0; // Sum for source measurement in x 472 float xSumVariance = 0.0; // Sum for variance measurement in x 473 float xSumGauss = 0.0, xSumGauss2 = 0.0; // Sums of Gaussian kernels in x 474 float yGauss = gauss->data.F32[v]; // Value of Gaussian in y 475 for (int u = 0, x = xPix - size; u < fullSize; u++, x++) { 476 if (mask && mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal) { 372 int numCols = image->numCols, numRows = image->numRows; // Size of image 373 374 int xMin, xMax, yMin, yMax; // Bounds of image 375 if (mask) { 376 xMin = numCols; 377 xMax = 0; 378 yMin = numRows; 379 yMax = 0; 380 for (int y = 0; y < numRows; y++) { 381 for (int x = 0; x < numCols; x++) { 382 if (mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal) { 477 383 continue; 478 384 } 479 float value = image->data.F32[y][x] - bgMean; // Value of image 480 float xGauss = gauss->data.F32[u]; // Value of Gaussian in x 481 float xGauss2 = gauss2->data.F32[u]; // Value of Gaussian^2 in x 482 xSumNoise += value * xGauss; 483 xSumSource += (value + peakFlux * xGauss * yGauss) * xGauss; 484 xSumVariance += variance->data.F32[y][x] * xGauss2; 485 xSumGauss += xGauss; 486 xSumGauss2 += xGauss2; 487 } 488 float yGauss2 = gauss2->data.F32[v]; // Value of Gaussian^2 in y 489 sumNoise += xSumNoise * yGauss; 490 sumSource += xSumSource * yGauss; 491 sumVariance += xSumVariance * yGauss2; 492 sumGauss += xSumGauss * yGauss; 493 sumGauss2 += xSumGauss2 * yGauss2; 494 } 495 496 photMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = ((isfinite(sumNoise) && isfinite(sumSource) && 497 isfinite(sumVariance) && sumGauss > 0 && sumGauss2 > 0) ? 498 0 : 0xFF); 499 500 float smoothImageNoise = sumNoise / sumGauss; // Value of smoothed image pixel for noise 501 float smoothImageSource = sumSource / sumGauss; // Value of smoothed image pixel for source 502 float smoothVariance = sumVariance / sumGauss2; // Value of smoothed variance pixel 503 504 noise->data.F32[i] = smoothImageNoise; 505 source->data.F32[i] = smoothImageSource; 506 guess->data.F32[i] = (sumSource > 0) ? sigFactor * PS_SQR(smoothImageSource) / smoothVariance : 0.0; 507 psTrace("psModules.camera", 10, "Flux %d (%d,%d): %f, %f, %f\n", 508 i, xPix, yPix, smoothImageNoise, smoothImageSource, smoothVariance); 509 } 510 psFree(gauss); 511 psFree(gauss2); 512 psFree(rng); 513 514 // Standard deviation of fluxes gives us the real significance 515 psStats *stdevStats = psStatsAlloc(stdevStat); // Statistics 516 if (!psVectorStats(stdevStats, noise, NULL, photMask, 0xFF)) { 517 psError(PS_ERR_UNKNOWN, false, "Unable to measure standard deviation of fluxes"); 518 psFree(stdevStats); 519 psFree(noise); 520 psFree(source); 521 psFree(guess); 522 psFree(photMask); 385 xMin = PS_MIN(xMin, x); 386 xMax = PS_MAX(xMax, x); 387 yMin = PS_MIN(yMin, y); 388 yMax = PS_MAX(yMax, y); 389 } 390 } 391 } else { 392 xMin = 0; 393 xMax = numCols; 394 yMin = 0; 395 yMax = numRows; 396 } 397 398 int xNum = xMax - xMin, yNum = yMax - yMin; // Number of pixels 399 400 int numPix = xNum * yNum; // Number of pixels 401 int num = PS_MIN(sample, numPix); // Number we care about 402 psVector *signoise = psVectorAllocEmpty(num, PS_TYPE_F32); // Signal-to-noise values 403 404 if (num >= numPix) { 405 // We have an image smaller than Nsubset, so just loop over the image pixels 406 int index = 0; // Index for vector 407 for (int y = yMin; y < yMax; y++) { 408 for (int x = xMin; x < xMax; x++) { 409 if ((mask && mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal) || 410 !isfinite(image->data.F32[y][x]) || !isfinite(variance->data.F32[y][x])) { 411 continue; 412 } 413 414 signoise->data.F32[index] = image->data.F32[y][x] / sqrtf(variance->data.F32[y][x]); 415 index++; 416 } 417 } 418 signoise->n = index; 419 } else { 420 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator 421 int index = 0; // Index for vector 422 for (long i = 0; i < num; i++) { 423 // Pixel coordinates 424 int pixel = numPix * psRandomUniform(rng); 425 int x = xMin + pixel % xNum; 426 int y = yMin + pixel / xNum; 427 428 if ((mask && mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal) || 429 !isfinite(image->data.F32[y][x]) || !isfinite(variance->data.F32[y][x])) { 430 continue; 431 } 432 433 signoise->data.F32[index] = image->data.F32[y][x] / sqrtf(variance->data.F32[y][x]); 434 index++; 435 } 436 signoise->n = index; 437 psFree(rng); 438 } 439 440 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_STDEV); // Statistics 441 442 if (!psVectorStats(stats, signoise, NULL, NULL, 0)) { 443 psError(PS_ERR_UNKNOWN, false, "Unable to measure statistics on S/N image"); 444 psFree(signoise); 523 445 return false; 524 446 } 525 float stdev = psStatsGetValue(stdevStats, stdevStat); // Standard deviation of fluxes 526 psFree(stdevStats); 527 psFree(noise); 528 psTrace("psModules.camera", 5, "Standard deviation of fluxes is %f\n", stdev); 529 530 // Ratio of measured significance to guessed significance 531 psVector *ratio = psVectorAlloc(num, PS_TYPE_F32); // Ratio of measured to guess 532 for (int i = 0; i < num; i++) { 533 float measuredSig = PS_SQR(source->data.F32[i] / stdev); // Measured significance 534 ratio->data.F32[i] = measuredSig / guess->data.F32[i]; 535 if (guess->data.F32[i] <= 0.0 || source->data.F32[i] <= 0.0 || !isfinite(ratio->data.F32[i])) { 536 photMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = 0xFF; 537 } 538 psTrace("psModules.camera", 9, "Ratio %d: %f, %f, %f\n", 539 i, guess->data.F32[i], measuredSig, ratio->data.F32[i]); 540 } 541 psFree(source); 542 psFree(guess); 543 544 psStats *meanStats = psStatsAlloc(meanStat | stdevStat); // Statistics 545 if (!psVectorStats(meanStats, ratio, NULL, photMask, 0xFF)) { 546 psError(PS_ERR_UNKNOWN, false, "Unable to measure mean ratio"); 547 psFree(meanStats); 548 psFree(ratio); 549 psFree(photMask); 447 psFree(signoise); 448 449 float covar = sqrtf(psImageCovarianceFactor(readout->covariance)); // Covariance factor 450 float correction = stats->robustStdev / covar; // Correction factor 451 psFree(stats); 452 psLogMsg("psModules.camera", PS_LOG_DETAIL, "Variance renormalisation factor is %f", correction); 453 454 // Check valid range of correction factor 455 if ((isfinite(minValid) && correction < minValid) || (isfinite(maxValid) && correction > maxValid)) { 456 psError(PS_ERR_UNKNOWN, true, "Variance renormalisation is outside valid range: %f vs %f:%f --- no correction made", correction, minValid, maxValid); 457 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, PM_READOUT_ANALYSIS_RENORM, 0, "Renormalisation of variance", PS_SQR(correction)); 550 458 return false; 551 459 } 552 float meanRatio = psStatsGetValue(meanStats, meanStat); // Mean ratio 553 psTrace("psModules.camera", 5, "Mean significance ratio is %f +/- %f\n", 554 meanRatio, psStatsGetValue(meanStats, stdevStat)); 555 psFree(meanStats); 556 psFree(ratio); 557 psFree(photMask); 558 559 psLogMsg("psModules.camera", PS_LOG_INFO, "Renormalising variance map by %f", meanRatio); 560 psBinaryOp(variance, variance, "*", psScalarAlloc(meanRatio, PS_TYPE_F32)); 561 562 return true; 563 } 564 565 566 bool pmReadoutVarianceRenorm(const pmReadout *readout, psImageMaskType maskVal, psStatsOptions meanStat, 567 psStatsOptions stdevStat, int width, psRandom *rng) 568 { 569 PM_ASSERT_READOUT_NON_NULL(readout, false); 570 PM_ASSERT_READOUT_IMAGE(readout, false); 571 PM_ASSERT_READOUT_VARIANCE(readout, false); 572 PS_ASSERT_INT_POSITIVE(width, false); 573 574 if (!psMemIncrRefCounter(rng)) { 575 rng = psRandomAlloc(PS_RANDOM_TAUS); 576 } 577 578 psImage *image = readout->image, *mask = readout->mask, *variance = readout->variance; // Readout images 579 int numCols = image->numCols, numRows = image->numRows; // Size of images 580 int xNum = numCols / width + 1, yNum = numRows / width + 1; // Number of renormalisation regions 581 float xSize = numCols / (float)xNum, ySize = numRows / (float)yNum; // Size of renormalisation regions 582 583 psStats *meanStats = psStatsAlloc(meanStat), *stdevStats = psStatsAlloc(stdevStat); // Statistics 584 psVector *buffer = NULL; 585 586 for (int j = 0; j < yNum; j++) { 587 // Bounds in y 588 int yMin = j * ySize; 589 int yMax = (j + 1) * ySize; 590 for (int i = 0; i < xNum; i++) { 591 // Bounds in x 592 int xMin = i * xSize; 593 int xMax = (i + 1) * xSize; 594 595 psRegion region = psRegionSet(xMin, xMax, yMin, yMax); // Region of interest 596 psImage *subImage = psImageSubset(image, region); // Sub-image of the image pixels 597 psImage *subVariance = psImageSubset(variance, region); // Sub image of the variance pixels 598 psImage *subMask = mask ? psImageSubset(mask, region) : NULL; // Sub-image of the mask pixels 599 600 if (!psImageBackground(stdevStats, &buffer, subImage, subMask, maskVal, rng) || 601 !psImageBackground(meanStats, &buffer, subVariance, subMask, maskVal, rng)) { 602 // Nothing we can do about it, but don't want to keel over and die, so do our best to flag it. 603 psString regionStr = psRegionToString(region); // String with region 604 psWarning("Unable to measure statistics over %s", regionStr); 605 psFree(regionStr); 606 psErrorClear(); 607 psImageInit(subVariance, NAN); 608 if (subMask) { 609 psImageInit(subMask, maskVal); 610 } 611 } else { 612 double meanVar = psStatsGetValue(meanStats, meanStat); // Mean of variance map 613 double stdev = psStatsGetValue(stdevStats, stdevStat); // Standard deviation of image 614 psTrace("psModules.camera", 3, 615 "Region [%d:%d,%d:%d] has variance %lf, but mean of variance map is %lf\n", 616 xMin, xMax, yMin, yMax, PS_SQR(stdev), meanVar); 617 psBinaryOp(subVariance, subVariance, "*", psScalarAlloc(PS_SQR(stdev) / meanVar, PS_TYPE_F32)); 618 } 619 620 psFree(subImage); 621 psFree(subVariance); 622 psFree(subMask); 623 } 624 } 625 psFree(meanStats); 626 psFree(stdevStats); 627 psFree(rng); 628 psFree(buffer); 629 630 return true; 631 } 460 461 psImage *subImage = psImageSubset(variance, psRegionSet(xMin, xMax, yMin, yMax)); // Smaller image 462 psBinaryOp(subImage, subImage, "*", psScalarAlloc(PS_SQR(correction), PS_TYPE_F32)); 463 psFree(subImage); 464 465 pmHDU *hdu = pmHDUFromReadout(readout); // HDU for readout 466 if (hdu) { 467 psString history = NULL; 468 psStringAppend(&history, "Rescaled variance by %6.4f (stdev by %6.4f)", 469 PS_SQR(correction), correction); 470 psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, NULL, history); 471 psFree(history); 472 } 473 474 return psMetadataAddF32(readout->analysis, PS_LIST_TAIL, PM_READOUT_ANALYSIS_RENORM, 0, 475 "Renormalisation of variance", PS_SQR(correction)); 476 } 477 632 478 633 479
Note:
See TracChangeset
for help on using the changeset viewer.
