Coverage for tests/test_utils.py: 22%
121 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-03-21 02:23 -0700
« prev ^ index » next coverage.py v6.5.0, created at 2023-03-21 02:23 -0700
1# This file is part of summit_utils.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://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 <https://www.gnu.org/licenses/>.
22"""Test cases for utils."""
24import copy
25import itertools
26import unittest
28import astropy.time
29import astropy.units as u
30import lsst.afw.image as afwImage
31import lsst.geom as geom
32import lsst.utils.tests
33import numpy as np
34from astro_metadata_translator import makeObservationInfo
35from lsst.obs.base import createInitialSkyWcsFromBoresight
36from lsst.obs.base.makeRawVisitInfoViaObsInfo import MakeRawVisitInfoViaObsInfo
37from lsst.obs.lsst import Latiss
38from lsst.summit.utils.utils import (getExpPositionOffset,
39 getFieldNameAndTileNumber,
40 getAirmassSeeingCorrection,
41 getFilterSeeingCorrection,
42 quickSmooth,
43 )
44from lsst.obs.lsst.translators.latiss import AUXTEL_LOCATION
47class ExpSkyPositionOffsetTestCase(lsst.utils.tests.TestCase):
48 """A test case for testing sky position offsets for exposures."""
50 def setUp(self):
51 camera = Latiss.getCamera()
52 self.assertTrue(len(camera) == 1)
53 self.detector = camera[0]
55 self.viMaker = MakeRawVisitInfoViaObsInfo()
56 self.mi = afwImage.maskedImage.MaskedImageF(0, 0)
57 self.baseHeader = dict(boresight_airmass=1.5,
58 temperature=15*u.deg_C,
59 observation_type="science",
60 exposure_time=5*u.ks,
61 detector_num=32,
62 location=AUXTEL_LOCATION,
63 )
65 def test_getExpPositionOffset(self):
66 epsilon = 0.0001
67 ra1s = [0, 45, 90]
68 ra2s = copy.copy(ra1s)
69 ra2s.extend([r + epsilon for r in ra1s])
70 ra1s = np.deg2rad(ra1s)
71 ra2s = np.deg2rad(ra2s)
73 epsilon = 0.0001
74 dec1s = [0, 45, 90]
75 dec2s = copy.copy(dec1s)
76 dec2s.extend([d + epsilon for d in dec1s[:-1]]) # skip last point as >90 not allowed for dec
78 rotAngle1 = geom.Angle(43.2, geom.degrees) # arbitrary non-zero
79 rotAngle2 = geom.Angle(56.7, geom.degrees)
81 t1 = astropy.time.Time("2021-09-15T12:00:00", format="isot", scale="utc")
82 t2 = astropy.time.Time("2021-09-15T12:01:00", format="isot", scale="utc")
83 expTime = astropy.time.TimeDelta(20, format='sec')
85 header1 = copy.copy(self.baseHeader)
86 header2 = copy.copy(self.baseHeader)
87 header1['datetime_begin'] = astropy.time.Time(t1, format="isot", scale="utc")
88 header2['datetime_begin'] = astropy.time.Time(t2, format="isot", scale="utc")
90 header1['datetime_end'] = astropy.time.Time(t1+expTime, format="isot", scale="utc")
91 header2['datetime_end'] = astropy.time.Time(t2+expTime, format="isot", scale="utc")
93 obsInfo1 = makeObservationInfo(**header1)
94 obsInfo2 = makeObservationInfo(**header2)
96 vi1 = self.viMaker.observationInfo2visitInfo(obsInfo1)
97 vi2 = self.viMaker.observationInfo2visitInfo(obsInfo2)
98 expInfo1 = afwImage.ExposureInfo()
99 expInfo1.setVisitInfo(vi1)
100 expInfo2 = afwImage.ExposureInfo()
101 expInfo2.setVisitInfo(vi2)
103 for ra1, dec1, ra2, dec2 in itertools.product(ra1s, dec1s, ra2s, dec2s):
104 pos1 = geom.SpherePoint(ra1, dec1, geom.degrees)
105 pos2 = geom.SpherePoint(ra2, dec2, geom.degrees)
107 wcs1 = createInitialSkyWcsFromBoresight(pos1, rotAngle1, self.detector, flipX=True)
108 wcs2 = createInitialSkyWcsFromBoresight(pos2, rotAngle2, self.detector, flipX=True)
110 exp1 = afwImage.ExposureF(self.mi, expInfo1)
111 exp2 = afwImage.ExposureF(self.mi, expInfo2)
113 exp1.setWcs(wcs1)
114 exp2.setWcs(wcs2)
116 result = getExpPositionOffset(exp1, exp2)
118 deltaRa = ra1 - ra2
119 deltaDec = dec1 - dec2
121 self.assertAlmostEqual(result.deltaRa.asDegrees(), deltaRa, 6)
122 self.assertAlmostEqual(result.deltaDec.asDegrees(), deltaDec, 6)
125class MiscUtilsTestCase(lsst.utils.tests.TestCase):
127 def setUp(self) -> None:
128 return super().setUp()
130 def test_getFieldNameAndTileNumber(self):
131 field, num = getFieldNameAndTileNumber('simple')
132 self.assertEqual(field, 'simple')
133 self.assertIsNone(num)
135 field, num = getFieldNameAndTileNumber('_simple')
136 self.assertEqual(field, '_simple')
137 self.assertIsNone(num)
139 field, num = getFieldNameAndTileNumber('simple_321')
140 self.assertEqual(field, 'simple')
141 self.assertEqual(num, 321)
143 field, num = getFieldNameAndTileNumber('_simple_321')
144 self.assertEqual(field, '_simple')
145 self.assertEqual(num, 321)
147 field, num = getFieldNameAndTileNumber('test_321a_123')
148 self.assertEqual(field, 'test_321a')
149 self.assertEqual(num, 123)
151 field, num = getFieldNameAndTileNumber('test_321a_123_')
152 self.assertEqual(field, 'test_321a_123_')
153 self.assertIsNone(num)
155 field, num = getFieldNameAndTileNumber('test_321a_123a')
156 self.assertEqual(field, 'test_321a_123a')
157 self.assertIsNone(num)
159 field, num = getFieldNameAndTileNumber('test_321a:asd_asd-dsa_321')
160 self.assertEqual(field, 'test_321a:asd_asd-dsa')
161 self.assertEqual(num, 321)
163 def test_getAirmassSeeingCorrection(self):
164 for airmass in (1.1, 2.0, 20.0):
165 correction = getAirmassSeeingCorrection(airmass)
166 self.assertGreater(correction, 0.01)
167 self.assertLess(correction, 1.0)
169 correction = getAirmassSeeingCorrection(1)
170 self.assertEqual(correction, 1.0)
172 with self.assertRaises(ValueError):
173 getAirmassSeeingCorrection(0.5)
175 def test_getFilterSeeingCorrection(self):
176 for filterName in ('SDSSg_65mm', 'SDSSr_65mm', 'SDSSi_65mm'):
177 correction = getFilterSeeingCorrection(filterName)
178 self.assertGreater(correction, 0.5)
179 self.assertLess(correction, 1.5)
181 def test_quickSmooth(self):
182 # just test that it runs and returns the right shape. It's a wrapper on
183 # scipy.ndimage.gaussian_filter we can trust that it does what it
184 # should, and we just test the interface hasn't bitrotted on either end
185 data = np.zeros((100, 100), dtype=np.float32)
186 data = quickSmooth(data, 5.0)
187 self.assertEqual(data.shape, (100, 100))
190class TestMemory(lsst.utils.tests.MemoryTestCase):
191 pass
194def setup_module(module):
195 lsst.utils.tests.init()
198if __name__ == "__main__": 198 ↛ 199line 198 didn't jump to line 199, because the condition on line 198 was never true
199 lsst.utils.tests.init()
200 unittest.main()