Coverage for tests/test_interp.py: 26%

132 statements  

« prev     ^ index     » next       coverage.py v7.5.0, created at 2024-04-30 10:20 +0000

1# This file is part of meas_algorithms. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# This program is free software: you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation, either version 3 of the License, or 

12# (at your option) any later version. 

13# 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18# 

19# You should have received a copy of the GNU General Public License 

20# along with this program. If not, see <https://www.gnu.org/licenses/>. 

21 

22import os 

23import unittest 

24import math 

25import numpy as np 

26 

27import lsst.geom 

28import lsst.afw.image as afwImage 

29import lsst.meas.algorithms as algorithms 

30import lsst.meas.algorithms.testUtils as testUtils 

31import lsst.utils.tests 

32 

33try: 

34 type(display) 

35except NameError: 

36 display = False 

37else: 

38 import lsst.afw.display as afwDisplay 

39 afwDisplay.setDefaultMaskTransparency(75) 

40 

41# Determine if we have afwdata 

42try: 

43 afwdataDir = lsst.utils.getPackageDir('afwdata') 

44except Exception: 

45 afwdataDir = None 

46 

47TESTDIR = os.path.abspath(os.path.dirname(__file__)) 

48 

49 

50class InterpolationTestCase(lsst.utils.tests.TestCase): 

51 """A test case for interpolation.""" 

52 

53 def setUp(self): 

54 self.FWHM = 5 

55 self.psf = algorithms.DoubleGaussianPsf(15, 15, self.FWHM/(2*math.sqrt(2*math.log(2)))) 

56 maskedImageFile = os.path.join(afwdataDir, "CFHT", "D4", "cal-53535-i-797722_1.fits") 

57 

58 self.mi = afwImage.MaskedImageF(maskedImageFile) 

59 if False: # use sub-image? 

60 self.mi = self.mi.Factory(self.mi, afwImage.BBox(afwImage.PointI(760, 20), 256, 256)) 

61 self.mi.getMask().addMaskPlane("INTERP") 

62 

63 self.badPixels = testUtils.makeDefectList() 

64 

65 def tearDown(self): 

66 del self.mi 

67 del self.psf 

68 del self.badPixels 

69 

70 @unittest.skipUnless(afwdataDir, "afwdata not available") 

71 def testDetection(self): 

72 """Test Interp algorithms.""" 

73 

74 if display: 

75 frame = 0 

76 afwDisplay.Display(frame=frame).mtv(self.mi, title=self._testMethodName + ": Original") 

77 

78 algorithms.interpolateOverDefects(self.mi, self.psf, self.badPixels) 

79 

80 if display: 

81 frame += 1 

82 afwDisplay.Display(frame=frame).mtv(self.mi, title=self._testMethodName + ": Interpolated") 

83 frame += 1 

84 afwDisplay.Display(frame=frame).mtv(self.mi.getVariance(), 

85 title=self._testMethodName + ": Variance") 

86 

87 @unittest.skipUnless(afwdataDir, "afwdata not available") 

88 def test818(self): 

89 """A test case for #818; the full test is in /lsst/DC3root/ticketFiles/818""" 

90 

91 badPixels = [] 

92 defects = [((82, 663), 6, 8), 

93 ((83, 659), 9, 6), 

94 ((85, 660), 10, 11), 

95 ((87, 669), 3, 3), 

96 ] 

97 

98 for xy0, width, height in defects: 

99 x0, y0 = xy0 

100 bbox = lsst.geom.BoxI(lsst.geom.PointI(x0, y0), lsst.geom.ExtentI(width, height)) 

101 badPixels.append(algorithms.Defect(bbox)) 

102 

103 mi = afwImage.MaskedImageF(517, 800) 

104 

105 algorithms.interpolateOverDefects(mi, self.psf, badPixels) 

106 

107 @unittest.skipUnless(afwdataDir, "afwdata not available") 

108 def test1295(self): 

109 """A test case for #1295 (failure to interpolate over groups of defects.""" 

110 im = afwImage.ImageF(lsst.geom.ExtentI(100, 100)) 

111 mi = afwImage.makeMaskedImage(im) 

112 mi.set(100) 

113 flat = afwImage.ImageF(im.getDimensions()) 

114 flat.set(1) 

115 flat[50:51, :, afwImage.LOCAL] = 0.0 

116 flat[55:56, :, afwImage.LOCAL] = 0.0 

117 flat[58:59, :, afwImage.LOCAL] = 0.0 

118 flat[51:60, 51:, afwImage.LOCAL] = 0.0 

119 

120 mi /= flat 

121 

122 if display: 

123 afwDisplay.Display(frame=0).mtv(mi, title=self._testMethodName + ": Raw") 

124 

125 defectList = [] 

126 bbox = lsst.geom.BoxI(lsst.geom.PointI(50, 0), lsst.geom.ExtentI(1, 100)) 

127 defectList.append(algorithms.Defect(bbox)) 

128 bbox = lsst.geom.BoxI(lsst.geom.PointI(55, 0), lsst.geom.ExtentI(1, 100)) 

129 defectList.append(algorithms.Defect(bbox)) 

130 bbox = lsst.geom.BoxI(lsst.geom.PointI(58, 0), lsst.geom.ExtentI(1, 100)) 

131 defectList.append(algorithms.Defect(bbox)) 

132 bbox = lsst.geom.BoxI(lsst.geom.PointI(51, 51), lsst.geom.ExtentI(9, 49)) 

133 defectList.append(algorithms.Defect(bbox)) 

134 

