Coverage for tests/test_makePixelToTanPixel.py: 21%

82 statements  

« prev     ^ index     » next       coverage.py v6.4.2, created at 2022-07-19 04:54 -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 

27 

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 

33 

34 

35class MakePixelToTanPixelTestCaseCase(lsst.utils.tests.TestCase): 

36 

37 def testSimpleCurvedFocalPlane(self): 

38 """Test a trivial curved focal plane with square pixels 

39 

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) 

64 

65 pixelToTanPixel = makePixelToTanPixel( 

66 bbox=bbox, 

67 orientation=orientation, 

68 focalPlaneToField=focalPlaneToField, 

69 pixelSizeMm=pixelSizeMm, 

70 ) 

71 

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]) 

78 

79 # build same camera geometry transforms without optical distortion 

80 focalPlaneToFieldNoDistortion = afwGeom.makeRadialTransform( 

81 (0.0, plateScaleRad)) 

82 pixelToFieldNoDistortion = pixelToFocalPlane.then(focalPlaneToFieldNoDistortion) 

83 

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 ) 

93 

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) 

101 

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) 

125 

126 pixelToTanPixel = makePixelToTanPixel( 

127 bbox=bbox, 

128 orientation=orientation, 

129 focalPlaneToField=focalPlaneToField, 

130 pixelSizeMm=pixelSizeMm, 

131 ) 

132 

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) 

137 

138 # build same camera geometry transforms without optical distortion 

139 focalPlaneToFieldNoDistortion = afwGeom.makeRadialTransform( 

140 (0.0, plateScaleRad)) 

141 pixelToFieldNoDistortion = pixelToFocalPlane.then(focalPlaneToFieldNoDistortion) 

142 

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) 

147 

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) 

156 

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)) 

177 

178 pixelToTanPixel = makePixelToTanPixel( 

179 bbox=bbox, 

180 orientation=orientation, 

181 focalPlaneToField=focalPlaneToField, 

182 pixelSizeMm=pixelSizeMm, 

183 ) 

184 

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) 

193 

194 

195class MemoryTester(lsst.utils.tests.MemoryTestCase): 

196 pass 

197 

198 

199def setup_module(module): 

200 lsst.utils.tests.init() 

201 

202 

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()