Coverage for tests/test_calexpCutout.py: 19%
116 statements
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-04 13:31 +0000
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-04 13:31 +0000
1#
2# LSST Data Management System
3# Copyright 2008-2016 AURA/LSST.
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 <https://www.lsstcorp.org/LegalNotices/>.
21#
22"""Test configuration of CalexpCutoutTask and the run method.
24Run the task on one test image and perform various checks on the results
25"""
26import os
27import random
28import unittest
29from astropy.coordinates import SkyCoord
30from astropy.table import QTable
31import astropy.units as u
33import lsst.utils
34import lsst.utils.tests
35from lsst.afw.image import ExposureF
36from lsst.pipe.tasks.calexpCutout import CalexpCutoutTask
38random.seed(208241138)
40packageDir = lsst.utils.getPackageDir('pipe_tasks')
41datadir = os.path.join(packageDir, 'tests', "data")
44def make_data(bbox, wcs, border=100, ngood=13, nbad=7, nedge=3):
45 dx, dy = bbox.getDimensions()
46 data = {}
48 ident = []
49 pt = []
50 xspan = []
51 yspan = []
52 for i in range(ngood):
53 x = random.random()*(dx - 2*border) + border
54 y = random.random()*(dy - 2*border) + border
55 sphpt = wcs.pixelToSky(x, y)
56 pt.append(SkyCoord(sphpt.getRa().asDegrees(), sphpt.getDec().asDegrees(),
57 frame='icrs', unit=u.deg))
58 ident.append((i+1)*u.dimensionless_unscaled)
59 xspan.append(random.randint(13, 26)*u.dimensionless_unscaled)
60 yspan.append(random.randint(13, 26)*u.dimensionless_unscaled)
61 data['good'] = QTable([ident, pt, xspan, yspan], names=['id', 'position', 'xspan', 'yspan'])
63 ident = []
64 pt = []
65 xspan = []
66 yspan = []
67 for i in range(nbad):
68 x = random.random()*(dx - 2*border) + border
69 y = random.random()*(dy - 2*border) + border
70 sphpt = wcs.pixelToSky(-x, -y)
71 pt.append(SkyCoord(sphpt.getRa().asDegrees(), sphpt.getDec().asDegrees(),
72 frame='icrs', unit=u.deg))
73 ident.append((i+1)*u.dimensionless_unscaled)
74 xspan.append(random.randint(13, 26)*u.dimensionless_unscaled)
75 yspan.append(random.randint(13, 26)*u.dimensionless_unscaled)
76 data['bad'] = QTable([ident, pt, xspan, yspan], names=['id', 'position', 'xspan', 'yspan'])
78 ident = []
79 pt = []
80 xspan = []
81 yspan = []
82 for i in range(nedge):
83 x_or_y = random.randint(0, 1)
84 if x_or_y:
85 x = random.random()*dx
86 y = [0, dy][random.randint(0, 1)]
87 else:
88 x = [0, dx][random.randint(0, 1)]
89 y = random.random()*dy
91 sphpt = wcs.pixelToSky(x, y)
92 pt.append(SkyCoord(sphpt.getRa().asDegrees(), sphpt.getDec().asDegrees(),
93 frame='icrs', unit=u.deg))
94 ident.append((i+1)*u.dimensionless_unscaled)
95 xspan.append(random.randint(13, 26)*u.dimensionless_unscaled)
96 yspan.append(random.randint(13, 26)*u.dimensionless_unscaled)
97 data['edge'] = QTable([ident, pt, xspan, yspan], names=['id', 'position', 'xspan', 'yspan'])
98 return data
101class CalexpCutoutTestCase(lsst.utils.tests.TestCase):
102 def setUp(self):
103 self.exp = ExposureF.readFits(os.path.join(datadir, 'v695833-e0-c000-a00.sci.fits'))
104 self.data = make_data(self.exp.getBBox(), self.exp.getWcs())
106 def tearDown(self):
107 del self.data
108 del self.exp
110 def testCalexpCutout(self):
111 config = CalexpCutoutTask.ConfigClass()
112 task = CalexpCutoutTask(config=config)
113 result = task.run(self.data['good'], self.exp)
114 self.assertEqual(len(result.cutouts), len(self.data['good']))
115 indims = [(x, y) for x, y in zip(self.data['good']['xspan'], self.data['good']['yspan'])]
116 outdims = [tuple(el.stamp_im.getDimensions()) for el in result.cutouts]
117 self.assertEqual(indims, outdims)
119 # Test configuration of the max number of cutouts
120 config.max_cutouts = 4
121 task = CalexpCutoutTask(config=config)
122 result = task.run(self.data['good'], self.exp)
123 self.assertEqual(len(result.cutouts), task.config.max_cutouts)
124 indims = [(x, y) for x, y in zip(self.data['good']['xspan'][:config.max_cutouts],
125 self.data['good']['yspan'][:config.max_cutouts])]
126 outdims = [tuple(el.stamp_im.getDimensions()) for el in result.cutouts[:config.max_cutouts]]
127 self.assertEqual(indims, outdims)
129 def testEdge(self):
130 # Currently edge cutouts are handled the same way
131 # as cutouts completely outside the image. That
132 # could change in the future
133 config = CalexpCutoutTask.ConfigClass()
134 task = CalexpCutoutTask(config=config)
135 result = task.run(self.data['edge'], self.exp)
136 # Cutouts on the edge should be skipped
137 self.assertEqual(len(result.cutouts), 0)
138 self.assertEqual(len(result.skipped_positions), len(self.data['edge']))
140 config.skip_bad = False
141 task = CalexpCutoutTask(config=config)
142 # Should now raise for cutouts on the edge
143 with self.assertRaises(ValueError):
144 result = task.run(self.data['edge'], self.exp)
146 def testBad(self):
147 config = CalexpCutoutTask.ConfigClass()
148 task = CalexpCutoutTask(config=config)
149 result = task.run(self.data['bad'], self.exp)
150 # Cutouts outside the image should be skipped
151 self.assertEqual(len(result.cutouts), 0)
152 self.assertEqual(len(result.skipped_positions), len(self.data['bad']))
154 config.skip_bad = False
155 task = CalexpCutoutTask(config=config)
156 # Should now raise for cutouts outside the image
157 with self.assertRaises(ValueError):
158 result = task.run(self.data['bad'], self.exp)
160 def testBadColumns(self):
161 config = CalexpCutoutTask.ConfigClass()
162 task = CalexpCutoutTask(config=config)
163 table = QTable([[], []], names=['one', 'two'])
164 with self.assertRaises(ValueError):
165 result = task.run(table, self.exp) # noqa
168class MemoryTestCase(lsst.utils.tests.MemoryTestCase):
169 pass
172def setup_module(module):
173 lsst.utils.tests.init()
176if __name__ == "__main__": 176 ↛ 177line 176 didn't jump to line 177, because the condition on line 176 was never true
177 lsst.utils.tests.init()
178 unittest.main()