- Timestamp:
- May 3, 2010, 8:41:49 AM (16 years ago)
- Location:
- branches/tap_branches
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/tap_branches
- Property svn:mergeinfo changed
-
branches/tap_branches/psModules
-
Property svn:mergeinfo
set to (toggle deleted branches)
/trunk/psModules merged eligible /branches/eam_branches/stackphot.20100406/psModules 27623-27653 /branches/pap_delete/psModules 27530-27595
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
branches/tap_branches/psModules/src/imcombine/pmSubtractionStamps.c
r25120 r27838 46 46 psFree(list->y); 47 47 psFree(list->flux); 48 psFree(list->window); 48 49 } 49 50 … … 54 55 psFree(stamp->image1); 55 56 psFree(stamp->image2); 56 psFree(stamp-> variance);57 psFree(stamp->weight); 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) 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; 231 list->sysErr = sysErr; 232 list->skyErr = skyErr; 223 233 224 234 return list; … … 238 248 out->y = NULL; 239 249 out->flux = NULL; 250 out->window = psMemIncrRefCounter(in->window); 240 251 out->footprint = in->footprint; 252 out->normWindow = in->normWindow; 241 253 242 254 for (int i = 0; i < num; i++) { … … 256 268 outStamp->image1 = inStamp->image1 ? psKernelCopy(inStamp->image1) : NULL; 257 269 outStamp->image2 = inStamp->image2 ? psKernelCopy(inStamp->image2) : NULL; 258 outStamp-> variance = inStamp->variance ? psKernelCopy(inStamp->variance) : NULL;270 outStamp->weight = inStamp->weight ? psKernelCopy(inStamp->weight) : NULL; 259 271 260 272 if (inStamp->convolutions1) { … … 279 291 } 280 292 281 outStamp->matrix1 = inStamp->matrix1 ? psImageCopy(NULL, inStamp->matrix1, PS_TYPE_F64) : NULL; 282 outStamp->matrix2 = inStamp->matrix2 ? psImageCopy(NULL, inStamp->matrix2, PS_TYPE_F64) : NULL; 283 outStamp->matrixX = inStamp->matrixX ? psImageCopy(NULL, inStamp->matrixX, PS_TYPE_F64) : NULL; 284 outStamp->vector1 = inStamp->vector1 ? psVectorCopy(NULL, inStamp->vector1, PS_TYPE_F64) : NULL; 285 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; 286 295 287 296 out->stamps->data[i] = outStamp; … … 305 314 stamp->image1 = NULL; 306 315 stamp->image2 = NULL; 307 stamp-> variance= NULL;316 stamp->weight = NULL; 308 317 stamp->convolutions1 = NULL; 309 318 stamp->convolutions2 = NULL; 310 319 311 stamp->matrix1 = NULL; 312 stamp->matrix2 = NULL; 313 stamp->matrixX = NULL; 314 stamp->vector1 = NULL; 315 stamp->vector2 = NULL; 320 stamp->matrix = NULL; 321 stamp->vector = NULL; 322 stamp->norm = NAN; 316 323 317 324 return stamp; … … 322 329 const psImage *image2, const psImage *subMask, 323 330 const psRegion *region, float thresh1, float thresh2, 324 int size, int footprint, float spacing, 325 pmSubtractionMode mode)331 int size, int footprint, float spacing, float normFrac, 332 float sysErr, float skyErr, pmSubtractionMode mode) 326 333 { 327 334 if (!image1 && !image2) { … … 362 369 if (psRegionIsNaN(*region)) { 363 370 psString string = psRegionToString(*region); 364 psError(P S_ERR_BAD_PARAMETER_VALUE, true, "Input region (%s) contains NAN values", string);371 psError(PM_ERR_PROG, true, "Input region (%s) contains NAN values", string); 365 372 psFree(string); 366 373 return false; … … 369 376 region->y0 < 0 || region->y1 > numRows) { 370 377 psString string = psRegionToString(*region); 371 psError(P S_ERR_BAD_PARAMETER_VALUE, true, "Input region (%s) does not fit in image (%dx%d)",378 psError(PM_ERR_PROG, true, "Input region (%s) does not fit in image (%dx%d)", 372 379 string, numCols, numRows); 373 380 psFree(string); … … 379 386 380 387 if (!stamps) { 381 stamps = pmSubtractionStampListAlloc(numCols, numRows, region, footprint, spacing); 388 stamps = pmSubtractionStampListAlloc(numCols, numRows, region, footprint, spacing, 389 normFrac, sysErr, skyErr); 382 390 } 383 391 … … 401 409 numSearch++; 402 410 403 int xStamp = 0, yStamp =0; // Coordinates of stamp411 float xStamp = 0.0, yStamp = 0.0; // Coordinates of stamp 404 412 float fluxStamp = -INFINITY; // Flux of stamp 405 413 bool goodStamp = false; // Found a good stamp? … … 413 421 // Take stamps off the top of the (sorted) list 414 422 for (int j = xList->n - 1; j >= 0 && !goodStamp; j--) { 415 int xCentre = xList->data.F32[j] + 0.5, yCentre = yList->data.F32[j] + 0.5;// Stamp centre416 417 423 // Chop off the top of the list 418 424 xList->n = j; … … 420 426 fluxList->n = j; 421 427 428 #if 0 422 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 423 431 psTrace("psModules.imcombine", 7, "Searching for stamp %d around %d,%d\n", 424 432 i, xCentre, yCentre); 425 433 426 434 // Search bounds 435 int xCentre = xList->data.F32[j] - 0.5, yCentre = yList->data.F32[j] - 0.5;// Stamp centre 427 436 int search = footprint - size; // Search radius 428 437 int xMin = PS_MAX(border, xCentre - search); … … 433 442 goodStamp = stampSearch(&xStamp, &yStamp, &fluxStamp, image1, image2, thresh1, thresh2, 434 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 } 435 456 } 436 457 } else { … … 452 473 psFree(stamp->image1); 453 474 psFree(stamp->image2); 454 psFree(stamp-> variance);475 psFree(stamp->weight); 455 476 psFree(stamp->convolutions1); 456 477 psFree(stamp->convolutions2); 457 stamp->image1 = stamp->image2 = stamp-> variance= NULL;478 stamp->image1 = stamp->image2 = stamp->weight = NULL; 458 479 stamp->convolutions1 = stamp->convolutions2 = NULL; 459 480 … … 487 508 const psImage *image, const psImage *subMask, 488 509 const psRegion *region, int size, int footprint, 489 float spacing, pmSubtractionMode mode) 510 float spacing, float normFrac, float sysErr, float skyErr, 511 pmSubtractionMode mode) 490 512 491 513 { … … 507 529 int numStars = x->n; // Number of stars 508 530 pmSubtractionStampList *stamps = pmSubtractionStampListAlloc(subMask->numCols, subMask->numRows, 509 region, footprint, spacing); // Stamp list 531 region, footprint, spacing, 532 normFrac, sysErr, skyErr); // Stamp list 510 533 int numStamps = stamps->num; // Number of stamps 511 534 … … 514 537 psStringAppend(&ds9name, "stamps_all_%d.ds9", ds9num); 515 538 FILE *ds9 = pmSubtractionStampsFile(stamps, ds9name, "all stamps"); // ds9 region file 539 psFree(ds9name); 516 540 ds9num++; 517 541 … … 529 553 for (int i = 0; i < numStars; i++) { 530 554 float xStamp = x->data.F32[i], yStamp = y->data.F32[i]; // Coordinates of stamp 531 int xPix = xStamp + 0.5, yPix = yStamp +0.5; // Pixel coordinate of stamp555 int xPix = xStamp - 0.5, yPix = yStamp - 0.5; // Pixel coordinate of stamp 532 556 if (!checkStampRegion(xPix, yPix, region)) { 533 557 // It's not in the big region … … 537 561 continue; 538 562 } 563 564 // fprintf (stderr, "stamp: %5.1f %5.1f == %d %d\n", xStamp, yStamp, xPix, yPix); 539 565 540 566 bool found = false; … … 605 631 606 632 633 bool pmSubtractionStampsGetWindow(pmSubtractionStampList *stamps, int kernelSize) 634 { 635 PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, false); 636 PS_ASSERT_INT_NONNEGATIVE(kernelSize, false); 637 638 int size = stamps->footprint; // Size of postage stamps 639 640 psFree (stamps->window); 641 stamps->window = psKernelAlloc(-size, size, -size, size); 642 psImageInit(stamps->window->image, 0.0); 643 644 // generate normalizations for each stamp 645 psVector *norm1 = psVectorAlloc(stamps->num, PS_TYPE_F32); 646 psVector *norm2 = psVectorAlloc(stamps->num, PS_TYPE_F32); 647 for (int i = 0; i < stamps->num; i++) { 648 pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest 649 if (!stamp) continue; 650 if (!stamp->image1) continue; 651 if (!stamp->image2) continue; 652 653 float sum1 = 0.0; 654 float sum2 = 0.0; 655 for (int y = -size; y <= size; y++) { 656 for (int x = -size; x <= size; x++) { 657 sum1 += stamp->image1->kernel[y][x]; 658 sum2 += stamp->image2->kernel[y][x]; 659 } 660 } 661 norm1->data.F32[i] = sum1; 662 norm2->data.F32[i] = sum2; 663 } 664 665 // storage vector for flux data 666 psStats *stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 667 psVector *flux1 = psVectorAllocEmpty(2*stamps->num, PS_TYPE_F32); 668 psVector *flux2 = psVectorAllocEmpty(2*stamps->num, PS_TYPE_F32); 669 670 // generate the window pixels 671 double sum = 0.0; // Sum inside the window 672 float maxValue = 0.0; // Maximum value, for normalisation 673 for (int y = -size; y <= size; y++) { 674 for (int x = -size; x <= size; x++) { 675 676 flux1->n = 0; 677 flux2->n = 0; 678 for (int i = 0; i < stamps->num; i++) { 679 pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest 680 if (!stamp) continue; 681 if (!stamp->image1) continue; 682 if (!stamp->image2) continue; 683 684 psVectorAppend(flux1, stamp->image1->kernel[y][x] / norm1->data.F32[i]); 685 psVectorAppend(flux2, stamp->image2->kernel[y][x] / norm2->data.F32[i]); 686 } 687 688 psStatsInit (stats); 689 if (!psVectorStats (stats, flux1, NULL, NULL, 0)) { 690 psAbort ("failed to generate stats"); 691 } 692 float f1 = stats->robustMedian; 693 psStatsInit (stats); 694 if (!psVectorStats (stats, flux2, NULL, NULL, 0)) { 695 psAbort ("failed to generate stats"); 696 } 697 float f2 = stats->robustMedian; 698 699 stamps->window->kernel[y][x] = f1 + f2; 700 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(size)) { 701 sum += stamps->window->kernel[y][x]; 702 } 703 maxValue = PS_MAX(maxValue, stamps->window->kernel[y][x]); 704 } 705 } 706 707 psTrace("psModules.imcombine", 3, "Window total: %f, threshold: %f\n", 708 sum, (1.0 - stamps->normFrac) * sum); 709 bool done = false; 710 for (int radius = 1; radius <= size && !done; radius++) { 711 double within = 0.0; 712 for (int y = -radius; y <= radius; y++) { 713 for (int x = -radius; x <= radius; x++) { 714 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(radius)) { 715 within += stamps->window->kernel[y][x]; 716 } 717 } 718 } 719 psTrace("psModules.imcombine", 5, "Radius %d: %f\n", radius, within); 720 if (within > (1.0 - stamps->normFrac) * sum) { 721 stamps->normWindow = radius; 722 done = true; 723 } 724 } 725 726 psTrace("psModules.imcombine", 3, "Normalisation window radius set to %d\n", stamps->normWindow); 727 if (stamps->normWindow == 0 || stamps->normWindow >= size) { 728 psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size."); 729 return false; 730 } 731 732 // re-normalize so chisquare values are sensible 733 for (int y = -size; y <= size; y++) { 734 for (int x = -size; x <= size; x++) { 735 stamps->window->kernel[y][x] /= maxValue; 736 } 737 } 738 739 #if 0 740 { 741 psFits *fits = psFitsOpen ("window.fits", "w"); 742 psFitsWriteImage (fits, NULL, stamps->window->image, 0, NULL); 743 psFitsClose (fits); 744 } 745 #endif 746 747 psFree (stats); 748 psFree (flux1); 749 psFree(flux2); 750 psFree (norm1); 751 psFree (norm2); 752 return true; 753 } 754 607 755 bool pmSubtractionStampsExtract(pmSubtractionStampList *stamps, psImage *image1, psImage *image2, 608 psImage *variance, int kernelSize )756 psImage *variance, int kernelSize, psRegion bounds) 609 757 { 610 758 PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, false); … … 616 764 PS_ASSERT_IMAGE_TYPE(image2, PS_TYPE_F32, false); 617 765 } 618 PS_ASSERT_IMAGE_NON_NULL(variance, false); 619 PS_ASSERT_IMAGES_SIZE_EQUAL(variance, image1, false); 620 PS_ASSERT_IMAGE_TYPE(variance, PS_TYPE_F32, false); 621 PS_ASSERT_INT_NONNEGATIVE(kernelSize, false); 622 623 int numCols = image1->numCols, numRows = image1->numRows; // Size of images 766 if (variance) { 767 PS_ASSERT_IMAGE_NON_NULL(variance, false); 768 PS_ASSERT_IMAGES_SIZE_EQUAL(variance, image1, false); 769 PS_ASSERT_IMAGE_TYPE(variance, PS_TYPE_F32, false); 770 PS_ASSERT_INT_NONNEGATIVE(kernelSize, false); 771 } 772 624 773 int size = kernelSize + stamps->footprint; // Size of postage stamps 625 774 … … 630 779 } 631 780 632 if (isnan(stamp->xNorm)) { 633 stamp->xNorm = 2.0 * (stamp->x - (float)numCols/2.0) / (float)numCols; 634 } 635 if (isnan(stamp->yNorm)) { 636 stamp->yNorm = 2.0 * (stamp->y - (float)numRows/2.0) / (float)numRows; 637 } 638 639 int x = stamp->x + 0.5, y = stamp->y + 0.5; // Stamp coordinates 640 if (x < size || x > numCols - size || y < size || y > numRows - size) { 641 psError(PS_ERR_UNKNOWN, false, "Stamp %d (%d,%d) is within the image border.\n", i, x, y); 781 p_pmSubtractionPolynomialNormCoords(&stamp->xNorm, &stamp->yNorm, stamp->x, stamp->y, 782 bounds.x0, bounds.x1, bounds.y0, bounds.y1); 783 784 int x = stamp->x - 0.5, y = stamp->y - 0.5; // Stamp coordinates 785 // fprintf (stderr, "stamp: %5.1f %5.1f == %d %d (size: %d)\n", stamp->x, stamp->y, x, y, size); 786 787 if (x < bounds.x0 + size || x > bounds.x1 - size || y < bounds.y0 + size || y > bounds.y1 - size) { 788 psError(PM_ERR_PROG, false, "Stamp %d (%d,%d) is within the region border.\n", i, x, y); 642 789 return false; 643 790 } … … 646 793 assert(stamp->image1 == NULL); 647 794 assert(stamp->image2 == NULL); 648 assert(stamp-> variance== NULL);795 assert(stamp->weight == NULL); 649 796 650 797 psRegion region = psRegionSet(x - size, x + size + 1, y - size, y + size + 1); // Region of interest … … 660 807 } 661 808 662 psImage *wtSub = psImageSubset(variance, region); // Subimage with stamp 663 stamp->variance = psKernelAllocFromImage(wtSub, size, size); 664 psFree(wtSub); // Drop reference 809 psKernel *weight = stamp->weight = psKernelAlloc(-size, size, -size, size); // Weight = 1/variance 810 if (variance) { 811 psImage *varSub = psImageSubset(variance, region); // Subimage with stamp 812 psKernel *var = psKernelAllocFromImage(varSub, size, size); // Variance postage stamp 813 814 if ((isfinite(stamps->skyErr) && (stamps->skyErr > 0)) || 815 (isfinite(stamps->sysErr) && (stamps->sysErr > 0))) { 816 float sysErr = 0.25 * PS_SQR(stamps->sysErr); // Systematic error 817 float skyErr = stamps->skyErr; 818 psKernel *image1 = stamp->image1, *image2 = stamp->image2; // Input images 819 for (int y = -size; y <= size; y++) { 820 for (int x = -size; x <= size; x++) { 821 float additional = image1->kernel[y][x] + image2->kernel[y][x]; 822 weight->kernel[y][x] = 1.0 / (skyErr + var->kernel[y][x] + sysErr * PS_SQR(additional)); 823 } 824 } 825 } else { 826 for (int y = -size; y <= size; y++) { 827 for (int x = -size; x <= size; x++) { 828 weight->kernel[y][x] = 1.0 / var->kernel[y][x]; 829 } 830 } 831 } 832 psFree(var); 833 psFree(varSub); 834 } else { 835 psImageInit(weight->image, 1.0); 836 } 665 837 666 838 stamp->status = PM_SUBTRACTION_STAMP_CALCULATE; … … 673 845 const psImage *subMask, const psRegion *region, 674 846 int size, int footprint, float spacing, 847 float normFrac, float sysErr, float skyErr, 675 848 pmSubtractionMode mode) 676 849 { … … 696 869 y->data.F32[numOut] = source->peak->yf; 697 870 } 871 // fprintf (stderr, "stamp: %5.1f %5.1f\n", x->data.F32[numOut], y->data.F32[numOut]); 698 872 numOut++; 699 873 } … … 702 876 703 877 pmSubtractionStampList *stamps = pmSubtractionStampsSet(x, y, image, subMask, region, size, 704 footprint, spacing, mode); // Stamps to return 878 footprint, spacing, normFrac, 879 sysErr, skyErr, mode); // Stamps 705 880 psFree(x); 706 881 psFree(y); 707 882 708 883 if (!stamps) { 709 psError( PS_ERR_UNKNOWN, false, "Unable to set stamps from sources.");884 psError(psErrorCodeLast(), false, "Unable to set stamps from sources."); 710 885 } 711 886 … … 716 891 pmSubtractionStampList *pmSubtractionStampsSetFromFile(const char *filename, const psImage *image, 717 892 const psImage *subMask, const psRegion *region, 718 int size, int footprint, float spacing, 719 pmSubtractionMode mode)893 int size, int footprint, float spacing, float normFrac, 894 float sysErr, float skyErr, pmSubtractionMode mode) 720 895 { 721 896 PS_ASSERT_STRING_NON_EMPTY(filename, NULL); … … 724 899 psArray *data = psVectorsReadFromFile(filename, "%f %f"); 725 900 if (!data) { 726 psError( PS_ERR_IO, false, "Unable to read stamps file %s", filename);901 psError(psErrorCodeLast(), false, "Unable to read stamps file %s", filename); 727 902 return NULL; 728 903 } … … 734 909 735 910 pmSubtractionStampList *stamps = pmSubtractionStampsSet(x, y, image, subMask, region, size, footprint, 736 spacing, mode);911 spacing, normFrac, sysErr, skyErr, mode); 737 912 psFree(data); 738 913 … … 740 915 741 916 } 917 918 919 bool pmSubtractionStampsResetStatus (pmSubtractionStampList *stamps) { 920 921 for (int i = 0; i < stamps->num; i++) { 922 pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest 923 if (!stamp) continue; 924 if (stamp->status != PM_SUBTRACTION_STAMP_USED) continue; 925 stamp->status = PM_SUBTRACTION_STAMP_CALCULATE; 926 } 927 return true; 928 } 929
Note:
See TracChangeset
for help on using the changeset viewer.
