Coverage for tests/test_wcsFitsTable.py: 12%
158 statements
« prev ^ index » next coverage.py v6.5.0, created at 2022-10-28 03:10 -0700
« prev ^ index » next coverage.py v6.5.0, created at 2022-10-28 03:10 -0700
1#
2# LSST Data Management System
3# Copyright 2008, 2009, 2010 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 unittest
25import astropy.io.fits
27import lsst.geom
28import lsst.afw.image
29import lsst.afw.geom
30import lsst.utils.tests
31import lsst.daf.base
34class WcsFitsTableTestCase(unittest.TestCase):
35 """Test that we can read and write Wcs objects saved to FITS binary tables.
36 """
38 def setUp(self):
39 # metadata taken from CFHT data
40 # v695856-e0/v695856-e0-c000-a00.sci.fits
42 self.metadata = lsst.daf.base.PropertySet()
44 self.metadata.set("SIMPLE", "T")
45 self.metadata.set("BITPIX", -32)
46 self.metadata.set("NAXIS", 2)
47 self.metadata.set("NAXIS1", 1024)
48 self.metadata.set("NAXIS2", 1153)
49 self.metadata.set("RADESYS", "FK5")
50 self.metadata.set("EQUINOX", 2000.)
52 self.metadata.setDouble("CRVAL1", 215.604025685476)
53 self.metadata.setDouble("CRVAL2", 53.1595451514076)
54 self.metadata.setDouble("CRPIX1", 1109.99981456774)
55 self.metadata.setDouble("CRPIX2", 560.018167811613)
56 self.metadata.set("CTYPE1", "RA---SIN")
57 self.metadata.set("CTYPE2", "DEC--SIN")
59 self.metadata.setDouble("CD1_1", 5.10808596133527E-05)
60 self.metadata.setDouble("CD1_2", 1.85579539217196E-07)
61 self.metadata.setDouble("CD2_2", -5.10281493481982E-05)
62 self.metadata.setDouble("CD2_1", -8.27440751733828E-07)
64 def tearDown(self):
65 del self.metadata
67 def doFitsRoundTrip(self, fileName, wcsIn):
68 wcsIn.writeFits(fileName)
69 wcsOut = lsst.afw.geom.SkyWcs.readFits(fileName)
70 return wcsOut
72 def testSimpleWcs(self):
73 with lsst.utils.tests.getTempFilePath(".fits") as fileName:
74 wcsIn = lsst.afw.geom.makeSkyWcs(self.metadata)
75 wcsOut = self.doFitsRoundTrip(fileName, wcsIn)
76 self.assertEqual(wcsIn, wcsOut)
78 def addSipMetadata(self):
79 self.metadata.add("A_ORDER", 3)
80 self.metadata.add("A_0_0", -3.4299726900155e-05)
81 self.metadata.add("A_0_2", 2.9999243742039e-08)
82 self.metadata.add("A_0_3", 5.3160367322875e-12)
83 self.metadata.add("A_1_0", -1.1102230246252e-16)
84 self.metadata.add("A_1_1", 1.7804837804549e-07)
85 self.metadata.add("A_1_2", -3.9117665277930e-10)
86 self.metadata.add("A_2_0", 1.2614116305773e-07)
87 self.metadata.add("A_2_1", 2.4753748298399e-12)
88 self.metadata.add("A_3_0", -4.0559790823371e-10)
89 self.metadata.add("B_ORDER", 3)
90 self.metadata.add("B_0_0", -0.00040333633853922)
91 self.metadata.add("B_0_2", 2.7329405108287e-07)
92 self.metadata.add("B_0_3", -4.1945333823804e-10)
93 self.metadata.add("B_1_1", 1.0211300606274e-07)
94 self.metadata.add("B_1_2", -1.1907781112538e-12)
95 self.metadata.add("B_2_0", 7.1256679698479e-08)
96 self.metadata.add("B_2_1", -4.0026664120969e-10)
97 self.metadata.add("B_3_0", 7.2509034631981e-14)
98 self.metadata.add("AP_ORDER", 5)
99 self.metadata.add("AP_0_0", 0.065169424373537)
100 self.metadata.add("AP_0_1", 3.5323035231808e-05)
101 self.metadata.add("AP_0_2", -2.4878457741060e-08)
102 self.metadata.add("AP_0_3", -1.4288745247360e-11)
103 self.metadata.add("AP_0_4", -2.0000000098183)
104 self.metadata.add("AP_0_5", 4.3337569354109e-19)
105 self.metadata.add("AP_1_0", 1.9993638555698)
106 self.metadata.add("AP_1_1", -2.0722860000493e-07)
107 self.metadata.add("AP_1_2", 4.7562056847339e-10)
108 self.metadata.add("AP_1_3", -8.5172068319818e-06)
109 self.metadata.add("AP_1_4", -1.3242986537057e-18)
110 self.metadata.add("AP_2_0", -1.4594781790233e-07)
111 self.metadata.add("AP_2_1", -2.9254828606617e-12)
112 self.metadata.add("AP_2_2", -2.7203380713516e-11)
113 self.metadata.add("AP_2_3", 1.5030517486646e-19)
114 self.metadata.add("AP_3_0", 4.7856034999197e-10)
115 self.metadata.add("AP_3_1", 1.5571061278960e-15)
116 self.metadata.add("AP_3_2", -3.2422164667295e-18)
117 self.metadata.add("AP_4_0", 5.8904402441647e-16)
118 self.metadata.add("AP_4_1", -4.5488928339401e-20)
119 self.metadata.add("AP_5_0", -1.3198044795585e-18)
120 self.metadata.add("BP_ORDER", 5)
121 self.metadata.add("BP_0_0", 0.00025729974056661)
122 self.metadata.add("BP_0_1", -0.00060857907313083)
123 self.metadata.add("BP_0_2", -3.1283728005742e-07)
124 self.metadata.add("BP_0_3", 5.0413932972962e-10)
125 self.metadata.add("BP_0_4", -0.0046142128142681)
126 self.metadata.add("BP_0_5", -2.2359607268985e-18)
127 self.metadata.add("BP_1_0", 0.0046783112625990)
128 self.metadata.add("BP_1_1", -1.2304042740813e-07)
129 self.metadata.add("BP_1_2", -2.3756827881344e-12)
130 self.metadata.add("BP_1_3", -3.9300202582816e-08)
131 self.metadata.add("BP_1_4", -9.7385290942256e-21)
132 self.metadata.add("BP_2_0", -6.5238116398890e-08)
133 self.metadata.add("BP_2_1", 4.7855579009100e-10)
134 self.metadata.add("BP_2_2", -1.2297758131839e-13)
135 self.metadata.add("BP_2_3", -3.0849793267035e-18)
136 self.metadata.add("BP_3_0", -9.3923321275113e-12)
137 self.metadata.add("BP_3_1", -1.3193479628568e-17)
138 self.metadata.add("BP_3_2", 2.1762350028059e-19)
139 self.metadata.add("BP_4_0", -5.9687252632035e-16)
140 self.metadata.add("BP_4_1", -1.4096893423344e-18)
141 self.metadata.add("BP_5_0", 2.8085458107813e-19)
142 self.metadata.set("CTYPE1", "RA---TAN-SIP")
143 self.metadata.set("CTYPE2", "DEC--TAN-SIP")
145 def testTanWcs(self):
146 self.addSipMetadata()
147 wcsIn = lsst.afw.geom.makeSkyWcs(self.metadata)
148 with lsst.utils.tests.getTempFilePath(".fits") as fileName:
149 wcsOut = self.doFitsRoundTrip(fileName, wcsIn)
150 wcsIn1 = wcsIn
151 wcsOut1 = wcsOut
152 self.assertIsNotNone(wcsIn1)
153 self.assertIsNotNone(wcsOut1)
154 self.assertEqual(wcsIn1, wcsOut1)
156 def testExposure(self):
157 """Test that we load the Wcs from the binary table instead of headers when possible."""
158 self.addSipMetadata()
159 wcsIn = lsst.afw.geom.makeSkyWcs(self.metadata)
160 dim = lsst.geom.Extent2I(20, 30)
161 expIn = lsst.afw.image.ExposureF(dim)
162 expIn.setWcs(wcsIn)
163 with lsst.utils.tests.getTempFilePath(".fits") as fileName:
164 expIn.writeFits(fileName)
165 # Manually mess up the headers, so we'd know if we were loading the Wcs from that;
166 # when there is a WCS in the header and a WCS in the FITS table, we should use the
167 # latter, because the former might just be an approximation.
168 fits = astropy.io.fits.open(fileName)
169 fits[1].header.remove("CTYPE1")
170 fits[1].header.remove("CTYPE2")
171 fits.writeto(fileName, overwrite=True)
172 fits.close()
173 # now load it using afw
174 expOut = lsst.afw.image.ExposureF(fileName)
175 wcsOut = expOut.getWcs()
176 self.assertEqual(wcsIn, wcsOut)
178 def testSkyOriginPrecision(self):
179 """Test that we don't lose precision in CRVAL when round-tripping
180 (DM-10105), using a WCS in which we previously did.
181 """
182 metadata = lsst.daf.base.PropertyList()
183 metadata.add('CD1_1', -4.66666666666667e-05)
184 metadata.add('CD1_2', 0.0)
185 metadata.add('CD2_1', 0.0)
186 metadata.add('CD2_2', 4.66666666666667e-05)
187 metadata.add('CRPIX1', 18000.0)
188 metadata.add('CRPIX2', 18000.0)
189 metadata.add('CRVAL1', 247.5)
190 metadata.add('CRVAL2', -87.0247933884297)
191 metadata.add('CTYPE1', 'RA---TAN')
192 metadata.add('CTYPE2', 'DEC--TAN')
193 metadata.add('CUNIT1', 'deg')
194 metadata.add('CUNIT2', 'deg')
195 metadata.add('NAXIS', 2)
196 metadata.add('RADESYS', 'ICRS')
197 wcs1 = lsst.afw.geom.makeSkyWcs(metadata)
198 with lsst.utils.tests.getTempFilePath(".fits") as fileName:
199 wcs1.writeFits(fileName)
200 wcs2 = lsst.afw.geom.SkyWcs.readFits(fileName)
201 self.assertEqual(wcs1, wcs2)
204class MemoryTester(lsst.utils.tests.MemoryTestCase):
205 pass
208def setup_module(module):
209 lsst.utils.tests.init()
212if __name__ == "__main__": 212 ↛ 213line 212 didn't jump to line 213, because the condition on line 212 was never true
213 lsst.utils.tests.init()
214 unittest.main()