Coverage for tests/test_readFitsCatalog.py: 27%
78 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-02-23 03:15 -0800
« prev ^ index » next coverage.py v6.5.0, created at 2023-02-23 03:15 -0800
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#
24import os
25import unittest
27import numpy as np
28from astropy.io import fits
29from astropy.table import Table
31from lsst.meas.algorithms.readFitsCatalogTask import ReadFitsCatalogTask
32import lsst.utils.tests
34# If you want to update the FITS table used for this test:
35# - modify makeFitsTable to create the table as you want it
36# - set SaveFitsTable = True
37# - sun the test once to create the new file
38# - set SaveFitsTable = False again
39SaveFitsTable = False # construct and save a new FITS table file?
40TestDir = os.path.dirname(__file__)
41FitsPath = os.path.join(TestDir, "data", "testReadFitsCatalog.fits")
44def makeFitsTable():
45 """Create a fits file containing two tables"""
46 hdu0 = fits.PrimaryHDU()
48 # table for HDU 1
49 cols1 = [
50 fits.Column(name='name', format='10A', array=np.array(["object 1", "object 2"])),
51 fits.Column(name='ra', format='E', array=[10, 5]),
52 fits.Column(name='dec', format='E', array=[-5, 45]),
53 fits.Column(name='counts', format='J', array=[1000, 2000]),
54 fits.Column(name='flux', format='D', array=[1.1, 2.2]),
55 fits.Column(name='resolved', format='L', array=[True, False]),
56 ]
57 hdu1 = fits.BinTableHDU.from_columns(fits.ColDefs(cols1), character_as_bytes=True)
59 # table for HDU 2,
60 cols2 = [
61 fits.Column(name='name', format='10A', array=["object 3", "object 4"]),
62 fits.Column(name='ra', format='E', array=[16, 3]),
63 fits.Column(name='dec', format='E', array=[75, -34]),
64 fits.Column(name='resolved', format='L', array=[False, True]),
65 fits.Column(name='flux', format='D', array=[10.1, 20.2]),
66 fits.Column(name='counts', format='J', array=[15000, 22000]),
67 fits.Column(name='other', format='D', array=[11, 12]),
68 ]
69 hdu2 = fits.BinTableHDU.from_columns(fits.ColDefs(cols2), character_as_bytes=True)
71 # add an image HDU to test that these are not treated as tables
72 hdu3 = fits.ImageHDU(data=np.zeros([5, 5]))
74 foo = fits.HDUList([hdu0, hdu1, hdu2, hdu3])
75 return foo
78if SaveFitsTable: 78 ↛ 79line 78 didn't jump to line 79, because the condition on line 78 was never true
79 print("Warning: writing a new FITS file; to stop this set SaveFitsTable = False")
80 fitsTable = makeFitsTable()
81 fitsTable.writeto(FitsPath, clobber=True)
84class ReadFitsCatalogTaskTestCase(lsst.utils.tests.TestCase):
85 """Test ReadFitsCatalogTask"""
87 def setUp(self):
88 fitsTable = makeFitsTable()
89 self.arr1 = Table(fitsTable[1].data).as_array()
90 self.arr2 = Table(fitsTable[2].data).as_array()
91 self.fitsTable = fitsTable
93 def testHDU1DefaultNames(self):
94 """Test the data in HDU 1, loading all columns without renaming
95 """
96 task = ReadFitsCatalogTask()
97 table = task.run(FitsPath)
98 self.assertTrue(np.array_equal(self.arr1, table))
99 self.assertEqual(len(table), 2)
101 def testHDU1GivenNames(self):
102 """Test the data in HDU 1 with some column renaming
104 All columns should be in the same order; those that are renamed should have
105 their new name, and the rest should have their original name.
106 """
107 column_map = {
108 "name": "source",
109 "ra": "ra_deg",
110 "dec": "dec_deg",
111 }
112 config = ReadFitsCatalogTask.ConfigClass()
113 config.column_map = column_map
114 self.assertEqual(config.hdu, 1)
115 task = ReadFitsCatalogTask(config=config)
116 arr = task.run(FitsPath)
117 self.assertEqual(len(Table(arr).columns), len(Table(self.arr1).columns))
118 for inname, outname in zip(self.arr1.dtype.names, arr.dtype.names):
119 des_outname = column_map.get(inname, inname)
120 self.assertEqual(outname, des_outname)
121 self.assertTrue(np.array_equal(self.arr1[inname], arr[outname]))
123 def testHDU2(self):
124 """Test reading HDU 2 with original order"""
125 config = ReadFitsCatalogTask.ConfigClass()
126 config.hdu = 2
127 task = ReadFitsCatalogTask(config=config)
128 arr = task.run(FitsPath)
129 self.assertTrue(np.array_equal(self.arr2, arr))
131 def testBadPath(self):
132 """Test that an invalid path causes an error"""
133 task = ReadFitsCatalogTask()
134 badPath = "does/not/exists.garbage"
135 with self.assertRaises(IOError):
136 task.run(badPath)
138 def testBadColumnName(self):
139 """Test that non-existent columns in column_map cause an error"""
140 config = ReadFitsCatalogTask.ConfigClass()
141 for badColNames in (
142 ["name", "ra", "dec", "counts", "flux", "resolved", "other"], # "other" only in hdu 2
143 ["name", "ra", "dec", "counts", "flux", "invalidname"],
144 ["invalid1"],
145 ):
146 config.column_map = dict((name, "col %s" % (i,)) for i, name in enumerate(badColNames))
147 task = ReadFitsCatalogTask(config=config)
148 with self.assertRaises(RuntimeError):
149 task.run(FitsPath)
151 def testBadHdu(self):
152 """Test that non-existent HDUs cause an error"""
153 for badHdu in [0, 3, 4]:
154 config = ReadFitsCatalogTask.ConfigClass()
155 config.hdu = badHdu
156 task = ReadFitsCatalogTask(config=config)
157 with self.assertRaises(Exception):
158 task.run(FitsPath)
161class TestMemory(lsst.utils.tests.MemoryTestCase):
162 pass
165def setup_module(module):
166 lsst.utils.tests.init()
169if __name__ == "__main__": 169 ↛ 170line 169 didn't jump to line 170, because the condition on line 169 was never true
170 lsst.utils.tests.init()
171 unittest.main()