Coverage for tests/test_fits.py: 22%
65 statements
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-25 00:01 -0700
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-25 00:01 -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#
23import os
24import unittest
26from lsst.daf.base import PropertyList
28import lsst.afw.fits
29import lsst.utils.tests
31testPath = os.path.abspath(os.path.dirname(__file__))
34class FitsTestCase(lsst.utils.tests.TestCase):
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"]
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
51 def testSimpleIO(self):
52 """Check that a simple header can be written and read back."""
54 expected = {
55 "ASTRING": "Test String",
56 "ANUNDEF": None,
57 "AFLOAT": 3.1415,
58 "ANINT": 42,
59 }
61 header = PropertyList()
62 for k, v in expected.items():
63 header[k] = v
65 output = self.writeAndRead(header)
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"]
74 self.assertEqual(output.toDict(), header.toDict())
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)
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)
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)
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)
94 self.assertEqual("---- Checksums ----", metadata["COMMENT"])
95 self.assertNotIn("", metadata, "Check empty strings as keys")
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"]
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)
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])
132class TestMemory(lsst.utils.tests.MemoryTestCase):
133 pass
136def setup_module(module):
137 lsst.utils.tests.init()
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()