- Timestamp:
- Feb 14, 2011, 1:05:28 PM (15 years ago)
- Location:
- branches/czw_branch/20101203
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
psModules/src/imcombine/pmSubtractionStamps.c (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/czw_branch/20101203
- Property svn:mergeinfo changed
-
branches/czw_branch/20101203/psModules/src/imcombine/pmSubtractionStamps.c
r29543 r30631 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 … … 122 124 if ((image1 && image1->data.F32[y][x] < thresh1) || 123 125 (image2 && image2->data.F32[y][x] < thresh2)) { 126 // fprintf (stderr, "%f,%f : thresh\n", xRaw, yRaw); 124 127 continue; 125 128 } … … 366 369 } 367 370 368 369 pmSubtractionStampList *pmSubtractionStampsFind(pmSubtractionStampList *stamps, const psImage *image1, 370 const psImage *image2, const psImage *subMask, 371 const psRegion *region, float thresh1, float thresh2, 372 int size, int footprint, float spacing, float normFrac, 373 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) 374 430 { 375 431 if (!image1 && !image2) { … … 429 485 stamps = pmSubtractionStampListAlloc(numCols, numRows, region, footprint, spacing, 430 486 normFrac, sysErr, skyErr); 487 } 488 489 // XXX TEST : dump all stars in the stamps here 490 if (0) { 491 FILE *f = fopen ("stamp.dat", "w"); 492 for (int i = 0; i < stamps->num; i++) { 493 psVector *xList = stamps->x->data[i]; 494 psVector *yList = stamps->y->data[i]; // Coordinate lists 495 psVector *fluxList = stamps->flux->data[i]; // List of stamp fluxes 496 497 for (int j = 0; j < xList->n; j++) { 498 fprintf (f, "%d %d %f %f %f\n", i, j, xList->data.F32[j], yList->data.F32[j], fluxList->data.F32[j]); 499 } 500 } 501 fclose (f); 431 502 } 432 503 … … 636 707 } 637 708 709 int nTotal = 0; 710 638 711 // Sort the list by flux, with the brightest last 639 712 for (int i = 0; i < numStamps; i++) { … … 662 735 stamps->y->data[i] = ySorted; 663 736 stamps->flux->data[i] = fluxSorted; 664 } 665 737 nTotal += num; 738 } 739 // fprintf (stderr, "nTotal %d\n", nTotal); 740 666 741 return stamps; 667 742 } 668 743 669 670 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) 671 750 { 672 751 PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, false); 673 752 PS_ASSERT_INT_NONNEGATIVE(kernelSize, false); 674 753 754 // if we succeed, or fail with an unrecoverable error, do not try again 755 if (tryAgain) { 756 *tryAgain = false; 757 } 758 675 759 int size = stamps->footprint; // Size of postage stamps 676 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 677 768 psFree (stamps->window1); 678 769 stamps->window1 = psKernelAlloc(-size, size, -size, size); … … 683 774 psImageInit(stamps->window2->image, 0.0); 684 775 685 // Generate a weighting window based on the fwhms (20% larger than the largest) 686 { 687 float fwhm1, fwhm2; 688 689 // XXX this is annoyingly hack-ish 690 pmSubtractionGetFWHMs(&fwhm1, &fwhm2); 691 692 float sigma = 1.5 * PS_MAX(fwhm1, fwhm2) / 2.35; 693 694 psFree (stamps->window); 695 stamps->window = psKernelAlloc(-size, size, -size, size); 696 psImageInit(stamps->window->image, 0.0); 697 698 for (int y = -size; y <= size; y++) { 699 for (int x = -size; x <= size; x++) { 700 stamps->window->kernel[y][x] = exp(-0.5*(x*x + y*y)/(sigma*sigma)); 701 } 702 } 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 } 703 788 } 704 789 … … 790 875 psTrace("psModules.imcombine", 3, "Window total (2): %f, threshold: %f\n", sum2, (1.0 - stamps->normFrac) * sum2); 791 876 792 # if (1) 793 // 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 794 878 double Sr1 = 0.0; 795 879 double Sr2 = 0.0; … … 809 893 float R2 = Sr2 / Sf2; 810 894 811 stamps->normWindow1 = 2.0*R1; 812 stamps->normWindow2 = 2.0*R2; 813 psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "Kron Radii: %f for 1, %f for 2\n", stamps->normWindow1, stamps->normWindow2); 814 815 # else 816 // XXX : this block attempts to calculate the radius by looking at the curve of growth (or something vaguely equivalent). 817 // It did not do very well (though a true curve-of-growth analysis might be better...) 818 bool done1 = false; 819 bool done2 = false; 820 double prior1 = 0.0; 821 double prior2 = 0.0; 822 double delta1o = 1.0; 823 double delta2o = 1.0; 824 for (int radius = 1; radius <= size && !(done1 && done2); radius++) { 825 double within1 = 0.0; 826 double within2 = 0.0; 827 for (int y = -radius; y <= radius; y++) { 828 for (int x = -radius; x <= radius; x++) { 829 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(radius)) { 830 within1 += stamps->window1->kernel[y][x]; 831 } 832 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(radius)) { 833 within2 += stamps->window2->kernel[y][x]; 834 } 835 } 836 } 837 double delta1 = (within1 - prior1) / within1; 838 if (!done1 && (fabs(delta1) < stamps->normFrac)) { 839 // interpolate to the radius at which delta2 is normFrac: 840 stamps->normWindow1 = radius - (stamps->normFrac - delta1) / (delta1o - delta1); 841 psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "choosing %f (%d) for 1 (%f : %f)\n", stamps->normWindow1, radius, within1, delta1); 842 done1 = true; 843 } 844 double delta2 = (within2 - prior2) / within2; 845 if (!done2 && (fabs(delta2) < stamps->normFrac)) { 846 // interpolate to the radius at which delta2 is normFrac: 847 stamps->normWindow2 = radius - (stamps->normFrac - delta2) / (delta2o - delta2); 848 psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "choosing %f (%d) for 2 (%f : %f)\n", stamps->normWindow2, radius, within2, delta2); 849 done2 = true; 850 } 851 psTrace("psModules.imcombine", 5, "Radius %d: %f (%f) and %f (%f)\n", radius, within1, delta1, within2, delta2); 852 853 prior1 = within1; 854 prior2 = within2; 855 delta1o = delta1; 856 delta2o = delta2; 857 858 // if (!done1 && (within1 > (1.0 - stamps->normFrac) * sum1)) { 859 // stamps->normWindow1 = radius; 860 // done1 = true; 861 // } 862 // if (!done2 && (within2 > (1.0 - stamps->normFrac) * sum2)) { 863 // stamps->normWindow2 = radius; 864 // done2 = true; 865 // } 866 867 } 868 # endif 869 870 psTrace("psModules.imcombine", 3, "Normalisation window radii set to %f and %f\n", stamps->normWindow1, stamps->normWindow2); 871 if (stamps->normWindow1 == 0 || stamps->normWindow1 >= size) { 895 // Compare the Kron Radii (R1 & R2) to above to the FWHMs : if they are too discrepant, we will need to rescale 896 psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "Kron Radii vs FWHMs 1: fwhm: %f, kron %f\n", fwhm1, R1); 897 psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "Kron Radii vs FWHMs 2: fwhm: %f, kron %f\n", fwhm2, R2); 898 899 // XXX CAREFUL : in pmSubtractionMatch.c:703, we rely on this factor of 2.75.. 900 stamps->normWindow1 = 2.75*R1; 901 stamps->normWindow2 = 2.75*R2; 902 psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "Windows from Kron Radii: %f for 1, %f for 2\n", stamps->normWindow1, stamps->normWindow2); 903 904 // if the calculated normWindows are too large, we will fall off the stamps. In this case, we need to try again. 905 if ((stamps->normWindow1 > size) || (stamps->normWindow2 > size)) { 906 if (tryAgain) { 907 *tryAgain = true; 908 } 909 psFree (stats); 910 psFree (flux1); 911 psFree (flux2); 912 psFree (norm1); 913 psFree (norm2); 914 return false; 915 } 916 917 // this is an unrecoverable error : something really bogus in the data 918 if (stamps->normWindow1 == 0) { 872 919 psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size (1)."); 920 psFree (stats); 921 psFree (flux1); 922 psFree (flux2); 923 psFree (norm1); 924 psFree (norm2); 873 925 return false; 874 926 } 875 if (stamps->normWindow2 == 0 || stamps->normWindow2 >= size) {927 if (stamps->normWindow2 == 0) { 876 928 psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size (2)."); 929 psFree (stats); 930 psFree (flux1); 931 psFree (flux2); 932 psFree (norm1); 933 psFree (norm2); 877 934 return false; 935 } 936 937 // Generate a weighting window based on the kron radii 938 float radius = 2.0 * PS_MAX(R1, R2); 939 psImageInit(stamps->window->image, 0.0); 940 941 // we use a top-hat window for the moments analysis 942 for (int y = -size; y <= size; y++) { 943 for (int x = -size; x <= size; x++) { 944 if (hypot(x,y) > radius) continue; 945 stamps->window->kernel[y][x] = 1.0; 946 } 878 947 } 879 948 … … 890 959 } 891 960 } 892 893 #if 0894 {895 psFits *fits = NULL;896 fits = psFitsOpen ("window1.norm.fits", "w");897 psFitsWriteImage (fits, NULL, stamps->window1->image, 0, NULL);898 psFitsClose (fits);899 fits = psFitsOpen ("window2.norm.fits", "w");900 psFitsWriteImage (fits, NULL, stamps->window2->image, 0, NULL);901 psFitsClose (fits);902 }903 #endif904 961 905 962 psFree (stats); … … 1128 1185 continue; 1129 1186 } 1187 1188 // XXX this is somewhat arbitrary... 1189 if (source->errMag > 0.05) continue; 1190 if (fabs(source->psfMag - source->apMag) > 0.5) continue; 1191 1130 1192 if (source->modelPSF) { 1131 1193 x->data.F32[numOut] = source->modelPSF->params->data.F32[PM_PAR_XPOS]; … … 1135 1197 y->data.F32[numOut] = source->peak->yf; 1136 1198 } 1137 // fprintf (stderr, "stamp: %5.1f %5.1f\n", x->data.F32[numOut], y->data.F32[numOut]);1138 1199 numOut++; 1139 1200 }
Note:
See TracChangeset
for help on using the changeset viewer.
