Coverage for tests/test_imageIo1.py: 25%

159 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2022-08-30 02:37 -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/>. 

21 

22""" 

23Test cases to test image I/O 

24""" 

25import itertools 

26import os.path 

27import unittest 

28 

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 

36 

37try: 

38 type(display) 

39except NameError: 

40 display = 0 

41 

42try: 

43 dataDir = os.path.join(lsst.utils.getPackageDir("afwdata"), "data") 

44except LookupError: 

45 dataDir = None 

46 

47 

48class ReadFitsTestCase(lsst.utils.tests.TestCase): 

49 """A test case for reading FITS images""" 

50 

51 def setUp(self): 

52 pass 

53 

54 def tearDown(self): 

55 pass 

56 

57 @unittest.skipIf(dataDir is None, "afwdata not setup") 

58 def testU16(self): 

59 """Test reading U16 image""" 

60 

61 im = afwImage.ImageD(os.path.join(dataDir, "small_img.fits")) 

62 

63 col, row, val = 0, 0, 1154 

64 self.assertEqual(im[col, row, afwImage.LOCAL], val) 

65 

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")) 

70 

71 if display: 

72 afwDisplay.Display(frame=1).mtv(im) 

73 

74 col, row, val = 32, 1, 62 

75 self.assertEqual(im[col, row, afwImage.LOCAL], val) 

76 

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) 

81 

82 col, row, val = 32, 1, 39.11672 

83 self.assertAlmostEqual(im[col, row, afwImage.LOCAL], val, 4) 

84 

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) 

91 

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) 

100 

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) 

106 

107 bbox = lsst.geom.Box2I(lsst.geom.Point2I(110, 120), 

108 lsst.geom.Extent2I(20, 15)) 

109 sim = im.Factory(im, bbox, afwImage.LOCAL) 

110 

111 im2 = afwImage.ImageF(fileName, hdu, None, bbox, afwImage.LOCAL) 

112 

113 self.assertEqual(im2.getDimensions(), sim.getDimensions()) 

114 self.assertEqual(im2[1, 1, afwImage.LOCAL], sim[1, 1, afwImage.LOCAL]) 

115 

116 self.assertEqual(im2.getX0(), sim.getX0()) 

117 self.assertEqual(im2.getY0(), sim.getY0()) 

118 

119 def testMEF(self): 

120 """Test writing a set of images to an MEF fits file, and then reading them back 

121 

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)) 

127 

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) 

135 

136 for hdu in range(4): 

137 im = afwImage.ImageF(tmpFile, hdu) 

138 self.assertEqual(im[0, 0, afwImage.LOCAL], 100*hdu) 

139 

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) 

158 

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) 

169 

170 im.writeFits(tmpFile, md) 

171 

172 jim = afwImage.DecoratedImageF(tmpFile) 

173 

174 for k, v in keys.items(): 

175 self.assertEqual(jim.getMetadata().getScalar(k), v) 

176 

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) 

181 

182 expOrig = afwImage.ExposureF(100, 100) 

183 mdOrig = expOrig.getMetadata() 

184 mdOrig.set(keyWord, longString) 

185 expOrig.writeFits(tmpFile) 

186 

187 expNew = afwImage.ExposureF(tmpFile) 

188 self.assertEqual(expNew.getMetadata().getScalar(keyWord), longString) 

189 

190 def checkBBoxFromMetadata(self, filename, expected, hdu=0): 

191 metadata = afwFits.readMetadata(filename, hdu) 

192 bbox = afwImage.bboxFromMetadata(metadata) 

193 self.assertEqual(bbox, expected) 

194 

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) 

209 

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)) 

214 

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) 

221 

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)) 

240 

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) 

246 

247 badOptions = options.deepCopy() 

248 badOptions.set("imageOrigin", "INVALID") 

249 with self.assertRaises(RuntimeError): 

250 ImageClass.readFitsWithOptions(filepath, badOptions) 

251 

252 

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

254 pass 

255 

256 

257def setup_module(module): 

258 lsst.utils.tests.init() 

259 

260 

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()