Coverage for tests/test_readFitsCatalog.py: 25%

92 statements  

« prev     ^ index     » next       coverage.py v7.4.0, created at 2024-01-04 12:18 +0000

1# 

2# LSST Data Management System 

3# 

4# Copyright 2008-2016 AURA/LSST. 

5# 

6# This product includes software developed by the 

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

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 LSST License Statement and 

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

21# see <https://www.lsstcorp.org/LegalNotices/>. 

22# 

23 

24import os 

25import unittest 

26 

27import numpy as np 

28from astropy.io import fits 

29from astropy.table import Table 

30 

31from lsst.meas.algorithms.readFitsCatalogTask import ReadFitsCatalogTask 

32from lsst.meas.algorithms.convertReferenceCatalog import _addExtraColumnsToSchema 

33import lsst.afw.table 

34import lsst.utils.tests 

35 

36# If you want to update the FITS table used for this test: 

37# - modify makeFitsTable to create the table as you want it 

38# - set SaveFitsTable = True 

39# - sun the test once to create the new file 

40# - set SaveFitsTable = False again 

41SaveFitsTable = False # construct and save a new FITS table file? 

42TestDir = os.path.dirname(__file__) 

43FitsPath = os.path.join(TestDir, "data", "testReadFitsCatalog.fits") 

44 

45 

46def makeFitsTable(): 

47 """Create a fits file containing two tables""" 

48 hdu0 = fits.PrimaryHDU() 

49 

50 # table for HDU 1 

51 cols1 = [ 

52 fits.Column(name='name', format='10A', array=np.array(["object 1", "object 2"])), 

53 fits.Column(name='ra', format='E', array=[10, 5]), 

54 fits.Column(name='dec', format='E', array=[-5, 45]), 

55 fits.Column(name='counts', format='J', array=[1000, 2000]), 

56 fits.Column(name='flux', format='D', array=[1.1, 2.2]), 

57 fits.Column(name='resolved', format='L', array=[True, False]), 

58 ] 

59 hdu1 = fits.BinTableHDU.from_columns(fits.ColDefs(cols1), character_as_bytes=True) 

60 

61 # table for HDU 2, 

62 cols2 = [ 

63 fits.Column(name='name', format='10A', array=["object 3", "object 4"]), 

64 fits.Column(name='ra', format='E', array=[16, 3]), 

65 fits.Column(name='dec', format='E', array=[75, -34]), 

66 fits.Column(name='resolved', format='L', array=[False, True]), 

67 fits.Column(name='flux', format='D', array=[10.1, 20.2]), 

68 fits.Column(name='counts', format='J', array=[15000, 22000]), 

69 fits.Column(name='other', format='D', array=[11, 12]), 

70 ] 

71 hdu2 = fits.BinTableHDU.from_columns(fits.ColDefs(cols2), character_as_bytes=True) 

72 

73 # add an image HDU to test that these are not treated as tables 

74 hdu3 = fits.ImageHDU(data=np.zeros([5, 5])) 

75 

76 foo = fits.HDUList([hdu0, hdu1, hdu2, hdu3]) 

77 return foo 

78 

79 

80if SaveFitsTable: 80 ↛ 81line 80 didn't jump to line 81, because the condition on line 80 was never true

81 print("Warning: writing a new FITS file; to stop this set SaveFitsTable = False") 

82 fitsTable = makeFitsTable() 

83 fitsTable.writeto(FitsPath, clobber=True) 

84 

85 

86class ReadFitsCatalogTaskTestCase(lsst.utils.tests.TestCase): 

87 """Test ReadFitsCatalogTask""" 

88 

89 def setUp(self): 

90 fitsTable = makeFitsTable() 

91 self.arr1 = Table(fitsTable[1].data).as_array() 

92 self.arr2 = Table(fitsTable[2].data).as_array() 

93 

94 self.fitsTable = fitsTable 

95 

96 def testHDU1DefaultNames(self): 

97 """Test the data in HDU 1, loading all columns without renaming 

98 """ 

99 task = ReadFitsCatalogTask() 

100 table = task.run(FitsPath) 

101 self.assertTrue(np.array_equal(self.arr1, table)) 

