- Timestamp:
- May 3, 2010, 8:50:52 AM (16 years ago)
- Location:
- branches/simtest_nebulous_branches
- Files:
-
- 3 edited
-
. (modified) (1 prop)
-
ppStack/src (modified) (1 prop)
-
ppStack/src/ppStackMatch.c (modified) (22 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/simtest_nebulous_branches
- Property svn:mergeinfo changed
-
branches/simtest_nebulous_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/simtest_nebulous_branches/ppStack/src/ppStackMatch.c
r25045 r27840 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 if (!readImage(&readout->image, options-> imageNames->data[index], config) ||226 !readImage(&readout->mask, options-> maskNames->data[index], config) ||227 !readImage(&readout->variance, options-> varianceNames->data[index], config)) {228 psError(P S_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."); 229 268 return false; 230 269 } … … 232 271 psRegion *region = psMetadataLookupPtr(NULL, conv->analysis, 233 272 PM_SUBTRACTION_ANALYSIS_REGION); // Convolution region 234 235 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, 236 277 readout->image->numCols, readout->image->numRows); 237 278 238 279 psKernel *kernel = pmSubtractionKernel(kernels, 0.0, 0.0, false); // Convolution kernel 280 bool oldThreads = psImageCovarianceSetThreads(true); // Old thread setting 239 281 psKernel *covar = psImageCovarianceCalculate(kernel, readout->covariance); // Covariance matrix 282 psImageCovarianceSetThreads(oldThreads); 240 283 psFree(readout->covariance); 241 284 readout->covariance = covar; … … 256 299 int iter = psMetadataLookupS32(NULL, ppsub, "ITER"); // Rejection iterations 257 300 float rej = psMetadataLookupF32(NULL, ppsub, "REJ"); // Rejection threshold 258 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 259 307 const char *typeStr = psMetadataLookupStr(NULL, ppsub, "KERNEL.TYPE"); // Kernel type 260 308 pmSubtractionKernelsType type = pmSubtractionKernelsTypeFromString(typeStr); // Kernel type … … 273 321 float poorFrac = psMetadataLookupF32(&mdok, ppsub, "POOR.FRACTION"); // Fraction for "poor" 274 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 275 335 // These values are specified specifically for stacking 276 336 const char *stampsName = psMetadataLookupStr(NULL, config->arguments, "STAMPS");// Stamps filename … … 283 343 pmReadout *fake = pmReadoutAlloc(NULL); // Fake readout with target PSF 284 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 285 360 // For the sake of stamps, remove nearby sources 286 361 psArray *stampSources = stackSourcesFilter(options->sourceLists->data[index], 287 362 footprint); // Filtered list of sources 288 363 364 bool oldThreads = pmReadoutFakeThreads(true); // Old threading state 289 365 if (!pmReadoutFakeFromSources(fake, readout->image->numCols, readout->image->numRows, 290 stampSources, NULL, NULL, options->psf, NAN, footprint + size,291 false, true)) {292 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."); 293 369 psFree(fake); 294 370 psFree(optWidths); … … 296 372 return false; 297 373 } 374 pmReadoutFakeThreads(oldThreads); 298 375 299 376 fake->mask = psImageCopy(NULL, readout->mask, PS_TYPE_IMAGE_MASK); 300 377 378 #if 1 301 379 // Add the background into the target image 302 380 psImage *bgImage = stackBackgroundModel(readout, config); // Image of background 303 381 psBinaryOp(fake->image, fake->image, "+", bgImage); 304 382 psFree(bgImage); 383 #endif 305 384 306 385 #ifdef TESTING … … 328 407 329 408 if (threads > 0) { 330 pmSubtractionThreadsInit( readout, fake);409 pmSubtractionThreadsInit(); 331 410 } 332 411 … … 335 414 PM_SUBTRACTION_ANALYSIS_KERNEL); // Conv kernel 336 415 if (kernel) { 337 if (!pmSubtractionMatchPrecalc( conv, NULL, readout, fake, readout->analysis,338 stride, sysError, maskVal, maskBad, maskPoor,416 if (!pmSubtractionMatchPrecalc(NULL, conv, fake, readout, readout->analysis, 417 stride, kernelError, covarFrac, maskVal, maskBad, maskPoor, 339 418 poorFrac, badFrac)) { 340 psError( PS_ERR_UNKNOWN, false, "Unable to convolve images.");419 psError(psErrorCodeLast(), false, "Unable to convolve images."); 341 420 psFree(fake); 342 421 psFree(optWidths); … … 344 423 psFree(conv); 345 424 if (threads > 0) { 346 pmSubtractionThreadsFinalize( readout, fake);425 pmSubtractionThreadsFinalize(); 347 426 } 348 427 return false; 349 428 } 350 429 } else { 351 if (!pmSubtractionMatch(conv, NULL, readout, fake, footprint, stride, regionSize, spacing, 352 threshold, stampSources, stampsName, type, size, order, widths, 353 orders, inner, ringsOrder, binning, penalty, 354 optimum, optWidths, optOrder, optThresh, iter, rej, sysError, 355 maskVal, maskBad, maskPoor, poorFrac, badFrac, 356 PM_SUBTRACTION_MODE_1)) { 357 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"); 358 436 psFree(fake); 359 437 psFree(optWidths); 360 438 psFree(stampSources); 361 439 psFree(conv); 440 psFree(widthsCopy); 362 441 if (threads > 0) { 363 pmSubtractionThreadsFinalize( readout, fake);442 pmSubtractionThreadsFinalize(); 364 443 } 365 444 return false; 366 445 } 367 } 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 368 467 369 468 #ifdef TESTING … … 396 495 397 496 if (threads > 0) { 398 pmSubtractionThreadsFinalize( readout, fake);497 pmSubtractionThreadsFinalize(); 399 498 } 400 499 … … 436 535 while ((item = psMetadataGetAndIncrement(iter))) { 437 536 assert(item->type == PS_DATA_UNKNOWN); 438 // Set the normalisation dimensions, since these will be otherwise unavailable when reading439 // the images by scans.440 537 pmSubtractionKernels *kernel = item->data.V; // Kernel used in subtraction 441 kernel->numCols = readout->image->numCols;442 kernel->numRows = readout->image->numRows;443 444 538 kernels = psArrayAdd(kernels, ARRAY_BUFFER, kernel); 445 539 } … … 467 561 } 468 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 469 588 // Reject image completely if the maximum deconvolution fraction exceeds the limit 470 589 float deconv = psMetadataLookupF32(NULL, conv->analysis, 471 590 PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Max deconvolution fraction 472 591 if (deconv > deconvLimit) { 473 psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting \n",474 deconv, deconvLimit );592 psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting image %d\n", 593 deconv, deconvLimit, index); 475 594 psFree(conv); 476 595 return NULL; … … 491 610 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator 492 611 if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal | maskBad, rng)) { 493 psWarning("Can't measure background for image.");494 psErrorClear();612 psWarning("Can't measure background for image."); 613 psErrorClear(); 495 614 } else { 496 if (!psMetadataLookupBool(NULL, config->arguments, "PPSTACK.SKIP.BG.SUB")) { 497 psLogMsg("ppStack", PS_LOG_INFO, "Correcting convolved image background by %lf (+/- %lf)", 498 psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), psStatsGetValue(bg, PS_STAT_ROBUST_STDEV)); 499 (void)psBinaryOp(readout->image, readout->image, "-", 500 psScalarAlloc(psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), PS_TYPE_F32)); 501 } 502 } 503 504 505 // Measure the variance level for the weighting 506 if (!psImageBackground(bg, NULL, readout->variance, readout->mask, maskVal | maskBad, rng)) { 507 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)) { 508 624 psFree(rng); 509 625 psFree(bg); 510 626 return false; 511 627 } 512 options->weightings->data.F32[index] = 1.0 / (psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN) * 513 psImageCovarianceFactor(readout->covariance)); 514 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "PPSTACK.WEIGHTING", 0, 515 "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]); 516 644 517 645 psFree(rng);
Note:
See TracChangeset
for help on using the changeset viewer.
