Coverage for tests/test_readers.py : 12%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# This file is part of afw.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
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 GNU General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
22import unittest
24import numpy as np
26import lsst.utils.tests
27from lsst.daf.base import PropertyList
28from lsst.geom import Box2I, Point2I, Extent2I, Point2D, Box2D, SpherePoint, degrees
29from lsst.afw.geom import makeSkyWcs, Polygon
30from lsst.afw.table import ExposureTable
31from lsst.afw.image import (Image, Mask, Exposure, LOCAL, PARENT, MaskPixel, VariancePixel,
32 ImageFitsReader, MaskFitsReader, MaskedImageFitsReader, ExposureFitsReader,
33 Filter, PhotoCalib, ApCorrMap, VisitInfo, TransmissionCurve, CoaddInputs)
34from lsst.afw.image.utils import defineFilter
35from lsst.afw.detection import GaussianPsf
36from lsst.afw.cameraGeom.testUtils import DetectorWrapper
39class FitsReaderTestCase(lsst.utils.tests.TestCase):
41 def setUp(self):
42 self.dtypes = [np.dtype(t) for t in (np.uint16, np.int32, np.float32, np.float64)]
43 self.bbox = Box2I(Point2I(2, 1), Extent2I(5, 7))
44 self.args = [
45 (),
46 (Box2I(Point2I(3, 4), Extent2I(2, 1)),),
47 (Box2I(Point2I(3, 4), Extent2I(2, 1)), PARENT),
48 (Box2I(Point2I(1, 0), Extent2I(3, 2)), LOCAL),
49 ]
51 def testImageFitsReader(self):
52 for n, dtypeIn in enumerate(self.dtypes):
53 with self.subTest(dtypeIn=dtypeIn):
54 imageIn = Image(self.bbox, dtype=dtypeIn)
55 imageIn.array[:, :] = np.random.randint(low=1, high=5, size=imageIn.array.shape)
56 with lsst.utils.tests.getTempFilePath(".fits") as fileName:
57 imageIn.writeFits(fileName)
58 reader = ImageFitsReader(fileName)
59 self.assertEqual(reader.readBBox(), self.bbox)
60 self.assertEqual(reader.readDType(), dtypeIn)
61 self.assertEqual(reader.fileName, fileName)
62 for args in self.args:
63 with self.subTest(args=args):
64 array1 = reader.readArray(*args)
65 image1 = reader.read(*args)
66 subIn = imageIn.subset(*args) if args else imageIn
67 self.assertEqual(dtypeIn, array1.dtype)
68 self.assertTrue(np.all(subIn.array == array1))
69 self.assertEqual(subIn.getXY0(), reader.readXY0(*args))
70 self.assertImagesEqual(subIn, image1)
71 for dtype2 in self.dtypes[n:]:
72 for args in self.args:
73 with self.subTest(dtype2=dtype2, args=args):
74 subIn = imageIn.subset(*args) if args else imageIn
75 array2 = reader.readArray(*args, dtype=dtype2)
76 image2 = reader.read(*args, dtype=dtype2)
77 self.assertEqual(dtype2, array2.dtype)
78 self.assertTrue(np.all(subIn.array == array2))
79 self.assertEqual(subIn.getXY0(), reader.readXY0(*args))
80 self.assertEqual(subIn.getBBox(), image2.getBBox())
81 self.assertTrue(np.all(image2.array == array2))
83 def testMaskFitsReader(self):
84 maskIn = Mask(self.bbox, dtype=MaskPixel)
85 maskIn.array[:, :] = np.random.randint(low=1, high=5, size=maskIn.array.shape)
86 with lsst.utils.tests.getTempFilePath(".fits") as fileName:
87 maskIn.writeFits(fileName)
88 reader = MaskFitsReader(fileName)
89 self.assertEqual(reader.readBBox(), self.bbox)
90 self.assertEqual(reader.readDType(), MaskPixel)
91 self.assertEqual(reader.fileName, fileName)
92 for args in self.args:
93 with self.subTest(args=args):
94 array = reader.readArray(*args)
95 mask = reader.read(*args)
96 subIn = maskIn.subset(*args) if args else maskIn
97 self.assertEqual(MaskPixel, array.dtype)
98 self.assertTrue(np.all(subIn.array == array))
99 self.assertEqual(subIn.getXY0(), reader.readXY0(*args))
100 self.assertImagesEqual(subIn, mask)
102 def checkMultiPlaneReader(self, reader, objectIn, fileName, dtypesOut, compare):
103 """Test operations common to MaskedImageFitsReader and ExposureFitsReader.
105 Parameters
106 ----------
107 reader : `MaskedImageFitsReader` or `ExposureFitsReader` instance
108 Reader object to test.
109 objectIn : `MaskedImage` or `Exposure`
110 Object originally saved, to compare against.
111 fileName : `str`
112 Name of the file the reader is reading.
113 dtypesOut : sequence of `numpy.dype`
114 Compatible image pixel types to try to read in.
115 compare : callable
116 Callable that compares objects of the same type as objectIn and
117 asserts if they are not equal.
118 """
119 dtypeIn = objectIn.image.dtype
120 self.assertEqual(reader.readBBox(), self.bbox)
121 self.assertEqual(reader.readImageDType(), dtypeIn)
122 self.assertEqual(reader.readMaskDType(), MaskPixel)
123 self.assertEqual(reader.readVarianceDType(), VariancePixel)
124 self.assertEqual(reader.fileName, fileName)
125 for args in self.args:
126 with self.subTest(args=args):
127 object1 = reader.read(*args)
128 subIn = objectIn.subset(*args) if args else objectIn
129 self.assertEqual(object1.image.array.dtype, dtypeIn)
130 self.assertEqual(object1.mask.array.dtype, MaskPixel)
131 self.assertEqual(object1.variance.array.dtype, VariancePixel)
132 self.assertImagesEqual(subIn.image, reader.readImage(*args))
133 self.assertImagesEqual(subIn.mask, reader.readMask(*args))
134 self.assertImagesEqual(subIn.variance, reader.readVariance(*args))
135 compare(subIn, object1)
136 for dtype2 in dtypesOut:
137 with self.subTest(dtype2=dtype2, args=args):
138 object2 = reader.read(*args, dtype=dtype2)
139 image2 = reader.readImage(*args, dtype=dtype2)
140 self.assertEqual(object2.image.array.dtype, dtype2)
141 self.assertEqual(object2.mask.array.dtype, MaskPixel)
142 self.assertEqual(object2.variance.array.dtype, VariancePixel)
143 self.assertImagesEqual(subIn.image, Image(image2, deep=True, dtype=dtypeIn))
144 self.assertImagesEqual(image2, object2.image)
145 compare(subIn, object2)
147 def checkMaskedImageFitsReader(self, exposureIn, fileName, dtypesOut):
148 """Test MaskedImageFitsReader.
150 Parameters
151 ----------
152 exposureIn : `Exposure`
153 Object originally saved, to compare against.
154 fileName : `str`
155 Name of the file the reader is reading.
156 dtypesOut : sequence of `numpy.dype`
157 Compatible image pixel types to try to read in.
158 """
159 reader = MaskedImageFitsReader(fileName)
160 self.checkMultiPlaneReader(reader, exposureIn.maskedImage, fileName, dtypesOut,
161 compare=self.assertMaskedImagesEqual)
163 def checkExposureFitsReader(self, exposureIn, fileName, dtypesOut):
164 """Test ExposureFitsReader.
166 Parameters
167 ----------
168 exposureIn : `Exposure`
169 Object originally saved, to compare against.
170 fileName : `str`
171 Name of the file the reader is reading.
172 dtypesOut : sequence of `numpy.dype`
173 Compatible image pixel types to try to read in.
174 """
175 reader = ExposureFitsReader(fileName)
176 self.assertIn('EXPINFO_V', reader.readMetadata().toDict(), "metadata is automatically versioned")
177 reader.readMetadata().remove('EXPINFO_V')
178 self.assertEqual(exposureIn.getMetadata().toDict(), reader.readMetadata().toDict())
179 self.assertWcsAlmostEqualOverBBox(exposureIn.getWcs(), reader.readWcs(), self.bbox,
180 maxDiffPix=0, maxDiffSky=0*degrees)
181 self.assertEqual(exposureIn.getFilter(), reader.readFilter())
182 self.assertEqual(exposureIn.getPhotoCalib(), reader.readPhotoCalib())
183 self.assertImagesEqual(exposureIn.getPsf().computeImage(), reader.readPsf().computeImage())
184 self.assertEqual(exposureIn.getInfo().getValidPolygon(), reader.readValidPolygon())
185 self.assertCountEqual(exposureIn.getInfo().getApCorrMap(), reader.readApCorrMap())
186 self.assertEqual(exposureIn.getInfo().getVisitInfo().getExposureTime(),
187 reader.readVisitInfo().getExposureTime())
188 point = Point2D(2.3, 3.1)
189 wavelengths = np.linspace(4000, 5000, 5)
190 self.assertFloatsEqual(exposureIn.getInfo().getTransmissionCurve().sampleAt(point, wavelengths),
191 reader.readTransmissionCurve().sampleAt(point, wavelengths))
192 # Because we persisted the same instances, we should get back the same
193 # instances for *archive* components, and hence equality comparisons
194 # should work even if it just amounts to C++ pointer equality.
195 record = reader.readCoaddInputs().ccds[0]
196 self.assertEqual(record.getWcs(), reader.readWcs())
197 self.assertEqual(record.getPsf(), reader.readPsf())
198 self.assertEqual(record.getValidPolygon(), reader.readValidPolygon())
199 self.assertEqual(record.getApCorrMap(), reader.readApCorrMap())
200 self.assertEqual(record.getPhotoCalib(), reader.readPhotoCalib())
201 self.assertEqual(record.getDetector(), reader.readDetector())
202 self.checkMultiPlaneReader(
203 reader, exposureIn, fileName, dtypesOut,
204 compare=lambda a, b: self.assertMaskedImagesEqual(a.maskedImage, b.maskedImage)
205 )
207 def testMultiPlaneFitsReaders(self):
208 """Run tests for MaskedImageFitsReader and ExposureFitsReader.
209 """
210 metadata = PropertyList()
211 metadata.add("FIVE", 5)
212 metadata.add("SIX", 6.0)
213 wcs = makeSkyWcs(Point2D(2.5, 3.75), SpherePoint(40.0*degrees, 50.0*degrees),
214 np.array([[1E-5, 0.0], [0.0, -1E-5]]))
215 defineFilter("test_readers_filter", lambdaEff=470.0)
216 calib = PhotoCalib(2.5E4)
217 psf = GaussianPsf(21, 21, 8.0)
218 polygon = Polygon(Box2D(self.bbox))
219 apCorrMap = ApCorrMap()
220 visitInfo = VisitInfo(exposureTime=5.0)
221 transmissionCurve = TransmissionCurve.makeIdentity()
222 coaddInputs = CoaddInputs(ExposureTable.makeMinimalSchema(), ExposureTable.makeMinimalSchema())
223 detector = DetectorWrapper().detector
224 record = coaddInputs.ccds.addNew()
225 record.setWcs(wcs)
226 record.setPhotoCalib(calib)
227 record.setPsf(psf)
228 record.setValidPolygon(polygon)
229 record.setApCorrMap(apCorrMap)
230 record.setVisitInfo(visitInfo)
231 record.setTransmissionCurve(transmissionCurve)
232 record.setDetector(detector)
233 for n, dtypeIn in enumerate(self.dtypes):
234 with self.subTest(dtypeIn=dtypeIn):
235 exposureIn = Exposure(self.bbox, dtype=dtypeIn)
236 shape = exposureIn.image.array.shape
237 exposureIn.image.array[:, :] = np.random.randint(low=1, high=5, size=shape)
238 exposureIn.mask.array[:, :] = np.random.randint(low=1, high=5, size=shape)
239 exposureIn.variance.array[:, :] = np.random.randint(low=1, high=5, size=shape)
240 exposureIn.setMetadata(metadata)
241 exposureIn.setWcs(wcs)
242 exposureIn.setFilter(Filter("test_readers_filter"))
243 exposureIn.setPhotoCalib(calib)
244 exposureIn.setPsf(psf)
245 exposureIn.getInfo().setValidPolygon(polygon)
246 exposureIn.getInfo().setApCorrMap(apCorrMap)
247 exposureIn.getInfo().setVisitInfo(visitInfo)
248 exposureIn.getInfo().setTransmissionCurve(transmissionCurve)
249 exposureIn.getInfo().setCoaddInputs(coaddInputs)
250 exposureIn.setDetector(detector)
251 with lsst.utils.tests.getTempFilePath(".fits") as fileName:
252 exposureIn.writeFits(fileName)
253 self.checkMaskedImageFitsReader(exposureIn, fileName, self.dtypes[n:])
254 self.checkExposureFitsReader(exposureIn, fileName, self.dtypes[n:])
257class TestMemory(lsst.utils.tests.MemoryTestCase):
258 pass
261def setup_module(module):
262 lsst.utils.tests.init()
265if __name__ == "__main__": 265 ↛ 266line 265 didn't jump to line 266, because the condition on line 265 was never true
266 import sys
267 setup_module(sys.modules[__name__])
268 unittest.main()