Coverage for tests/test_imageIo1.py: 28%
159 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-06 04:03 -0700
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-06 04:03 -0700
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"""
23Test cases to test image I/O
24"""
25import itertools
26import os.path
27import unittest
29import lsst.utils
30import lsst.daf.base as dafBase
31import lsst.geom
32import lsst.afw.image as afwImage
33import lsst.afw.fits as afwFits
34import lsst.utils.tests
35import lsst.afw.display as afwDisplay
37try:
38 type(display)
39except NameError:
40 display = 0
42try:
43 dataDir = os.path.join(lsst.utils.getPackageDir("afwdata"), "data")
44except LookupError:
45 dataDir = None
48class ReadFitsTestCase(lsst.utils.tests.TestCase):
49 """A test case for reading FITS images"""
51 def setUp(self):
52 pass
54 def tearDown(self):
55 pass
57 @unittest.skipIf(dataDir is None, "afwdata not setup")
58 def testU16(self):
59 """Test reading U16 image"""
61 im = afwImage.ImageD(os.path.join(dataDir, "small_img.fits"))
63 col, row, val = 0, 0, 1154
64 self.assertEqual(im[col, row, afwImage.LOCAL], val)
66 @unittest.skipIf(dataDir is None, "afwdata not setup")
67 def testS16(self):
68 """Test reading S16 image"""
69 im = afwImage.ImageD(os.path.join(dataDir, "871034p_1_img.fits"))
71 if display:
72 afwDisplay.Display(frame=1).mtv(im)
74 col, row, val = 32, 1, 62
75 self.assertEqual(im[col, row, afwImage.LOCAL], val)
77 @unittest.skipIf(dataDir is None, "afwdata not setup")
78 def testF32(self):
79 """Test reading F32 image"""
80 im = afwImage.ImageD(os.path.join(dataDir, "871034p_1_MI.fits"), 3)
82 col, row, val = 32, 1, 39.11672
83 self.assertAlmostEqual(im[col, row, afwImage.LOCAL], val, 4)
85 @unittest.skipIf(dataDir is None, "afwdata not setup")
86 def testF64(self):
87 """Test reading a U16 file into a F64 image"""
88 im = afwImage.ImageD(os.path.join(dataDir, "small_img.fits"))
89 col, row, val = 0, 0, 1154
90 self.assertEqual(im[col, row, afwImage.LOCAL], val)
92 # print "IM = ", im
93 def testWriteReadF64(self):
94 """Test writing then reading an F64 image"""
95 with lsst.utils.tests.getTempFilePath(".fits") as tmpFile:
96 im = afwImage.ImageD(lsst.geom.Extent2I(100, 100))
97 im.set(666)
98 im.writeFits(tmpFile)
99 afwImage.ImageD(tmpFile)
101 @unittest.skipIf(dataDir is None, "afwdata not setup")
102 def testSubimage(self):
103 """Test reading a subimage image"""
104 fileName, hdu = os.path.join(dataDir, "871034p_1_MI.fits"), 3
105 im = afwImage.ImageF(fileName, hdu)
107 bbox = lsst.geom.Box2I(lsst.geom.Point2I(110, 120),
108 lsst.geom.Extent2I(20, 15))
109 sim = im.Factory(im, bbox, afwImage.LOCAL)
111 im2 = afwImage.ImageF(fileName, hdu, None, bbox, afwImage.LOCAL)
113 self.assertEqual(im2.getDimensions(), sim.getDimensions())
114 self.assertEqual(im2[1, 1, afwImage.LOCAL], sim[1, 1, afwImage.LOCAL])
116 self.assertEqual(im2.getX0(), sim.getX0())
117 self.assertEqual(im2.getY0(), sim.getY0())
119 def testMEF(self):
120 """Test writing a set of images to an MEF fits file, and then reading them back
122 We disable compression to avoid the empty PHU that comes when writing FITS
123 compressed images.
124 """
125 with lsst.utils.tests.getTempFilePath(".fits") as tmpFile, afwFits.imageCompressionDisabled():
126 im = afwImage.ImageF(lsst.geom.Extent2I(20, 20))
128 for hdu in range(4):
129 im.set(100*hdu)
130 if hdu == 0:
131 mode = "w"
132 else:
133 mode = "a"
134 im.writeFits(tmpFile, None, mode)
136 for hdu in range(4):
137 im = afwImage.ImageF(tmpFile, hdu)
138 self.assertEqual(im[0, 0, afwImage.LOCAL], 100*hdu)
140 # TODO: neither this test nor the one above it is thread-safe because
141 # image compression is a global flag
142 def testImageCompressionDisabled(self):
143 """Test that imageCompressionDisabled handles errors correctly.
144 """
145 defaultState = afwFits.getAllowImageCompression()
146 try:
147 for initState in [True, False]:
148 afwFits.setAllowImageCompression(initState)
149 try:
150 with afwFits.imageCompressionDisabled():
151 self.assertFalse(afwFits.getAllowImageCompression())
152 raise RuntimeError("Processing failed; abort!")
153 except RuntimeError:
154 pass
155 self.assertEqual(afwFits.getAllowImageCompression(), initState)
156 finally:
157 afwFits.setAllowImageCompression(defaultState)
159 def testWriteBool(self):
160 """Test that we can read and write bools"""
161 with lsst.utils.tests.getTempFilePath(".fits") as tmpFile:
162 im = afwImage.ImageF(lsst.geom.ExtentI(10, 20))
163 md = dafBase.PropertySet()
164 keys = {"BAD": False,
165 "GOOD": True,
166 }
167 for k, v in keys.items():
168 md.add(k, v)
170 im.writeFits(tmpFile, md)
172 jim = afwImage.DecoratedImageF(tmpFile)
174 for k, v in keys.items():
175 self.assertEqual(jim.getMetadata().getScalar(k), v)
177 def testLongStrings(self):
178 keyWord = 'ZZZ'
179 with lsst.utils.tests.getTempFilePath(".fits") as tmpFile:
180 longString = ' '.join(['This is a long string.'] * 8)
182 expOrig = afwImage.ExposureF(100, 100)
183 mdOrig = expOrig.getMetadata()
184 mdOrig.set(keyWord, longString)
185 expOrig.writeFits(tmpFile)
187 expNew = afwImage.ExposureF(tmpFile)
188 self.assertEqual(expNew.getMetadata().getScalar(keyWord), longString)
190 def checkBBoxFromMetadata(self, filename, expected, hdu=0):
191 metadata = afwFits.readMetadata(filename, hdu)
192 bbox = afwImage.bboxFromMetadata(metadata)
193 self.assertEqual(bbox, expected)
195 @unittest.skipIf(dataDir is None, "afwdata not setup")
196 def testBBoxFromMetadata(self):
197 self.checkBBoxFromMetadata(os.path.join(dataDir, "871034p_1_img.fits"),
198 lsst.geom.Box2I(lsst.geom.Point2I(0, 0),
199 lsst.geom.Extent2I(2112, 4644)))
200 for hdu in range(1, 4):
201 self.checkBBoxFromMetadata(os.path.join(dataDir, "871034p_1_MI.fits"),
202 lsst.geom.Box2I(lsst.geom.Point2I(0, 0),
203 lsst.geom.Extent2I(2112, 4644)),
204 hdu=hdu)
205 self.checkBBoxFromMetadata(os.path.join(dataDir, "medsub.fits"),
206 lsst.geom.Box2I(lsst.geom.Point2I(40, 150),
207 lsst.geom.Extent2I(145, 200)),
208 hdu=hdu)
210 @unittest.skipIf(dataDir is None, "afwdata not setup")
211 def testReadFitsWithOptions(self):
212 xy0Offset = lsst.geom.Extent2I(7, 5)
213 bbox = lsst.geom.Box2I(lsst.geom.Point2I(10, 11), lsst.geom.Extent2I(31, 22))
215 with lsst.utils.tests.getTempFilePath(".fits") as filepath:
216 # write a temporary version of the image with non-zero XY0
217 imagePath = os.path.join(dataDir, "med.fits")
218 maskedImage = afwImage.MaskedImageD(imagePath)
219 maskedImage.setXY0(lsst.geom.Point2I(xy0Offset))
220 maskedImage.writeFits(filepath)
222 for ImageClass, imageOrigin in itertools.product(
223 (afwImage.ImageF, afwImage.ImageD),
224 (None, "LOCAL", "PARENT"),
225 ):
226 with self.subTest(ImageClass=str(ImageClass), imageOrigin=imageOrigin):
227 fullImage = ImageClass(filepath)
228 options = dafBase.PropertySet()
229 options.set("llcX", bbox.getMinX())
230 options.set("llcY", bbox.getMinY())
231 options.set("width", bbox.getWidth())
232 options.set("height", bbox.getHeight())
233 if imageOrigin is not None:
234 options.set("imageOrigin", imageOrigin)
235 image1 = ImageClass.readFitsWithOptions(filepath, options)
236 readBBoxParent = lsst.geom.Box2I(bbox)
237 if imageOrigin == "LOCAL":
238 readBBoxParent.shift(xy0Offset)
239 self.assertImagesEqual(image1, ImageClass(fullImage, readBBoxParent))
241 for name in ("llcY", "width", "height"):
242 badOptions = options.deepCopy()
243 badOptions.remove(name)
244 with self.assertRaises(LookupError):
245 ImageClass.readFitsWithOptions(filepath, badOptions)
247 badOptions = options.deepCopy()
248 badOptions.set("imageOrigin", "INVALID")
249 with self.assertRaises(RuntimeError):
250 ImageClass.readFitsWithOptions(filepath, badOptions)
253class TestMemory(lsst.utils.tests.MemoryTestCase):
254 pass
257def setup_module(module):
258 lsst.utils.tests.init()
261if __name__ == "__main__": 261 ↛ 262line 261 didn't jump to line 262, because the condition on line 261 was never true
262 lsst.utils.tests.init()
263 unittest.main()