Changeset 30322
- Timestamp:
- Jan 20, 2011, 11:53:03 AM (15 years ago)
- Location:
- branches/eam_branches/ipp-20101205/psModules/src
- Files:
-
- 1 added
- 22 edited
-
extras/pmVisual.c (modified) (1 diff)
-
imcombine/Makefile.am (modified) (1 diff)
-
imcombine/pmStackReject.c (modified) (1 diff)
-
imcombine/pmSubtraction.c (modified) (1 diff)
-
imcombine/pmSubtraction.h (modified) (2 diffs)
-
imcombine/pmSubtractionAnalysis.c (modified) (1 diff)
-
imcombine/pmSubtractionDeconvolve.c (modified) (1 diff)
-
imcombine/pmSubtractionEquation.c (modified) (1 diff)
-
imcombine/pmSubtractionEquation.h (modified) (1 diff)
-
imcombine/pmSubtractionEquation.v0.c (modified) (1 diff)
-
imcombine/pmSubtractionHermitian.c (modified) (1 diff)
-
imcombine/pmSubtractionIO.c (modified) (1 diff)
-
imcombine/pmSubtractionKernels.c (modified) (1 diff)
-
imcombine/pmSubtractionKernels.h (modified) (1 diff)
-
imcombine/pmSubtractionMask.c (modified) (1 diff)
-
imcombine/pmSubtractionMatch.c (modified) (29 diffs)
-
imcombine/pmSubtractionParams.c (modified) (1 diff)
-
imcombine/pmSubtractionStamps.c (modified) (7 diffs)
-
imcombine/pmSubtractionStamps.h (modified) (3 diffs)
-
imcombine/pmSubtractionThreads.c (modified) (1 diff)
-
imcombine/pmSubtractionTypes.h (added)
-
imcombine/pmSubtractionVisual.c (modified) (1 diff)
-
psmodules.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20101205/psModules/src/extras/pmVisual.c
r30266 r30322 16 16 #include <pslib.h> 17 17 18 #include "pmHDU.h" 19 #include "pmFPA.h" 20 #include "pmFPAfile.h" 21 #include "pmAstrometryObjects.h" 22 #include "pmSubtractionStamps.h" 23 24 #include "pmTrend2D.h" 25 #include "pmResiduals.h" 26 #include "pmGrowthCurve.h" 27 #include "pmSpan.h" 28 #include "pmFootprintSpans.h" 29 #include "pmFootprint.h" 30 #include "pmPeaks.h" 31 #include "pmMoments.h" 32 #include "pmModelFuncs.h" 33 #include "pmModel.h" 34 #include "pmSourceMasks.h" 35 #include "pmSourceExtendedPars.h" 36 #include "pmSourceDiffStats.h" 37 #include "pmSource.h" 38 #include "pmSourceFitModel.h" 39 #include "pmPSF.h" 40 #include "pmPSFtry.h" 41 42 #include "pmFPAExtent.h" 43 44 #include "pmAstrometryVisual.h" 45 #include "pmSubtractionVisual.h" 46 #include "pmStackVisual.h" 47 #include "pmSourceVisual.h" 18 bool pmSubtractionVisualClose(void); 19 bool pmAstromVisualClose(void); 20 bool pmSubtractionVisualClose(void); 21 bool pmStackVisualClose(void); 22 bool pmSourceVisualClose(void); 23 24 // #include "pmHDU.h" 25 // #include "pmFPA.h" 26 // #include "pmFPAfile.h" 27 // #include "pmAstrometryObjects.h" 28 // #include "pmSubtractionStamps.h" 29 // #include "pmTrend2D.h" 30 // #include "pmResiduals.h" 31 // #include "pmGrowthCurve.h" 32 // #include "pmSpan.h" 33 // #include "pmFootprintSpans.h" 34 // #include "pmFootprint.h" 35 // #include "pmPeaks.h" 36 // #include "pmMoments.h" 37 // #include "pmModelFuncs.h" 38 // #include "pmModel.h" 39 // #include "pmSourceMasks.h" 40 // #include "pmSourceExtendedPars.h" 41 // #include "pmSourceDiffStats.h" 42 // #include "pmSource.h" 43 // #include "pmSourceFitModel.h" 44 // #include "pmPSF.h" 45 // #include "pmPSFtry.h" 46 // #include "pmFPAExtent.h" 47 // #include "pmAstrometryVisual.h" 48 // #include "pmSubtractionVisual.h" 49 // #include "pmStackVisual.h" 50 // #include "pmSourceVisual.h" 48 51 49 52 # if (HAVE_KAPA) -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/Makefile.am
r26893 r30322 30 30 pmStackReject.h \ 31 31 pmSubtraction.h \ 32 pmSubtractionTypes.h \ 32 33 pmSubtractionAnalysis.h \ 33 34 pmSubtractionEquation.h \ -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmStackReject.c
r28405 r30322 7 7 #include <pslib.h> 8 8 9 #include "pmFPA.h" 10 #include "pmSubtractionTypes.h" 9 11 #include "pmSubtraction.h" 10 12 #include "pmSubtractionThreads.h" -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtraction.c
r30303 r30322 20 20 #include "pmHDU.h" // Required for pmFPA.h 21 21 #include "pmFPA.h" 22 #include "pmSubtractionTypes.h" 22 23 #include "pmSubtractionStamps.h" 23 24 #include "pmSubtractionEquation.h" -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtraction.h
r30288 r30322 14 14 #define PM_SUBTRACTION_H 15 15 16 #include <pslib.h> 17 18 #include <pmHDU.h> 19 #include <pmFPA.h> 20 #include <pmSubtractionKernels.h> 21 #include <pmSubtractionStamps.h> 16 // #include <pslib.h> 17 // #include <pmHDU.h> 18 // #include <pmFPA.h> 19 // #include <pmSubtractionKernels.h> 20 // #include <pmSubtractionStamps.h> 22 21 23 22 // if we use the original ppSub implementation, we subtract a central delta-function for all … … 30 29 /// @addtogroup imcombine Image Combinations 31 30 /// @{ 32 33 /// Mask values for the subtraction mask34 typedef enum {35 PM_SUBTRACTION_MASK_CLEAR = 0x00, // No masking36 PM_SUBTRACTION_MASK_BAD_1 = 0x01, // Image 1 is bad37 PM_SUBTRACTION_MASK_BAD_2 = 0x02, // Image 2 is bad38 PM_SUBTRACTION_MASK_CONVOLVE_1 = 0x04, // If image 1 is convolved, would be poor or bad39 PM_SUBTRACTION_MASK_CONVOLVE_2 = 0x08, // If image 2 is convolved, would be poor or bad40 PM_SUBTRACTION_MASK_CONVOLVE_BAD_1 = 0x10, // If image 1 is convolved, would be bad41 PM_SUBTRACTION_MASK_CONVOLVE_BAD_2 = 0x20, // If image 2 is convolved, would be bad42 PM_SUBTRACTION_MASK_BORDER = 0x40, // Image border43 PM_SUBTRACTION_MASK_REJ = 0x80, // Previously tried as a stamp, and rejected44 } pmSubtractionMasks;45 46 typedef struct {47 double score;48 pmSubtractionMode mode;49 int spatialOrder;50 int nGood;51 psVector *fluxes;52 psVector *chisq;53 psVector *moments;54 psVector *stampMask;55 } pmSubtractionQuality;56 31 57 32 /// Number of terms in a polynomial -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionAnalysis.c
r29595 r30322 7 7 8 8 #include "pmFPA.h" 9 #include "pmSubtractionTypes.h" 9 10 #include "pmSubtraction.h" 10 11 #include "pmSubtractionKernels.h" -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionDeconvolve.c
r26893 r30322 10 10 11 11 #include "pmFPA.h" 12 #include "pmSubtractionTypes.h" 12 13 #include "pmSubtractionKernels.h" 13 14 #include "pmSubtractionDeconvolve.h" -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionEquation.c
r30308 r30322 9 9 #include "pmErrorCodes.h" 10 10 #include "pmVisual.h" 11 #include "pmFPA.h" 12 #include "pmSubtractionTypes.h" 11 13 #include "pmSubtraction.h" 12 14 #include "pmSubtractionKernels.h" -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionEquation.h
r30289 r30322 5 5 #include "pmSubtractionKernels.h" 6 6 #include "pmSubtraction.h" 7 8 // typedef enum {9 // PM_SUBTRACTION_EQUATION_NONE = 0x00,10 // PM_SUBTRACTION_EQUATION_NORM = 0x01,11 // PM_SUBTRACTION_EQUATION_BG = 0x02,12 // PM_SUBTRACTION_EQUATION_KERNELS = 0x04,13 // PM_SUBTRACTION_EQUATION_ALL = 0x07, // value should be NORM | BG | KERNELS14 // } pmSubtractionEquationCalculationMode;15 7 16 8 /// Execute a thread job to calculate the least-squares equation for a stamp -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionEquation.v0.c
r29543 r30322 9 9 #include "pmErrorCodes.h" 10 10 #include "pmSubtraction.h" 11 #include "pmSubtractionTypes.h" 11 12 #include "pmSubtractionKernels.h" 12 13 #include "pmSubtractionStamps.h" -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionHermitian.c
r26893 r30322 8 8 #include <pslib.h> 9 9 10 #include "pmSubtractionTypes.h" 10 11 #include "pmSubtractionHermitian.h" 11 12 -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionIO.c
r27321 r30322 12 12 #include "pmConceptsRead.h" 13 13 14 #include "pmSubtractionTypes.h" 14 15 #include "pmSubtraction.h" 15 16 #include "pmSubtractionKernels.h" -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionKernels.c
r30266 r30322 8 8 #include <pslib.h> 9 9 10 #include "pmFPA.h" 11 #include "pmSubtractionTypes.h" 10 12 #include "pmSubtraction.h" 11 13 #include "pmSubtractionKernels.h" -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionKernels.h
r30266 r30322 2 2 #define PM_SUBTRACTION_KERNELS_H 3 3 4 #include <string.h> 5 #include <pslib.h> 6 7 /// Type of subtraction kernel 8 typedef enum { 9 PM_SUBTRACTION_KERNEL_NONE, ///< Nothing --- an error 10 PM_SUBTRACTION_KERNEL_POIS, ///< Pan-STARRS Optimal Image Subtraction --- delta functions 11 PM_SUBTRACTION_KERNEL_ISIS, ///< Traditional kernel --- gaussians modified by polynomials 12 PM_SUBTRACTION_KERNEL_ISIS_RADIAL, ///< ISIS + higher-order radial Hermitians 13 PM_SUBTRACTION_KERNEL_HERM, ///< Hermitian polynomial kernels 14 PM_SUBTRACTION_KERNEL_DECONV_HERM, ///< Deconvolved Hermitian polynomial kernels 15 PM_SUBTRACTION_KERNEL_SPAM, ///< Summed Pixels for Advanced Matching --- summed delta functions 16 PM_SUBTRACTION_KERNEL_FRIES, ///< Fibonacci Radius Increases Excellence of Subtraction 17 PM_SUBTRACTION_KERNEL_GUNK, ///< Grid United with Normal Kernel --- POIS and ISIS hybrid 18 PM_SUBTRACTION_KERNEL_RINGS, ///< Rings Instead of the Normal Gaussian Subtraction 19 } pmSubtractionKernelsType; 20 21 /// Modes --- specifies which image to convolve 22 typedef enum { 23 PM_SUBTRACTION_MODE_ERR, // Error in the mode 24 PM_SUBTRACTION_MODE_1, // Convolve image 1 25 PM_SUBTRACTION_MODE_2, // Convolve image 2 26 PM_SUBTRACTION_MODE_UNSURE, // Not sure yet which image to convolve so try to satisfy both 27 PM_SUBTRACTION_MODE_DUAL, // Dual convolution 28 } pmSubtractionMode; 29 30 /// Kernels specification 31 typedef struct { 32 pmSubtractionKernelsType type; ///< Type of kernels --- allowing the use of multiple kernels 33 psString description; ///< Description of the kernel parameters 34 int xMin, xMax, yMin, yMax; ///< Bounds of image (for normalisation) 35 long num; ///< Number of kernel components (not including the spatial ones) 36 psVector *u, *v; ///< Offset (for POIS) or polynomial order (for ISIS, HERM or DECONV_HERM) 37 psVector *widths; ///< Gaussian FWHMs (ISIS, HERM or DECONV_HERM) 38 psVector *uStop, *vStop; ///< Width of kernel element (SPAM,FRIES only) 39 psArray *preCalc; ///< Array of images containing pre-calculated kernel (for ISIS, HERM or DECONV_HERM) 40 float penalty; ///< Penalty for wideness 41 psVector *penalties1; ///< Penalty for each kernel component 42 psVector *penalties2; ///< Penalty for each kernel component 43 bool havePenalties; ///< flag to test if we have already calculated the penalties or not. 44 int size; ///< The half-size of the kernel 45 int inner; ///< The size of an inner region 46 int spatialOrder; ///< The spatial order of the kernels 47 int bgOrder; ///< The order for the background fitting 48 pmSubtractionMode mode; ///< Mode for subtraction 49 psVector *solution1, *solution2; ///< Solution for the PSF matching 50 psVector *solution1err, *solution2err; ///< error in solution for the PSF matching 51 // Quality information 52 float mean, rms; ///< Mean and RMS of chi^2 from stamps 53 int numStamps; ///< Number of good stamps 54 float fResSigmaMean; ///< mean fractional stdev of residuals 55 float fResSigmaStdev; ///< stdev of fractional stdev of residuals 56 float fResOuterMean; ///< mean fractional positive swing in residuals 57 float fResOuterStdev; ///< stdev of fractional positive swing in residuals 58 float fResTotalMean; ///< mean fractional negative swing in residuals 59 float fResTotalStdev; ///< stdev of fractional negative swing in residuals 60 psArray *sampleStamps; ///< array of brightest set of stamps for output visualizations 61 } pmSubtractionKernels; 62 63 // pmSubtractionKernels->preCalc is an array of pmSubtractionKernelPreCalc structures 64 typedef struct { 65 psVector *uCoords; // used by RINGS 66 psVector *vCoords; // used by RINGS 67 psVector *poly; // used by RINGS 68 69 psVector *xKernel; // used by ISIS, HERM, DECONV_HERM 70 psVector *yKernel; // used by ISIS, HERM, DECONV_HERM 71 psKernel *kernel; // used by ISIS, HERM, DECONV_HERM 72 } pmSubtractionKernelPreCalc; 4 // #include <string.h> 5 // #include <pslib.h> 73 6 74 7 // Assertion to check pmSubtractionKernels -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionMask.c
r27402 r30322 7 7 8 8 #include "pmErrorCodes.h" 9 #include "pmFPA.h" 10 #include "pmSubtractionTypes.h" 9 11 #include "pmSubtraction.h" 10 12 #include "pmSubtractionKernels.h" -
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; -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionParams.c
r30286 r30322 9 9 10 10 #include "pmErrorCodes.h" 11 #include "pmFPA.h" 12 #include "pmSubtractionTypes.h" 13 #include "pmSubtraction.h" 11 14 #include "pmSubtractionStamps.h" 12 #include "pmSubtraction.h"13 15 #include "pmSubtractionParams.h" 14 16 -
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); -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionStamps.h
r29543 r30322 1 1 #ifndef PM_SUBTRACTION_STAMPS_H 2 2 #define PM_SUBTRACTION_STAMPS_H 3 4 #include <pslib.h>5 6 #include "pmSubtractionKernels.h"7 8 /// Status of stamp9 typedef enum {10 PM_SUBTRACTION_STAMP_INIT, ///< Initial state11 PM_SUBTRACTION_STAMP_FOUND, ///< Found a suitable source for this stamp12 PM_SUBTRACTION_STAMP_CALCULATE, ///< Calculate matrix and vector values for this stamp13 PM_SUBTRACTION_STAMP_USED, ///< Use this stamp14 PM_SUBTRACTION_STAMP_REJECTED, ///< This stamp has been rejected15 PM_SUBTRACTION_STAMP_NONE ///< No stamp in this region16 } pmSubtractionStampStatus;17 18 /// A list of stamps19 typedef struct {20 long num; ///< Number of stamps21 psArray *stamps; ///< The stamps22 psArray *regions; ///< Regions for each stamp23 psArray *x, *y; ///< Coordinates for possible stamps (or NULL)24 psArray *flux; ///< Fluxes for possible stamps (or NULL)25 int footprint; ///< Half-size of stamps26 float normFrac; ///< Fraction of flux in window for normalisation window27 float normValue; ///< calculated normalization28 float normValue2; ///< calculated normalization29 psKernel *window1; ///< window function generated from ensemble of stamps (input 1)30 psKernel *window2; ///< window function generated from ensemble of stamps (input 2)31 psKernel *window; ///< weighting window function (sigma = 1.1 * MAX(fwhm))32 float normWindow1; ///< Size of window for measuring normalisation33 float normWindow2; ///< Size of window for measuring normalisation34 float sysErr; ///< Systematic error35 float skyErr; ///< increase effective readnoise36 } pmSubtractionStampList;37 3 38 4 /// Allocate a list of stamps … … 74 40 ); 75 41 76 77 /// A stamp for image subtraction78 typedef struct {79 float x, y; ///< Position80 float flux; ///< Flux81 float xNorm, yNorm; ///< Normalised position82 psKernel *image1; ///< Reference image postage stamp83 psKernel *image2; ///< Input image postage stamp84 psKernel *weight; ///< Weight image (1/variance) postage stamp, or NULL85 psArray *convolutions1; ///< Convolutions of image 1 for each kernel component, or NULL86 psArray *convolutions2; ///< Convolutions of image 2 for each kernel component, or NULL87 psImage *matrix; ///< Least-squares matrix, or NULL88 psVector *vector; ///< Least-squares vector, or NULL89 double norm; ///< Normalisation difference90 double normI1; ///< Sum(flux) for image 191 double normI2; ///< Sum(flux) for image 292 double normSquare1; ///< Sum(flux^2) for image 1 (used for penalty)93 double normSquare2; ///< Sum(flux^2) for image 2 (used for penalty)94 pmSubtractionStampStatus status; ///< Status of stamp95 psVector *MxxI1; ///< second moments of convolution images96 psVector *MyyI1; ///< second moments of convolution images97 psVector *MxxI2; ///< second moments of convolution images98 psVector *MyyI2; ///< second moments of convolution images99 double MxxI1raw;100 double MyyI1raw;101 double MxxI2raw;102 double MyyI2raw;103 } pmSubtractionStamp;104 105 42 /// Allocate a stamp 106 43 pmSubtractionStamp *pmSubtractionStampAlloc(void); 44 45 // find and extract the stamps 46 bool pmSubtractionStampsSelect(pmSubtractionStampList **stamps, // Stamps to read 47 const pmReadout *ro1, // Readout 1 48 const pmReadout *ro2, // Readout 2 49 const psImage *subMask, // Mask for subtraction, or NULL 50 psImage *variance, // Variance map 51 const psRegion *region, // Region of interest 52 float thresh1, // Threshold for stamp finding on readout 1 53 float thresh2, // Threshold for stamp finding on readout 2 54 float stampSpacing, // Spacing between stamps 55 float normFrac, // Fraction of flux in window for normalisation window 56 float sysError, // Relative systematic error in images 57 float skyError, // Relative systematic error in images 58 int size, // Kernel half-size 59 int footprint, // Convolution footprint for stamps 60 pmSubtractionMode mode // Mode for subtraction 61 ); 62 107 63 108 64 /// Find stamps on an image … … 172 128 /// Calculate the window and normalisation window from the stamps 173 129 bool pmSubtractionStampsGetWindow( 130 bool *tryAgain, ///< re-try with new stamp size? 174 131 pmSubtractionStampList *stamps, ///< List of stamps 175 132 int kernelSize ///< Half-size of kernel -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionThreads.c
r30287 r30322 6 6 #include <pslib.h> 7 7 8 #include "pmSubtractionTypes.h" 8 9 #include "pmSubtractionMatch.h" 9 10 #include "pmSubtractionEquation.h" -
branches/eam_branches/ipp-20101205/psModules/src/imcombine/pmSubtractionVisual.c
r30289 r30322 16 16 17 17 #include "pmKapaPlots.h" 18 #include "pmFPA.h" 19 #include "pmSubtractionTypes.h" 18 20 #include "pmSubtraction.h" 19 21 #include "pmSubtractionStamps.h" -
branches/eam_branches/ipp-20101205/psModules/src/psmodules.h
r29388 r30322 98 98 // the following headers are from psModule:imcombine 99 99 #include <pmStack.h> 100 #include <pmSubtractionTypes.h> 100 101 #include <pmStackReject.h> 101 102 #include <pmSubtraction.h>
Note:
See TracChangeset
for help on using the changeset viewer.
