Hide keyboard shortcuts

Hot-keys 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/>. 

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 

36import lsst.pex.exceptions as pexExcept 

37 

38try: 

39 type(display) 

40except NameError: 

41 display = 0 

42 

43try: 

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

45except pexExcept.NotFoundError: 

46 dataDir = None 

47 

48 

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

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

51 

52 def setUp(self): 

53 pass 

54 

55 def tearDown(self): 

56 pass 

57 

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

59 def testU16(self): 

60 """Test reading U16 image""" 

61 

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

63 

64 col, row, val = 0, 0, 1154 

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

66 

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

68 def testS16(self): 

69 """Test reading S16 image""" 

70 im = afwImage.ImageD(os.path.join(dataDir, "871034p_1_img.fits")) 

71 

72 if display: 

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

74 

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

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

77 

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

79 def testF32(self): 

80 """Test reading F32 image""" 

81 im = afwImage.ImageD(os.path.join(dataDir, "871034p_1_MI.fits"), 3) 

82 

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

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

85 

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

87 def testF64(self): 

88 """Test reading a U16 file into a F64 image""" 

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

90 col, row, val = 0, 0, 1154 

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

92 

93 # print "IM = ", im 

94 def testWriteReadF64(self): 

95 """Test writing then reading an F64 image""" 

96 with lsst.utils.tests.getTempFilePath(".fits") as tmpFile: 

97 im = afwImage.ImageD(lsst.geom.Extent2I(100, 100)) 

98 im.set(666) 

99 im.writeFits(tmpFile) 

100 afwImage.ImageD(tmpFile) 

101 

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

103 def testSubimage(self): 

104 """Test reading a subimage image""" 

105 fileName, hdu = os.path.join(dataDir, "871034p_1_MI.fits"), 3 

106 im = afwImage.ImageF(fileName, hdu) 

107 

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

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

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

111 

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

113 

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

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

116 

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

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

119 

120 def testMEF(self): 

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

122 

123 We disable compression to avoid the empty PHU that comes when writing FITS 

124 compressed images. 

125 """ 

126 with lsst.utils.tests.getTempFilePath(".fits") as tmpFile, afwFits.imageCompressionDisabled(): 

127 im = afwImage.ImageF(lsst.geom.Extent2I(20, 20)) 

128 

129 for hdu in range(4): 

130 im.set(100*hdu) 

131 if hdu == 0: 

132 mode = "w" 

133 else: 

134 mode = "a" 

135 im.writeFits(tmpFile, None, mode) 

136 

137 for hdu in range(4): 

138 im = afwImage.ImageF(tmpFile, hdu) 

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

140 

141 # TODO: neither this test nor the one above it is thread-safe because 

142 # image compression is a global flag 

143 def testImageCompressionDisabled(self): 

144 """Test that imageCompressionDisabled handles errors correctly. 