135 psf = algorithms.DoubleGaussianPsf(15, 15, 1./(2*math.sqrt(2*math.log(2)))) 

136 algorithms.interpolateOverDefects(mi, psf, defectList, 50.) 

137 

138 if display: 

139 afwDisplay.Display(frame=1).mtv(mi, title=self._testMethodName + ": Interpolated") 

140 

141 self.assertTrue(np.isfinite(mi.image[56, 51, afwImage.LOCAL])) 

142 

143 @unittest.skipUnless(afwdataDir, "afwdata not available") 

144 def testEdge(self): 

145 """Test that we can interpolate to the edge""" 

146 mi = afwImage.MaskedImageF(80, 30) 

147 

148 ima = mi.getImage().getArray() 

149 # 

150 # Loop over number of bad columns at left or right edge of image 

151 # 

152 for nBadCol in range(0, 20): 

153 mi.set((0, 0x0, 0)) 

154 

155 np.random.seed(666) 

156 ima[:] = np.random.uniform(-1, 1, ima.shape) 

157 

158 defects = [] 

159 

160 if nBadCol > 0: 

161 # 

162 # Bad left edge 

163 # 

164 ima[:, 0:nBadCol] = 10 

165 defects.append(lsst.geom.BoxI(lsst.geom.PointI(0, 0), 

166 lsst.geom.ExtentI(nBadCol, mi.getHeight()))) 

167 # 

168 # With another bad set of columns next to bad left edge 

169 # 

170 ima[:, -nBadCol:] = 10 

171 defects.append(lsst.geom.BoxI(lsst.geom.PointI(mi.getWidth() - nBadCol, 0), 

172 lsst.geom.ExtentI(nBadCol, mi.getHeight()))) 

173 # 

174 # Bad right edge 

175 # 

176 ima[0:10, nBadCol+1:nBadCol+4] = 100 

177 defects.append(lsst.geom.BoxI(lsst.geom.PointI(nBadCol+1, 0), 

178 lsst.geom.ExtentI(3, 10))) 

179 # 

180 # With another bad set of columns next to bad right edge 

181 # 

182 ima[0:10, -nBadCol-4:-nBadCol-1] = 100 

183 defects.append((lsst.geom.BoxI(lsst.geom.PointI(mi.getWidth() - nBadCol - 4, 0), 

184 lsst.geom.ExtentI(3, 10)))) 

185 # 

186 # Test cases that left and right bad patches nearly (or do) coalesce 

187 # 

188 ima[-3:, 0:mi.getWidth()//2-1] = 100 

189 defects.append(lsst.geom.BoxI(lsst.geom.PointI(0, mi.getHeight() - 3), 

190 lsst.geom.ExtentI(mi.getWidth()//2-1, 1))) 

191 

192 ima[-3:, mi.getWidth()//2+1:] = 100 

193 defects.append(lsst.geom.BoxI(lsst.geom.PointI(mi.getWidth()//2 + 1, mi.getHeight() - 3), 

194 lsst.geom.ExtentI(mi.getWidth()//2 - 1, 1))) 

195 

196 ima[-2:, 0:mi.getWidth()//2] = 100 

197 defects.append(lsst.geom.BoxI(lsst.geom.PointI(0, mi.getHeight() - 2), 

198 lsst.geom.ExtentI(mi.getWidth()//2, 1))) 

199 

200 ima[-2:, mi.getWidth()//2+1:] = 100 

201 defects.append(lsst.geom.BoxI(lsst.geom.PointI(mi.getWidth()//2 + 1, mi.getHeight() - 2), 

202 lsst.geom.ExtentI(mi.getWidth()//2 - 1, 1))) 

203 

204 ima[-1:, :] = 100 

205 defects.append(lsst.geom.BoxI(lsst.geom.PointI(0, mi.getHeight() - 1), 

206 lsst.geom.ExtentI(mi.getWidth(), 1))) 

207 

208 # Test fix for HSC-978: long defect stops one pixel shy of the edge (when nBadCol == 0) 

209 ima[13, :-1] = 100 

210 defects.append(lsst.geom.BoxI(lsst.geom.PointI(0, 13), lsst.geom.ExtentI(mi.getWidth() - 1, 1))) 

211 ima[14, 1:] = 100 

212 defects.append(lsst.geom.BoxI(lsst.geom.PointI(1, 14), lsst.geom.ExtentI(mi.getWidth() - 1, 1))) 

213 

214 # 

215 # Build list of defects to interpolate over 

216 # 

217 defectList = [] 

218 

219 for bbox in defects: 

220 defectList.append(algorithms.Defect(bbox)) 

221 # 

222 # Guess a PSF and do the work 

223 # 

224 if display: 

225 afwDisplay.Display(frame=2).mtv(mi, title=self._testMethodName + ": image") 

226 

227 psf = algorithms.DoubleGaussianPsf(15, 15, 1./(2*math.sqrt(2*math.log(2)))) 

228 algorithms.interpolateOverDefects(mi, psf, defectList, 0, True) 

229 

230 if display: 

231 afwDisplay.Display(frame=3).mtv(mi, title=self._testMethodName + ": image") 

232 

233 self.assertGreater(np.min(ima), -2) 

234 self.assertGreater(2, np.max(ima)) 

235 

236 

237class TestMemory(lsst.utils.tests.MemoryTestCase): 

238 pass 

239 

240 

241def setup_module(module): 

242 lsst.utils.tests.init() 

243 

244 

245if __name__ == "__main__": 245 ↛ 246line 245 didn't jump to line 246, because the condition on line 245 was never true

246 lsst.utils.tests.init() 

247 unittest.main()