Changeset 30322 for branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionStamps.c
- Timestamp:
- Jan 20, 2011, 11:53:03 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionStamps.c
r30289 r30322 27 27 #include "pmSource.h" 28 28 29 #include "pmSubtractionTypes.h" 29 30 #include "pmSubtraction.h" 30 31 #include "pmSubtractionStamps.h" 32 #include "pmSubtractionVisual.h" 31 33 32 34 #define STAMP_LIST_BUFFER 20 // Number of stamps to add to list at a time … … 367 369 } 368 370 369 370 pmSubtractionStampList *pmSubtractionStampsFind(pmSubtractionStampList *stamps, const psImage *image1, 371 const psImage *image2, const psImage *subMask, 372 const psRegion *region, float thresh1, float thresh2, 373 int size, int footprint, float spacing, float normFrac, 374 float sysErr, float skyErr, pmSubtractionMode mode) 371 bool pmSubtractionStampsSelect(pmSubtractionStampList **stamps, // Stamps to read 372 const pmReadout *ro1, // Readout 1 373 const pmReadout *ro2, // Readout 2 374 const psImage *subMask, // Mask for subtraction, or NULL 375 psImage *variance, // Variance map 376 const psRegion *region, // Region of interest 377 float thresh1, // Threshold for stamp finding on readout 1 378 float thresh2, // Threshold for stamp finding on readout 2 379 float stampSpacing, // Spacing between stamps 380 float normFrac, // Fraction of flux in window for normalisation window 381 float sysError, // Relative systematic error in images 382 float skyError, // Relative systematic error in images 383 int size, // Kernel half-size 384 int footprint, // Convolution footprint for stamps 385 pmSubtractionMode mode // Mode for subtraction 386 ) 387 { 388 PS_ASSERT_PTR_NON_NULL(stamps, false); 389 PM_ASSERT_READOUT_NON_NULL(ro1, false); 390 PM_ASSERT_READOUT_NON_NULL(ro2, false); 391 PS_ASSERT_IMAGE_NON_NULL(subMask, false); 392 PS_ASSERT_IMAGE_NON_NULL(variance, false); 393 PS_ASSERT_PTR_NON_NULL(region, false); 394 395 psTrace("psModules.imcombine", 3, "Finding stamps...\n"); 396 397 psImage *image1 = ro1 ? ro1->image : NULL, *image2 = ro2 ? ro2->image : NULL; // Images of interest 398 399 *stamps = pmSubtractionStampsFind(*stamps, image1, image2, subMask, region, thresh1, thresh2, 400 size, footprint, stampSpacing, normFrac, sysError, skyError, mode); 401 if (!*stamps) { 402 psError(psErrorCodeLast(), false, "Unable to find stamps."); 403 return false; 404 } 405 406 psTrace("psModules.imcombine", 3, "Extracting stamps...\n"); 407 if (!pmSubtractionStampsExtract(*stamps, ro1->image, ro2->image, variance, size, *region)) { 408 psError(psErrorCodeLast(), false, "Unable to extract stamps."); 409 return false; 410 } 411 412 pmSubtractionVisualPlotStamps(*stamps, (pmReadout *) ro1); 413 return true; 414 } 415 416 pmSubtractionStampList *pmSubtractionStampsFind(pmSubtractionStampList *stamps, 417 const psImage *image1, 418 const psImage *image2, 419 const psImage *subMask, 420 const psRegion *region, 421 float thresh1, 422 float thresh2, 423 int size, 424 int footprint, 425 float spacing, 426 float normFrac, 427 float sysErr, 428 float skyErr, 429 pmSubtractionMode mode) 375 430 { 376 431 if (!image1 && !image2) { … … 687 742 } 688 743 689 690 bool pmSubtractionStampsGetWindow(pmSubtractionStampList *stamps, int kernelSize) 744 // we are essentially using aperture photometry to determine the photometric match between the 745 // images. we need to choose an appropriate-sized aperture for this analysis. If it is too 746 // large, the measurement will be noisy (and possibly biased) due to the sky noise. If it is 747 // too small, or inconsistent, the measurement will be biased. We use Kron-mag like aperture 748 // scaled by the first radial moment. 749 bool pmSubtractionStampsGetWindow(bool *tryAgain, pmSubtractionStampList *stamps, int kernelSize) 691 750 { 692 751 PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, false); 693 752 PS_ASSERT_INT_NONNEGATIVE(kernelSize, false); 694 753 754 // if we succeed, or fail with an unrecoverable error, do not try again 755 if (tryAgain) { 756 *tryAgain = false; 757 } 758 695 759 int size = stamps->footprint; // Size of postage stamps 696 760 761 // window for moments calculations downstream 762 psFree (stamps->window); 763 stamps->window = psKernelAlloc(-size, size, -size, size); 764 psImageInit(stamps->window->image, 0.0); 765 766 // window1 and window2 are mean stamp images used here to measure the 767 // first radial moment, and thus the normalization window 697 768 psFree (stamps->window1); 698 769 stamps->window1 = psKernelAlloc(-size, size, -size, size); … … 703 774 psImageInit(stamps->window2->image, 0.0); 704 775 705 // Generate a weighting window based on the fwhms (20% larger than the largest) 706 { 707 float fwhm1, fwhm2; 708 709 // XXX this is annoyingly hack-ish 710 pmSubtractionGetFWHMs(&fwhm1, &fwhm2); 711 712 float sigma = 1.5 * PS_MAX(fwhm1, fwhm2) / 2.35; 713 714 psFree (stamps->window); 715 stamps->window = psKernelAlloc(-size, size, -size, size); 716 psImageInit(stamps->window->image, 0.0); 717 718 for (int y = -size; y <= size; y++) { 719 for (int x = -size; x <= size; x++) { 720 stamps->window->kernel[y][x] = exp(-0.5*(x*x + y*y)/(sigma*sigma)); 721 } 722 } 776 // Generate an initial weighting window based on the fwhms (50% larger than the largest) 777 float fwhm1, fwhm2; 778 779 // XXX this is annoyingly hack-ish 780 pmSubtractionGetFWHMs(&fwhm1, &fwhm2); 781 782 float sigma = 1.5 * PS_MAX(fwhm1, fwhm2) / 2.35; 783 784 for (int y = -size; y <= size; y++) { 785 for (int x = -size; x <= size; x++) { 786 stamps->window->kernel[y][x] = exp(-0.5*(x*x + y*y)/(sigma*sigma)); 787 } 723 788 } 724 789 … … 810 875 psTrace("psModules.imcombine", 3, "Window total (2): %f, threshold: %f\n", sum2, (1.0 - stamps->normFrac) * sum2); 811 876 812 # if (1) 813 // this block attempts to calculate the radius based on the first radial moment 877 // attempt to calculate the normalization window based on the first radial moment 814 878 double Sr1 = 0.0; 815 879 double Sr2 = 0.0; … … 833 897 psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "Kron Radii: %f for 1, %f for 2\n", stamps->normWindow1, stamps->normWindow2); 834 898 899 // if the calculated normWindows are too large, we will fall off the stamps. In this case, we need to try again. 900 if ((stamps->normWindow1 > size) || (stamps->normWindow2 > size)) { 901 if (tryAgain) { 902 *tryAgain = true; 903 } 904 psFree (stats); 905 psFree (flux1); 906 psFree (flux2); 907 psFree (norm1); 908 psFree (norm2); 909 return false; 910 } 911 912 // this is an unrecoverable error : something really bogus in the data 913 if (stamps->normWindow1 == 0) { 914 psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size (1)."); 915 psFree (stats); 916 psFree (flux1); 917 psFree (flux2); 918 psFree (norm1); 919 psFree (norm2); 920 return false; 921 } 922 if (stamps->normWindow2 == 0) { 923 psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size (2)."); 924 psFree (stats); 925 psFree (flux1); 926 psFree (flux2); 927 psFree (norm1); 928 psFree (norm2); 929 return false; 930 } 931 835 932 // Generate a weighting window based on the kron radii 836 { 837 float radius = 2.0 * PS_MAX(R1, R2); 838 839 psImageInit(stamps->window->image, 0.0); 840 841 for (int y = -size; y <= size; y++) { 842 for (int x = -size; x <= size; x++) { 843 if (hypot(x,y) > radius) continue; 844 stamps->window->kernel[y][x] = 1.0; 845 } 846 } 847 } 848 849 // complain if normWindow1 or normWindow2 are larger than size 850 psAssert(stamps->normWindow1 < size, "norm Window 1 too large"); 851 psAssert(stamps->normWindow2 < size, "norm Window 2 too large"); 852 853 # else 854 // XXX : this block attempts to calculate the radius by looking at the curve of growth (or something vaguely equivalent). 855 // It did not do very well (though a true curve-of-growth analysis might be better...) 856 bool done1 = false; 857 bool done2 = false; 858 double prior1 = 0.0; 859 double prior2 = 0.0; 860 double delta1o = 1.0; 861 double delta2o = 1.0; 862 for (int radius = 1; radius <= size && !(done1 && done2); radius++) { 863 double within1 = 0.0; 864 double within2 = 0.0; 865 for (int y = -radius; y <= radius; y++) { 866 for (int x = -radius; x <= radius; x++) { 867 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(radius)) { 868 within1 += stamps->window1->kernel[y][x]; 869 } 870 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(radius)) { 871 within2 += stamps->window2->kernel[y][x]; 872 } 873 } 874 } 875 double delta1 = (within1 - prior1) / within1; 876 if (!done1 && (fabs(delta1) < stamps->normFrac)) { 877 // interpolate to the radius at which delta2 is normFrac: 878 stamps->normWindow1 = radius - (stamps->normFrac - delta1) / (delta1o - delta1); 879 psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "choosing %f (%d) for 1 (%f : %f)\n", stamps->normWindow1, radius, within1, delta1); 880 done1 = true; 881 } 882 double delta2 = (within2 - prior2) / within2; 883 if (!done2 && (fabs(delta2) < stamps->normFrac)) { 884 // interpolate to the radius at which delta2 is normFrac: 885 stamps->normWindow2 = radius - (stamps->normFrac - delta2) / (delta2o - delta2); 886 psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "choosing %f (%d) for 2 (%f : %f)\n", stamps->normWindow2, radius, within2, delta2); 887 done2 = true; 888 } 889 psTrace("psModules.imcombine", 5, "Radius %d: %f (%f) and %f (%f)\n", radius, within1, delta1, within2, delta2); 890 891 prior1 = within1; 892 prior2 = within2; 893 delta1o = delta1; 894 delta2o = delta2; 895 896 // if (!done1 && (within1 > (1.0 - stamps->normFrac) * sum1)) { 897 // stamps->normWindow1 = radius; 898 // done1 = true; 899 // } 900 // if (!done2 && (within2 > (1.0 - stamps->normFrac) * sum2)) { 901 // stamps->normWindow2 = radius; 902 // done2 = true; 903 // } 904 905 } 906 # endif 907 908 psTrace("psModules.imcombine", 3, "Normalisation window radii set to %f and %f\n", stamps->normWindow1, stamps->normWindow2); 909 if (stamps->normWindow1 == 0 || stamps->normWindow1 >= size) { 910 psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size (1)."); 911 return false; 912 } 913 if (stamps->normWindow2 == 0 || stamps->normWindow2 >= size) { 914 psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size (2)."); 915 return false; 933 float radius = 2.0 * PS_MAX(R1, R2); 934 psImageInit(stamps->window->image, 0.0); 935 936 // we use a top-hat window for the moments analysis 937 for (int y = -size; y <= size; y++) { 938 for (int x = -size; x <= size; x++) { 939 if (hypot(x,y) > radius) continue; 940 stamps->window->kernel[y][x] = 1.0; 941 } 916 942 } 917 943 … … 928 954 } 929 955 } 930 931 #if 0932 {933 psFits *fits = NULL;934 fits = psFitsOpen ("window1.norm.fits", "w");935 psFitsWriteImage (fits, NULL, stamps->window1->image, 0, NULL);936 psFitsClose (fits);937 fits = psFitsOpen ("window2.norm.fits", "w");938 psFitsWriteImage (fits, NULL, stamps->window2->image, 0, NULL);939 psFitsClose (fits);940 }941 #endif942 956 943 957 psFree (stats);
Note:
See TracChangeset
for help on using the changeset viewer.
