Coverage for tests / test_flatGradient.py: 21%
88 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-23 08:35 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-23 08:35 +0000
1# This file is part of ip_isr.
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/>.
21import unittest
22import tempfile
23from scipy.interpolate import Akima1DInterpolator
25import numpy as np
27import lsst.utils.tests
29from lsst.ip.isr import FlatGradient
32class FlatGradientTest(lsst.utils.tests.TestCase):
33 """Test the FlatGradient dataset."""
34 def setUp(self):
36 radialNodes = np.array([0., 200., 250., 300., 310., 320., 330., 340., 350., 360., 368.])
37 radialValues = np.array(
38 [
39 1.03285683,
40 1.03457546,
41 1.02751129,
42 0.98331483,
43 0.97569776,
44 0.93527889,
45 0.79704968,
46 0.67758559,
47 0.60344388,
48 0.45119814,
49 -0.22979413,
50 ],
51 )
53 self.flatGradient = FlatGradient()
54 self.flatGradient.setParameters(
55 radialSplineNodes=radialNodes,
56 radialSplineValues=radialValues,
57 itlRatio=0.9,
58 centroidX=0.0,
59 centroidY=0.0,
60 centroidDeltaX=0.5,
61 centroidDeltaY=-0.5,
62 gradientX=1e-4,
63 gradientY=5e-5,
64 normalizationFactor=1.1,
65 )
67 def _checkEqual(self, a, b):
68 self.assertEqual(b.metadata, a.metadata)
69 np.testing.assert_array_almost_equal(b.radialSplineNodes, a.radialSplineNodes)
70 self.assertEqual(b.radialSplineNodes.dtype, a.radialSplineNodes.dtype)
71 np.testing.assert_array_almost_equal(b.radialSplineValues, a.radialSplineValues)
72 self.assertEqual(b.radialSplineValues.dtype, a.radialSplineValues.dtype)
73 self.assertEqual(b.itlRatio, a.itlRatio)
74 self.assertEqual(type(b.itlRatio), float)
75 self.assertEqual(b.centroidX, a.centroidX)
76 self.assertEqual(type(b.centroidX), float)
77 self.assertEqual(b.centroidY, a.centroidY)
78 self.assertEqual(type(b.centroidY), float)
79 self.assertEqual(b.centroidDeltaX, a.centroidDeltaX)
80 self.assertEqual(type(b.centroidDeltaX), float)
81 self.assertEqual(b.centroidDeltaY, a.centroidDeltaY)
82 self.assertEqual(type(b.centroidDeltaY), float)
83 self.assertEqual(b.gradientX, a.gradientX)
84 self.assertEqual(type(b.gradientX), float)
85 self.assertEqual(b.gradientY, a.gradientY)
86 self.assertEqual(type(b.gradientY), float)
87 self.assertEqual(b.normalizationFactor, a.normalizationFactor)
88 self.assertEqual(type(b.normalizationFactor), float)
90 def testRoundTrip(self):
91 """Test persistence round-tripping."""
93 with tempfile.NamedTemporaryFile(suffix=".yaml") as f:
94 usedFilename = self.flatGradient.writeText(f.name)
95 fromText = FlatGradient.readText(usedFilename)
96 self._checkEqual(fromText, self.flatGradient)
98 with tempfile.NamedTemporaryFile(suffix=".fits") as f:
99 usedFilename = self.flatGradient.writeFits(f.name)
100 fromFits = FlatGradient.readFits(usedFilename)
101 self._checkEqual(fromFits, self.flatGradient)
103 def testComputeRadialSplineModelXY(self):
104 x = np.arange(-300, 300, dtype=np.float64)
105 y = np.arange(-300, 300, dtype=np.float64)
107 spl = Akima1DInterpolator(
108 self.flatGradient.radialSplineNodes,
109 self.flatGradient.radialSplineValues,
110 )
111 centroidX = self.flatGradient.centroidX + self.flatGradient.centroidDeltaX
112 centroidY = self.flatGradient.centroidY + self.flatGradient.centroidDeltaY
113 radius = np.sqrt((x - centroidX)**2.
114 + (y - centroidY)**2.)
115 radial = spl(np.clip(radius, 0.0, 368.0))
117 model = self.flatGradient.computeRadialSplineModelXY(x, y)
119 np.testing.assert_array_almost_equal(model, radial)
121 def testComputeRadialSplineModel(self):
122 radius = np.linspace(0, 368.0, 1000)
124 spl = Akima1DInterpolator(
125 self.flatGradient.radialSplineNodes,
126 self.flatGradient.radialSplineValues,
127 )
128 radial = spl(np.clip(radius, 0.0, 368.0))
130 model = self.flatGradient.computeRadialSplineModel(radius)
132 np.testing.assert_array_almost_equal(model, radial)
134 def testComputeGradientModel(self):
135 x = np.arange(-300, 300, dtype=np.float64)
136 y = np.arange(-300, 300, dtype=np.float64)
138 gradient = (
139 1
140 + self.flatGradient.gradientX*(x - self.flatGradient.centroidX)
141 + self.flatGradient.gradientY*(y - self.flatGradient.centroidY)
142 )
144 model = self.flatGradient.computeGradientModel(x, y)
146 np.testing.assert_array_almost_equal(model, gradient)
148 def test_computeFullModel(self):
149 x = np.arange(-300, 300, dtype=np.float64)
150 y = np.arange(-300, 300, dtype=np.float64)
151 is_itl = np.zeros(len(x), dtype=np.bool_)
152 is_itl[0: 50] = True
154 # Compute the comparison model.
155 spl = Akima1DInterpolator(
156 self.flatGradient.radialSplineNodes,
157 self.flatGradient.radialSplineValues,
158 )
159 centroidX = self.flatGradient.centroidX + self.flatGradient.centroidDeltaX
160 centroidY = self.flatGradient.centroidY + self.flatGradient.centroidDeltaY
161 radius = np.sqrt((x - centroidX)**2.
162 + (y - centroidY)**2.)
163 radial = spl(np.clip(radius, 0.0, 368.0))
165 gradient = (
166 1
167 + self.flatGradient.gradientX*(x - self.flatGradient.centroidX)
168 + self.flatGradient.gradientY*(y - self.flatGradient.centroidY)
169 )
171 full_model = radial / gradient
172 full_model[is_itl] *= self.flatGradient.itlRatio
174 model = self.flatGradient.computeFullModel(x, y, is_itl)
176 np.testing.assert_array_almost_equal(full_model, model)
179class MemoryTester(lsst.utils.tests.MemoryTestCase):
180 pass
183def setup_module(module):
184 lsst.utils.tests.init()
187if __name__ == "__main__": 187 ↛ 188line 187 didn't jump to line 188 because the condition on line 187 was never true
188 import sys
189 setup_module(sys.modules[__name__])
190 unittest.main()