Coverage for tests/test_imagePca.py: 18%
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# This file is part of afw.
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/>.
22"""
23Tests for PCA on Images
25Run with:
26 python test_imagePca.py
27or
28 pytest test_imagePca.py
29"""
31import unittest
32import random
33import math
34import itertools
36import numpy as np
38import lsst.utils.tests
39import lsst.pex.exceptions as pexExcept
40import lsst.geom
41import lsst.afw.image as afwImage
42import lsst.afw.display as afwDisplay
44try:
45 type(display)
46except NameError:
47 display = False
50class ImagePcaTestCase(lsst.utils.tests.TestCase):
51 """A test case for ImagePca"""
53 def setUp(self):
54 random.seed(0)
55 self.ImageSet = afwImage.ImagePcaF()
57 def tearDown(self):
58 del self.ImageSet
60 def testInnerProducts(self):
61 """Test inner products"""
63 width, height = 10, 20
64 im1 = afwImage.ImageF(lsst.geom.Extent2I(width, height))
65 val1 = 10
66 im1.set(val1)
68 im2 = im1.Factory(im1.getDimensions())
69 val2 = 20
70 im2.set(val2)
72 self.assertEqual(afwImage.innerProduct(im1, im1),
73 width*height*val1*val1)
74 self.assertEqual(afwImage.innerProduct(im1, im2),
75 width*height*val1*val2)
77 im2[0, 0, afwImage.LOCAL] = 0
78 self.assertEqual(afwImage.innerProduct(im1, im2),
79 (width*height - 1)*val1*val2)
81 im2[0, 0, afwImage.LOCAL] = val2 # reinstate value
82 im2[width - 1, height - 1, afwImage.LOCAL] = 1
83 self.assertEqual(afwImage.innerProduct(im1, im2),
84 (width*height - 1)*val1*val2 + val1)
86 def testAddImages(self):
87 """Test adding images to a PCA set"""
89 nImage = 3
90 for i in range(nImage):
91 im = afwImage.ImageF(lsst.geom.Extent2I(21, 21))
92 val = 1
93 im.set(val)
95 self.ImageSet.addImage(im, 1.0)
97 vec = self.ImageSet.getImageList()
98 self.assertEqual(len(vec), nImage)
99 self.assertEqual(vec[nImage - 1][0, 0, afwImage.LOCAL], val)
101 def tst():
102 """Try adding an image with no flux"""
103 self.ImageSet.addImage(im, 0.0)
105 self.assertRaises(pexExcept.OutOfRangeError, tst)
107 def testMean(self):
108 """Test calculating mean image"""
110 width, height = 10, 20
112 values = (100, 200, 300)
113 meanVal = 0
114 for val in values:
115 im = afwImage.ImageF(lsst.geom.Extent2I(width, height))
116 im.set(val)
118 self.ImageSet.addImage(im, 1.0)
119 meanVal += val
121 meanVal = meanVal/len(values)
123 mean = self.ImageSet.getMean()
125 self.assertEqual(mean.getWidth(), width)
126 self.assertEqual(mean.getHeight(), height)
127 self.assertEqual(mean[0, 0, afwImage.LOCAL], meanVal)
128 self.assertEqual(mean[width - 1, height - 1, afwImage.LOCAL], meanVal)
130 def testPca(self):
131 """Test calculating PCA"""
132 width, height = 200, 100
133 numBases = 3
134 numInputs = 3
136 bases = []
137 for i in range(numBases):
138 im = afwImage.ImageF(width, height)
139 array = im.getArray()
140 x, y = np.indices(array.shape)
141 period = 5*(i+1)
142 fx = np.sin(2*math.pi/period*x + 2*math.pi/numBases*i)
143 fy = np.sin(2*math.pi/period*y + 2*math.pi/numBases*i)
144 array[x, y] = fx + fy
145 bases.append(im)
147 if display:
148 mos = afwDisplay.utils.Mosaic(background=-10)
149 afwDisplay.Display(frame=1).mtv(mos.makeMosaic(bases), title="Basis functions")
151 inputs = []
152 for i in range(numInputs):
153 im = afwImage.ImageF(lsst.geom.Extent2I(width, height))
154 im.set(0)
155 for b in bases:
156 im.scaledPlus(random.random(), b)
158 inputs.append(im)
159 self.ImageSet.addImage(im, 1.0)
161 if display:
162 mos = afwDisplay.utils.Mosaic(background=-10)
163 afwDisplay.Display(frame=2).mtv(mos.makeMosaic(inputs), title="Inputs")
165 self.ImageSet.analyze()
167 eImages = []
168 for img in self.ImageSet.getEigenImages():
169 eImages.append(img)
171 if display:
172 mos = afwDisplay.utils.Mosaic(background=-10)
173 afwDisplay.Display(frame=3).mtv(mos.makeMosaic(eImages), title="EigenImages")
175 self.assertEqual(len(eImages), numInputs)
177 # Test for orthogonality
178 for i1, i2 in itertools.combinations(list(range(len(eImages))), 2):
179 inner = afwImage.innerProduct(eImages[i1], eImages[i2])
180 norm1 = eImages[i1].getArray().sum()
181 norm2 = eImages[i2].getArray().sum()
182 inner /= norm1*norm2
183 self.assertAlmostEqual(inner, 0)
185 def testPcaNaN(self):
186 """Test calculating PCA when the images can contain NaNs"""
188 width, height = 20, 10
190 values = (100, 200, 300)
191 for i, val in enumerate(values):
192 im = afwImage.ImageF(lsst.geom.Extent2I(width, height))
193 im.set(val)
195 if i == 1:
196 im[width//2, height//2, afwImage.LOCAL] = np.nan
198 self.ImageSet.addImage(im, 1.0)
200 self.ImageSet.analyze()
202 eImages = []
203 for img in self.ImageSet.getEigenImages():
204 eImages.append(img)
206 if display:
207 mos = afwDisplay.utils.Mosaic(background=-10)
208 afwDisplay.Display(frame=0).mtv(mos.makeMosaic(eImages), title="testPcaNaN")
211class TestMemory(lsst.utils.tests.MemoryTestCase):
212 pass
215def setup_module(module):
216 lsst.utils.tests.init()
219if __name__ == "__main__": 219 ↛ 220line 219 didn't jump to line 220, because the condition on line 219 was never true
220 lsst.utils.tests.init()
221 unittest.main()