Coverage for tests/test_makePixelToTanPixel.py: 21%
82 statements
« prev ^ index » next coverage.py v6.4, created at 2022-06-02 03:42 -0700
« prev ^ index » next coverage.py v6.4, created at 2022-06-02 03:42 -0700
1#
2# LSST Data Management System
3# Copyright 2014 LSST Corporation.
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 <http://www.lsstcorp.org/LegalNotices/>.
21#
22"""
23Tests for lsst.afw.cameraGeom.Detector
24"""
25import unittest
26import math
28import lsst.utils.tests
29import lsst.geom
30import lsst.afw.geom as afwGeom
31import lsst.afw.cameraGeom as cameraGeom
32from lsst.afw.cameraGeom import makePixelToTanPixel
35class MakePixelToTanPixelTestCaseCase(lsst.utils.tests.TestCase):
37 def testSimpleCurvedFocalPlane(self):
38 """Test a trivial curved focal plane with square pixels
40 The CCD's lower left pixel is centered on the boresight
41 pupil center = focal plane center
42 CCD x is along focal plane x
43 """
44 bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0),
45 lsst.geom.Extent2I(1000, 1000))
46 pixelSizeMm = lsst.geom.Extent2D(0.02, 0.02)
47 plateScale = 25.0 # arcsec/mm
48 yaw = 0 * lsst.geom.degrees
49 # focal-plane position of ref position on detector (mm)
50 fpPosition = lsst.geom.Point2D(0, 0)
51 # ref position on detector (pos of lower left corner)
52 refPoint = lsst.geom.Point2D(0, 0)
53 orientation = cameraGeom.Orientation(
54 fpPosition,
55 refPoint,
56 yaw,
57 )
58 pixelToFocalPlane = orientation.makePixelFpTransform(pixelSizeMm)
59 plateScaleRad = lsst.geom.Angle( # rad/mm
60 plateScale, lsst.geom.arcseconds).asRadians()
61 focalPlaneToField = afwGeom.makeRadialTransform(
62 (0.0, plateScaleRad, 0.0, 0.001 * plateScaleRad))
63 pixelToField = pixelToFocalPlane.then(focalPlaneToField)
65 pixelToTanPixel = makePixelToTanPixel(
66 bbox=bbox,
67 orientation=orientation,
68 focalPlaneToField=focalPlaneToField,
69 pixelSizeMm=pixelSizeMm,
70 )
72 # field center should be pixel position 0, 0 and tan pixel position 0,
73 # 0
74 pixAtFieldCtr = pixelToField.applyInverse(lsst.geom.Point2D(0, 0))
75 self.assertPairsAlmostEqual(pixAtFieldCtr, [0, 0])
76 tanPixAtFieldCr = pixelToTanPixel.applyForward(pixAtFieldCtr)
77 self.assertPairsAlmostEqual(tanPixAtFieldCr, [0, 0])
79 # build same camera geometry transforms without optical distortion
80 focalPlaneToFieldNoDistortion = afwGeom.makeRadialTransform(
81 (0.0, plateScaleRad))
82 pixelToFieldNoDistortion = pixelToFocalPlane.then(focalPlaneToFieldNoDistortion)
84 for x in (100, 200, 1000):
85 for y in (100, 500, 800):
86 pixPos = lsst.geom.Point2D(x, y)
87 tanPixPos = pixelToTanPixel.applyForward(pixPos)
88 # pix to tan pix should be radial
89 self.assertAlmostEqual(
90 math.atan2(pixPos[1], pixPos[0]),
91 math.atan2(tanPixPos[1], tanPixPos[0]),
92 )
94 # for a given field angle (which, together with a pointing, gives a position on the sky):
95 # - field angle to pixels gives pixPos
96 # - undistorted field anle to pixels gives tanPixPos
97 fieldPos = pixelToField.applyForward(pixPos)
98 desTanPixPos = pixelToFieldNoDistortion.applyInverse(
99 fieldPos)
100 self.assertPairsAlmostEqual(desTanPixPos, tanPixPos)
102 def testCurvedFocalPlane(self):
103 """Test a curved focal plane (with rectangular pixels)
104 """
105 bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0),
106 lsst.geom.Extent2I(1000, 1000))
107 pixelSizeMm = lsst.geom.Extent2D(0.02, 0.03)
108 plateScale = 25.0 # arcsec/mm
109 yaw = lsst.geom.Angle(20, lsst.geom.degrees)
110 # focal-plane position of ref position on detector (mm)
111 fpPosition = lsst.geom.Point2D(50, 25)
112 # ref position on detector (pos of lower left corner)
113 refPoint = lsst.geom.Point2D(-0.5, -0.5)
114 orientation = cameraGeom.Orientation(
115 fpPosition,
116 refPoint,
117 yaw,
118 )
119 pixelToFocalPlane = orientation.makePixelFpTransform(pixelSizeMm)
120 plateScaleRad = lsst.geom.Angle(
121 plateScale, lsst.geom.arcseconds).asRadians()
122 focalPlaneToField = afwGeom.makeRadialTransform(
123 (0.0, plateScaleRad, 0.0, 0.001 * plateScaleRad))
124 pixelToField = pixelToFocalPlane.then(focalPlaneToField)
126 pixelToTanPixel = makePixelToTanPixel(
127 bbox=bbox,
128 orientation=orientation,
129 focalPlaneToField=focalPlaneToField,
130 pixelSizeMm=pixelSizeMm,
131 )
133 # the center point of the field angle frame should not move
134 pixAtFieldCtr = pixelToField.applyInverse(lsst.geom.Point2D(0, 0))
135 tanPixAtFieldCr = pixelToTanPixel.applyForward(pixAtFieldCtr)
136 self.assertPairsAlmostEqual(pixAtFieldCtr, tanPixAtFieldCr)
138 # build same camera geometry transforms without optical distortion
139 focalPlaneToFieldNoDistortion = afwGeom.makeRadialTransform(
140 (0.0, plateScaleRad))
141 pixelToFieldNoDistortion = pixelToFocalPlane.then(focalPlaneToFieldNoDistortion)
143 for x in (100, 200, 1000):
144 for y in (100, 500, 800):
145 pixPos = lsst.geom.Point2D(x, y)
146 tanPixPos = pixelToTanPixel.applyForward(pixPos)
148 # for a given field angle (which, together with a pointing, gives a position on the sky):
149 # - field angle to pixels gives pixPos
150 # - undistorted field angle to pixels gives tanPixPos
151 fieldPos = pixelToField.applyForward(pixPos)
152 desTanPixPos = pixelToFieldNoDistortion.applyInverse(
153 fieldPos)
154 # use a degraded accuracy because small Jacobian errors accumulate this far from the center
155 self.assertPairsAlmostEqual(desTanPixPos, tanPixPos, maxDiff=1e-5)
157 def testFlatFocalPlane(self):
158 """Test an undistorted focal plane (with rectangular pixels)
159 """
160 bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0),
161 lsst.geom.Extent2I(1000, 1000))
162 pixelSizeMm = lsst.geom.Extent2D(0.02, 0.03)
163 plateScale = 25.0 # arcsec/mm
164 yaw = lsst.geom.Angle(20, lsst.geom.degrees)
165 # focal-plane position of ref position on detector (mm)
166 fpPosition = lsst.geom.Point2D(50, 25)
167 # ref position on detector (pos of lower left corner)
168 refPoint = lsst.geom.Point2D(-0.5, -0.5)
169 orientation = cameraGeom.Orientation(
170 fpPosition,
171 refPoint,
172 yaw,
173 )
174 plateScaleRad = lsst.geom.Angle(
175 plateScale, lsst.geom.arcseconds).asRadians()
176 focalPlaneToField = afwGeom.makeRadialTransform((0.0, plateScaleRad))
178 pixelToTanPixel = makePixelToTanPixel(
179 bbox=bbox,
180 orientation=orientation,
181 focalPlaneToField=focalPlaneToField,
182 pixelSizeMm=pixelSizeMm,
183 )
185 # with no distortion, this should be a unity transform
186 for pointPix in (
187 lsst.geom.Point2D(0, 0),
188 lsst.geom.Point2D(1000, 2000),
189 lsst.geom.Point2D(-100.5, 27.23),
190 ):
191 pointTanPix = pixelToTanPixel.applyForward(pointPix)
192 self.assertPairsAlmostEqual(pointTanPix, pointPix)
195class MemoryTester(lsst.utils.tests.MemoryTestCase):
196 pass
199def setup_module(module):
200 lsst.utils.tests.init()
203if __name__ == "__main__": 203 ↛ 204line 203 didn't jump to line 204, because the condition on line 203 was never true
204 lsst.utils.tests.init()
205 unittest.main()