Changeset 23573 for trunk/ppStack/src/ppStackMatch.c
- Timestamp:
- Mar 27, 2009, 11:49:17 AM (17 years ago)
- File:
-
- 1 edited
-
trunk/ppStack/src/ppStackMatch.c (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ppStack/src/ppStackMatch.c
r23379 r23573 163 163 164 164 165 bool ppStackMatch(pmReadout *readout, psArray **regions, psArray **kernels, float *chi2, float *weighting, 166 psArray *sources, const pmPSF *psf, psRandom *rng, const pmConfig *config) 165 bool ppStackMatch(pmReadout *readout, ppStackOptions *options, int index, const pmConfig *config) 167 166 { 168 167 assert(readout); 169 assert(regions && !*regions); 170 assert(kernels && !*kernels); 168 assert(options); 171 169 assert(config); 172 *weighting = 0.0;173 170 174 171 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe … … 197 194 } 198 195 199 pmReadout *output = pmReadoutAlloc(NULL); // Output readout, for holding results temporarily 200 201 static int numInput = -1; // Index of input file 202 numInput++; 196 // Match the PSF 197 if (options->convolve) { 198 pmReadout *conv = pmReadoutAlloc(NULL); // Conv readout, for holding results temporarily 203 199 #ifdef TESTING 204 // Read previously produced kernel 205 if (psMetadataLookupBool(NULL, config->arguments, "PPSTACK.DEBUG.STACK")) { 206 const char *outName = psMetadataLookupStr(NULL, config->arguments, "OUTPUT"); // Output root 207 assert(outName); 208 // Read convolution kernel 209 psString filename = NULL; // Output filename 210 psStringAppend(&filename, "%s.%d.kernel", outName, numInput); 211 psString resolved = pmConfigConvertFilename(filename, config, false, false); // Resolved filename 212 psFree(filename); 213 psFits *fits = psFitsOpen(resolved, "r"); // FITS file for subtraction kernel 214 psFree(resolved); 215 if (!fits || !pmReadoutReadSubtractionKernels(output, fits)) { 216 psError(PS_ERR_IO, false, "Unable to read previously produced kernel"); 200 // This is a hack to use the temporary convolved images and kernel generated previously. 201 // This makes the 'matching' operation much faster, allowing debugging of the stack process easier. 202 // It implicitly assumes the output root name is the same between invocations. 203 204 // Read previously produced kernel 205 if (psMetadataLookupBool(NULL, config->arguments, "PPSTACK.DEBUG.STACK")) { 206 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPSTACK.CONV.KERNEL", index); 207 psAssert(file, "Require file"); 208 209 pmFPAview *view = pmFPAviewAlloc(0); // View to readout of interest 210 view->chip = view->cell = view->readout = 0; 211 psString filename = pmFPAfileNameFromRule(filerule->rule, file, view); // Filename of interest 212 213 // Read convolution kernel 214 psString resolved = pmConfigConvertFilename(filename, config, false, false); // Resolved filename 215 psFree(filename); 216 psFits *fits = psFitsOpen(resolved, "r"); // FITS file for subtraction kernel 217 psFree(resolved); 218 if (!fits || !pmReadoutReadSubtractionKernels(conv, fits)) { 219 psError(PS_ERR_IO, false, "Unable to read previously produced kernel"); 220 psFitsClose(fits); 221 return false; 222 } 217 223 psFitsClose(fits); 218 return false; 219 } 220 psFitsClose(fits); 221 222 // Add in variance factor 223 pmSubtractionKernels *kernels = psMetadataLookupPtr(NULL, output->analysis, 224 PM_SUBTRACTION_ANALYSIS_KERNEL); // Kernels 225 float vf = pmSubtractionVarianceFactor(kernels, 0.0, 0.0, false); // Variance factor 226 psMetadataItem *vfItem = psMetadataLookup(readout->parent->concepts, "CELL.VARFACTOR"); 227 if (!isfinite(vf)) { 228 vf = 1.0; 229 } 230 if (isfinite(vfItem->data.F32)) { 231 vfItem->data.F32 *= vf; 232 } else { 233 vfItem->data.F32 = vf; 234 } 235 236 // Read image, mask, variance 237 const char *tempImage = psMetadataLookupStr(NULL, recipe, "TEMP.IMAGE"); // Suffix for image 238 const char *tempMask = psMetadataLookupStr(NULL, recipe, "TEMP.MASK"); // Suffix for mask 239 const char *tempVariance = psMetadataLookupStr(NULL, recipe, "TEMP.VARIANCE"); // Suffix for variance map 240 psString imageName = NULL, maskName = NULL, varianceName = NULL; // Names for convolved images 241 psStringAppend(&imageName, "%s.%d.%s", outName, numInput, tempImage); 242 psStringAppend(&maskName, "%s.%d.%s", outName, numInput, tempMask); 243 psStringAppend(&varianceName, "%s.%d.%s", outName, numInput, tempVariance); 244 245 if (!readImage(&readout->image, imageName, config) || !readImage(&readout->mask, maskName, config) || 246 !readImage(&readout->variance, varianceName, config)) { 247 psError(PS_ERR_IO, false, "Unable to read previously produced image."); 224 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."); 243 psFree(imageName); 244 psFree(maskName); 245 psFree(varianceName); 246 return false; 247 } 248 248 psFree(imageName); 249 249 psFree(maskName); 250 250 psFree(varianceName); 251 return false; 252 } 253 psFree(imageName); 254 psFree(maskName); 255 psFree(varianceName); 256 257 psRegion *region = psMetadataLookupPtr(NULL, output->analysis, 258 PM_SUBTRACTION_ANALYSIS_REGION); // Convolution region 259 260 pmSubtractionAnalysis(readout->analysis, kernels, region, 261 readout->image->numCols, readout->image->numRows); 262 263 psKernel *kernel = pmSubtractionKernel(kernels, 0.0, 0.0, false); // Convolution kernel 264 psKernel *covar = psImageCovarianceCalculate(kernel, readout->covariance); // New covariance matrix 265 psFree(readout->covariance); 266 readout->covariance = covar; 267 psFree(kernel); 268 269 } else { 270 #endif 271 272 // Normal operations here 273 if (psMetadataLookupBool(&mdok, config->arguments, "HAVE.PSF")) { 274 assert(psf); 275 assert(sources); 251 252 psRegion *region = psMetadataLookupPtr(NULL, conv->analysis, 253 PM_SUBTRACTION_ANALYSIS_REGION); // Convolution region 254 255 pmSubtractionAnalysis(readout->analysis, kernels, region, 256 readout->image->numCols, readout->image->numRows); 257 258 psKernel *kernel = pmSubtractionKernel(kernels, 0.0, 0.0, false); // Convolution kernel 259 psKernel *covar = psImageCovarianceCalculate(kernel, readout->covariance); // Covariance matrix 260 psFree(readout->covariance); 261 readout->covariance = covar; 262 psFree(kernel); 263 } else { 264 #endif 265 266 // Normal operations here 267 psAssert(options->psf, "Require target PSF"); 268 psAssert(options->sourceLists && options->sourceLists->data[index], "Require source list"); 276 269 277 270 int order = psMetadataLookupS32(NULL, ppsub, "SPATIAL.ORDER"); // Spatial polynomial order … … 284 277 float rej = psMetadataLookupF32(NULL, ppsub, "REJ"); // Rejection threshold 285 278 float sysError = psMetadataLookupF32(NULL, ppsub, "SYS"); // Relative systematic error in kernel 286 pmSubtractionKernelsType type = pmSubtractionKernelsTypeFromString(287 psMetadataLookupStr(NULL, ppsub, "KERNEL.TYPE")); // Kernel type279 const char *typeStr = psMetadataLookupStr(NULL, ppsub, "KERNEL.TYPE"); // Kernel type 280 pmSubtractionKernelsType type = pmSubtractionKernelsTypeFromString(typeStr); // Kernel type 288 281 psVector *widths = psMetadataLookupPtr(NULL, ppsub, "ISIS.WIDTHS"); // ISIS Gaussian widths 289 282 psVector *orders = psMetadataLookupPtr(NULL, ppsub, "ISIS.ORDERS"); // ISIS Polynomial orders … … 308 301 } 309 302 310 #if 0311 // Testing the normalisation of the fake image312 {313 pmReadout *test = pmReadoutAlloc(NULL); // Test readout314 psArray *sources = psArrayAlloc(1); // Array of sources315 pmSource *source = pmSourceAlloc(); // Source316 sources->data[0] = source;317 source->peak = pmPeakAlloc(500, 500, 10000, PM_PEAK_LONE);318 source->psfMag = -13.0;319 pmReadoutFakeFromSources(test, 1000, 1000, sources, NULL, NULL, psf, 0.1, 0, false, true);320 float sum = 0.0;321 for (int y = 0; y < test->image->numRows; y++) {322 for (int x = 0; x < test->image->numCols; x++) {323 sum += test->image->data.F32[y][x];324 }325 }326 fprintf(stderr, "Photometry: %f --> %f = -13.0 ???\n", sum, -2.5*log10(sum));327 328 psFits *fits = psFitsOpen("testphot.fits", "w");329 psFitsWriteImage(fits, NULL, test->image, 0, NULL);330 psFitsClose(fits);331 exit(0);332 }333 #endif334 335 303 pmReadout *fake = pmReadoutAlloc(NULL); // Fake readout with target PSF 336 304 337 305 // For the sake of stamps, remove nearby sources 338 psArray *stampSources = stackSourcesFilter(sources, footprint); // Filtered list of sources 306 psArray *stampSources = stackSourcesFilter(options->sourceLists->data[index], 307 footprint); // Filtered list of sources 339 308 340 309 if (!pmReadoutFakeFromSources(fake, readout->image->numCols, readout->image->numRows, 341 stampSources, NULL, NULL, psf, NAN, footprint + size,310 stampSources, NULL, NULL, options->psf, NAN, footprint + size, 342 311 false, true)) { 343 312 psError(PS_ERR_UNKNOWN, false, "Unable to generate fake image with target PSF."); 344 313 psFree(fake); 345 314 psFree(optWidths); 346 psFree( output);315 psFree(conv); 347 316 return false; 348 317 } … … 357 326 pmHDU *hdu = pmHDUFromCell(readout->parent); 358 327 psString name = NULL; 359 psStringAppend(&name, "fake_%03d.fits", numInput);328 psStringAppend(&name, "fake_%03d.fits", index); 360 329 pmStackVisualPlotTestImage(fake->image, name); 361 330 psFits *fits = psFitsOpen(name, "w"); … … 367 336 pmHDU *hdu = pmHDUFromCell(readout->parent); 368 337 psString name = NULL; 369 psStringAppend(&name, "real_%03d.fits", numInput);338 psStringAppend(&name, "real_%03d.fits", index); 370 339 pmStackVisualPlotTestImage(readout->image, name); 371 340 psFits *fits = psFitsOpen(name, "w"); … … 384 353 PM_SUBTRACTION_ANALYSIS_KERNEL); // Conv kernel 385 354 if (kernel) { 386 if (!pmSubtractionMatchPrecalc( output, NULL, readout, fake, readout->analysis,355 if (!pmSubtractionMatchPrecalc(conv, NULL, readout, fake, readout->analysis, 387 356 stride, sysError, maskVal, maskBad, maskPoor, 388 357 poorFrac, badFrac)) { … … 391 360 psFree(optWidths); 392 361 psFree(stampSources); 393 psFree( output);362 psFree(conv); 394 363 return false; 395 364 } 396 365 } else { 397 if (!pmSubtractionMatch( output, NULL, readout, fake, footprint, stride, regionSize, spacing,366 if (!pmSubtractionMatch(conv, NULL, readout, fake, footprint, stride, regionSize, spacing, 398 367 threshold, stampSources, stampsName, type, size, order, widths, 399 368 orders, inner, ringsOrder, binning, penalty, … … 405 374 psFree(optWidths); 406 375 psFree(stampSources); 407 psFree( output);376 psFree(conv); 408 377 return false; 409 378 } … … 414 383 pmHDU *hdu = pmHDUFromCell(readout->parent); 415 384 psString name = NULL; 416 psStringAppend(&name, "conv_%03d.fits", numInput);417 pmStackVisualPlotTestImage( output->image, name);385 psStringAppend(&name, "conv_%03d.fits", index); 386 pmStackVisualPlotTestImage(conv->image, name); 418 387 psFits *fits = psFitsOpen(name, "w"); 419 388 psFree(name); 420 psFitsWriteImage(fits, hdu->header, output->image, 0, NULL);389 psFitsWriteImage(fits, hdu->header, conv->image, 0, NULL); 421 390 psFitsClose(fits); 422 391 } … … 424 393 pmHDU *hdu = pmHDUFromCell(readout->parent); 425 394 psString name = NULL; 426 psStringAppend(&name, "diff_%03d.fits", numInput);395 psStringAppend(&name, "diff_%03d.fits", index); 427 396 pmStackVisualPlotTestImage(fake->image, name); 428 397 psFits *fits = psFitsOpen(name, "w"); 429 398 psFree(name); 430 psBinaryOp(fake->image, output->image, "-", fake->image);399 psBinaryOp(fake->image, conv->image, "-", fake->image); 431 400 psFitsWriteImage(fits, hdu->header, fake->image, 0, NULL); 432 401 psFitsClose(fits); … … 444 413 // Set the variance factor 445 414 psMetadataItem *vfItem = psMetadataLookup(readout->parent->concepts, "CELL.VARFACTOR"); 446 float vf = psMetadataLookupF32(NULL, output->analysis, PM_SUBTRACTION_ANALYSIS_VARFACTOR_1);415 float vf = psMetadataLookupF32(NULL, conv->analysis, PM_SUBTRACTION_ANALYSIS_VARFACTOR_1); 447 416 if (!isfinite(vf)) { 448 417 vf = 1.0; … … 459 428 psFree(readout->variance); 460 429 psFree(readout->covariance); 461 readout->image = psMemIncrRefCounter(output->image); 462 readout->mask = psMemIncrRefCounter(output->mask); 463 readout->variance = psMemIncrRefCounter(output->variance); 464 readout->covariance = psImageCovarianceTruncate(output->covariance, COVAR_FRAC); 465 } else { 466 // Fake the convolution 467 psRegion *region = psRegionAlloc(0, readout->image->numCols - 1, 0, readout->image->numRows - 1); 468 psMetadataAddPtr(output->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_REGION, 469 PS_DATA_REGION | PS_META_DUPLICATE_OK, "Fake subtraction region", region); 470 psFree(region); 471 pmSubtractionKernels *kernels = pmSubtractionKernelsPOIS(FAKE_SIZE, 0, penalty, 472 PM_SUBTRACTION_MODE_1); 473 // Set solution to delta function 474 kernels->solution1 = psVectorAlloc(kernels->num + 2, PS_TYPE_F64); 475 psVectorInit(kernels->solution1, 0.0); 476 int normIndex = PM_SUBTRACTION_INDEX_NORM(kernels); // Index for normalisation 477 kernels->solution1->data.F64[normIndex] = 1.0; 478 psMetadataAddPtr(output->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_KERNEL, 479 PS_DATA_UNKNOWN | PS_META_DUPLICATE_OK, "Fake subtraction kernel", kernels); 480 psFree(kernels); 481 } 482 430 readout->image = psMemIncrRefCounter(conv->image); 431 readout->mask = psMemIncrRefCounter(conv->mask); 432 readout->variance = psMemIncrRefCounter(conv->variance); 433 readout->covariance = psImageCovarianceTruncate(conv->covariance, COVAR_FRAC); 483 434 #ifdef TESTING 484 // Write convolution kernel 435 } 436 #endif 437 438 // Extract the regions and solutions used in the image matching 439 // This stops them from being freed when we iterate back up the FPA 440 psArray *regions = options->regions->data[index] = psArrayAllocEmpty(ARRAY_BUFFER); // Match regions 485 441 { 486 const char *outName = psMetadataLookupStr(NULL, config->arguments, "OUTPUT"); // Output root 487 assert(outName); 488 489 psString filename = NULL; // Output filename 490 psStringAppend(&filename, "%s.%d.kernel", outName, numInput); 491 psString resolved = pmConfigConvertFilename(filename, config, true, false); // Resolved filename 492 psFree(filename); 493 psFits *fits = psFitsOpen(resolved, "w"); // FITS file for subtraction kernel 494 psFree(resolved); 495 pmReadoutWriteSubtractionKernels(output, fits); 496 psFitsClose(fits); 497 } 498 } 499 #endif 500 501 readout->analysis = psMetadataCopy(readout->analysis, output->analysis); 502 503 // Extract the regions and solutions used in the image matching 504 // This stops them from being freed when we iterate back up the FPA 505 *regions = psArrayAllocEmpty(ARRAY_BUFFER); // Array of regions 506 { 507 psString regex = NULL; // Regular expression 508 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_REGION); 509 psMetadataIterator *iter = psMetadataIteratorAlloc(output->analysis, PS_LIST_HEAD, regex); // Iterator 510 psFree(regex); 511 psMetadataItem *item = NULL;// Item from iteration 512 while ((item = psMetadataGetAndIncrement(iter))) { 513 assert(item->type == PS_DATA_REGION); 514 *regions = psArrayAdd(*regions, ARRAY_BUFFER, item->data.V); 515 } 516 psFree(iter); 517 } 518 *kernels = psArrayAllocEmpty(ARRAY_BUFFER); // Array of kernels 519 { 520 psString regex = NULL; // Regular expression 521 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_KERNEL); 522 psMetadataIterator *iter = psMetadataIteratorAlloc(output->analysis, PS_LIST_HEAD, regex); // Iterator 523 psFree(regex); 524 psMetadataItem *item = NULL;// Item from iteration 525 while ((item = psMetadataGetAndIncrement(iter))) { 526 assert(item->type == PS_DATA_UNKNOWN); 527 // Set the normalisation dimensions, since these will be otherwise unavailable when reading the 528 // images by scans. 529 pmSubtractionKernels *kernel = item->data.V; // Kernel used in subtraction 530 kernel->numCols = readout->image->numCols; 531 kernel->numRows = readout->image->numRows; 532 533 *kernels = psArrayAdd(*kernels, ARRAY_BUFFER, kernel); 534 } 535 psFree(iter); 536 } 537 assert((*regions)->n == (*kernels)->n); 538 539 // Record chi^2 540 { 541 *chi2 = 0.0; 542 int num = 0; // Number of measurements of chi^2 543 psString regex = NULL; // Regular expression 544 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_KERNEL); 545 psMetadataIterator *iter = psMetadataIteratorAlloc(output->analysis, PS_LIST_HEAD, regex); // Iterator 546 psFree(regex); 547 psMetadataItem *item = NULL;// Item from iteration 548 while ((item = psMetadataGetAndIncrement(iter))) { 549 assert(item->type == PS_DATA_UNKNOWN); 550 pmSubtractionKernels *kernels = item->data.V; // Convolution kernels 551 *chi2 += kernels->mean; 552 num++; 553 } 554 psFree(iter); 555 *chi2 /= psImageCovarianceFactor(readout->covariance) * num; 556 } 557 558 // Reject image completely if the maximum deconvolution fraction exceeds the limit 559 float deconv = psMetadataLookupF32(NULL, output->analysis, 560 PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Maximum deconvolution fraction 561 if (deconv > deconvLimit) { 562 psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting\n", 563 deconv, deconvLimit); 564 psFree(output); 565 return NULL; 442 psString regex = NULL; // Regular expression 443 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_REGION); 444 psMetadataIterator *iter = psMetadataIteratorAlloc(conv->analysis, PS_LIST_HEAD, regex); 445 psFree(regex); 446 psMetadataItem *item = NULL;// Item from iteration 447 while ((item = psMetadataGetAndIncrement(iter))) { 448 assert(item->type == PS_DATA_REGION); 449 regions = psArrayAdd(regions, ARRAY_BUFFER, item->data.V); 450 } 451 psFree(iter); 452 } 453 psArray *kernels = options->kernels->data[index] = psArrayAllocEmpty(ARRAY_BUFFER); // Match kernels 454 { 455 psString regex = NULL; // Regular expression 456 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_KERNEL); 457 psMetadataIterator *iter = psMetadataIteratorAlloc(conv->analysis, PS_LIST_HEAD, regex); 458 psFree(regex); 459 psMetadataItem *item = NULL;// Item from iteration 460 while ((item = psMetadataGetAndIncrement(iter))) { 461 assert(item->type == PS_DATA_UNKNOWN); 462 // Set the normalisation dimensions, since these will be otherwise unavailable when reading 463 // the images by scans. 464 pmSubtractionKernels *kernel = item->data.V; // Kernel used in subtraction 465 kernel->numCols = readout->image->numCols; 466 kernel->numRows = readout->image->numRows; 467 468 kernels = psArrayAdd(kernels, ARRAY_BUFFER, kernel); 469 } 470 psFree(iter); 471 } 472 psAssert((regions)->n == (kernels)->n, "Number of match regions and kernels should match"); 473 474 // Record chi^2 475 { 476 double sum = 0.0; // Sum of chi^2 477 int num = 0; // Number of measurements of chi^2 478 psString regex = NULL; // Regular expression 479 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_KERNEL); 480 psMetadataIterator *iter = psMetadataIteratorAlloc(conv->analysis, PS_LIST_HEAD, regex); 481 psFree(regex); 482 psMetadataItem *item = NULL;// Item from iteration 483 while ((item = psMetadataGetAndIncrement(iter))) { 484 assert(item->type == PS_DATA_UNKNOWN); 485 pmSubtractionKernels *kernels = item->data.V; // Convolution kernels 486 sum += kernels->mean; 487 num++; 488 } 489 psFree(iter); 490 options->matchChi2->data.F32[index] = sum / (psImageCovarianceFactor(readout->covariance) * num); 491 } 492 493 // Reject image completely if the maximum deconvolution fraction exceeds the limit 494 float deconv = psMetadataLookupF32(NULL, conv->analysis, 495 PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Max deconvolution fraction 496 if (deconv > deconvLimit) { 497 psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting\n", 498 deconv, deconvLimit); 499 psFree(conv); 500 return NULL; 501 } 502 503 readout->analysis = psMetadataCopy(readout->analysis, conv->analysis); 504 505 psFree(conv); 506 } else { 507 // Match the normalisation 508 float norm = powf(10.0, -0.4 * options->norm->data.F32[index]); // Normalisation 509 psBinaryOp(readout->image, readout->image, "*", psScalarAlloc(norm, PS_TYPE_F32)); 510 psBinaryOp(readout->variance, readout->variance, "*", psScalarAlloc(PS_SQR(norm), PS_TYPE_F32)); 566 511 } 567 512 568 513 // Ensure the background value is zero 569 514 psStats *bg = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics for background 515 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator 570 516 if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal | maskBad, rng)) { 571 517 psWarning("Can't measure background for image."); … … 581 527 if (!psImageBackground(bg, NULL, readout->variance, readout->mask, maskVal | maskBad, rng)) { 582 528 psError(PS_ERR_UNKNOWN, false, "Can't measure mean variance for image."); 583 psFree(output); 529 psFree(rng); 530 psFree(bg); 584 531 return false; 585 532 } 586 *weighting= 1.0 / (psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN) *587 psImageCovarianceFactor(readout->covariance));533 options->weightings->data.F32[index] = 1.0 / (psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN) * 534 psImageCovarianceFactor(readout->covariance)); 588 535 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "PPSTACK.WEIGHTING", 0, 589 "Weighting by 1/noise^2 for stack", *weighting); 590 536 "Weighting by 1/noise^2 for stack", options->weightings->data.F32[index]); 537 538 psFree(rng); 591 539 psFree(bg); 592 593 #if 0594 #define RADIUS 10 // Radius of photometry595 #define MIN_ERR 0.05 // Minimum photometric error, mag596 #define MAX_MAG -13 // Maximum magnitude for source597 598 // Ensure the normalisation is correct599 // XXX Ideally, would like to do proper PSF-fit photometry, but will settle for aperture photometry600 int numSources = sources->n; // Number of sources601 psVector *ratio = psVectorAlloc(numSources, PS_TYPE_F32); // Flux ratios for sources602 psVector *ratioMask = psVectorAlloc(numSources, PS_TYPE_MASK); // Mask for flux ratios603 psVectorInit(ratioMask, 0xFF);604 psImage *image = readout->image; // Image of interest605 psImage *mask = readout->mask; // Mask of interest606 int numCols = image->numCols, numRows = image->numRows; // Size of image607 for (int i = 0; i < numSources; i++) {608 pmSource *source = sources->data[i]; // Source of interest609 if (!source || source->mode & SOURCE_MASK || !isfinite(source->psfMag) || !isfinite(source->errMag) ||610 source->errMag > MIN_ERR || source->psfMag > MAX_MAG) {611 continue;612 }613 614 float xSrc, ySrc; // Source coordinates615 coordsFromSource(&xSrc, &ySrc, source);616 int xMin = PS_MAX(0, xSrc - RADIUS), xMax = PS_MIN(numCols - 1, xSrc + RADIUS); // Bounds in x617 int yMin = PS_MAX(0, ySrc - RADIUS), yMax = PS_MIN(numRows - 1, ySrc + RADIUS); // Bounds in y618 int numPix = 0; // Number of pixels619 float sum = 0.0; // Sum of pixels620 for (int y = yMin; y <= yMax; y++) {621 for (int x = xMin; x <= xMax; x++) {622 if (mask->data.PS_TYPE_MASK_DATA[y][x] & maskBad) {623 continue;624 }625 sum += image->data.F32[y][x];626 numPix++;627 }628 }629 if (sum >= 0 && numPix > 0) {630 float mag = -2.5 * log10(sum * M_PI * PS_SQR(RADIUS) / numPix); // Instrumental magnitude631 ratio->data.F32[i] = mag - source->psfMag;632 ratioMask->data.PS_TYPE_MASK_DATA[i] = 0;633 }634 }635 636 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics637 if (!psVectorStats(stats, ratio, NULL, ratioMask, 0xFF)) {638 psWarning("Unable to measure normalisation --- assuming correct.");639 } else {640 psLogMsg("ppStack", PS_LOG_INFO, "Renormalising image by %f (+/- %f) mag\n",641 stats->robustMedian, stats->robustStdev);642 float norm = powf(10.0, -0.4 * stats->robustMedian); // Normalisation to apply643 psBinaryOp(image, image, "*", psScalarAlloc(norm, PS_TYPE_F32));644 }645 psFree(stats);646 psFree(ratio);647 psFree(ratioMask);648 #endif649 540 650 541 #ifdef TESTING … … 652 543 pmHDU *hdu = pmHDUFromCell(readout->parent); 653 544 psString name = NULL; 654 psStringAppend(&name, "convolved_%03d.fits", numInput);655 pmStackVisualPlotTestImage( output->image, name);545 psStringAppend(&name, "convolved_%03d.fits", index); 546 pmStackVisualPlotTestImage(readout->image, name); 656 547 psFits *fits = psFitsOpen(name, "w"); 657 548 psFree(name); 658 psFitsWriteImage(fits, hdu->header, output->image, 0, NULL);549 psFitsWriteImage(fits, hdu->header, readout->image, 0, NULL); 659 550 psFitsClose(fits); 660 551 } 661 552 #endif 662 663 psFree(output);664 553 665 554 return true;
Note:
See TracChangeset
for help on using the changeset viewer.
