- Timestamp:
- Mar 29, 2009, 6:15:31 PM (17 years ago)
- Location:
- branches/cnb_branches/cnb_branch_20090301
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/cnb_branches/cnb_branch_20090301
-
branches/cnb_branches/cnb_branch_20090301/ppStack
- Property svn:mergeinfo changed
/trunk/ppStack merged: 23357,23360,23362,23364,23367-23368,23371-23373,23379,23462,23573,23575-23577
- Property svn:mergeinfo changed
-
branches/cnb_branches/cnb_branch_20090301/ppStack/src/ppStackMatch.c
r23352 r23594 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"); … … 381 350 382 351 // Do the image matching 383 if (!pmSubtractionMatch(output, NULL, readout, fake, footprint, stride, regionSize, spacing, 384 threshold, stampSources, stampsName, type, size, order, widths, orders, 385 inner, ringsOrder, binning, penalty, optimum, optWidths, optOrder, 386 optThresh, iter, rej, sysError, maskVal, maskBad, maskPoor, poorFrac, 387 badFrac, PM_SUBTRACTION_MODE_1)) { 388 psError(PS_ERR_UNKNOWN, false, "Unable to match images."); 389 psFree(fake); 390 psFree(optWidths); 391 psFree(stampSources); 392 psFree(output); 393 return false; 352 pmSubtractionKernels *kernel = psMetadataLookupPtr(&mdok, readout->analysis, 353 PM_SUBTRACTION_ANALYSIS_KERNEL); // Conv kernel 354 if (kernel) { 355 if (!pmSubtractionMatchPrecalc(conv, NULL, readout, fake, readout->analysis, 356 stride, sysError, maskVal, maskBad, maskPoor, 357 poorFrac, badFrac)) { 358 psError(PS_ERR_UNKNOWN, false, "Unable to convolve images."); 359 psFree(fake); 360 psFree(optWidths); 361 psFree(stampSources); 362 psFree(conv); 363 return false; 364 } 365 } else { 366 if (!pmSubtractionMatch(conv, NULL, readout, fake, footprint, stride, regionSize, spacing, 367 threshold, stampSources, stampsName, type, size, order, widths, 368 orders, inner, ringsOrder, binning, penalty, 369 optimum, optWidths, optOrder, optThresh, iter, rej, sysError, 370 maskVal, maskBad, maskPoor, poorFrac, badFrac, 371 PM_SUBTRACTION_MODE_1)) { 372 psError(PS_ERR_UNKNOWN, false, "Unable to match images."); 373 psFree(fake); 374 psFree(optWidths); 375 psFree(stampSources); 376 psFree(conv); 377 return false; 378 } 394 379 } 395 380 … … 398 383 pmHDU *hdu = pmHDUFromCell(readout->parent); 399 384 psString name = NULL; 400 psStringAppend(&name, "conv_%03d.fits", numInput);401 pmStackVisualPlotTestImage( output->image, name);385 psStringAppend(&name, "conv_%03d.fits", index); 386 pmStackVisualPlotTestImage(conv->image, name); 402 387 psFits *fits = psFitsOpen(name, "w"); 403 388 psFree(name); 404 psFitsWriteImage(fits, hdu->header, output->image, 0, NULL);389 psFitsWriteImage(fits, hdu->header, conv->image, 0, NULL); 405 390 psFitsClose(fits); 406 391 } … … 408 393 pmHDU *hdu = pmHDUFromCell(readout->parent); 409 394 psString name = NULL; 410 psStringAppend(&name, "diff_%03d.fits", numInput);395 psStringAppend(&name, "diff_%03d.fits", index); 411 396 pmStackVisualPlotTestImage(fake->image, name); 412 397 psFits *fits = psFitsOpen(name, "w"); 413 398 psFree(name); 414 psBinaryOp(fake->image, output->image, "-", fake->image);399 psBinaryOp(fake->image, conv->image, "-", fake->image); 415 400 psFitsWriteImage(fits, hdu->header, fake->image, 0, NULL); 416 401 psFitsClose(fits); … … 428 413 // Set the variance factor 429 414 psMetadataItem *vfItem = psMetadataLookup(readout->parent->concepts, "CELL.VARFACTOR"); 430 float vf = psMetadataLookupF32(NULL, output->analysis, PM_SUBTRACTION_ANALYSIS_VARFACTOR_1);415 float vf = psMetadataLookupF32(NULL, conv->analysis, PM_SUBTRACTION_ANALYSIS_VARFACTOR_1); 431 416 if (!isfinite(vf)) { 432 417 vf = 1.0; … … 443 428 psFree(readout->variance); 444 429 psFree(readout->covariance); 445 readout->image = psMemIncrRefCounter(output->image); 446 readout->mask = psMemIncrRefCounter(output->mask); 447 readout->variance = psMemIncrRefCounter(output->variance); 448 readout->covariance = psImageCovarianceTruncate(output->covariance, COVAR_FRAC); 449 } else { 450 // Fake the convolution 451 psRegion *region = psRegionAlloc(0, readout->image->numCols - 1, 0, readout->image->numRows - 1); 452 psMetadataAddPtr(output->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_REGION, 453 PS_DATA_REGION | PS_META_DUPLICATE_OK, "Fake subtraction region", region); 454 psFree(region); 455 pmSubtractionKernels *kernels = pmSubtractionKernelsPOIS(FAKE_SIZE, 0, penalty, 456 PM_SUBTRACTION_MODE_1); 457 // Set solution to delta function 458 kernels->solution1 = psVectorAlloc(kernels->num + 2, PS_TYPE_F64); 459 psVectorInit(kernels->solution1, 0.0); 460 int normIndex = PM_SUBTRACTION_INDEX_NORM(kernels); // Index for normalisation 461 kernels->solution1->data.F64[normIndex] = 1.0; 462 psMetadataAddPtr(output->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_KERNEL, 463 PS_DATA_UNKNOWN | PS_META_DUPLICATE_OK, "Fake subtraction kernel", kernels); 464 psFree(kernels); 465 } 466 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); 467 434 #ifdef TESTING 468 // 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 469 441 { 470 const char *outName = psMetadataLookupStr(NULL, config->arguments, "OUTPUT"); // Output root 471 assert(outName); 472 473 psString filename = NULL; // Output filename 474 psStringAppend(&filename, "%s.%d.kernel", outName, numInput); 475 psString resolved = pmConfigConvertFilename(filename, config, true, false); // Resolved filename 476 psFree(filename); 477 psFits *fits = psFitsOpen(resolved, "w"); // FITS file for subtraction kernel 478 psFree(resolved); 479 pmReadoutWriteSubtractionKernels(output, fits); 480 psFitsClose(fits); 481 } 482 } 483 #endif 484 485 readout->analysis = psMetadataCopy(readout->analysis, output->analysis); 486 487 // Extract the regions and solutions used in the image matching 488 // This stops them from being freed when we iterate back up the FPA 489 *regions = psArrayAllocEmpty(ARRAY_BUFFER); // Array of regions 490 { 491 psString regex = NULL; // Regular expression 492 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_REGION); 493 psMetadataIterator *iter = psMetadataIteratorAlloc(output->analysis, PS_LIST_HEAD, regex); // Iterator 494 psFree(regex); 495 psMetadataItem *item = NULL;// Item from iteration 496 while ((item = psMetadataGetAndIncrement(iter))) { 497 assert(item->type == PS_DATA_REGION); 498 *regions = psArrayAdd(*regions, ARRAY_BUFFER, item->data.V); 499 } 500 psFree(iter); 501 } 502 *kernels = psArrayAllocEmpty(ARRAY_BUFFER); // Array of kernels 503 { 504 psString regex = NULL; // Regular expression 505 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_KERNEL); 506 psMetadataIterator *iter = psMetadataIteratorAlloc(output->analysis, PS_LIST_HEAD, regex); // Iterator 507 psFree(regex); 508 psMetadataItem *item = NULL;// Item from iteration 509 while ((item = psMetadataGetAndIncrement(iter))) { 510 assert(item->type == PS_DATA_UNKNOWN); 511 // Set the normalisation dimensions, since these will be otherwise unavailable when reading the 512 // images by scans. 513 pmSubtractionKernels *kernel = item->data.V; // Kernel used in subtraction 514 kernel->numCols = readout->image->numCols; 515 kernel->numRows = readout->image->numRows; 516 517 *kernels = psArrayAdd(*kernels, ARRAY_BUFFER, kernel); 518 } 519 psFree(iter); 520 } 521 assert((*regions)->n == (*kernels)->n); 522 523 // Record chi^2 524 { 525 *chi2 = 0.0; 526 int num = 0; // Number of measurements of chi^2 527 psString regex = NULL; // Regular expression 528 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_KERNEL); 529 psMetadataIterator *iter = psMetadataIteratorAlloc(output->analysis, PS_LIST_HEAD, regex); // Iterator 530 psFree(regex); 531 psMetadataItem *item = NULL;// Item from iteration 532 while ((item = psMetadataGetAndIncrement(iter))) { 533 assert(item->type == PS_DATA_UNKNOWN); 534 pmSubtractionKernels *kernels = item->data.V; // Convolution kernels 535 *chi2 += kernels->mean; 536 num++; 537 } 538 psFree(iter); 539 *chi2 /= psImageCovarianceFactor(readout->covariance) * num; 540 } 541 542 // Reject image completely if the maximum deconvolution fraction exceeds the limit 543 float deconv = psMetadataLookupF32(NULL, output->analysis, 544 PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Maximum deconvolution fraction 545 if (deconv > deconvLimit) { 546 psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting\n", 547 deconv, deconvLimit); 548 psFree(output); 549 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)); 550 511 } 551 512 552 513 // Ensure the background value is zero 553 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 554 516 if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal | maskBad, rng)) { 555 517 psWarning("Can't measure background for image."); … … 565 527 if (!psImageBackground(bg, NULL, readout->variance, readout->mask, maskVal | maskBad, rng)) { 566 528 psError(PS_ERR_UNKNOWN, false, "Can't measure mean variance for image."); 567 psFree(output); 529 psFree(rng); 530 psFree(bg); 568 531 return false; 569 532 } 570 *weighting= 1.0 / (psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN) *571 psImageCovarianceFactor(readout->covariance));533 options->weightings->data.F32[index] = 1.0 / (psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN) * 534 psImageCovarianceFactor(readout->covariance)); 572 535 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "PPSTACK.WEIGHTING", 0, 573 "Weighting by 1/noise^2 for stack", *weighting); 574 536 "Weighting by 1/noise^2 for stack", options->weightings->data.F32[index]); 537 538 psFree(rng); 575 539 psFree(bg); 576 577 #if 0578 #define RADIUS 10 // Radius of photometry579 #define MIN_ERR 0.05 // Minimum photometric error, mag580 #define MAX_MAG -13 // Maximum magnitude for source581 582 // Ensure the normalisation is correct583 // XXX Ideally, would like to do proper PSF-fit photometry, but will settle for aperture photometry584 int numSources = sources->n; // Number of sources585 psVector *ratio = psVectorAlloc(numSources, PS_TYPE_F32); // Flux ratios for sources586 psVector *ratioMask = psVectorAlloc(numSources, PS_TYPE_MASK); // Mask for flux ratios587 psVectorInit(ratioMask, 0xFF);588 psImage *image = readout->image; // Image of interest589 psImage *mask = readout->mask; // Mask of interest590 int numCols = image->numCols, numRows = image->numRows; // Size of image591 for (int i = 0; i < numSources; i++) {592 pmSource *source = sources->data[i]; // Source of interest593 if (!source || source->mode & SOURCE_MASK || !isfinite(source->psfMag) || !isfinite(source->errMag) ||594 source->errMag > MIN_ERR || source->psfMag > MAX_MAG) {595 continue;596 }597 598 float xSrc, ySrc; // Source coordinates599 coordsFromSource(&xSrc, &ySrc, source);600 int xMin = PS_MAX(0, xSrc - RADIUS), xMax = PS_MIN(numCols - 1, xSrc + RADIUS); // Bounds in x601 int yMin = PS_MAX(0, ySrc - RADIUS), yMax = PS_MIN(numRows - 1, ySrc + RADIUS); // Bounds in y602 int numPix = 0; // Number of pixels603 float sum = 0.0; // Sum of pixels604 for (int y = yMin; y <= yMax; y++) {605 for (int x = xMin; x <= xMax; x++) {606 if (mask->data.PS_TYPE_MASK_DATA[y][x] & maskBad) {607 continue;608 }609 sum += image->data.F32[y][x];610 numPix++;611 }612 }613 if (sum >= 0 && numPix > 0) {614 float mag = -2.5 * log10(sum * M_PI * PS_SQR(RADIUS) / numPix); // Instrumental magnitude615 ratio->data.F32[i] = mag - source->psfMag;616 ratioMask->data.PS_TYPE_MASK_DATA[i] = 0;617 }618 }619 620 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics621 if (!psVectorStats(stats, ratio, NULL, ratioMask, 0xFF)) {622 psWarning("Unable to measure normalisation --- assuming correct.");623 } else {624 psLogMsg("ppStack", PS_LOG_INFO, "Renormalising image by %f (+/- %f) mag\n",625 stats->robustMedian, stats->robustStdev);626 float norm = powf(10.0, -0.4 * stats->robustMedian); // Normalisation to apply627 psBinaryOp(image, image, "*", psScalarAlloc(norm, PS_TYPE_F32));628 }629 psFree(stats);630 psFree(ratio);631 psFree(ratioMask);632 #endif633 540 634 541 #ifdef TESTING … … 636 543 pmHDU *hdu = pmHDUFromCell(readout->parent); 637 544 psString name = NULL; 638 psStringAppend(&name, "convolved_%03d.fits", numInput);639 pmStackVisualPlotTestImage( output->image, name);545 psStringAppend(&name, "convolved_%03d.fits", index); 546 pmStackVisualPlotTestImage(readout->image, name); 640 547 psFits *fits = psFitsOpen(name, "w"); 641 548 psFree(name); 642 psFitsWriteImage(fits, hdu->header, output->image, 0, NULL);549 psFitsWriteImage(fits, hdu->header, readout->image, 0, NULL); 643 550 psFitsClose(fits); 644 551 } 645 552 #endif 646 647 psFree(output);648 553 649 554 return true;
Note:
See TracChangeset
for help on using the changeset viewer.
