Coverage for tests/test_coordinateConverterConfig.py: 20%
74 statements
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-25 00:04 -0700
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-25 00:04 -0700
1# This file is part of cbp.
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/>.
22import math
23import unittest
25import numpy as np
27import lsst.utils.tests
28from lsst.geom import degrees
29from lsst.cbp import CoordinateConverterConfig
32class CoordinateConverterTestCase(lsst.utils.tests.TestCase):
34 def setUp(self):
35 self.argDict = dict(
36 telPupilDiameter=3000,
37 telPupilOffset=-0.134,
38 telPupilObscurationDiameter=333,
39 telFocalPlaneDiameter=550,
40 telFlipX=True,
41 telAzimuthOffsetDeg=1.1,
42 telAzimuthScale=-1, # must be ±1
43 telAltitudeOffsetDeg=2.2,
44 telAltitudeScale=-2.3,
45 telAltitudeLimitsDeg=(-3.1, 3.2),
46 telRotOffsetDeg=4.1,
47 telRotScale=-1, # must be ±1
48 defaultDetector=5,
49 cbpPosition=(6.1, 6.2, 6.3),
50 cbpFocalLength=7,
51 cbpFlipX=False,
52 cbpAzimuthOffsetDeg=8.1,
53 cbpAzimuthScale=-1, # must be ±1
54 cbpAltitudeOffsetDeg=9.1,
55 cbpAltitudeScale=9.2,
56 cbpAltitudeLimitsDeg=(10.1, 10.2),
57 )
58 # names of arguments that show up as a field of the same name and type
59 # (ignoring list vs. tuple)
60 self.matchedNames = [
61 "telPupilDiameter",
62 "telPupilOffset",
63 "telPupilObscurationDiameter",
64 "telFocalPlaneDiameter",
65 "telFlipX",
66 "telRotScale",
67 "defaultDetector",
68 "cbpPosition",
69 "cbpFocalLength",
70 "cbpFlipX",
71 ]
73 def testBasics(self):
74 argDict = self.argDict
75 config = CoordinateConverterConfig(**argDict)
76 self.checkValues(argDict, config)
78 def testDefaults(self):
79 argDict = self.argDict
80 minimalArgDict = argDict.copy()
81 defaultArgDict = dict(
82 telAltitudeOffsetDeg=0,
83 telAltitudeScale=1,
84 cbpAltitudeOffsetDeg=0,
85 cbpAltitudeScale=1,
86 )
87 for name in defaultArgDict:
88 del minimalArgDict[name]
89 argDict[name] = defaultArgDict[name]
90 config = CoordinateConverterConfig(**minimalArgDict)
91 self.checkValues(argDict, config)
93 def testLengthErrors(self):
94 for name, value in self.argDict.items():
95 if not isinstance(value, tuple):
96 continue
97 argDict = self.argDict.copy()
98 argDict[name] = value[0:-1] # too few values
99 with self.assertRaises(ValueError):
100 CoordinateConverterConfig(**argDict)
101 argDict[name] = value + (3.1,) # too many values
102 with self.assertRaises(ValueError):
103 CoordinateConverterConfig(**argDict)
105 def testScaleErrors(self):
106 """Rotator and azimuth scales must be ±1 degree
107 """
108 for name in ("telAzimuthScale", "telRotScale", "cbpAzimuthScale"):
109 argDict = self.argDict.copy()
110 argDict[name] = 1.01
111 with self.assertRaises(ValueError):
112 CoordinateConverterConfig(**argDict)
114 def checkValues(self, argDict, config):
115 """Check the values in a CoordinateConverterConfig
117 Parameters
118 ----------
119 argDict : `dict`
120 Dictionary of arguments used to construct ``config``,
121 plus values for defaulted arguments (if any)
122 config : `lsst.cbp.CoordinateConverterConfig`
123 The configuration to check
124 """
125 for name in self.matchedNames:
126 argValue = argDict[name]
127 fieldValue = getattr(config, name)
128 if isinstance(argValue, tuple):
129 self.assertEqual(len(argValue), len(fieldValue))
130 for a, f in zip(argValue, fieldValue):
131 self.assertEqual(a, f)
132 else:
133 self.assertEqual(argDict[name], getattr(config, name))
134 self.assertEqual(config.telRotOffset, argDict["telRotOffsetDeg"]*degrees)
135 desiredAzAltScale = (argDict["telAzimuthScale"],
136 argDict["telAltitudeScale"])
137 self.assertEqual(config.telAzAltScale, desiredAzAltScale)
138 desiredAzAltOffset = (argDict["telAzimuthOffsetDeg"]*degrees,
139 argDict["telAltitudeOffsetDeg"]*degrees)
140 self.assertEqual(config.telAzAltOffset, desiredAzAltOffset)
141 desiredAzAltScale = (argDict["cbpAzimuthScale"],
142 argDict["cbpAltitudeScale"])
143 self.assertEqual(config.cbpAzAltScale, desiredAzAltScale)
144 desiredAzAltOffset = (argDict["cbpAzimuthOffsetDeg"]*degrees,
145 argDict["cbpAltitudeOffsetDeg"]*degrees)
146 self.assertEqual(config.cbpAzAltOffset, desiredAzAltOffset)
148 self.checkCbpDistance(config)
150 # Try setting a different cbpPosition; cbpPosition and cbpDistance
151 # should update accordingly.
152 cbpPosition2 = config.cbpPosition + np.array((1.5, -3.2, 9.4))
153 config.cbpPosition = cbpPosition2
154 np.testing.assert_equal(config.cbpPosition, cbpPosition2)
155 self.checkCbpDistance(config)
157 def checkCbpDistance(self, config):
158 """Check that cbpPosition and cbpDistance are as desired
160 Parameters
161 ----------
162 config : `lsst.cbp.CoordinateConverterConfig`
163 The configuration to check
164 """
166 # This is less accurate than np.linalg.norm,
167 # as used by CoordinateConverterConfig, but is fine for unit tests
168 # and it's nice to have a different implementation.
169 cbpPosition = config.cbpPosition
170 desiredCbpDistance = math.sqrt(cbpPosition[0]**2 + cbpPosition[1]**2 + cbpPosition[2]**2)
171 self.assertAlmostEqual(config.cbpDistance, desiredCbpDistance)
174class MemoryTester(lsst.utils.tests.MemoryTestCase):
175 pass
178def setup_module(module):
179 lsst.utils.tests.init()
182if __name__ == "__main__": 182 ↛ 183line 182 didn't jump to line 183, because the condition on line 182 was never true
183 lsst.utils.tests.init()
184 unittest.main()