102 self.assertEqual(len(table), 2) 

103 

104 schema = lsst.afw.table.SimpleTable.makeMinimalSchema() 

105 keyMap = {} 

106 _addExtraColumnsToSchema(schema, table.dtype, table.dtype.names, keyMap) 

107 self.assertEqual( 

108 set(keyMap.keys()), 

109 set(table.dtype.names), 

110 ) 

111 self.assertEqual( 

112 set(schema.getNames()), 

113 set(table.dtype.names).union(set(["id", "coord_ra", "coord_dec"])), 

114 ) 

115 

116 def testHDU1GivenNames(self): 

117 """Test the data in HDU 1 with some column renaming 

118 

119 All columns should be in the same order; those that are renamed should have 

120 their new name, and the rest should have their original name. 

121 """ 

122 column_map = { 

123 "name": "source", 

124 "ra": "ra_deg", 

125 "dec": "dec_deg", 

126 } 

127 config = ReadFitsCatalogTask.ConfigClass() 

128 config.column_map = column_map 

129 self.assertEqual(config.hdu, 1) 

130 task = ReadFitsCatalogTask(config=config) 

131 arr = task.run(FitsPath) 

132 self.assertEqual(len(Table(arr).columns), len(Table(self.arr1).columns)) 

133 for inname, outname in zip(self.arr1.dtype.names, arr.dtype.names): 

134 des_outname = column_map.get(inname, inname) 

135 self.assertEqual(outname, des_outname) 

136 if inname == "name": 

137 # Special check for strings. 

138 np.testing.assert_array_equal(self.arr1[inname].astype(str), arr[outname].astype(str)) 

139 else: 

140 np.testing.assert_array_equal(self.arr1[inname], arr[outname]) 

141 

142 def testHDU2(self): 

143 """Test reading HDU 2 with original order""" 

144 config = ReadFitsCatalogTask.ConfigClass() 

145 config.hdu = 2 

146 task = ReadFitsCatalogTask(config=config) 

147 arr = task.run(FitsPath) 

148 self.assertTrue(np.array_equal(self.arr2, arr)) 

149 

150 schema = lsst.afw.table.SimpleTable.makeMinimalSchema() 

151 keyMap = {} 

152 _addExtraColumnsToSchema(schema, arr.dtype, arr.dtype.names, keyMap) 

153 self.assertEqual( 

154 set(keyMap.keys()), 

155 set(arr.dtype.names), 

156 ) 

157 self.assertEqual( 

158 set(schema.getNames()), 

159 set(arr.dtype.names).union(set(["id", "coord_ra", "coord_dec"])), 

160 ) 

161 

162 def testBadPath(self): 

163 """Test that an invalid path causes an error""" 

164 task = ReadFitsCatalogTask() 

165 badPath = "does/not/exists.garbage" 

166 with self.assertRaises(IOError): 

167 task.run(badPath) 

168 

169 def testBadColumnName(self): 

170 """Test that non-existent columns in column_map cause an error""" 

171 config = ReadFitsCatalogTask.ConfigClass() 

172 for badColNames in ( 

173 ["name", "ra", "dec", "counts", "flux", "resolved", "other"], # "other" only in hdu 2 

174 ["name", "ra", "dec", "counts", "flux", "invalidname"], 

175 ["invalid1"], 

176 ): 

177 config.column_map = dict((name, "col %s" % (i,)) for i, name in enumerate(badColNames)) 

178 task = ReadFitsCatalogTask(config=config) 

179 with self.assertRaises(RuntimeError): 

180 task.run(FitsPath) 

181 

182 def testBadHdu(self): 

183 """Test that non-existent HDUs cause an error""" 

184 for badHdu in [0, 3, 4]: 

185 config = ReadFitsCatalogTask.ConfigClass() 

186 config.hdu = badHdu 

187 task = ReadFitsCatalogTask(config=config) 

188 with self.assertRaises(Exception): 

189 task.run(FitsPath) 

190 

191 

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

193 pass 

194 

195 

196def setup_module(module): 

197 lsst.utils.tests.init() 

198 

199 

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

201 lsst.utils.tests.init() 

202 unittest.main()