Coverage for tests/test_fits.py: 25%

65 statements  

« prev     ^ index     » next       coverage.py v6.4, created at 2022-06-02 03:42 -0700

1# 

2# LSST Data Management System 

3# Copyright 2017 LSST Corporation. 

4# 

5# This product includes software developed by the 

6# LSST Project (http://www.lsst.org/). 

7# 

8# This program is free software: you can redistribute it and/or modify 

9# it under the terms of the GNU General Public License as published by 

10# the Free Software Foundation, either version 3 of the License, or 

11# (at your option) any later version. 

12# 

13# This program is distributed in the hope that it will be useful, 

14# but WITHOUT ANY WARRANTY; without even the implied warranty of 

15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

16# GNU General Public License for more details. 

17# 

18# You should have received a copy of the LSST License Statement and 

19# the GNU General Public License along with this program. If not, 

20# see <http://www.lsstcorp.org/LegalNotices/>. 

21# 

22 

23import os 

24import unittest 

25 

26from lsst.daf.base import PropertyList 

27 

28import lsst.afw.fits 

29import lsst.utils.tests 

30 

31testPath = os.path.abspath(os.path.dirname(__file__)) 

32 

33 

34class FitsTestCase(lsst.utils.tests.TestCase): 

35 

36 def setUp(self): 

37 # May appear only once in the FITS file (because cfitsio will insist on putting them there) 

38 self.single = ["SIMPLE", "BITPIX", "EXTEND", "NAXIS"] 

39 

40 def writeAndRead(self, header): 

41 """Write the supplied header and read it back again. 

42 """ 

43 fitsFile = lsst.afw.fits.MemFileManager() 

44 with lsst.afw.fits.Fits(fitsFile, "w") as fits: 

45 fits.createEmpty() 

46 fits.writeMetadata(header) 

47 with lsst.afw.fits.Fits(fitsFile, "r") as fits: 

48 metadata = fits.readMetadata() 

49 return metadata 

50 

51 def testSimpleIO(self): 

52 """Check that a simple header can be written and read back.""" 

53 

54 expected = { 

55 "ASTRING": "Test String", 

56 "ANUNDEF": None, 

57 "AFLOAT": 3.1415, 

58 "ANINT": 42, 

59 } 

60 

61 header = PropertyList() 

62 for k, v in expected.items(): 

63 header[k] = v 

64 

65 output = self.writeAndRead(header) 

66 

67 # Remove keys added by cfitsio 

68 for k in self.single: 

69 if k in output: 

70 del output[k] 

71 if "COMMENT" in output: 

72 del output["COMMENT"] 

73 

74 self.assertEqual(output.toDict(), header.toDict()) 

75 

76 def testReadUndefined(self): 

77 """Read a header with some undefined values that might override.""" 

78 testFile = os.path.join(testPath, "data", "ticket18864.fits") 

79 metadata = lsst.afw.fits.readMetadata(testFile) 

80 

81 # Neither of these should be arrays despite having doubled keywords 

82 # The first value for ADC-STR should override the second undef value 

83 self.assertAlmostEqual(metadata.getScalar("ADC-STR"), 22.01) 

84 

85 # The value for DOM-WND should be the second value since the first 

86 # was undefined 

87 self.assertAlmostEqual(metadata.getScalar("DOM-WND"), 4.8) 

88 

89 def testReadBlankKeywordComment(self): 

90 """Read a header that uses blank keyword comments.""" 

91 testFile = os.path.join(testPath, "data", "ticket20143.fits") 

92 metadata = lsst.afw.fits.readMetadata(testFile) 

93 

94 self.assertEqual("---- Checksums ----", metadata["COMMENT"]) 

95 self.assertNotIn("", metadata, "Check empty strings as keys") 

96 

97 def testIgnoreKeywords(self): 

98 """Check that certain keywords are ignored in read/write of headers""" 

99 # May not appear at all in the FITS file (cfitsio doesn't write these by default) 

100 notAtAll = [ 

101 # FITS core keywords 

102 "GCOUNT", "PCOUNT", "XTENSION", "BSCALE", "BZERO", "TZERO", "TSCAL", 

103 # FITS compression keywords 

104 "ZBITPIX", "ZIMAGE", "ZCMPTYPE", "ZSIMPLE", "ZEXTEND", "ZBLANK", "ZDATASUM", "ZHECKSUM", 

105 "ZNAXIS", "ZTILE", "ZNAME", "ZVAL", "ZQUANTIZ", 

106 # Not essential these be excluded, but will prevent fitsverify warnings 

107 "DATASUM", "CHECKSUM", 

108 ] 

109 # Additional keywords to check; these should go straight through 

110 # Some of these are longer/shorter versions of strings above, 

111 # to test that the checks for just the start of strings is working. 

112 others = ["FOOBAR", "SIMPLETN", "DATASUMX", "NAX", "SIM"] 

113 

114 header = PropertyList() 

115 for ii, key in enumerate(self.single + notAtAll + others): 

116 header.add(key, ii) 

117 metadata = self.writeAndRead(header) 

118 for key in self.single: 

119 self.assertEqual(metadata.valueCount(key), 1, key) 

120 for key in notAtAll: 

121 self.assertEqual(metadata.valueCount(key), 0, key) 

122 for key in others: 

123 self.assertEqual(metadata.valueCount(key), 1, key) 

124 

125 def testUndefinedVector(self): 

126 header = PropertyList() 

127 header.set("FOO", [None, None]) 

128 metadata = self.writeAndRead(header) 

129 self.assertEqual(metadata.getArray("FOO"), [None, None]) 

130 

131 

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

133 pass 

134 

135 

136def setup_module(module): 

137 lsst.utils.tests.init() 

138 

139 

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

141 import sys 

142 setup_module(sys.modules[__name__]) 

143 unittest.main()