145 """ 

146 defaultState = afwFits.getAllowImageCompression() 

147 try: 

148 for initState in [True, False]: 

149 afwFits.setAllowImageCompression(initState) 

150 try: 

151 with afwFits.imageCompressionDisabled(): 

152 self.assertFalse(afwFits.getAllowImageCompression()) 

153 raise RuntimeError("Processing failed; abort!") 

154 except RuntimeError: 

155 pass 

156 self.assertEqual(afwFits.getAllowImageCompression(), initState) 

157 finally: 

158 afwFits.setAllowImageCompression(defaultState) 

159 

160 def testWriteBool(self): 

161 """Test that we can read and write bools""" 

162 with lsst.utils.tests.getTempFilePath(".fits") as tmpFile: 

163 im = afwImage.ImageF(lsst.geom.ExtentI(10, 20)) 

164 md = dafBase.PropertySet() 

165 keys = {"BAD": False, 

166 "GOOD": True, 

167 } 

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

169 md.add(k, v) 

170 

171 im.writeFits(tmpFile, md) 

172 

173 jim = afwImage.DecoratedImageF(tmpFile) 

174 

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

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

177 

178 def testLongStrings(self): 

179 keyWord = 'ZZZ' 

180 with lsst.utils.tests.getTempFilePath(".fits") as tmpFile: 

181 longString = ' '.join(['This is a long string.'] * 8) 

182 

183 expOrig = afwImage.ExposureF(100, 100) 

184 mdOrig = expOrig.getMetadata() 

185 mdOrig.set(keyWord, longString) 

186 expOrig.writeFits(tmpFile) 

187 

188 expNew = afwImage.ExposureF(tmpFile) 

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

190 

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

192 metadata = afwFits.readMetadata(filename, hdu) 

193 bbox = afwImage.bboxFromMetadata(metadata) 

194 self.assertEqual(bbox, expected) 

195 

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

197 def testBBoxFromMetadata(self): 

198 self.checkBBoxFromMetadata(os.path.join(dataDir, "871034p_1_img.fits"), 

199 lsst.geom.Box2I(lsst.geom.Point2I(0, 0), 

200 lsst.geom.Extent2I(2112, 4644))) 

201 for hdu in range(1, 4): 

202 self.checkBBoxFromMetadata(os.path.join(dataDir, "871034p_1_MI.fits"), 

203 lsst.geom.Box2I(lsst.geom.Point2I(0, 0), 

204 lsst.geom.Extent2I(2112, 4644)), 

205 hdu=hdu) 

206 self.checkBBoxFromMetadata(os.path.join(dataDir, "medsub.fits"), 

207 lsst.geom.Box2I(lsst.geom.Point2I(40, 150), 

208 lsst.geom.Extent2I(145, 200)), 

209 hdu=hdu) 

210 

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

212 def testReadFitsWithOptions(self): 

213 xy0Offset = lsst.geom.Extent2I(7, 5) 

214 bbox = lsst.geom.Box2I(lsst.geom.Point2I(10, 11), lsst.geom.Extent2I(31, 22)) 

215 

216 with lsst.utils.tests.getTempFilePath(".fits") as filepath: 

217 # write a temporary version of the image with non-zero XY0 

218 imagePath = os.path.join(dataDir, "med.fits") 

219 maskedImage = afwImage.MaskedImageD(imagePath) 

220 maskedImage.setXY0(lsst.geom.Point2I(xy0Offset)) 

221 maskedImage.writeFits(filepath) 

222 

223 for ImageClass, imageOrigin in itertools.product( 

224 (afwImage.ImageF, afwImage.ImageD), 

225 (None, "LOCAL", "PARENT"), 

226 ): 

227 with self.subTest(ImageClass=ImageClass, imageOrigin=imageOrigin): 

228 fullImage = ImageClass(filepath) 

229 options = dafBase.PropertySet() 

230 options.set("llcX", bbox.getMinX()) 

231 options.set("llcY", bbox.getMinY()) 

232 options.set("width", bbox.getWidth()) 

233 options.set("height", bbox.getHeight()) 

234 if imageOrigin is not None: 

235 options.set("imageOrigin", imageOrigin) 

236 image1 = ImageClass.readFitsWithOptions(filepath, options) 

237 readBBoxParent = lsst.geom.Box2I(bbox) 

238 if imageOrigin == "LOCAL": 

239 readBBoxParent.shift(xy0Offset) 

240 self.assertImagesEqual(image1, ImageClass(fullImage, readBBoxParent)) 

241 

242 for name in ("llcY", "width", "height"): 

243 badOptions = options.deepCopy() 

244 badOptions.remove(name) 

245 with self.assertRaises(pexExcept.NotFoundError): 

246 ImageClass.readFitsWithOptions(filepath, badOptions) 

247 

248 badOptions = options.deepCopy() 

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

250 with self.assertRaises(RuntimeError): 

251 ImageClass.readFitsWithOptions(filepath, badOptions) 

252 

253 

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

255 pass 

256 

257 

258def setup_module(module): 

259 lsst.utils.tests.init() 

260 

261 

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

263 lsst.utils.tests.init() 

264 unittest.main()