Coverage for tests/test_interp.py: 26%
132 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 10:10 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 10:10 +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/>.
22import os
23import unittest
24import math
25import numpy as np
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
33try:
34 type(display)
35except NameError:
36 display = False
37else:
38 import lsst.afw.display as afwDisplay
39 afwDisplay.setDefaultMaskTransparency(75)
41# Determine if we have afwdata
42try:
43 afwdataDir = lsst.utils.getPackageDir('afwdata')
44except Exception:
45 afwdataDir = None
47TESTDIR = os.path.abspath(os.path.dirname(__file__))
50class InterpolationTestCase(lsst.utils.tests.TestCase):
51 """A test case for interpolation."""
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")
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")
63 self.badPixels = testUtils.makeDefectList()
65 def tearDown(self):
66 del self.mi
67 del self.psf
68 del self.badPixels
70 @unittest.skipUnless(afwdataDir, "afwdata not available")
71 def testDetection(self):
72 """Test Interp algorithms."""
74 if display:
75 frame = 0
76 afwDisplay.Display(frame=frame).mtv(self.mi, title=self._testMethodName + ": Original")
78 algorithms.interpolateOverDefects(self.mi, self.psf, self.badPixels)
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")
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"""
91 badPixels = []
92 defects = [((82, 663), 6, 8),
93 ((83, 659), 9, 6),
94 ((85, 660), 10, 11),
95 ((87, 669), 3, 3),
96 ]
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))
103 mi = afwImage.MaskedImageF(517, 800)
105 algorithms.interpolateOverDefects(mi, self.psf, badPixels)
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
120 mi /= flat
122 if display:
123 afwDisplay.Display(frame=0).mtv(mi, title=self._testMethodName + ": Raw")
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))
135 psf = algorithms.DoubleGaussianPsf(15, 15, 1./(2*math.sqrt(2*math.log(2))))
136 algorithms.interpolateOverDefects(mi, psf, defectList, 50.)
138 if display:
139 afwDisplay.Display(frame=1).mtv(mi, title=self._testMethodName + ": Interpolated")
141 self.assertTrue(np.isfinite(mi.image[56, 51, afwImage.LOCAL]))
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)
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))
155 np.random.seed(666)
156 ima[:] = np.random.uniform(-1, 1, ima.shape)
158 defects = []
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)))
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)))
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)))
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)))
204 ima[-1:, :] = 100
205 defects.append(lsst.geom.BoxI(lsst.geom.PointI(0, mi.getHeight() - 1),
206 lsst.geom.ExtentI(mi.getWidth(), 1)))
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)))
214 #
215 # Build list of defects to interpolate over
216 #
217 defectList = []
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")
227 psf = algorithms.DoubleGaussianPsf(15, 15, 1./(2*math.sqrt(2*math.log(2))))
228 algorithms.interpolateOverDefects(mi, psf, defectList, 0, True)
230 if display:
231 afwDisplay.Display(frame=3).mtv(mi, title=self._testMethodName + ": image")
233 self.assertGreater(np.min(ima), -2)
234 self.assertGreater(2, np.max(ima))
237class TestMemory(lsst.utils.tests.MemoryTestCase):
238 pass
241def setup_module(module):
242 lsst.utils.tests.init()
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()