Changeset 28866 for branches/eam_branches/ipp-20100621/psModules/src/imcombine/pmSubtractionStamps.c
- Timestamp:
- Aug 9, 2010, 8:27:57 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20100621/psModules/src/imcombine/pmSubtractionStamps.c
r28643 r28866 51 51 psFree(list->y); 52 52 psFree(list->flux); 53 psFree(list->window); 53 psFree(list->window1); 54 psFree(list->window2); 54 55 } 55 56 … … 230 231 list->y = NULL; 231 232 list->flux = NULL; 232 list->window = NULL;233 233 list->normFrac = normFrac; 234 list->normWindow = 0; 234 list->window1 = NULL; 235 list->window2 = NULL; 236 list->normWindow1 = 0; 237 list->normWindow2 = 0; 235 238 list->footprint = footprint; 236 239 list->sysErr = sysErr; … … 253 256 out->y = NULL; 254 257 out->flux = NULL; 255 out->window = psMemIncrRefCounter(in->window); 258 out->window1 = psMemIncrRefCounter(in->window1); 259 out->window2 = psMemIncrRefCounter(in->window2); 256 260 out->footprint = in->footprint; 257 out->normWindow = in->normWindow; 261 out->normWindow1 = in->normWindow1; 262 out->normWindow2 = in->normWindow2; 258 263 259 264 for (int i = 0; i < num; i++) { … … 643 648 int size = stamps->footprint; // Size of postage stamps 644 649 645 psFree (stamps->window); 646 stamps->window = psKernelAlloc(-size, size, -size, size); 647 psImageInit(stamps->window->image, 0.0); 650 psFree (stamps->window1); 651 stamps->window1 = psKernelAlloc(-size, size, -size, size); 652 psImageInit(stamps->window1->image, 0.0); 653 654 psFree (stamps->window2); 655 stamps->window2 = psKernelAlloc(-size, size, -size, size); 656 psImageInit(stamps->window2->image, 0.0); 648 657 649 658 // generate normalizations for each stamp … … 674 683 675 684 // generate the window pixels 676 double sum = 0.0; // Sum inside the window 677 float maxValue = 0.0; // Maximum value, for normalisation 685 double sum1 = 0.0; // Sum inside the window 686 double sum2 = 0.0; // Sum inside the window 687 float maxValue1 = 0.0; // Maximum value, for normalisation 688 float maxValue2 = 0.0; // Maximum value, for normalisation 678 689 for (int y = -size; y <= size; y++) { 679 690 for (int x = -size; x <= size; x++) { … … 696 707 } 697 708 float f1 = stats->robustMedian; 709 698 710 psStatsInit (stats); 699 711 if (!psVectorStats (stats, flux2, NULL, NULL, 0)) { … … 702 714 float f2 = stats->robustMedian; 703 715 704 stamps->window ->kernel[y][x] = f1 + f2;716 stamps->window1->kernel[y][x] = f1; 705 717 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(size)) { 706 sum += stamps->window->kernel[y][x]; 707 } 708 maxValue = PS_MAX(maxValue, stamps->window->kernel[y][x]); 709 } 710 } 711 712 psTrace("psModules.imcombine", 3, "Window total: %f, threshold: %f\n", 713 sum, (1.0 - stamps->normFrac) * sum); 714 bool done = false; 715 for (int radius = 1; radius <= size && !done; radius++) { 716 double within = 0.0; 718 sum1 += stamps->window1->kernel[y][x]; 719 } 720 maxValue1 = PS_MAX(maxValue1, stamps->window1->kernel[y][x]); 721 722 stamps->window2->kernel[y][x] = f2; 723 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(size)) { 724 sum2 += stamps->window2->kernel[y][x]; 725 } 726 maxValue2 = PS_MAX(maxValue2, stamps->window2->kernel[y][x]); 727 } 728 } 729 730 psTrace("psModules.imcombine", 3, "Window total (1): %f, threshold: %f\n", sum1, (1.0 - stamps->normFrac) * sum1); 731 psTrace("psModules.imcombine", 3, "Window total (2): %f, threshold: %f\n", sum2, (1.0 - stamps->normFrac) * sum2); 732 733 # if (0) 734 // this block attempts to calculate the radius based on the first radial moment 735 bool done1 = false; 736 bool done2 = false; 737 double prior1 = 0.0; 738 double prior2 = 0.0; 739 for (int y = -size; y <= size; y++) { 740 for (int x = -size; x <= size; x++) { 741 float r = hypot(x, y); 742 Sr1 += r * stamps->window1->kernel[y][x]; 743 Sr2 += r * stamps->window2->kernel[y][x]; 744 Sf1 += stamps->window1->kernel[y][x]; 745 Sf2 += stamps->window2->kernel[y][x]; 746 } 747 } 748 749 float R1 = Sr1 / Sf1; 750 float R2 = Sr2 / Sf2; 751 752 stamps->normWindow1 = 2.5*R1; 753 stamps->normWindow1 = 2.5*R2; 754 # else 755 // XXX : this block attempts to calculate the radius by looking at the curve of growth (or something vaguely equivalent). 756 // It did not do very well (though a true curve-of-growth analysis might be better...) 757 bool done1 = false; 758 bool done2 = false; 759 double prior1 = 0.0; 760 double prior2 = 0.0; 761 double delta1o = 1.0; 762 double delta2o = 1.0; 763 for (int radius = 1; radius <= size && !(done1 && done2); radius++) { 764 double within1 = 0.0; 765 double within2 = 0.0; 717 766 for (int y = -radius; y <= radius; y++) { 718 767 for (int x = -radius; x <= radius; x++) { 719 768 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(radius)) { 720 within += stamps->window->kernel[y][x];769 within1 += stamps->window1->kernel[y][x]; 721 770 } 722 } 723 } 724 psTrace("psModules.imcombine", 5, "Radius %d: %f\n", radius, within); 725 if (within > (1.0 - stamps->normFrac) * sum) { 726 stamps->normWindow = radius; 727 done = true; 728 } 729 } 730 731 psTrace("psModules.imcombine", 3, "Normalisation window radius set to %d\n", stamps->normWindow); 732 if (stamps->normWindow == 0 || stamps->normWindow >= size) { 733 psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size."); 771 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(radius)) { 772 within2 += stamps->window2->kernel[y][x]; 773 } 774 } 775 } 776 double delta1 = (within1 - prior1) / within1; 777 if (!done1 && (fabs(delta1) < stamps->normFrac)) { 778 // interpolate to the radius at which delta2 is normFrac: 779 stamps->normWindow1 = radius - (stamps->normFrac - delta1) / (delta1o - delta1); 780 fprintf (stderr, "choosing %f (%d) for 1 (%f : %f)\n", stamps->normWindow1, radius, within1, delta1); 781 done1 = true; 782 } 783 double delta2 = (within2 - prior2) / within2; 784 if (!done2 && (fabs(delta2) < stamps->normFrac)) { 785 // interpolate to the radius at which delta2 is normFrac: 786 stamps->normWindow2 = radius - (stamps->normFrac - delta2) / (delta2o - delta2); 787 fprintf (stderr, "choosing %f (%d) for 2 (%f : %f)\n", stamps->normWindow2, radius, within2, delta2); 788 done2 = true; 789 } 790 psTrace("psModules.imcombine", 5, "Radius %d: %f (%f) and %f (%f)\n", radius, within1, delta1, within2, delta2); 791 792 prior1 = within1; 793 prior2 = within2; 794 delta1o = delta1; 795 delta2o = delta2; 796 797 // if (!done1 && (within1 > (1.0 - stamps->normFrac) * sum1)) { 798 // stamps->normWindow1 = radius; 799 // done1 = true; 800 // } 801 // if (!done2 && (within2 > (1.0 - stamps->normFrac) * sum2)) { 802 // stamps->normWindow2 = radius; 803 // done2 = true; 804 // } 805 806 } 807 # endif 808 809 psTrace("psModules.imcombine", 3, "Normalisation window radii set to %f and %f\n", stamps->normWindow1, stamps->normWindow2); 810 if (stamps->normWindow1 == 0 || stamps->normWindow1 >= size) { 811 psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size (1)."); 812 return false; 813 } 814 if (stamps->normWindow2 == 0 || stamps->normWindow2 >= size) { 815 psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size (2)."); 734 816 return false; 735 817 } … … 738 820 for (int y = -size; y <= size; y++) { 739 821 for (int x = -size; x <= size; x++) { 740 stamps->window->kernel[y][x] /= maxValue; 741 } 742 } 743 744 #if 0 822 stamps->window1->kernel[y][x] /= maxValue1; 823 } 824 } 825 // re-normalize so chisquare values are sensible 826 for (int y = -size; y <= size; y++) { 827 for (int x = -size; x <= size; x++) { 828 stamps->window2->kernel[y][x] /= maxValue2; 829 } 830 } 831 832 #if 1 745 833 { 746 psFits *fits = psFitsOpen ("window.fits", "w"); 747 psFitsWriteImage (fits, NULL, stamps->window->image, 0, NULL); 834 psFits *fits = NULL; 835 fits = psFitsOpen ("window1.fits", "w"); 836 psFitsWriteImage (fits, NULL, stamps->window1->image, 0, NULL); 837 psFitsClose (fits); 838 fits = psFitsOpen ("window2.fits", "w"); 839 psFitsWriteImage (fits, NULL, stamps->window2->image, 0, NULL); 748 840 psFitsClose (fits); 749 841 } … … 752 844 psFree (stats); 753 845 psFree (flux1); 754 psFree (flux2);846 psFree (flux2); 755 847 psFree (norm1); 756 848 psFree (norm2); 757 849 return true; 850 } 851 852 static pthread_mutex_t getPenaltiesMutex = PTHREAD_MUTEX_INITIALIZER; 853 854 // kernels->penalty is an overall scaling factor (user-supplied) 855 bool pmSubtractionKernelPenaltiesStamp(pmSubtractionStamp *stamp, pmSubtractionKernels *kernels) 856 { 857 // we only need the penalties if we are doing dual convolution 858 if (kernels->mode != PM_SUBTRACTION_MODE_DUAL) return true; 859 860 // we only calculate the penalties once. 861 if (kernels->havePenalties) return true; 862 863 // in a threaded context, only one thread can calculate the penalties. attempt to grab a 864 // mutex before continuing 865 pthread_mutex_lock(&getPenaltiesMutex); 866 867 // did someone else already get the mutex and do this? 868 if (kernels->havePenalties) { 869 pthread_mutex_unlock(&getPenaltiesMutex); 870 return true; 871 } 872 873 for (int i = 0; i < kernels->num; i++) { 874 pmSubtractionKernelPenalties(stamp, kernels, i); 875 } 876 877 kernels->havePenalties = true; 878 pthread_mutex_unlock(&getPenaltiesMutex); 879 return true; 880 } 881 882 # define EMPIRICAL 0 883 884 // kernels->penalty is an overall scaling factor (user-supplied) 885 bool pmSubtractionKernelPenalties(pmSubtractionStamp *stamp, pmSubtractionKernels *kernels, int index) 886 { 887 float penalty1, penalty2; 888 float fwhm1, fwhm2; 889 890 // XXX this is annoyingly hack-ish 891 pmSubtractionGetFWHMs(&fwhm1, &fwhm2); 892 893 if (EMPIRICAL) { 894 psKernel *convolution1 = stamp->convolutions1->data[index]; 895 penalty1 = pmSubtractionKernelPenaltySingle(convolution1); 896 897 psKernel *convolution2 = stamp->convolutions2->data[index]; 898 penalty2 = pmSubtractionKernelPenaltySingle(convolution2); 899 } else { 900 pmSubtractionKernelPreCalc *kernel = kernels->preCalc->data[index]; 901 float M2 = pmSubtractionKernelPenaltySingle(kernel->kernel); 902 903 penalty1 = M2 * PS_SQR(fwhm1 / 2.35); // rescale the unconvolved second-moment by the image second moment 904 penalty2 = M2 * PS_SQR(fwhm2 / 2.35); // rescale the unconvolved second-moment by the image second moment 905 } 906 kernels->penalties1->data.F32[index] = kernels->penalty * penalty1; 907 psAssert (isfinite(kernels->penalties1->data.F32[index]), "invalid penalty"); 908 909 kernels->penalties2->data.F32[index] = kernels->penalty * penalty2; 910 psAssert (isfinite(kernels->penalties2->data.F32[index]), "invalid penalty"); 911 912 fprintf(stderr, "penalty1: %f, penalty2: %f\n", penalty1, penalty2); 913 914 return true; 915 } 916 917 float pmSubtractionKernelPenaltySingle(psKernel *kernel) 918 { 919 // Calculate moments 920 double penalty = 0.0; // Moment, for penalty 921 double sum = 0.0, sum2 = 0.0; // Sum of kernel component 922 float min = INFINITY, max = -INFINITY; // Minimum and maximum kernel value 923 for (int v = kernel->yMin; v <= kernel->yMax; v++) { 924 for (int u = kernel->xMin; u <= kernel->xMax; u++) { 925 double value = kernel->kernel[v][u]; 926 double value2 = PS_SQR(value); 927 sum += value; 928 sum2 += value2; 929 penalty += value2 * PS_SQR((PS_SQR(u) + PS_SQR(v))); 930 min = PS_MIN(value, min); 931 max = PS_MAX(value, max); 932 } 933 } 934 penalty *= 1.0 / sum2; 935 936 if (0) { 937 fprintf(stderr, "min: %lf, max: %lf, moment: %lf\n", min, max, penalty); 938 // psTrace("psModules.imcombine", 7, "Kernel %d: %f %d %d %f\n", index, fwhm, uOrder, vOrder, penalty); 939 } 940 941 return penalty; 758 942 } 759 943
Note:
See TracChangeset
for help on using the changeset viewer.
