- 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/pmSubtractionMatch.c
r30304 r30322 11 11 #include "pmFPA.h" 12 12 #include "pmHDUUtils.h" 13 #include "pmSubtractionTypes.h" 14 #include "pmSubtraction.h" 13 15 #include "pmSubtractionParams.h" 14 16 #include "pmSubtractionKernels.h" 15 17 #include "pmSubtractionStamps.h" 16 18 #include "pmSubtractionEquation.h" 17 #include "pmSubtraction.h"18 19 #include "pmSubtractionAnalysis.h" 19 20 #include "pmSubtractionMask.h" … … 57 58 } 58 59 59 60 static bool subtractionGetStamps(pmSubtractionStampList **stamps, // Stamps to read61 const pmReadout *ro1, // Readout 162 const pmReadout *ro2, // Readout 263 const psImage *subMask, // Mask for subtraction, or NULL64 psImage *variance, // Variance map65 const psRegion *region, // Region of interest66 float thresh1, // Threshold for stamp finding on readout 167 float thresh2, // Threshold for stamp finding on readout 268 float stampSpacing, // Spacing between stamps69 float normFrac, // Fraction of flux in window for normalisation window70 float sysError, // Relative systematic error in images71 float skyError, // Relative systematic error in images72 int size, // Kernel half-size73 int footprint, // Convolution footprint for stamps74 pmSubtractionMode mode // Mode for subtraction75 )76 {77 PS_ASSERT_PTR_NON_NULL(stamps, false);78 PM_ASSERT_READOUT_NON_NULL(ro1, false);79 PM_ASSERT_READOUT_NON_NULL(ro2, false);80 PS_ASSERT_IMAGE_NON_NULL(subMask, false);81 PS_ASSERT_IMAGE_NON_NULL(variance, false);82 PS_ASSERT_PTR_NON_NULL(region, false);83 84 psTrace("psModules.imcombine", 3, "Finding stamps...\n");85 86 psImage *image1 = ro1 ? ro1->image : NULL, *image2 = ro2 ? ro2->image : NULL; // Images of interest87 88 *stamps = pmSubtractionStampsFind(*stamps, image1, image2, subMask, region, thresh1, thresh2,89 size, footprint, stampSpacing, normFrac, sysError, skyError, mode);90 if (!*stamps) {91 psError(psErrorCodeLast(), false, "Unable to find stamps.");92 return false;93 }94 95 memCheck(" find stamps");96 97 psTrace("psModules.imcombine", 3, "Extracting stamps...\n");98 if (!pmSubtractionStampsExtract(*stamps, ro1->image, ro2->image, variance, size, *region)) {99 psError(psErrorCodeLast(), false, "Unable to extract stamps.");100 return false;101 }102 103 memCheck(" extract stamps");104 pmSubtractionVisualPlotStamps(*stamps, (pmReadout *) ro1);105 return true;106 }107 108 60 // Check input arguments 109 61 static bool subtractionMatchCheck(pmReadout *conv1, pmReadout *conv2, // Convolved images … … 121 73 float badFrac, // Maximum fraction of bad input pixels to accept 122 74 pmSubtractionMode subMode // Mode of subtraction 123 )75 ) 124 76 { 125 77 if (subMode != PM_SUBTRACTION_MODE_2) { … … 700 652 regionString = psRegionToString(*region); 701 653 psLogMsg("psModules.imcombine", PS_LOG_DETAIL, "Iso-kernel region: %s out of %d,%d\n", 702 regionString, numCols, numRows);654 regionString, numCols, numRows); 703 655 704 656 if (stampsName && strlen(stampsName) > 0) { … … 712 664 } 713 665 714 // We get the stamps here; we will also attempt to get stamps at the first iteration, but it 715 // doesn't matter. 716 if (!subtractionGetStamps(&stamps, ro1, ro2, subMask, variance, region, stampThresh1, stampThresh2, 717 stampSpacing, normFrac, sysError, skyError, size, footprint, subMode)) { 718 goto MATCH_ERROR; 719 } 720 721 722 // generate the window function from the set of stamps 723 if (!pmSubtractionStampsGetWindow(stamps, size)) { 724 psError(psErrorCodeLast(), false, "Unable to get stamp window."); 725 goto MATCH_ERROR; 726 } 727 728 // Define kernel basis functions 729 if (optimum && (type == PM_SUBTRACTION_KERNEL_ISIS || type == PM_SUBTRACTION_KERNEL_GUNK)) { 730 kernels = pmSubtractionKernelsOptimumISIS(type, size, inner, spatialOrder, 731 optFWHMs, optOrder, stamps, footprint, 732 optThreshold, penalty, bounds, subMode); 733 if (!kernels) { 734 psErrorClear(); 735 psWarning("Unable to derive optimum ISIS kernel --- switching to default."); 736 } 737 } 738 if (kernels == NULL) { 739 // Not an ISIS/GUNK kernel, or the optimum kernel search failed 740 kernels = pmSubtractionKernelsGenerate(type, size, spatialOrder, isisWidths, isisOrders, 741 inner, binning, ringsOrder, penalty, bounds, subMode); 742 } 743 744 memCheck("kernels"); 745 746 if (subMode == PM_SUBTRACTION_MODE_UNSURE) { 747 pmSubtractionMode newMode = pmSubtractionBestMode(&stamps, &kernels, subMask, rej); 748 switch (newMode) { 749 case PM_SUBTRACTION_MODE_1: 750 psLogMsg("psModules.imcombine", PS_LOG_INFO, "Convolving image 1 to match image 2."); 751 break; 752 case PM_SUBTRACTION_MODE_2: 753 psLogMsg("psModules.imcombine", PS_LOG_INFO, "Convolving image 2 to match image 1."); 754 break; 755 default: 756 psError(psErrorCodeLast(), false, "Unable to determine subtraction order."); 757 goto MATCH_ERROR; 758 } 759 subMode = newMode; 760 } 761 762 int numRejected = -1; // Number of rejected stamps in each iteration 763 for (int k = 0; (k < iter) && (numRejected != 0); k++) { 764 psLogMsg("psModules.imcombine", PS_LOG_INFO, "Iteration %d.", k); 765 766 if (!subtractionGetStamps(&stamps, ro1, ro2, subMask, variance, region, 767 stampThresh1, stampThresh2, stampSpacing, normFrac, 768 sysError, skyError, size, footprint, subMode)) { 769 goto MATCH_ERROR; 770 } 771 772 // generate the window function from the set of stamps 773 if (!pmSubtractionStampsGetWindow(stamps, size)) { 774 psError(psErrorCodeLast(), false, "Unable to get stamps window."); 775 goto MATCH_ERROR; 776 } 666 bool tryAgain = true; 667 while (tryAgain) { 668 // We get the stamps here; we will also attempt to get stamps at the first iteration, but it 669 // doesn't matter. 670 if (!pmSubtractionStampsSelect(&stamps, ro1, ro2, subMask, variance, region, stampThresh1, stampThresh2, 671 stampSpacing, normFrac, sysError, skyError, size, footprint, subMode)) { 672 goto MATCH_ERROR; 673 } 674 675 // generate the window function from the set of stamps 676 if (!pmSubtractionStampsGetWindow(&tryAgain, stamps, size)) { 677 // if we failed, it might be due to the desired normWindow being larger than the current size. 678 // in this case, just adjust the size and try again. 679 if (tryAgain) { 680 // keep the same footprint-size buffer: 681 int boundary = footprint - size; 682 size = PS_MAX(stamps->normWindow1, stamps->normWindow2) + 2; 683 footprint = size + boundary; 684 685 // we need to reconstruct everything, so just free the stamps here and retry 686 psFree(stamps); 687 } else { 688 // unrecoverable error 689 psError(psErrorCodeLast(), false, "Unable to get stamp window."); 690 goto MATCH_ERROR; 691 } 692 } 693 } 694 695 // Define kernel basis functions 696 if (optimum && (type == PM_SUBTRACTION_KERNEL_ISIS || type == PM_SUBTRACTION_KERNEL_GUNK)) { 697 kernels = pmSubtractionKernelsOptimumISIS(type, size, inner, spatialOrder, 698 optFWHMs, optOrder, stamps, footprint, 699 optThreshold, penalty, bounds, subMode); 700 if (!kernels) { 701 psErrorClear(); 702 psWarning("Unable to derive optimum ISIS kernel --- switching to default."); 703 } 704 } 705 if (kernels == NULL) { 706 // Not an ISIS/GUNK kernel, or the optimum kernel search failed 707 kernels = pmSubtractionKernelsGenerate(type, size, spatialOrder, isisWidths, isisOrders, 708 inner, binning, ringsOrder, penalty, bounds, subMode); 709 } 710 711 memCheck("kernels"); 712 713 if (subMode == PM_SUBTRACTION_MODE_UNSURE) { 714 pmSubtractionMode newMode = pmSubtractionBestMode(&stamps, &kernels, subMask, rej); 715 switch (newMode) { 716 case PM_SUBTRACTION_MODE_1: 717 psLogMsg("psModules.imcombine", PS_LOG_INFO, "Convolving image 1 to match image 2."); 718 break; 719 case PM_SUBTRACTION_MODE_2: 720 psLogMsg("psModules.imcombine", PS_LOG_INFO, "Convolving image 2 to match image 1."); 721 break; 722 default: 723 psError(psErrorCodeLast(), false, "Unable to determine subtraction order."); 724 goto MATCH_ERROR; 725 } 726 subMode = newMode; 727 } 728 729 int numRejected = -1; // Number of rejected stamps in each iteration 730 for (int k = 0; (k < iter) && (numRejected != 0); k++) { 731 psLogMsg("psModules.imcombine", PS_LOG_INFO, "Iteration %d.", k); 732 733 if (!pmSubtractionStampsSelect(&stamps, ro1, ro2, subMask, variance, region, 734 stampThresh1, stampThresh2, stampSpacing, normFrac, 735 sysError, skyError, size, footprint, subMode)) { 736 goto MATCH_ERROR; 737 } 738 739 // Generate the window function from the set of stamps. Since we succeeded 740 // above to define a normWindow, if we fail here, it is probably unrecoverable. 741 if (!pmSubtractionStampsGetWindow(NULL, stamps, size)) { 742 psError(psErrorCodeLast(), false, "Unable to get stamps window."); 743 goto MATCH_ERROR; 744 } 777 745 778 746 // step 0 : calculate the normalizations, pass along to the next steps via stamps->normValue 779 psTrace("psModules.imcombine", 3, "Calculating normalization...\n");780 if (!pmSubtractionCalculateNormalization(stamps, kernels->mode)) {781 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation.");782 goto MATCH_ERROR;783 }747 psTrace("psModules.imcombine", 3, "Calculating normalization...\n"); 748 if (!pmSubtractionCalculateNormalization(stamps, kernels->mode)) { 749 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 750 goto MATCH_ERROR; 751 } 784 752 785 753 // on each iteration, we start from scratch … … 797 765 798 766 // reject the deviant stamps based on the stats of the best match 799 psTrace("psModules.imcombine", 3, "Rejecting stamps...\n");800 numRejected = pmSubtractionRejectStamps(kernels, stamps, bestMatch, subMask, rej);801 if (numRejected < 0) {802 psError(psErrorCodeLast(), false, "Unable to reject stamps.");803 goto MATCH_ERROR;804 }805 memCheck(" reject stamps");806 }767 psTrace("psModules.imcombine", 3, "Rejecting stamps...\n"); 768 numRejected = pmSubtractionRejectStamps(kernels, stamps, bestMatch, subMask, rej); 769 if (numRejected < 0) { 770 psError(psErrorCodeLast(), false, "Unable to reject stamps."); 771 goto MATCH_ERROR; 772 } 773 memCheck(" reject stamps"); 774 } 807 775 808 776 // apply the best fit so we are ready to roll … … 811 779 goto MATCH_ERROR; 812 780 } 813 psFree(stamps);781 psFree(stamps); 814 782 psFree(bestMatch); 815 memCheck("solution");816 817 if (!pmSubtractionAnalysis(analysis, header, kernels, region, numCols, numRows)) {818 psError(psErrorCodeLast(), false, "Unable to generate QA data");819 goto MATCH_ERROR;820 }821 memCheck("diag outputs");822 823 psTrace("psModules.imcombine", 2, "Convolving...\n");824 if (!pmSubtractionConvolve(conv1, conv2, ro1, ro2, subMask, stride, maskBad, maskPoor, poorFrac,825 kernelError, covarFrac, region, kernels, true, useFFT)) {826 psError(psErrorCodeLast(), false, "Unable to convolve image.");827 goto MATCH_ERROR;828 }829 830 psFree(kernels);831 kernels = NULL;832 }783 memCheck("solution"); 784 785 if (!pmSubtractionAnalysis(analysis, header, kernels, region, numCols, numRows)) { 786 psError(psErrorCodeLast(), false, "Unable to generate QA data"); 787 goto MATCH_ERROR; 788 } 789 memCheck("diag outputs"); 790 791 psTrace("psModules.imcombine", 2, "Convolving...\n"); 792 if (!pmSubtractionConvolve(conv1, conv2, ro1, ro2, subMask, stride, maskBad, maskPoor, poorFrac, 793 kernelError, covarFrac, region, kernels, true, useFFT)) { 794 psError(psErrorCodeLast(), false, "Unable to convolve image."); 795 goto MATCH_ERROR; 796 } 797 798 psFree(kernels); 799 kernels = NULL; 800 } 833 801 } 834 802 psFree(rng); … … 844 812 845 813 if (conv1 && !pmSubtractionBorder(conv1->image, conv1->variance, conv1->mask, size, maskBad)) { 846 psError(psErrorCodeLast(), false, "Unable to set border of convolved image.");847 goto MATCH_ERROR;814 psError(psErrorCodeLast(), false, "Unable to set border of convolved image."); 815 goto MATCH_ERROR; 848 816 } 849 817 if (conv2 && !pmSubtractionBorder(conv2->image, conv2->variance, conv2->mask, size, maskBad)) { 850 psError(psErrorCodeLast(), false, "Unable to set border of convolved image.");851 goto MATCH_ERROR;818 psError(psErrorCodeLast(), false, "Unable to set border of convolved image."); 819 goto MATCH_ERROR; 852 820 } 853 821 … … 860 828 #ifdef TESTING 861 829 { 862 if (subMode == PM_SUBTRACTION_MODE_1 || subMode == PM_SUBTRACTION_MODE_DUAL) {863 psFits *fits = psFitsOpen("convolved1.fits", "w");864 psFitsWriteImage(fits, NULL, conv1->image, 0, NULL);865 psFitsClose(fits);866 }867 868 if (subMode == PM_SUBTRACTION_MODE_2 || subMode == PM_SUBTRACTION_MODE_DUAL) {869 psFits *fits = psFitsOpen("convolved2.fits", "w");870 psFitsWriteImage(fits, NULL, conv2->image, 0, NULL);871 psFitsClose(fits);872 }830 if (subMode == PM_SUBTRACTION_MODE_1 || subMode == PM_SUBTRACTION_MODE_DUAL) { 831 psFits *fits = psFitsOpen("convolved1.fits", "w"); 832 psFitsWriteImage(fits, NULL, conv1->image, 0, NULL); 833 psFitsClose(fits); 834 } 835 836 if (subMode == PM_SUBTRACTION_MODE_2 || subMode == PM_SUBTRACTION_MODE_DUAL) { 837 psFits *fits = psFitsOpen("convolved2.fits", "w"); 838 psFitsWriteImage(fits, NULL, conv2->image, 0, NULL); 839 psFitsClose(fits); 840 } 873 841 } 874 842 #endif … … 895 863 // increment). 896 864 static int subtractionOrderWidth(const psKernel *kernel, // Image 897 float bg, // Background in image898 int size, // Maximum size899 const psArray *models, // Buffer of models900 const psVector *modelSums // Buffer of model sums865 float bg, // Background in image 866 int size, // Maximum size 867 const psArray *models, // Buffer of models 868 const psVector *modelSums // Buffer of model sums 901 869 ) 902 870 { … … 911 879 psVector *chi2 = psVectorAlloc(size, PS_TYPE_F32); // chi^2 as a function of radius 912 880 for (int sigma = 0; sigma < size; sigma++) { 913 double sumFG = 0.0; // Sum for calculating the normalisation of the Gaussian914 psKernel *model = models->data[sigma]; // Model of interest915 for (int y = yMin; y <= yMax; y++) {916 for (int x = xMin; x <= xMax; x++) {917 sumFG += model->kernel[y][x] * (kernel->kernel[y][x] - bg);918 }919 }920 float norm = sumFG * modelSums->data.F64[sigma]; // Normalisation for Gaussian921 double sumDev2 = 0.0; // Sum of square deviations922 for (int y = yMin; y <= yMax; y++) {923 for (int x = xMin; x <= xMax; x++) {924 float dev = kernel->kernel[y][x] - bg - norm * model->kernel[y][x]; // Deviation925 sumDev2 += PS_SQR(dev);926 }927 }928 chi2->data.F32[sigma] = sumDev2;881 double sumFG = 0.0; // Sum for calculating the normalisation of the Gaussian 882 psKernel *model = models->data[sigma]; // Model of interest 883 for (int y = yMin; y <= yMax; y++) { 884 for (int x = xMin; x <= xMax; x++) { 885 sumFG += model->kernel[y][x] * (kernel->kernel[y][x] - bg); 886 } 887 } 888 float norm = sumFG * modelSums->data.F64[sigma]; // Normalisation for Gaussian 889 double sumDev2 = 0.0; // Sum of square deviations 890 for (int y = yMin; y <= yMax; y++) { 891 for (int x = xMin; x <= xMax; x++) { 892 float dev = kernel->kernel[y][x] - bg - norm * model->kernel[y][x]; // Deviation 893 sumDev2 += PS_SQR(dev); 894 } 895 } 896 chi2->data.F32[sigma] = sumDev2; 929 897 } 930 898 … … 933 901 float bestChi2 = INFINITY; // Best chi^2 934 902 for (int i = 0; i < size; i++) { 935 if (chi2->data.F32[i] < bestChi2) {936 bestChi2 = chi2->data.F32[i];937 bestIndex = i;938 }903 if (chi2->data.F32[i] < bestChi2) { 904 bestChi2 = chi2->data.F32[i]; 905 bestIndex = i; 906 } 939 907 } 940 908 psFree(chi2); … … 945 913 946 914 bool pmSubtractionOrderStamp(psVector *ratios, psVector *mask, const pmSubtractionStampList *stamps, 947 const psArray *models, const psVector *modelSums,948 int index, float bg1, float bg2)915 const psArray *models, const psVector *modelSums, 916 int index, float bg1, float bg2) 949 917 { 950 918 PS_ASSERT_VECTOR_NON_NULL(ratios, false); … … 960 928 pmSubtractionStamp *stamp = stamps->stamps->data[index]; // Stamp of interest 961 929 psAssert(stamp->status == PM_SUBTRACTION_STAMP_CALCULATE || stamp->status == PM_SUBTRACTION_STAMP_USED, 962 "We checked this earlier.");930 "We checked this earlier."); 963 931 964 932 // Widths of stars … … 967 935 968 936 if (width1 == 0 || width2 == 0) { 969 ratios->data.F32[index] = NAN;970 mask->data.PS_TYPE_VECTOR_MASK_DATA[index] = 0xff;937 ratios->data.F32[index] = NAN; 938 mask->data.PS_TYPE_VECTOR_MASK_DATA[index] = 0xff; 971 939 } else { 972 ratios->data.F32[index] = (float)width1 / (float)width2;973 mask->data.PS_TYPE_VECTOR_MASK_DATA[index] = 0;974 psTrace("psModules.imcombine", 3, "Stamp %d (%.1f,%.1f) widths: %d, %d --> %f\n",975 index, stamp->x, stamp->y, width1, width2, ratios->data.F32[index]);940 ratios->data.F32[index] = (float)width1 / (float)width2; 941 mask->data.PS_TYPE_VECTOR_MASK_DATA[index] = 0; 942 psTrace("psModules.imcombine", 3, "Stamp %d (%.1f,%.1f) widths: %d, %d --> %f\n", 943 index, stamp->x, stamp->y, width1, width2, ratios->data.F32[index]); 976 944 } 977 945 … … 1007 975 psVector *modelSums = psVectorAlloc(size, PS_TYPE_F64); // Gaussian model sums 1008 976 for (int sigma = 0; sigma < size; sigma++) { 1009 psKernel *model = psKernelAlloc(-size, size, -size, size); // Gaussian model1010 float invSigma2 = 1.0 / (float)PS_SQR(1 + sigma); // Inverse sigma squared1011 double sumGG = 0.0; // Sum of square of Gaussian1012 for (int y = -size; y <= size; y++) {1013 int y2 = PS_SQR(y); // y squared1014 for (int x = -size; x <= size; x++) {1015 float rad2 = PS_SQR(x) + y2; // Radius squared1016 float value = expf(-rad2 * invSigma2); // Model value1017 model->kernel[y][x] = value;1018 sumGG += PS_SQR(value);1019 }1020 }1021 models->data[sigma] = model;1022 modelSums->data.F64[sigma] = 1.0 / sumGG;977 psKernel *model = psKernelAlloc(-size, size, -size, size); // Gaussian model 978 float invSigma2 = 1.0 / (float)PS_SQR(1 + sigma); // Inverse sigma squared 979 double sumGG = 0.0; // Sum of square of Gaussian 980 for (int y = -size; y <= size; y++) { 981 int y2 = PS_SQR(y); // y squared 982 for (int x = -size; x <= size; x++) { 983 float rad2 = PS_SQR(x) + y2; // Radius squared 984 float value = expf(-rad2 * invSigma2); // Model value 985 model->kernel[y][x] = value; 986 sumGG += PS_SQR(value); 987 } 988 } 989 models->data[sigma] = model; 990 modelSums->data.F64[sigma] = 1.0 / sumGG; 1023 991 } 1024 992 1025 993 // Fit models to stamps 1026 994 for (int i = 0; i < stamps->num; i++) { 1027 pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest1028 if (stamp->status != PM_SUBTRACTION_STAMP_CALCULATE && stamp->status != PM_SUBTRACTION_STAMP_USED) {1029 mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = 0xff;1030 continue;1031 }1032 1033 if (pmSubtractionThreaded()) {1034 psThreadJob *job = psThreadJobAlloc("PSMODULES_SUBTRACTION_ORDER");1035 psArrayAdd(job->args, 1, ratios);1036 psArrayAdd(job->args, 1, mask);1037 psArrayAdd(job->args, 1, stamps);1038 psArrayAdd(job->args, 1, models);1039 psArrayAdd(job->args, 1, modelSums);1040 PS_ARRAY_ADD_SCALAR(job->args, i, PS_TYPE_S32);1041 PS_ARRAY_ADD_SCALAR(job->args, bg1, PS_TYPE_F32);1042 PS_ARRAY_ADD_SCALAR(job->args, bg2, PS_TYPE_F32);1043 if (!psThreadJobAddPending(job)) {1044 return false;1045 }1046 } else {1047 if (!pmSubtractionOrderStamp(ratios, mask, stamps, models, modelSums, i, bg1, bg2)) {1048 psError(psErrorCodeLast(), false, "Unable to measure PSF width for stamp %d", i);1049 psFree(models);1050 psFree(modelSums);1051 psFree(ratios);1052 psFree(mask);1053 return false;1054 }1055 }995 pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest 996 if (stamp->status != PM_SUBTRACTION_STAMP_CALCULATE && stamp->status != PM_SUBTRACTION_STAMP_USED) { 997 mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = 0xff; 998 continue; 999 } 1000 1001 if (pmSubtractionThreaded()) { 1002 psThreadJob *job = psThreadJobAlloc("PSMODULES_SUBTRACTION_ORDER"); 1003 psArrayAdd(job->args, 1, ratios); 1004 psArrayAdd(job->args, 1, mask); 1005 psArrayAdd(job->args, 1, stamps); 1006 psArrayAdd(job->args, 1, models); 1007 psArrayAdd(job->args, 1, modelSums); 1008 PS_ARRAY_ADD_SCALAR(job->args, i, PS_TYPE_S32); 1009 PS_ARRAY_ADD_SCALAR(job->args, bg1, PS_TYPE_F32); 1010 PS_ARRAY_ADD_SCALAR(job->args, bg2, PS_TYPE_F32); 1011 if (!psThreadJobAddPending(job)) { 1012 return false; 1013 } 1014 } else { 1015 if (!pmSubtractionOrderStamp(ratios, mask, stamps, models, modelSums, i, bg1, bg2)) { 1016 psError(psErrorCodeLast(), false, "Unable to measure PSF width for stamp %d", i); 1017 psFree(models); 1018 psFree(modelSums); 1019 psFree(ratios); 1020 psFree(mask); 1021 return false; 1022 } 1023 } 1056 1024 } 1057 1025 1058 1026 if (!psThreadPoolWait(true)) { 1059 psError(psErrorCodeLast(), false, "Error waiting for threads.");1060 psFree(models);1061 psFree(modelSums);1062 psFree(ratios);1063 psFree(mask);1064 return false;1027 psError(psErrorCodeLast(), false, "Error waiting for threads."); 1028 psFree(models); 1029 psFree(modelSums); 1030 psFree(ratios); 1031 psFree(mask); 1032 return false; 1065 1033 } 1066 1034 … … 1070 1038 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN); 1071 1039 if (!psVectorStats(stats, ratios, NULL, mask, 0xff)) { 1072 psError(psErrorCodeLast(), false, "Unable to calculate statistics for moments ratio.");1073 psFree(mask);1074 psFree(ratios);1075 psFree(stats);1076 return PM_SUBTRACTION_MODE_ERR;1040 psError(psErrorCodeLast(), false, "Unable to calculate statistics for moments ratio."); 1041 psFree(mask); 1042 psFree(ratios); 1043 psFree(stats); 1044 return PM_SUBTRACTION_MODE_ERR; 1077 1045 } 1078 1046 psFree(ratios); … … 1081 1049 // XXX raise an error here or not? 1082 1050 if (isnan(stats->robustMedian)) { 1083 psFree(stats);1084 return PM_SUBTRACTION_MODE_ERR;1051 psFree(stats); 1052 return PM_SUBTRACTION_MODE_ERR; 1085 1053 } 1086 1054 … … 1095 1063 // Test a subtraction mode by performing a single iteration 1096 1064 static bool subtractionModeTest(pmSubtractionStampList *stamps, // Stamps to use to find best mode 1097 pmSubtractionKernels *kernels, // Kernel description1098 const char *description, // Description for trace1099 psImage *subMask, // Subtraction mask1100 float rej // Rejection threshold1101 )1065 pmSubtractionKernels *kernels, // Kernel description 1066 const char *description, // Description for trace 1067 psImage *subMask, // Subtraction mask 1068 float rej // Rejection threshold 1069 ) 1102 1070 { 1103 1071 assert(stamps); … … 1114 1082 psTrace("psModules.imcombine", 3, "Calculating %s normalization equation...\n", description); 1115 1083 if (!pmSubtractionCalculateEquation(stamps, kernels)) { 1116 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation.");1117 return false;1084 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 1085 return false; 1118 1086 } 1119 1087 1120 1088 psTrace("psModules.imcombine", 3, "Solving %s normalization equation...\n", description); 1121 1089 if (!pmSubtractionSolveEquation(kernels, stamps)) { 1122 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation.");1123 return false;1090 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 1091 return false; 1124 1092 } 1125 1093 … … 1127 1095 psVector *deviations = pmSubtractionCalculateDeviations(stamps, kernels); // Stamp deviations 1128 1096 if (!deviations) { 1129 psError(psErrorCodeLast(), false, "Unable to calculate deviations.");1130 return false;1097 psError(psErrorCodeLast(), false, "Unable to calculate deviations."); 1098 return false; 1131 1099 } 1132 1100 … … 1135 1103 long numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, rej); 1136 1104 if (numRejected < 0) { 1137 psError(psErrorCodeLast(), false, "Unable to reject stamps.");1138 psFree(deviations);1139 return false;1105 psError(psErrorCodeLast(), false, "Unable to reject stamps."); 1106 psFree(deviations); 1107 return false; 1140 1108 } 1141 1109 psFree(deviations); 1142 1110 1143 1111 if (numRejected > 0) { 1144 // Allow re-fit with reduced stamps set1145 psTrace("psModules.imcombine", 3, "Calculating %s normalization equation...\n", description);1146 if (!pmSubtractionCalculateEquation(stamps, kernels)) {1147 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation.");1148 return false;1149 }1150 1151 psTrace("psModules.imcombine", 3, "Resolving %s equation...\n", description);1152 if (!pmSubtractionSolveEquation(kernels, stamps)) {1153 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation.");1154 return false;1155 }1156 psTrace("psModules.imcombine", 3, "Recalculate %s deviations...\n", description);1157 1158 psVector *deviations = pmSubtractionCalculateDeviations(stamps, kernels); // Stamp deviations1159 if (!deviations) {1160 psError(psErrorCodeLast(), false, "Unable to calculate deviations.");1161 return false;1162 }1163 psTrace("psModules.imcombine", 3, "Measuring %s quality...\n", description);1164 long numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, NAN);1165 if (numRejected < 0) {1166 psError(psErrorCodeLast(), false, "Unable to reject stamps.");1167 psFree(deviations);1168 return false;1169 }1170 psFree(deviations);1112 // Allow re-fit with reduced stamps set 1113 psTrace("psModules.imcombine", 3, "Calculating %s normalization equation...\n", description); 1114 if (!pmSubtractionCalculateEquation(stamps, kernels)) { 1115 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 1116 return false; 1117 } 1118 1119 psTrace("psModules.imcombine", 3, "Resolving %s equation...\n", description); 1120 if (!pmSubtractionSolveEquation(kernels, stamps)) { 1121 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 1122 return false; 1123 } 1124 psTrace("psModules.imcombine", 3, "Recalculate %s deviations...\n", description); 1125 1126 psVector *deviations = pmSubtractionCalculateDeviations(stamps, kernels); // Stamp deviations 1127 if (!deviations) { 1128 psError(psErrorCodeLast(), false, "Unable to calculate deviations."); 1129 return false; 1130 } 1131 psTrace("psModules.imcombine", 3, "Measuring %s quality...\n", description); 1132 long numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, NAN); 1133 if (numRejected < 0) { 1134 psError(psErrorCodeLast(), false, "Unable to reject stamps."); 1135 psFree(deviations); 1136 return false; 1137 } 1138 psFree(deviations); 1171 1139 } 1172 1140 # endif … … 1176 1144 1177 1145 pmSubtractionMode pmSubtractionBestMode(pmSubtractionStampList **stamps, pmSubtractionKernels **kernels, 1178 const psImage *subMask, float rej)1146 const psImage *subMask, float rej) 1179 1147 { 1180 1148 PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(*stamps, PM_SUBTRACTION_MODE_ERR); … … 1188 1156 1189 1157 if (!subtractionModeTest(stamps1, kernels1, "convolve 1", subMask1, rej)) { 1190 psError(psErrorCodeLast(), false, "Unable to test subtraction with convolution of image 1");1191 psFree(stamps1);1192 psFree(kernels1);1193 psFree(subMask1);1194 return PM_SUBTRACTION_MODE_ERR;1158 psError(psErrorCodeLast(), false, "Unable to test subtraction with convolution of image 1"); 1159 psFree(stamps1); 1160 psFree(kernels1); 1161 psFree(subMask1); 1162 return PM_SUBTRACTION_MODE_ERR; 1195 1163 } 1196 1164 psFree(subMask1); … … 1203 1171 1204 1172 if (!subtractionModeTest(stamps2, kernels2, "convolve 2", subMask2, rej)) { 1205 psError(psErrorCodeLast(), false, "Unable to test subtraction with convolution of image 2");1206 psFree(stamps2);1207 psFree(kernels2);1208 psFree(subMask2);1209 psFree(stamps1);1210 psFree(kernels1);1211 return PM_SUBTRACTION_MODE_ERR;1173 psError(psErrorCodeLast(), false, "Unable to test subtraction with convolution of image 2"); 1174 psFree(stamps2); 1175 psFree(kernels2); 1176 psFree(subMask2); 1177 psFree(stamps1); 1178 psFree(kernels1); 1179 return PM_SUBTRACTION_MODE_ERR; 1212 1180 } 1213 1181 psFree(subMask2); … … 1217 1185 pmSubtractionKernels *bestKernels = NULL; // Best choice for kernels 1218 1186 psLogMsg("psModules.imcombine", PS_LOG_INFO, 1219 "Image 1: %f +/- %f from %d stamps\nImage 2: %f +/- %f from %d stamps\n",1220 kernels1->mean, kernels1->rms, kernels1->numStamps,1221 kernels2->mean, kernels2->rms, kernels2->numStamps);1187 "Image 1: %f +/- %f from %d stamps\nImage 2: %f +/- %f from %d stamps\n", 1188 kernels1->mean, kernels1->rms, kernels1->numStamps, 1189 kernels2->mean, kernels2->rms, kernels2->numStamps); 1222 1190 1223 1191 if (kernels1->mean < kernels2->mean) { 1224 bestStamps = stamps1;1225 bestKernels = kernels1;1192 bestStamps = stamps1; 1193 bestKernels = kernels1; 1226 1194 } else { 1227 bestStamps = stamps2;1228 bestKernels = kernels2;1195 bestStamps = stamps2; 1196 bestKernels = kernels2; 1229 1197 } 1230 1198 … … 1244 1212 1245 1213 bool pmSubtractionParamsScale(int *kernelSize, int *stampSize, psVector *widths, 1246 float scaleRef, float scaleMin, float scaleMax)1214 float scaleRef, float scaleMin, float scaleMax) 1247 1215 { 1248 1216 PS_ASSERT_PTR_NON_NULL(kernelSize, false); … … 1266 1234 1267 1235 if (isfinite(scaleMin) && scale < scaleMin) { 1268 scale = scaleMin;1236 scale = scaleMin; 1269 1237 } 1270 1238 if (isfinite(scaleMax) && scale > scaleMax) { 1271 scale = scaleMax;1239 scale = scaleMax; 1272 1240 } 1273 1241 1274 1242 for (int i = 0; i < widths->n; i++) { 1275 widths->data.F32[i] *= scale;1243 widths->data.F32[i] *= scale; 1276 1244 } 1277 1245 *kernelSize = *kernelSize * scale + 0.5; … … 1279 1247 1280 1248 psLogMsg("psModules.imcombine", PS_LOG_INFO, 1281 "Scaling kernel parameters by %f: %d %d", scale, *kernelSize, *stampSize);1249 "Scaling kernel parameters by %f: %d %d", scale, *kernelSize, *stampSize); 1282 1250 1283 1251 return true;
Note:
See TracChangeset
for help on using the changeset viewer.
