Changeset 25766 for branches/eam_branches/20090820/psModules/src/camera
- Timestamp:
- Oct 2, 2009, 5:10:19 PM (17 years ago)
- Location:
- branches/eam_branches/20090820
- Files:
-
- 9 edited
-
. (modified) (1 prop)
-
psModules/src/camera/pmFPA.h (modified) (1 diff)
-
psModules/src/camera/pmFPAMaskWeight.c (modified) (10 diffs)
-
psModules/src/camera/pmFPAMaskWeight.h (modified) (1 diff)
-
psModules/src/camera/pmFPAMosaic.c (modified) (13 diffs)
-
psModules/src/camera/pmFPARead.c (modified) (1 diff)
-
psModules/src/camera/pmHDUGenerate.c (modified) (3 diffs)
-
psModules/src/camera/pmReadoutFake.c (modified) (7 diffs, 1 prop)
-
psModules/src/camera/pmReadoutFake.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/20090820
- Property svn:mergeinfo changed
-
branches/eam_branches/20090820/psModules/src/camera/pmFPA.h
r21363 r25766 48 48 psPlaneTransform *toTPA; ///< Transformation from focal plane to tangent plane, or NULL 49 49 psProjection *toSky; ///< Projection from tangent plane to sky, or NULL 50 bool wcsCDkeys; 50 51 // Information 51 52 psMetadata *concepts; ///< FPA-level concepts -
branches/eam_branches/20090820/psModules/src/camera/pmFPAMaskWeight.c
r24767 r25766 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); … … 371 371 psImage *image = readout->image, *mask = readout->mask, *variance = readout->variance; // Readout parts 372 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) { 373 int numCols = image->numCols, numRows = image->numRows; // Size of image 374 int numPix = numCols * numRows; // Number of pixels 375 int num = PS_MAX(sample, numPix); // Number we care about 376 psVector *signoise = psVectorAllocEmpty(num, PS_TYPE_F32); // Signal-to-noise values 377 378 if (num >= numPix) { 379 // We have an image smaller than Nsubset, so just loop over the image pixels 380 int index = 0; // Index for vector 381 for (int y = 0; y < numRows; y++) { 382 for (int x = 0; x < numCols; x++) { 383 if ((mask && mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal) || 384 !isfinite(image->data.F32[y][x]) || !isfinite(variance->data.F32[y][x])) { 477 385 continue; 478 386 } 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); 387 388 signoise->data.F32[index] = image->data.F32[y][x] / sqrtf(variance->data.F32[y][x]); 389 index++; 390 } 391 } 392 signoise->n = index; 393 } else { 394 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator 395 int index = 0; // Index for vector 396 for (long i = 0; i < num; i++) { 397 // Pixel coordinates 398 int pixel = numPix * psRandomUniform(rng); 399 int x = pixel % numCols; 400 int y = pixel / numCols; 401 402 if ((mask && mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal) || 403 !isfinite(image->data.F32[y][x]) || !isfinite(variance->data.F32[y][x])) { 404 continue; 405 } 406 407 signoise->data.F32[index] = image->data.F32[y][x] / sqrtf(variance->data.F32[y][x]); 408 index++; 409 } 410 signoise->n = index; 411 psFree(rng); 412 } 413 414 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_STDEV); // Statistics 415 416 if (!psVectorStats(stats, signoise, NULL, NULL, 0)) { 417 psError(PS_ERR_UNKNOWN, false, "Unable to measure statistics on S/N image"); 418 psFree(signoise); 523 419 return false; 524 420 } 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); 550 return false; 551 } 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)); 421 psFree(signoise); 422 423 float covar = sqrtf(psImageCovarianceFactor(readout->covariance)); // Covariance factor 424 float correction = stats->robustStdev / covar; // Correction factor 425 psFree(stats); 426 psLogMsg("psModules.camera", PS_LOG_DETAIL, "Variance renormalisation factor is %f", correction); 427 428 // Check valid range of correction factor 429 if ((isfinite(minValid) && correction < minValid) || (isfinite(maxValid) && correction > maxValid)) { 430 psWarning("Variance renormalisation is outside valid range: %f vs %f:%f --- no correction made", 431 correction, minValid, maxValid); 432 return true; 433 } 434 435 psBinaryOp(variance, variance, "*", psScalarAlloc(PS_SQR(correction), PS_TYPE_F32)); 436 437 pmHDU *hdu = pmHDUFromReadout(readout); // HDU for readout 438 if (hdu) { 439 psString history = NULL; 440 psStringAppend(&history, "Rescaled variance by %6.4f (stdev by %6.4f)", 441 PS_SQR(correction), correction); 442 psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, NULL, history); 443 psFree(history); 444 } 561 445 562 446 return true; 563 447 } 564 448 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 images579 int numCols = image->numCols, numRows = image->numRows; // Size of images580 int xNum = numCols / width + 1, yNum = numRows / width + 1; // Number of renormalisation regions581 float xSize = numCols / (float)xNum, ySize = numRows / (float)yNum; // Size of renormalisation regions582 583 psStats *meanStats = psStatsAlloc(meanStat), *stdevStats = psStatsAlloc(stdevStat); // Statistics584 psVector *buffer = NULL;585 586 for (int j = 0; j < yNum; j++) {587 // Bounds in y588 int yMin = j * ySize;589 int yMax = (j + 1) * ySize;590 for (int i = 0; i < xNum; i++) {591 // Bounds in x592 int xMin = i * xSize;593 int xMax = (i + 1) * xSize;594 595 psRegion region = psRegionSet(xMin, xMax, yMin, yMax); // Region of interest596 psImage *subImage = psImageSubset(image, region); // Sub-image of the image pixels597 psImage *subVariance = psImageSubset(variance, region); // Sub image of the variance pixels598 psImage *subMask = mask ? psImageSubset(mask, region) : NULL; // Sub-image of the mask pixels599 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 region604 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 map613 double stdev = psStatsGetValue(stdevStats, stdevStat); // Standard deviation of image614 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 }632 449 633 450 -
branches/eam_branches/20090820/psModules/src/camera/pmFPAMaskWeight.h
r25116 r25766 80 80 /// 81 81 /// The variance map is adjusted so that the mean matches the actual pixel variance in the image 82 bool pmReadoutVarianceRenormPixels( 83 const pmReadout *readout, ///< Readout to normalise 84 psImageMaskType maskVal, ///< Value to mask 85 psStatsOptions meanStat, ///< Statistic to measure the mean (of the variance map) 86 psStatsOptions stdevStat, ///< Statistic to measure the stdev (of the image) 87 psRandom *rng ///< Random number generator 88 ); 89 90 /// Renormalise the variance map to match the actual photometry variance 91 /// 92 /// The variance map is adjusted so that the actual significance of fake sources matches the 93 /// guestimated significance 94 bool pmReadoutVarianceRenormPhot( 82 bool pmReadoutVarianceRenormalise( 95 83 const pmReadout *readout, ///< Readout to normalise 96 84 psImageMaskType maskVal, ///< Value to mask 97 int num, ///< Number of instances to measure over the image 98 float width, ///< Photometry width 99 psStatsOptions meanStat, ///< Statistic to measure the mean 100 psStatsOptions stdevStat, ///< Statistic to measure the stdev 101 psRandom *rng ///< Random number generator 102 ); 103 104 /// Renormalise the variance map to match the actual variance 105 /// 106 /// The variance in the image is measured in patches, and the variance map is adjusted so that the mean for 107 /// that patch corresponds. 108 bool pmReadoutVarianceRenorm(const pmReadout *readout, // Readout to normalise 109 psImageMaskType maskVal, // Value to mask 110 psStatsOptions meanStat, // Statistic to measure the mean (of the variance map) 111 psStatsOptions stdevStat, // Statistic to measure the stdev (of the image) 112 int width, // Width of patch (pixels) 113 psRandom *rng // Random number generator (for sub-sampling images) 85 int sample, ///< Sample size 86 float minValid, ///< Minimum valid renormalisation, or NAN 87 float maxValid ///< Maximum valid renormalisation, or NAN 114 88 ); 115 89 -
branches/eam_branches/20090820/psModules/src/camera/pmFPAMosaic.c
r21363 r25766 740 740 static bool chipMosaic(psImage **mosaicImage, // The mosaic image, to be returned 741 741 psImage **mosaicMask, // The mosaic mask, to be returned 742 psImage **mosaicVariance s, // The mosaic variances, to be returned742 psImage **mosaicVariance, // The mosaic variance, to be returned 743 743 int *xBinChip, int *yBinChip, // The binning in x and y, to be returned 744 744 const pmChip *chip, // Chip to mosaic … … 749 749 assert(mosaicImage); 750 750 assert(mosaicMask); 751 assert(mosaicVariance s);751 assert(mosaicVariance); 752 752 assert(xBinChip); 753 753 assert(yBinChip); … … 826 826 if (allGood) { 827 827 *mosaicImage = imageMosaic(images, xFlip, yFlip, xBin, yBin, *xBinChip, *yBinChip, x0, y0, BLANK_VALUE); 828 *mosaicVariance s= imageMosaic(variances, xFlip, yFlip, xBin, yBin, *xBinChip, *yBinChip, x0, y0, BLANK_VALUE);828 *mosaicVariance = imageMosaic(variances, xFlip, yFlip, xBin, yBin, *xBinChip, *yBinChip, x0, y0, BLANK_VALUE); 829 829 *mosaicMask = imageMosaic(masks, xFlip, yFlip, xBin, yBin, *xBinChip, *yBinChip, x0, y0, blank); 830 830 } … … 847 847 static bool fpaMosaic(psImage **mosaicImage, // The mosaic image, to be returned 848 848 psImage **mosaicMask, // The mosaic mask, to be returned 849 psImage **mosaicVariance s, // The mosaic variances, to be returned849 psImage **mosaicVariance, // The mosaic variance, to be returned 850 850 int *xBinFPA, int *yBinFPA, // The binning in x and y, to be returned 851 851 const pmFPA *fpa, // FPA to mosaic … … 857 857 assert(mosaicImage); 858 858 assert(mosaicMask); 859 assert(mosaicVariance s);859 assert(mosaicVariance); 860 860 assert(xBinFPA); 861 861 assert(yBinFPA); … … 960 960 if (allGood) { 961 961 *mosaicImage = imageMosaic(images, xFlip, yFlip, xBin, yBin, *xBinFPA, *yBinFPA, x0, y0, BLANK_VALUE); 962 *mosaicVariance s= imageMosaic(variances, xFlip, yFlip, xBin, yBin, *xBinFPA, *yBinFPA, x0, y0, BLANK_VALUE);962 *mosaicVariance = imageMosaic(variances, xFlip, yFlip, xBin, yBin, *xBinFPA, *yBinFPA, x0, y0, BLANK_VALUE); 963 963 *mosaicMask = imageMosaic(masks, xFlip, yFlip, xBin, yBin, *xBinFPA, *yBinFPA, x0, y0, blank); 964 964 } … … 1025 1025 psImage *mosaicImage = NULL; // The mosaic image 1026 1026 psImage *mosaicMask = NULL; // The mosaic mask 1027 psImage *mosaicVariance s= NULL; // The mosaic variances1027 psImage *mosaicVariance = NULL; // The mosaic variances 1028 1028 1029 1029 // Find the HDU … … 1052 1052 } 1053 1053 if (hdu->variances) { 1054 mosaicVariance s= psImageSubset(hdu->variances->data[0], bounds);1055 if (!mosaicVariance s) {1054 mosaicVariance = psImageSubset(hdu->variances->data[0], bounds); 1055 if (!mosaicVariance) { 1056 1056 psError(PS_ERR_UNKNOWN, false, "Unable to select variance pixels.\n"); 1057 1057 return false; … … 1061 1061 // Case 2 --- we need to mosaic by cut and paste 1062 1062 psTrace("psModules.camera", 1, "Case 2 mosaicking: cut and paste.\n"); 1063 if (!chipMosaic(&mosaicImage, &mosaicMask, &mosaicVariance s, &xBin, &yBin, source, targetCell, blank)) {1063 if (!chipMosaic(&mosaicImage, &mosaicMask, &mosaicVariance, &xBin, &yBin, source, targetCell, blank)) { 1064 1064 psError(PS_ERR_UNKNOWN, false, "Unable to mosaic cells.\n"); 1065 1065 return false; … … 1069 1069 } 1070 1070 psTrace("psModules.camera", 1, "xBin,yBin: %d,%d\n", xBin, yBin); 1071 1071 1072 1072 1073 // Set the concepts for the target cell … … 1090 1091 target->parent->concepts = psMetadataCopy(target->parent->concepts, source->parent->concepts); // FPA lvl 1091 1092 1093 // Average the covariances 1094 psList *covariances = psListAlloc(NULL); // Input covariance matrices 1095 for (int i = 0; i < source->cells->n; i++) { 1096 pmCell *cell = source->cells->data[i]; // Cell of interest 1097 if (!cell || !cell->data_exists) { 1098 continue; 1099 } 1100 pmReadout *ro = cell->readouts->data[0]; // Readout of interest 1101 if (!ro || !ro->covariance) { 1102 continue; 1103 } 1104 psListAdd(covariances, PS_LIST_TAIL, ro->covariance); 1105 } 1106 psKernel *mosaicCovariance = NULL; // Covariance for mosaic 1107 if (psListLength(covariances) > 0) { 1108 psArray *covarArray = psListToArray(covariances); // Array with covariances 1109 mosaicCovariance = psImageCovarianceAverage(covarArray); 1110 psFree(covarArray); 1111 } 1112 psFree(covariances); 1113 1092 1114 // Now make a new readout to go in the target cell 1093 1115 pmReadout *newReadout = pmReadoutAlloc(targetCell); // New readout 1094 1116 newReadout->image = mosaicImage; 1095 1117 newReadout->mask = mosaicMask; 1096 newReadout->variance = mosaicVariances; 1118 newReadout->variance = mosaicVariance; 1119 newReadout->covariance = mosaicCovariance; 1097 1120 psFree(newReadout); // Drop reference 1098 1121 … … 1334 1357 target->concepts = psMetadataCopy(target->concepts, source->concepts); 1335 1358 1359 // Average the covariances 1360 psList *covariances = psListAlloc(NULL); // Input covariance matrices 1361 for (int i = 0; i < covariances->n; i++) { 1362 pmChip *chip = chips->data[i]; // Chip of interest 1363 if (!chip || !chip->data_exists) { 1364 continue; 1365 } 1366 psArray *cells = chip->cells; // Cells in chip 1367 for (long j = 0; j < cells->n; j++) { 1368 pmCell *cell = cells->data[i]; // Cell of interest 1369 if (!cell || !cell->data_exists) { 1370 continue; 1371 } 1372 pmReadout *ro = cell->readouts->data[0]; // Readout of interest 1373 if (!ro || !ro->covariance) { 1374 continue; 1375 } 1376 psListAdd(covariances, PS_LIST_TAIL, ro->covariance); 1377 } 1378 } 1379 psKernel *mosaicCovariances = NULL; // Covariance for mosaic 1380 if (psListLength(covariances) > 0) { 1381 psArray *covarArray = psListToArray(covariances); // Array with covariances 1382 mosaicCovariances = psImageCovarianceAverage(covarArray); 1383 psFree(covarArray); 1384 } 1385 psFree(covariances); 1386 1336 1387 // Now make a new readout to go in the new cell 1337 1388 pmReadout *newReadout = pmReadoutAlloc(targetCell); // New readout … … 1339 1390 newReadout->mask = mosaicMask; 1340 1391 newReadout->variance = mosaicVariances; 1392 newReadout->covariance = mosaicCovariances; 1341 1393 psFree(newReadout); // Drop reference 1342 1394 -
branches/eam_branches/20090820/psModules/src/camera/pmFPARead.c
r24792 r25766 387 387 psFree(regionString); 388 388 psFree(readout); 389 psFree(iter); 389 390 return false; 390 391 } -
branches/eam_branches/20090820/psModules/src/camera/pmHDUGenerate.c
r25167 r25766 611 611 if (cells->n == 0) { 612 612 // Nothing to do 613 psFree (cells); 613 614 return true; 614 615 } … … 660 661 if (cells->n == 0) { 661 662 // Nothing to do 663 psFree (cells); 662 664 return true; 663 665 } … … 710 712 return true; 711 713 } 712 713 714 bool status = generateHDU(hdu, cells); 714 715 psFree(cells); -
branches/eam_branches/20090820/psModules/src/camera/pmReadoutFake.c
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/czw_branch/cleanup/psModules/src/camera/pmReadoutFake.c merged eligible /branches/eam_branches/20090522/psModules/src/camera/pmReadoutFake.c merged eligible /branches/eam_branches/20090715/psModules/src/camera/pmReadoutFake.c merged eligible /trunk/psModules/src/camera/pmReadoutFake.c merged eligible /branches/pap/psModules/src/camera/pmReadoutFake.c 23948-25229,25238-25382,25508-25737 /branches/pap_mops/psModules/src/camera/pmReadoutFake.c 25137-25255
r23960 r25766 28 28 #define MODEL_TYPE "PS_MODEL_RGAUSS" // Type of model to use 29 29 #define MAX_AXIS_RATIO 20.0 // Maximum axis ratio for PSF model 30 #define SOURCE_MASK (PM_SOURCE_MODE_DEFECT | PM_SOURCE_MODE_CR_LIMIT) // Mask to apply to input sources31 30 #define MODEL_MASK (PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE | \ 32 31 PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_LIMITS) // Mask to apply to models … … 50 49 } 51 50 52 bool pmReadoutFakeFromSources(pmReadout *readout, int numCols, int numRows, const psArray *sources, 53 const psVector *xOffset, const psVector *yOffset, const pmPSF *psf, 54 float minFlux, int radius, bool circularise, bool normalisePeak) 51 52 bool pmReadoutFakeFromVectors(pmReadout *readout, int numCols, int numRows, 53 const psVector *x, const psVector *y, const psVector *mag, 54 const psVector *xOffset, const psVector *yOffset, 55 const pmPSF *psf, float minFlux, int radius, 56 bool circularise, bool normalisePeak) 55 57 { 56 58 PS_ASSERT_PTR_NON_NULL(readout, false); 57 59 PS_ASSERT_INT_LARGER_THAN(numCols, 0, false); 58 60 PS_ASSERT_INT_LARGER_THAN(numRows, 0, false); 59 PS_ASSERT_ARRAY_NON_NULL(sources, false); 60 61 PS_ASSERT_VECTOR_NON_NULL(x, false); 62 PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_F32, false); 63 PS_ASSERT_VECTOR_NON_NULL(y, false); 64 PS_ASSERT_VECTOR_TYPE(y, PS_TYPE_F32, false); 65 PS_ASSERT_VECTORS_SIZE_EQUAL(y, x, false); 66 PS_ASSERT_VECTOR_NON_NULL(mag, false); 67 PS_ASSERT_VECTOR_TYPE(mag, PS_TYPE_F32, false); 68 PS_ASSERT_VECTORS_SIZE_EQUAL(mag, x, false); 69 long numSources = x->n; // Number of sources 61 70 if (xOffset || yOffset) { 62 71 PS_ASSERT_VECTOR_NON_NULL(xOffset, false); … … 64 73 PS_ASSERT_VECTORS_SIZE_EQUAL(xOffset, yOffset, false); 65 74 PS_ASSERT_VECTOR_TYPE(xOffset, PS_TYPE_S32, false); 66 PS_ASSERT_VECTOR_TYPE _EQUAL(xOffset, yOffset, false);67 if (xOffset->n != sources->n) {75 PS_ASSERT_VECTOR_TYPE(yOffset, PS_TYPE_S32, false); 76 if (xOffset->n != numSources) { 68 77 psError(PS_ERR_BAD_PARAMETER_SIZE, true, 69 78 "Number of offset vectors (%ld) and sources (%ld) doesn't match", 70 xOffset->n, sources->n);79 xOffset->n, numSources); 71 80 return false; 72 81 } 73 82 } 74 83 PS_ASSERT_PTR_NON_NULL(psf, false); 75 if (radius > 0 && isfinite(minFlux) && minFlux > 0.0) {76 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Cannot define both minimum flux and fixed radius.");77 return false;78 }79 84 80 85 readout->image = psImageRecycle(readout->image, numCols, numRows, PS_TYPE_F32); 81 86 psImageInit(readout->image, 0); 82 87 83 int numSources = sources->n; // Number of stars 84 for (int i = 0; i < numSources; i++) { 85 pmSource *source = sources->data[i]; // Source of interest 86 if (!source) { 87 continue; 88 } 89 if (source->mode & SOURCE_MASK) { 90 continue; 91 } 92 if (!isfinite(source->psfMag)) { 93 continue; 94 } 95 float x, y; // Coordinates of source 96 if (source->modelPSF) { 97 x = source->modelPSF->params->data.F32[PM_PAR_XPOS]; 98 y = source->modelPSF->params->data.F32[PM_PAR_YPOS]; 99 } else { 100 x = source->peak->xf; 101 y = source->peak->yf; 102 } 103 104 float flux = powf(10.0, -0.4 * source->psfMag); // Flux of source 88 for (long i = 0; i < numSources; i++) { 89 float flux = powf(10.0, -0.4 * mag->data.F32[i]); // Flux of source 90 float xSrc = x->data.F32[i], ySrc = y->data.F32[i]; // Coordinates of source 105 91 106 92 if (normalisePeak) { 107 93 // Normalise flux 108 pmModel *normModel = pmModelFromPSFforXY(psf, x , y, 1.0); // Model for normalisation94 pmModel *normModel = pmModelFromPSFforXY(psf, xSrc, ySrc, 1.0); // Model for normalisation 109 95 if (!normModel || (normModel->flags & MODEL_MASK)) { 110 96 psFree(normModel); 111 97 continue; 112 98 } 99 // check that all params are valid: 100 bool validParams = true; 101 for (int n = 0; validParams && (n < normModel->params->n); n++) { 102 if (n == PM_PAR_SKY) continue; 103 if (n == PM_PAR_I0) continue; 104 if (n == PM_PAR_XPOS) continue; 105 if (n == PM_PAR_YPOS) continue; 106 if (!isfinite(normModel->params->data.F32[n])) validParams = false; 107 } 108 if (!validParams) { 109 psFree(normModel); 110 continue; 111 } 113 112 if (circularise && !circulariseModel(normModel)) { 114 113 psError(PS_ERR_UNKNOWN, false, "Unable to circularise PSF model."); … … 121 120 } 122 121 123 pmModel *fakeModel = pmModelFromPSFforXY(psf, x , y, flux);122 pmModel *fakeModel = pmModelFromPSFforXY(psf, xSrc, ySrc, flux); 124 123 if (!fakeModel || (fakeModel->flags & MODEL_MASK)) { 125 124 psFree(fakeModel); 126 125 continue; 127 126 } 127 // check that all params are valid: 128 bool validParams = true; 129 for (int n = 0; validParams && (n < fakeModel->params->n); n++) { 130 if (n == PM_PAR_SKY) continue; 131 if (n == PM_PAR_I0) continue; 132 if (n == PM_PAR_XPOS) continue; 133 if (n == PM_PAR_YPOS) continue; 134 if (!isfinite(fakeModel->params->data.F32[n])) validParams = false; 135 } 136 if (!validParams) { 137 psFree(fakeModel); 138 continue; 139 } 128 140 if (circularise && !circulariseModel(fakeModel)) { 129 141 psError(PS_ERR_UNKNOWN, false, "Unable to circularise PSF model."); … … 137 149 138 150 pmSource *fakeSource = pmSourceAlloc(); // Fake source to generate 139 fakeSource->peak = pmPeakAlloc(x, y, fakeModel->params->data.F32[PM_PAR_I0], PM_PEAK_LONE); 140 float fakeRadius = radius > 0 ? radius : 141 PS_MAX(1.0, fakeModel->modelRadius(fakeModel->params, minFlux)); // Radius of fake source 151 fakeSource->peak = pmPeakAlloc(xSrc, ySrc, fakeModel->params->data.F32[PM_PAR_I0], PM_PEAK_LONE); 152 float fakeRadius = 1.0; // Radius of fake source 153 if (isfinite(minFlux)) { 154 fakeRadius = PS_MAX(fakeRadius, fakeModel->modelRadius(fakeModel->params, minFlux)); 155 } 156 if (radius > 0) { 157 fakeRadius = PS_MAX(fakeRadius, radius); 158 } 142 159 143 160 if (xOffset) { 144 if (!pmSourceDefinePixels(fakeSource, readout, x + xOffset->data.S32[i],145 y + yOffset->data.S32[i], fakeRadius)) {161 if (!pmSourceDefinePixels(fakeSource, readout, xSrc + xOffset->data.S32[i], 162 ySrc + yOffset->data.S32[i], fakeRadius)) { 146 163 psErrorClear(); 147 164 continue; … … 153 170 } 154 171 } else { 155 if (!pmSourceDefinePixels(fakeSource, readout, x , y, fakeRadius)) {172 if (!pmSourceDefinePixels(fakeSource, readout, xSrc, ySrc, fakeRadius)) { 156 173 psErrorClear(); 157 174 continue; … … 168 185 return true; 169 186 } 187 188 189 bool pmReadoutFakeFromSources(pmReadout *readout, int numCols, int numRows, const psArray *sources, 190 pmSourceMode sourceMask, const psVector *xOffset, const psVector *yOffset, 191 const pmPSF *psf, float minFlux, int radius, 192 bool circularise, bool normalisePeak) 193 { 194 PS_ASSERT_ARRAY_NON_NULL(sources, false); 195 196 int numSources = sources->n; // Number of stars 197 psVector *x = psVectorAllocEmpty(numSources, PS_TYPE_F32); 198 psVector *y = psVectorAllocEmpty(numSources, PS_TYPE_F32); 199 psVector *mag = psVectorAllocEmpty(numSources, PS_TYPE_F32); 200 201 int numGood = 0; // Number of good sources 202 for (int i = 0; i < numSources; i++) { 203 pmSource *source = sources->data[i]; // Source of interest 204 if (!source) { 205 continue; 206 } 207 if (source->mode & sourceMask) { 208 continue; 209 } 210 if (!isfinite(source->psfMag)) { 211 continue; 212 } 213 float xSrc, ySrc; // Coordinates of source 214 if (source->modelPSF) { 215 xSrc = source->modelPSF->params->data.F32[PM_PAR_XPOS]; 216 ySrc = source->modelPSF->params->data.F32[PM_PAR_YPOS]; 217 } else { 218 xSrc = source->peak->xf; 219 ySrc = source->peak->yf; 220 } 221 222 x->data.F32[numGood] = xSrc; 223 y->data.F32[numGood] = ySrc; 224 mag->data.F32[numGood] = source->psfMag; 225 numGood++; 226 } 227 x->n = numGood; 228 y->n = numGood; 229 mag->n = numGood; 230 231 bool status = pmReadoutFakeFromVectors(readout, numCols, numRows, x, y, mag, xOffset, yOffset, psf, 232 minFlux, radius, circularise, normalisePeak); 233 psFree(x); 234 psFree(y); 235 psFree(mag); 236 237 return status; 238 } -
Property svn:mergeinfo
set to (toggle deleted branches)
-
branches/eam_branches/20090820/psModules/src/camera/pmReadoutFake.h
r20999 r25766 11 11 #include <pmTrend2D.h> 12 12 #include <pmPSF.h> 13 #include <pmSourceMasks.h> 14 15 /// Generate a fake readout from vectors 16 bool pmReadoutFakeFromVectors(pmReadout *readout, ///< Output readout 17 int numCols, int numRows, ///< Dimension of image 18 const psVector *x, const psVector *y, ///< Source coordinates 19 const psVector *mag, ///< Source magnitudes 20 const psVector *xOffset, ///< x offsets for sources (source -> img), or NULL 21 const psVector *yOffset, ///< y offsets for sources (source -> img), or NULL 22 const pmPSF *psf, ///< PSF for sources 23 float minFlux, ///< Minimum flux to bother about; for setting source radius 24 int radius, ///< Fixed radius for sources 25 bool circularise, ///< Circularise PSF model? 26 bool normalisePeak ///< Normalise the peak value? 27 ); 13 28 14 29 /// Generate a fake readout from an array of sources 15 bool pmReadoutFakeFromSources(pmReadout *readout, ///< Output readout , or NULL30 bool pmReadoutFakeFromSources(pmReadout *readout, ///< Output readout 16 31 int numCols, int numRows, ///< Dimension of image 17 32 const psArray *sources, ///< Array of pmSource 33 pmSourceMode sourceMask, ///< Mask for sources 18 34 const psVector *xOffset, ///< x offsets for sources (source -> img), or NULL 19 35 const psVector *yOffset, ///< y offsets for sources (source -> img), or NULL
Note:
See TracChangeset
for help on using the changeset viewer.
