Changeset 26893 for trunk/psModules/src/imcombine/pmSubtractionStamps.c
- Timestamp:
- Feb 10, 2010, 7:34:39 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/imcombine/pmSubtractionStamps.c
r26046 r26893 46 46 psFree(list->y); 47 47 psFree(list->flux); 48 psFree(list->window); 48 49 } 49 50 … … 57 58 psFree(stamp->convolutions1); 58 59 psFree(stamp->convolutions2); 59 60 psFree(stamp->matrix1); 61 psFree(stamp->matrix2); 62 psFree(stamp->matrixX); 63 psFree(stamp->vector1); 64 psFree(stamp->vector2); 65 60 psFree(stamp->matrix); 61 psFree(stamp->vector); 66 62 } 67 63 … … 80 76 81 77 // Search a region for a suitable stamp 82 bool stampSearch( int *xStamp, int *yStamp, // Coordinates of stamp, to return78 bool stampSearch(float *xStamp, float *yStamp, // Coordinates of stamp, to return 83 79 float *fluxStamp, // Flux of stamp, to return 84 80 const psImage *image1, const psImage *image2, // Images to search … … 93 89 *fluxStamp = -INFINITY; // Flux of best stamp 94 90 91 // fprintf (stderr, "xMin, xMax: %d, %d -> ", xMin, xMax); 92 95 93 // Ensure we're not going to go outside the bounds of the image 96 94 xMin = PS_MAX(border, xMin); … … 99 97 yMax = PS_MIN(numRows - border - 1, yMax); 100 98 99 if (xMax < xMin) return false; 100 if (yMax < yMin) return false; 101 102 psAssert (xMin <= xMax, "x mismatch?"); 103 psAssert (yMin <= yMax, "y mismatch?"); 104 101 105 for (int y = yMin; y <= yMax; y++) { 102 106 for (int x = xMin; x <= xMax; x++) { … … 115 119 ((image1) ? image1->data.F32[y][x] : image2->data.F32[y][x]); // Flux at pixel 116 120 if (flux > *fluxStamp) { 117 *xStamp = x ;118 *yStamp = y ;121 *xStamp = x + 0.5; 122 *yStamp = y + 0.5; 119 123 *fluxStamp = flux; 120 124 found = true; … … 180 184 181 185 pmSubtractionStampList *pmSubtractionStampListAlloc(int numCols, int numRows, const psRegion *region, 182 int footprint, float spacing, float sysErr) 186 int footprint, float spacing, float normFrac, 187 float sysErr, float skyErr) 183 188 { 184 189 pmSubtractionStampList *list = psAlloc(sizeof(pmSubtractionStampList)); // Stamp list to return … … 220 225 list->y = NULL; 221 226 list->flux = NULL; 227 list->window = NULL; 228 list->normFrac = normFrac; 229 list->normWindow = 0; 222 230 list->footprint = footprint; 223 231 list->sysErr = sysErr; 232 list->skyErr = skyErr; 224 233 225 234 return list; … … 239 248 out->y = NULL; 240 249 out->flux = NULL; 250 out->window = psMemIncrRefCounter(in->window); 241 251 out->footprint = in->footprint; 252 out->normWindow = in->normWindow; 242 253 243 254 for (int i = 0; i < num; i++) { … … 280 291 } 281 292 282 outStamp->matrix1 = inStamp->matrix1 ? psImageCopy(NULL, inStamp->matrix1, PS_TYPE_F64) : NULL; 283 outStamp->matrix2 = inStamp->matrix2 ? psImageCopy(NULL, inStamp->matrix2, PS_TYPE_F64) : NULL; 284 outStamp->matrixX = inStamp->matrixX ? psImageCopy(NULL, inStamp->matrixX, PS_TYPE_F64) : NULL; 285 outStamp->vector1 = inStamp->vector1 ? psVectorCopy(NULL, inStamp->vector1, PS_TYPE_F64) : NULL; 286 outStamp->vector2 = inStamp->vector2 ? psVectorCopy(NULL, inStamp->vector2, PS_TYPE_F64) : NULL; 293 outStamp->matrix = inStamp->matrix ? psImageCopy(NULL, inStamp->matrix, PS_TYPE_F64) : NULL; 294 outStamp->vector = inStamp->vector ? psVectorCopy(NULL, inStamp->vector, PS_TYPE_F64) : NULL; 287 295 288 296 out->stamps->data[i] = outStamp; … … 310 318 stamp->convolutions2 = NULL; 311 319 312 stamp->matrix1 = NULL; 313 stamp->matrix2 = NULL; 314 stamp->matrixX = NULL; 315 stamp->vector1 = NULL; 316 stamp->vector2 = NULL; 320 stamp->matrix = NULL; 321 stamp->vector = NULL; 322 stamp->norm = NAN; 317 323 318 324 return stamp; … … 323 329 const psImage *image2, const psImage *subMask, 324 330 const psRegion *region, float thresh1, float thresh2, 325 int size, int footprint, float spacing, float sysErr,326 pmSubtractionMode mode)331 int size, int footprint, float spacing, float normFrac, 332 float sysErr, float skyErr, pmSubtractionMode mode) 327 333 { 328 334 if (!image1 && !image2) { … … 380 386 381 387 if (!stamps) { 382 stamps = pmSubtractionStampListAlloc(numCols, numRows, region, footprint, spacing, sysErr); 388 stamps = pmSubtractionStampListAlloc(numCols, numRows, region, footprint, spacing, 389 normFrac, sysErr, skyErr); 383 390 } 384 391 … … 402 409 numSearch++; 403 410 404 int xStamp = 0, yStamp =0; // Coordinates of stamp411 float xStamp = 0.0, yStamp = 0.0; // Coordinates of stamp 405 412 float fluxStamp = -INFINITY; // Flux of stamp 406 413 bool goodStamp = false; // Found a good stamp? … … 414 421 // Take stamps off the top of the (sorted) list 415 422 for (int j = xList->n - 1; j >= 0 && !goodStamp; j--) { 416 int xCentre = xList->data.F32[j] + 0.5, yCentre = yList->data.F32[j] + 0.5;// Stamp centre417 418 423 // Chop off the top of the list 419 424 xList->n = j; … … 421 426 fluxList->n = j; 422 427 428 #if 0 423 429 // Fish around a bit to see if we can find a pixel that isn't masked 430 // This is not a good idea if we're using the window feature 424 431 psTrace("psModules.imcombine", 7, "Searching for stamp %d around %d,%d\n", 425 432 i, xCentre, yCentre); 426 433 427 434 // Search bounds 435 int xCentre = xList->data.F32[j] - 0.5, yCentre = yList->data.F32[j] - 0.5;// Stamp centre 428 436 int search = footprint - size; // Search radius 429 437 int xMin = PS_MAX(border, xCentre - search); … … 434 442 goodStamp = stampSearch(&xStamp, &yStamp, &fluxStamp, image1, image2, thresh1, thresh2, 435 443 subMask, xMin, xMax, yMin, yMax, numCols, numRows, border); 444 // fprintf (stderr, "find: %d %d ==> %5.1f %5.1f (\n", xCentre, yCentre, xStamp, yStamp); 445 #else 446 // Only search the exact centre pixel 447 goodStamp = stampSearch(&xStamp, &yStamp, &fluxStamp, image1, image2, thresh1, thresh2, 448 subMask, xList->data.F32[j], xList->data.F32[j], 449 yList->data.F32[j], yList->data.F32[j], numCols, numRows, border); 450 #endif 451 if (0 && goodStamp) { 452 fprintf (stderr, "find: %6.1f < %6.1f < %6.1f, %6.1f < %6.1f %6.1f\n", 453 region->x0 + size, xStamp, region->x1 - size, 454 region->y0 + size, yStamp, region->y1 - size); 455 } 436 456 } 437 457 } else { … … 488 508 const psImage *image, const psImage *subMask, 489 509 const psRegion *region, int size, int footprint, 490 float spacing, float sysErr, pmSubtractionMode mode) 510 float spacing, float normFrac, float sysErr, float skyErr, 511 pmSubtractionMode mode) 491 512 492 513 { … … 509 530 pmSubtractionStampList *stamps = pmSubtractionStampListAlloc(subMask->numCols, subMask->numRows, 510 531 region, footprint, spacing, 511 sysErr); // Stamp list532 normFrac, sysErr, skyErr); // Stamp list 512 533 int numStamps = stamps->num; // Number of stamps 513 534 … … 531 552 for (int i = 0; i < numStars; i++) { 532 553 float xStamp = x->data.F32[i], yStamp = y->data.F32[i]; // Coordinates of stamp 533 int xPix = xStamp + 0.5, yPix = yStamp +0.5; // Pixel coordinate of stamp554 int xPix = xStamp - 0.5, yPix = yStamp - 0.5; // Pixel coordinate of stamp 534 555 if (!checkStampRegion(xPix, yPix, region)) { 535 556 // It's not in the big region … … 539 560 continue; 540 561 } 562 563 // fprintf (stderr, "stamp: %5.1f %5.1f == %d %d\n", xStamp, yStamp, xPix, yPix); 541 564 542 565 bool found = false; … … 607 630 608 631 632 bool pmSubtractionStampsGetWindow(pmSubtractionStampList *stamps, int kernelSize) 633 { 634 PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, false); 635 PS_ASSERT_INT_NONNEGATIVE(kernelSize, false); 636 637 int size = stamps->footprint; // Size of postage stamps 638 639 psFree (stamps->window); 640 stamps->window = psKernelAlloc(-size, size, -size, size); 641 psImageInit(stamps->window->image, 0.0); 642 643 // generate normalizations for each stamp 644 psVector *norm1 = psVectorAlloc(stamps->num, PS_TYPE_F32); 645 psVector *norm2 = psVectorAlloc(stamps->num, PS_TYPE_F32); 646 for (int i = 0; i < stamps->num; i++) { 647 pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest 648 if (!stamp) continue; 649 if (!stamp->image1) continue; 650 if (!stamp->image2) continue; 651 652 float sum1 = 0.0; 653 float sum2 = 0.0; 654 for (int y = -size; y <= size; y++) { 655 for (int x = -size; x <= size; x++) { 656 sum1 += stamp->image1->kernel[y][x]; 657 sum2 += stamp->image2->kernel[y][x]; 658 } 659 } 660 norm1->data.F32[i] = sum1; 661 norm2->data.F32[i] = sum2; 662 } 663 664 // storage vector for flux data 665 psStats *stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 666 psVector *flux1 = psVectorAllocEmpty(2*stamps->num, PS_TYPE_F32); 667 psVector *flux2 = psVectorAllocEmpty(2*stamps->num, PS_TYPE_F32); 668 669 // generate the window pixels 670 double sum = 0.0; // Sum inside the window 671 float maxValue = 0.0; // Maximum value, for normalisation 672 for (int y = -size; y <= size; y++) { 673 for (int x = -size; x <= size; x++) { 674 675 flux1->n = 0; 676 flux2->n = 0; 677 for (int i = 0; i < stamps->num; i++) { 678 pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest 679 if (!stamp) continue; 680 if (!stamp->image1) continue; 681 if (!stamp->image2) continue; 682 683 psVectorAppend(flux1, stamp->image1->kernel[y][x] / norm1->data.F32[i]); 684 psVectorAppend(flux2, stamp->image2->kernel[y][x] / norm2->data.F32[i]); 685 } 686 687 psStatsInit (stats); 688 if (!psVectorStats (stats, flux1, NULL, NULL, 0)) { 689 psAbort ("failed to generate stats"); 690 } 691 float f1 = stats->robustMedian; 692 psStatsInit (stats); 693 if (!psVectorStats (stats, flux2, NULL, NULL, 0)) { 694 psAbort ("failed to generate stats"); 695 } 696 float f2 = stats->robustMedian; 697 698 stamps->window->kernel[y][x] = f1 + f2; 699 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(size)) { 700 sum += stamps->window->kernel[y][x]; 701 } 702 maxValue = PS_MAX(maxValue, stamps->window->kernel[y][x]); 703 } 704 } 705 706 psTrace("psModules.imcombine", 3, "Window total: %f, threshold: %f\n", 707 sum, (1.0 - stamps->normFrac) * sum); 708 bool done = false; 709 for (int radius = 1; radius <= size && !done; radius++) { 710 double within = 0.0; 711 for (int y = -radius; y <= radius; y++) { 712 for (int x = -radius; x <= radius; x++) { 713 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(radius)) { 714 within += stamps->window->kernel[y][x]; 715 } 716 } 717 } 718 psTrace("psModules.imcombine", 5, "Radius %d: %f\n", radius, within); 719 if (within > (1.0 - stamps->normFrac) * sum) { 720 stamps->normWindow = radius; 721 done = true; 722 } 723 } 724 725 psTrace("psModules.imcombine", 3, "Normalisation window radius set to %d\n", stamps->normWindow); 726 if (stamps->normWindow == 0 || stamps->normWindow >= size) { 727 psError(PS_ERR_UNKNOWN, true, "Unable to determine normalisation window size."); 728 return false; 729 } 730 731 // re-normalize so chisquare values are sensible 732 for (int y = -size; y <= size; y++) { 733 for (int x = -size; x <= size; x++) { 734 stamps->window->kernel[y][x] /= maxValue; 735 } 736 } 737 738 #if 0 739 { 740 psFits *fits = psFitsOpen ("window.fits", "w"); 741 psFitsWriteImage (fits, NULL, stamps->window->image, 0, NULL); 742 psFitsClose (fits); 743 } 744 #endif 745 746 psFree (stats); 747 psFree (flux1); 748 psFree(flux2); 749 psFree (norm1); 750 psFree (norm2); 751 return true; 752 } 753 609 754 bool pmSubtractionStampsExtract(pmSubtractionStampList *stamps, psImage *image1, psImage *image2, 610 psImage *variance, int kernelSize )755 psImage *variance, int kernelSize, psRegion bounds) 611 756 { 612 757 PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, false); … … 625 770 } 626 771 627 int numCols = image1->numCols, numRows = image1->numRows; // Size of images628 772 int size = kernelSize + stamps->footprint; // Size of postage stamps 629 773 … … 634 778 } 635 779 636 if (isnan(stamp->xNorm)) { 637 stamp->xNorm = 2.0 * (stamp->x - (float)numCols/2.0) / (float)numCols; 638 } 639 if (isnan(stamp->yNorm)) { 640 stamp->yNorm = 2.0 * (stamp->y - (float)numRows/2.0) / (float)numRows; 641 } 642 643 int x = stamp->x + 0.5, y = stamp->y + 0.5; // Stamp coordinates 644 if (x < size || x > numCols - size || y < size || y > numRows - size) { 645 psError(PS_ERR_UNKNOWN, false, "Stamp %d (%d,%d) is within the image border.\n", i, x, y); 780 p_pmSubtractionPolynomialNormCoords(&stamp->xNorm, &stamp->yNorm, stamp->x, stamp->y, 781 bounds.x0, bounds.x1, bounds.y0, bounds.y1); 782 783 int x = stamp->x - 0.5, y = stamp->y - 0.5; // Stamp coordinates 784 // fprintf (stderr, "stamp: %5.1f %5.1f == %d %d (size: %d)\n", stamp->x, stamp->y, x, y, size); 785 786 if (x < bounds.x0 + size || x > bounds.x1 - size || y < bounds.y0 + size || y > bounds.y1 - size) { 787 psError(PS_ERR_UNKNOWN, false, "Stamp %d (%d,%d) is within the region border.\n", i, x, y); 646 788 return false; 647 789 } … … 668 810 psImage *varSub = psImageSubset(variance, region); // Subimage with stamp 669 811 psKernel *var = psKernelAllocFromImage(varSub, size, size); // Variance postage stamp 670 if (isfinite(stamps->sysErr) && stamps->sysErr > 0) { 812 813 if ((isfinite(stamps->skyErr) && (stamps->skyErr > 0)) || 814 (isfinite(stamps->sysErr) && (stamps->sysErr > 0))) { 671 815 float sysErr = 0.25 * PS_SQR(stamps->sysErr); // Systematic error 816 float skyErr = stamps->skyErr; 672 817 psKernel *image1 = stamp->image1, *image2 = stamp->image2; // Input images 673 818 for (int y = -size; y <= size; y++) { 674 819 for (int x = -size; x <= size; x++) { 675 820 float additional = image1->kernel[y][x] + image2->kernel[y][x]; 676 weight->kernel[y][x] = 1.0 / ( var->kernel[y][x] + sysErr * PS_SQR(additional));821 weight->kernel[y][x] = 1.0 / (skyErr + var->kernel[y][x] + sysErr * PS_SQR(additional)); 677 822 } 678 823 } … … 698 843 pmSubtractionStampList *pmSubtractionStampsSetFromSources(const psArray *sources, const psImage *image, 699 844 const psImage *subMask, const psRegion *region, 700 int size, int footprint, float spacing, float sysErr, 845 int size, int footprint, float spacing, 846 float normFrac, float sysErr, float skyErr, 701 847 pmSubtractionMode mode) 702 848 { … … 722 868 y->data.F32[numOut] = source->peak->yf; 723 869 } 870 // fprintf (stderr, "stamp: %5.1f %5.1f\n", x->data.F32[numOut], y->data.F32[numOut]); 724 871 numOut++; 725 872 } … … 728 875 729 876 pmSubtractionStampList *stamps = pmSubtractionStampsSet(x, y, image, subMask, region, size, 730 footprint, spacing, sysErr, mode); // Stamps 877 footprint, spacing, normFrac, 878 sysErr, skyErr, mode); // Stamps 731 879 psFree(x); 732 880 psFree(y); … … 742 890 pmSubtractionStampList *pmSubtractionStampsSetFromFile(const char *filename, const psImage *image, 743 891 const psImage *subMask, const psRegion *region, 744 int size, int footprint, float spacing, float sysErr,745 pmSubtractionMode mode)892 int size, int footprint, float spacing, float normFrac, 893 float sysErr, float skyErr, pmSubtractionMode mode) 746 894 { 747 895 PS_ASSERT_STRING_NON_EMPTY(filename, NULL); … … 760 908 761 909 pmSubtractionStampList *stamps = pmSubtractionStampsSet(x, y, image, subMask, region, size, footprint, 762 spacing, sysErr, mode);910 spacing, normFrac, sysErr, skyErr, mode); 763 911 psFree(data); 764 912 … … 766 914 767 915 } 916 917 918 bool pmSubtractionStampsResetStatus (pmSubtractionStampList *stamps) { 919 920 for (int i = 0; i < stamps->num; i++) { 921 pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest 922 if (!stamp) continue; 923 if (stamp->status != PM_SUBTRACTION_STAMP_USED) continue; 924 stamp->status = PM_SUBTRACTION_STAMP_CALCULATE; 925 } 926 return true; 927 } 928
Note:
See TracChangeset
for help on using the changeset viewer.
