Changeset 27839 for branches/simmosaic_branches/ppStack/src/ppStackMatch.c
- Timestamp:
- May 3, 2010, 8:45:22 AM (16 years ago)
- Location:
- branches/simmosaic_branches
- Files:
-
- 3 edited
-
. (modified) (1 prop)
-
ppStack/src (modified) (1 prop)
-
ppStack/src/ppStackMatch.c (modified) (22 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/simmosaic_branches
- Property svn:mergeinfo changed
-
branches/simmosaic_branches/ppStack/src
- Property svn:ignore
-
old new 10 10 stamp-h1 11 11 ppStackVersionDefinitions.h 12 ppStackErrorCodes.c 13 ppStackErrorCodes.h
-
- Property svn:ignore
-
branches/simmosaic_branches/ppStack/src/ppStackMatch.c
r24846 r27839 14 14 #define FAKE_SIZE 1 // Size of fake convolution kernel 15 15 #define SOURCE_MASK (PM_SOURCE_MODE_FAIL | PM_SOURCE_MODE_DEFECT | PM_SOURCE_MODE_SATURATED | \ 16 PM_SOURCE_MODE_CR_LIMIT ) // Mask to apply to input sources17 #define FAINT_SOURCE_FRAC 1.0e-4 // Set minimum flux to this fraction of faintest source flux16 PM_SOURCE_MODE_CR_LIMIT | PM_SOURCE_MODE_EXT_LIMIT) // Mask to apply to input sources 17 #define NOISE_FRACTION 0.01 // Set minimum flux to this fraction of noise 18 18 #define COVAR_FRAC 0.01 // Truncation fraction for covariance matrix 19 19 20 // #define TESTING // Enable debugging output20 // #define TESTING // Enable debugging output 21 21 22 22 #ifdef TESTING … … 31 31 psFree(resolved); 32 32 if (!fits) { 33 psError(P S_ERR_IO, false, "Unable to open previously produced image: %s", name);33 psError(PPSTACK_ERR_IO, false, "Unable to open previously produced image: %s", name); 34 34 return false; 35 35 } 36 36 psImage *image = psFitsReadImage(fits, psRegionSet(0,0,0,0), 0); // Image of interest 37 37 if (!image) { 38 psError(P S_ERR_IO, false, "Unable to read previously produced image: %s", name);38 psError(PPSTACK_ERR_IO, false, "Unable to read previously produced image: %s", name); 39 39 psFitsClose(fits); 40 40 return false; … … 87 87 x->n = y->n = numGood; 88 88 89 psTree *tree = psTreePlant(2, 2, x, y); // kd tree89 psTree *tree = psTreePlant(2, 2, PS_TREE_EUCLIDEAN, x, y); // kd tree 90 90 91 91 psArray *filtered = psArrayAllocEmpty(numGood); // Filtered list of sources … … 115 115 psFree(coords); 116 116 psFree(tree); 117 psFree(x); 118 psFree(y); 117 119 118 120 psLogMsg("ppStack", PS_LOG_INFO, "Filtered out %d of %d sources", numFiltered, numGood); … … 144 146 psMetadataAddU8(psphotRecipe, PS_LIST_TAIL, "MASK.PSPHOT", PS_META_REPLACE, "user-defined mask", maskBad); 145 147 146 psImage *binned = psphot BackgroundModel(ro, config); // Binned background model148 psImage *binned = psphotModelBackgroundReadoutNoFile(ro, config); // Binned background model 147 149 psImageBinning *binning = psMetadataLookupPtr(NULL, ro->analysis, 148 150 "PSPHOT.BACKGROUND.BINNING"); // Binning for model … … 150 152 psImage *unbinned = psImageAlloc(numCols, numRows, PS_TYPE_F32); // Unbinned background model 151 153 if (!psImageUnbin(unbinned, binned, binning)) { 152 psError(PS_ERR_UNKNOWN, false, "Unable to unbin background model"); 154 psError(PPSTACK_ERR_DATA, false, "Unable to unbin background model"); 155 psFree(binned); 153 156 psFree(unbinned); 154 157 return NULL; 155 158 } 156 157 // XXX should these really be here?? (probably not...) 158 // pmFPAfileDropInternal(config->files, "PSPHOT.BACKMDL"); 159 // pmFPAfileDropInternal(config->files, "PSPHOT.BACKMDL.STDEV"); 160 161 return unbinned; 159 psFree(binned); 160 161 return unbinned; 162 162 } 163 164 // Renormalise a readout's variance map 165 bool stackRenormaliseReadout(const pmConfig *config, // Configuration 166 pmReadout *readout // Readout to renormalise 167 ) 168 { 169 #if 1 170 bool mdok; // Status of metadata lookups 171 172 psMetadata *recipe = psMetadataLookupPtr(NULL, config->recipes, PPSTACK_RECIPE); // Recipe for ppStack 173 psAssert(recipe, "Need PPSTACK recipe"); 174 175 if (!psMetadataLookupBool(&mdok, recipe, "RENORM")) return true; 176 177 int num = psMetadataLookupS32(&mdok, recipe, "RENORM.NUM"); 178 if (!mdok) { 179 psError(PPSTACK_ERR_CONFIG, true, "RENORM.NUM is not set in the recipe"); 180 return false; 181 } 182 float minValid = psMetadataLookupF32(&mdok, recipe, "RENORM.MIN"); 183 if (!mdok) { 184 psError(PPSTACK_ERR_CONFIG, true, "RENORM.MIN is not set in the recipe"); 185 return false; 186 } 187 float maxValid = psMetadataLookupF32(&mdok, recipe, "RENORM.MAX"); 188 if (!mdok) { 189 psError(PPSTACK_ERR_CONFIG, true, "RENORM.MAX is not set in the recipe"); 190 return false; 191 } 192 193 psImageMaskType maskBad = pmConfigMaskGet("BLANK", config); // Bits to mask 194 195 psImageCovarianceTransfer(readout->variance, readout->covariance); 196 return pmReadoutVarianceRenormalise(readout, maskBad, num, minValid, maxValid); 197 #else 198 return true; 199 #endif 200 } 201 163 202 164 203 … … 178 217 int size = psMetadataLookupS32(NULL, ppsub, "KERNEL.SIZE"); // Kernel half-size 179 218 180 psString maskValStr = psMetadataLookupStr(NULL, recipe, "MASK.VAL"); // Name of bits to mask going in219 psString maskValStr = psMetadataLookupStr(NULL, ppsub, "MASK.VAL"); // Name of bits to mask going in 181 220 psImageMaskType maskVal = pmConfigMaskGet(maskValStr, config); // Bits to mask going in to pmSubtractionMatch 182 221 psString maskPoorStr = psMetadataLookupStr(NULL, recipe, "MASK.POOR"); // Name of bits to mask for poor … … 190 229 191 230 if (!pmReadoutMaskNonfinite(readout, maskVal)) { 192 psError( PS_ERR_UNKNOWN, false, "Unable to mask non-finite pixels in readout.");231 psError(psErrorCodeLast(), false, "Unable to mask non-finite pixels in readout."); 193 232 return false; 194 233 } … … 217 256 psFree(resolved); 218 257 if (!fits || !pmReadoutReadSubtractionKernels(conv, fits)) { 219 psError(P S_ERR_IO, false, "Unable to read previously produced kernel");258 psError(PPSTACK_ERR_IO, false, "Unable to read previously produced kernel"); 220 259 psFitsClose(fits); 221 260 return false; … … 223 262 psFitsClose(fits); 224 263 225 // Add in variance factor 226 pmSubtractionKernels *kernels = psMetadataLookupPtr(NULL, conv->analysis, 227 PM_SUBTRACTION_ANALYSIS_KERNEL); // Kernels 228 float vf = pmSubtractionVarianceFactor(kernels, 0.0, 0.0, false); // Variance factor 229 psMetadataItem *vfItem = psMetadataLookup(readout->parent->concepts, "CELL.VARFACTOR"); 230 if (!isfinite(vf)) { 231 vf = 1.0; 232 } 233 if (isfinite(vfItem->data.F32)) { 234 vfItem->data.F32 *= vf; 235 } else { 236 vfItem->data.F32 = vf; 237 } 238 239 if (!readImage(&readout->image, options->imageNames->data[index], config) || 240 !readImage(&readout->mask, options->maskNames->data[index], config) || 241 !readImage(&readout->variance, options->varianceNames->data[index], config)) { 242 psError(PS_ERR_IO, false, "Unable to read previously produced image."); 264 if (!readImage(&readout->image, options->convImages->data[index], config) || 265 !readImage(&readout->mask, options->convMasks->data[index], config) || 266 !readImage(&readout->variance, options->convVariances->data[index], config)) { 267 psError(PPSTACK_ERR_IO, false, "Unable to read previously produced image."); 243 268 return false; 244 269 } … … 246 271 psRegion *region = psMetadataLookupPtr(NULL, conv->analysis, 247 272 PM_SUBTRACTION_ANALYSIS_REGION); // Convolution region 248 249 pmSubtractionAnalysis(readout->analysis, kernels, region, 273 pmSubtractionKernels *kernels = psMetadataLookupPtr(NULL, conv->analysis, 274 PM_SUBTRACTION_ANALYSIS_KERNEL); 275 276 pmSubtractionAnalysis(conv->analysis, NULL, kernels, region, 250 277 readout->image->numCols, readout->image->numRows); 251 278 252 279 psKernel *kernel = pmSubtractionKernel(kernels, 0.0, 0.0, false); // Convolution kernel 280 bool oldThreads = psImageCovarianceSetThreads(true); // Old thread setting 253 281 psKernel *covar = psImageCovarianceCalculate(kernel, readout->covariance); // Covariance matrix 282 psImageCovarianceSetThreads(oldThreads); 254 283 psFree(readout->covariance); 255 284 readout->covariance = covar; … … 270 299 int iter = psMetadataLookupS32(NULL, ppsub, "ITER"); // Rejection iterations 271 300 float rej = psMetadataLookupF32(NULL, ppsub, "REJ"); // Rejection threshold 272 float sysError = psMetadataLookupF32(NULL, ppsub, "SYS"); // Relative systematic error in kernel 301 float kernelError = psMetadataLookupF32(NULL, ppsub, "KERNEL.ERR"); // Relative systematic error in kernel 302 float normFrac = psMetadataLookupF32(NULL, ppsub, "NORM.FRAC"); // Fraction of window for normalisn windw 303 float sysError = psMetadataLookupF32(NULL, ppsub, "SYS.ERR"); // Relative systematic error in images 304 float skyErr = psMetadataLookupF32(NULL, ppsub, "SKY.ERR"); // Additional error in sky 305 float covarFrac = psMetadataLookupF32(NULL, ppsub, "COVAR.FRAC"); // Fraction for covariance calculation 306 273 307 const char *typeStr = psMetadataLookupStr(NULL, ppsub, "KERNEL.TYPE"); // Kernel type 274 308 pmSubtractionKernelsType type = pmSubtractionKernelsTypeFromString(typeStr); // Kernel type … … 287 321 float poorFrac = psMetadataLookupF32(&mdok, ppsub, "POOR.FRACTION"); // Fraction for "poor" 288 322 323 bool scale = psMetadataLookupBool(NULL, ppsub, "SCALE"); // Scale kernel parameters? 324 float scaleRef = psMetadataLookupF32(NULL, ppsub, "SCALE.REF"); // Reference for scaling 325 float scaleMin = psMetadataLookupF32(NULL, ppsub, "SCALE.MIN"); // Minimum for scaling 326 float scaleMax = psMetadataLookupF32(NULL, ppsub, "SCALE.MAX"); // Maximum for scaling 327 if (!isfinite(scaleRef) || !isfinite(scaleMin) || !isfinite(scaleMax)) { 328 psError(PPSTACK_ERR_CONFIG, false, 329 "Scale parameters (SCALE.REF=%f, SCALE.MIN=%f, SCALE.MAX=%f) not set in PPSUB recipe.", 330 scaleRef, scaleMin, scaleMax); 331 return false; 332 } 333 334 289 335 // These values are specified specifically for stacking 290 336 const char *stampsName = psMetadataLookupStr(NULL, config->arguments, "STAMPS");// Stamps filename … … 297 343 pmReadout *fake = pmReadoutAlloc(NULL); // Fake readout with target PSF 298 344 345 psStats *bg = psStatsAlloc(PS_STAT_ROBUST_STDEV); // Statistics for background 346 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator 347 if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal | maskBad, rng)) { 348 psError(PPSTACK_ERR_DATA, false, "Can't measure background for image."); 349 psFree(fake); 350 psFree(optWidths); 351 psFree(conv); 352 psFree(bg); 353 psFree(rng); 354 return false; 355 } 356 float minFlux = NOISE_FRACTION * bg->robustStdev; // Minimum flux level for fake image 357 psFree(rng); 358 psFree(bg); 359 299 360 // For the sake of stamps, remove nearby sources 300 361 psArray *stampSources = stackSourcesFilter(options->sourceLists->data[index], 301 362 footprint); // Filtered list of sources 302 363 364 bool oldThreads = pmReadoutFakeThreads(true); // Old threading state 303 365 if (!pmReadoutFakeFromSources(fake, readout->image->numCols, readout->image->numRows, 304 stampSources, NULL, NULL, options->psf, NAN, footprint + size,305 false, true)) {306 psError(P S_ERR_UNKNOWN, false, "Unable to generate fake image with target PSF.");366 stampSources, SOURCE_MASK, NULL, NULL, options->psf, 367 minFlux, footprint + size, false, true)) { 368 psError(PPSTACK_ERR_DATA, false, "Unable to generate fake image with target PSF."); 307 369 psFree(fake); 308 370 psFree(optWidths); … … 310 372 return false; 311 373 } 374 pmReadoutFakeThreads(oldThreads); 312 375 313 376 fake->mask = psImageCopy(NULL, readout->mask, PS_TYPE_IMAGE_MASK); 314 377 378 #if 1 315 379 // Add the background into the target image 316 380 psImage *bgImage = stackBackgroundModel(readout, config); // Image of background 317 381 psBinaryOp(fake->image, fake->image, "+", bgImage); 318 382 psFree(bgImage); 383 #endif 319 384 320 385 #ifdef TESTING … … 342 407 343 408 if (threads > 0) { 344 pmSubtractionThreadsInit( readout, fake);409 pmSubtractionThreadsInit(); 345 410 } 346 411 … … 349 414 PM_SUBTRACTION_ANALYSIS_KERNEL); // Conv kernel 350 415 if (kernel) { 351 if (!pmSubtractionMatchPrecalc( conv, NULL, readout, fake, readout->analysis,352 stride, sysError, maskVal, maskBad, maskPoor,416 if (!pmSubtractionMatchPrecalc(NULL, conv, fake, readout, readout->analysis, 417 stride, kernelError, covarFrac, maskVal, maskBad, maskPoor, 353 418 poorFrac, badFrac)) { 354 psError( PS_ERR_UNKNOWN, false, "Unable to convolve images.");419 psError(psErrorCodeLast(), false, "Unable to convolve images."); 355 420 psFree(fake); 356 421 psFree(optWidths); … … 358 423 psFree(conv); 359 424 if (threads > 0) { 360 pmSubtractionThreadsFinalize( readout, fake);425 pmSubtractionThreadsFinalize(); 361 426 } 362 427 return false; 363 428 } 364 429 } else { 365 if (!pmSubtractionMatch(conv, NULL, readout, fake, footprint, stride, regionSize, spacing, 366 threshold, stampSources, stampsName, type, size, order, widths, 367 orders, inner, ringsOrder, binning, penalty, 368 optimum, optWidths, optOrder, optThresh, iter, rej, sysError, 369 maskVal, maskBad, maskPoor, poorFrac, badFrac, 370 PM_SUBTRACTION_MODE_1)) { 371 psError(PS_ERR_UNKNOWN, false, "Unable to match images."); 430 // Scale the input parameters 431 psVector *widthsCopy = psVectorCopy(NULL, widths, PS_TYPE_F32); // Copy of kernel widths 432 if (scale && !pmSubtractionParamsScale(&size, &footprint, widthsCopy, 433 options->inputSeeing->data.F32[index], 434 options->targetSeeing, scaleRef, scaleMin, scaleMax)) { 435 psError(psErrorCodeLast(), false, "Unable to scale kernel parameters"); 372 436 psFree(fake); 373 437 psFree(optWidths); 374 438 psFree(stampSources); 375 439 psFree(conv); 440 psFree(widthsCopy); 376 441 if (threads > 0) { 377 pmSubtractionThreadsFinalize( readout, fake);442 pmSubtractionThreadsFinalize(); 378 443 } 379 444 return false; 380 445 } 381 } 446 447 if (!pmSubtractionMatch(NULL, conv, fake, readout, footprint, stride, regionSize, spacing, 448 threshold, stampSources, stampsName, type, size, order, widthsCopy, 449 orders, inner, ringsOrder, binning, penalty, 450 optimum, optWidths, optOrder, optThresh, iter, rej, normFrac, 451 sysError, skyErr, kernelError, covarFrac, maskVal, maskBad, maskPoor, 452 poorFrac, badFrac, PM_SUBTRACTION_MODE_2)) { 453 psError(psErrorCodeLast(), false, "Unable to match images."); 454 psFree(fake); 455 psFree(optWidths); 456 psFree(stampSources); 457 psFree(conv); 458 psFree(widthsCopy); 459 if (threads > 0) { 460 pmSubtractionThreadsFinalize(); 461 } 462 return false; 463 } 464 psFree(widthsCopy); 465 } 466 382 467 383 468 #ifdef TESTING … … 410 495 411 496 if (threads > 0) { 412 pmSubtractionThreadsFinalize(readout, fake); 413 } 414 415 // Set the variance factor 416 psMetadataItem *vfItem = psMetadataLookup(readout->parent->concepts, "CELL.VARFACTOR"); 417 float vf = psMetadataLookupF32(NULL, conv->analysis, PM_SUBTRACTION_ANALYSIS_VARFACTOR_1); 418 if (!isfinite(vf)) { 419 vf = 1.0; 420 } 421 if (isfinite(vfItem->data.F32)) { 422 vfItem->data.F32 *= vf; 423 } else { 424 vfItem->data.F32 = vf; 497 pmSubtractionThreadsFinalize(); 425 498 } 426 499 … … 462 535 while ((item = psMetadataGetAndIncrement(iter))) { 463 536 assert(item->type == PS_DATA_UNKNOWN); 464 // Set the normalisation dimensions, since these will be otherwise unavailable when reading465 // the images by scans.466 537 pmSubtractionKernels *kernel = item->data.V; // Kernel used in subtraction 467 kernel->numCols = readout->image->numCols;468 kernel->numRows = readout->image->numRows;469 470 538 kernels = psArrayAdd(kernels, ARRAY_BUFFER, kernel); 471 539 } … … 493 561 } 494 562 563 // Kernel normalisation 564 { 565 double sum = 0.0; // Sum of chi^2 566 int num = 0; // Number of measurements of chi^2 567 psString regex = NULL; // Regular expression 568 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_NORM); 569 psMetadataIterator *iter = psMetadataIteratorAlloc(conv->analysis, PS_LIST_HEAD, regex); 570 psFree(regex); 571 psMetadataItem *item = NULL;// Item from iteration 572 while ((item = psMetadataGetAndIncrement(iter))) { 573 assert(item->type == PS_TYPE_F32); 574 float norm = item->data.F32; // Normalisation 575 sum += norm; 576 num++; 577 } 578 psFree(iter); 579 float conv = sum/num; // Mean normalisation from convolution 580 float stars = powf(10.0, -0.4 * options->norm->data.F32[index]); // Normalisation from stars 581 float renorm = stars / conv; // Renormalisation to apply 582 psLogMsg("ppStack", PS_LOG_INFO, "Renormalising image %d by %f (kernel: %f, stars: %f)\n", 583 index, renorm, conv, stars); 584 psBinaryOp(readout->image, readout->image, "*", psScalarAlloc(renorm, PS_TYPE_F32)); 585 psBinaryOp(readout->variance, readout->variance, "*", psScalarAlloc(PS_SQR(renorm), PS_TYPE_F32)); 586 } 587 495 588 // Reject image completely if the maximum deconvolution fraction exceeds the limit 496 589 float deconv = psMetadataLookupF32(NULL, conv->analysis, 497 590 PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Max deconvolution fraction 498 591 if (deconv > deconvLimit) { 499 psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting \n",500 deconv, deconvLimit );592 psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting image %d\n", 593 deconv, deconvLimit, index); 501 594 psFree(conv); 502 595 return NULL; … … 512 605 psBinaryOp(readout->variance, readout->variance, "*", psScalarAlloc(PS_SQR(norm), PS_TYPE_F32)); 513 606 } 514 607 515 608 // Ensure the background value is zero 516 609 psStats *bg = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics for background 517 610 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator 518 611 if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal | maskBad, rng)) { 519 psWarning("Can't measure background for image.");520 psErrorClear();612 psWarning("Can't measure background for image."); 613 psErrorClear(); 521 614 } else { 522 if (!psMetadataLookupBool(NULL, config->arguments, "PPSTACK.SKIP.BG.SUB")) { 523 psLogMsg("ppStack", PS_LOG_INFO, "Correcting convolved image background by %lf (+/- %lf)", 524 psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), psStatsGetValue(bg, PS_STAT_ROBUST_STDEV)); 525 (void)psBinaryOp(readout->image, readout->image, "-", 526 psScalarAlloc(psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), PS_TYPE_F32)); 527 } 528 } 529 530 531 // Measure the variance level for the weighting 532 if (!psImageBackground(bg, NULL, readout->variance, readout->mask, maskVal | maskBad, rng)) { 533 psError(PS_ERR_UNKNOWN, false, "Can't measure mean variance for image."); 615 if (!psMetadataLookupBool(NULL, config->arguments, "PPSTACK.SKIP.BG.SUB")) { 616 psLogMsg("ppStack", PS_LOG_INFO, "Correcting convolved image background by %lf (+/- %lf)", 617 psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), psStatsGetValue(bg, PS_STAT_ROBUST_STDEV)); 618 (void)psBinaryOp(readout->image, readout->image, "-", 619 psScalarAlloc(psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), PS_TYPE_F32)); 620 } 621 } 622 623 if (!stackRenormaliseReadout(config, readout)) { 534 624 psFree(rng); 535 625 psFree(bg); 536 626 return false; 537 627 } 538 options->weightings->data.F32[index] = 1.0 / (psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN) * 539 psImageCovarianceFactor(readout->covariance)); 540 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "PPSTACK.WEIGHTING", 0, 541 "Weighting by 1/noise^2 for stack", options->weightings->data.F32[index]); 628 629 // Measure the variance level for the weighting 630 if (psMetadataLookupBool(NULL, recipe, "WEIGHTS")) { 631 if (!psImageBackground(bg, NULL, readout->variance, readout->mask, maskVal | maskBad, rng)) { 632 psError(PPSTACK_ERR_DATA, false, "Can't measure mean variance for image."); 633 psFree(rng); 634 psFree(bg); 635 return false; 636 } 637 options->weightings->data.F32[index] = 1.0 / (psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN) * 638 psImageCovarianceFactor(readout->covariance)); 639 } else { 640 options->weightings->data.F32[index] = 1.0; 641 } 642 psLogMsg("ppStack", PS_LOG_INFO, "Weighting for image %d is %f\n", 643 index, options->weightings->data.F32[index]); 542 644 543 645 psFree(rng);
Note:
See TracChangeset
for help on using the changeset viewer.
