Coverage for tests/test_detector.py: 12%

150 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2022-10-28 03:10 -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 

26 

27import numpy as np 

28 

29import lsst.utils.tests 

30import lsst.pex.exceptions 

31import lsst.geom 

32import lsst.afw.geom 

33import lsst.afw.cameraGeom as cameraGeom 

34from lsst.afw.cameraGeom.testUtils import DetectorWrapper 

35 

36 

37class DetectorTestCase(lsst.utils.tests.TestCase): 

38 

39 def testBasics(self): 

40 """Test getters and other basics 

41 """ 

42 dw = DetectorWrapper() 

43 detector = dw.detector 

44 for methodName in ("begin", "end", "size"): 

45 if hasattr(detector, methodName): 

46 self.assertFalse(hasattr(detector, methodName)) 

47 self.assertEqual(dw.name, detector.getName()) 

48 self.assertEqual(dw.id, detector.getId()) 

49 self.assertEqual(dw.type, detector.getType()) 

50 self.assertEqual(dw.serial, detector.getSerial()) 

51 bbox = detector.getBBox() 

52 for i in range(2): 

53 self.assertEqual(bbox.getMin()[i], dw.bbox.getMin()[i]) 

54 self.assertEqual(bbox.getMax()[i], dw.bbox.getMax()[i]) 

55 self.assertAlmostEqual(dw.pixelSize, detector.getPixelSize()) 

56 self.assertEqual(len(detector), len(dw.ampList)) 

57 

58 orientation = detector.getOrientation() 

59 

60 transformMap = detector.getTransformMap() 

61 # add 1 for null transform 

62 self.assertEqual(len(transformMap), len(dw.transMap) + 1) 

63 for cameraSys in dw.transMap: 

64 self.assertTrue(cameraSys in transformMap) 

65 

66 self.assertEqual(detector.getPhysicalType(), "CCD") # the default in DetectorWrapper, not Detector 

67 

68 # make sure some complex objects stick around after detector is deleted 

69 

70 detectorName = detector.getName() 

71 nativeCoordSys = detector.getNativeCoordSys() 

72 offset = dw.orientation.getFpPosition() 

73 del detector 

74 del dw 

75 self.assertEqual(orientation.getFpPosition(), offset) 

76 self.assertEqual(nativeCoordSys, 

77 cameraGeom.CameraSys(cameraGeom.PIXELS.getSysName(), detectorName)) 

78 

79 def testConstructorErrors(self): 

80 """Test constructor errors 

81 """ 

82 def duplicateAmpName(dw): 

83 """Set two amplifiers to the same name""" 

84 builder = dw.ampList[1] 

85 builder.setName(dw.ampList[0].getName()) 

86 dw.ampList[1] = builder 

87 with self.assertRaises(lsst.pex.exceptions.Exception): 

88 DetectorWrapper(modFunc=duplicateAmpName) 

89 

90 # These break in the pybind layer 

91 for crosstalk in ([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], # 1D and not numpy 

92 np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]), # 1D, wrong numpy type 

93 np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], dtype=np.float32), # 1D 

94 ): 

95 self.assertRaises(TypeError, DetectorWrapper, crosstalk=crosstalk) 

96 # These break in the Detector ctor: wrong shape 

97 self.assertRaises(lsst.pex.exceptions.InvalidParameterError, 

98 DetectorWrapper, crosstalk=np.array([[1.0, 2.0], [3.0, 4.0]])) 

99 self.assertRaises(lsst.pex.exceptions.InvalidParameterError, 

100 DetectorWrapper, crosstalk=np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])) 

101 

102 def testTransform(self): 

103 """Test the transform method 

104 """ 

105 dw = DetectorWrapper() 

106 pixOffset = dw.orientation.getReferencePoint() 

107 for xyMM in ((25.6, -31.07), (0, 0), (-1.234e5, 3.123e4)): 

108 fpPoint = lsst.geom.Point2D(*xyMM) 

109 pixPoint = dw.detector.transform(fpPoint, cameraGeom.FOCAL_PLANE, cameraGeom.PIXELS) 

110 for i in range(2): 

111 self.assertAlmostEqual( 

112 fpPoint[i]/dw.pixelSize[i] + pixOffset[i], pixPoint[i]) 

113 fpPoint2 = dw.detector.transform(pixPoint, cameraGeom.PIXELS, cameraGeom.FOCAL_PLANE) 

114 self.assertPairsAlmostEqual(fpPoint, fpPoint2) 

115 

116 # test pix to pix 

117 pixPoint2 = dw.detector.transform(pixPoint, cameraGeom.PIXELS, cameraGeom.PIXELS) 

118 self.assertPairsAlmostEqual(pixPoint, pixPoint2) 

119 

120 def testIteration(self): 

121 """Test iteration over amplifiers and __getitem__ 

122 """ 

123 dw = DetectorWrapper() 

124 ampList = [amp for amp in dw.detector] 

125 self.assertEqual(len(ampList), len(dw.ampList)) 

126 for i, amp in enumerate(ampList): 

127 self.assertEqual(amp.getName(), dw.detector[i].getName()) 

128 self.assertEqual(amp.getName(), dw.ampList[i].getName()) 

129 self.assertEqual( 

130 amp.getName(), dw.detector[amp.getName()].getName()) 

131 

132 def testTransformAccess(self): 

133 """Test hasTransform and getTransform 

134 """ 

135 detector = DetectorWrapper().detector 

136 for fromSys in (cameraGeom.FOCAL_PLANE, cameraGeom.PIXELS, cameraGeom.TAN_PIXELS): 

137 fullFromSys = detector.makeCameraSys(fromSys) 

138 for toSys in (cameraGeom.FOCAL_PLANE, cameraGeom.PIXELS, cameraGeom.TAN_PIXELS): 

139 fullToSys = detector.makeCameraSys(toSys) 

140 self.assertTrue(detector.hasTransform(fromSys)) 

141 self.assertTrue(detector.hasTransform(fullFromSys)) 

142 self.assertTrue(detector.hasTransform(toSys)) 

143 self.assertTrue(detector.hasTransform(fullToSys)) 

144 detector.getTransform(fromSys, toSys) 

145 detector.getTransform(fromSys, fullToSys) 

146 detector.getTransform(fullFromSys, toSys) 

147 detector.getTransform(fullFromSys, fullToSys) 

148 

149 for badCamSys in ( 

150 cameraGeom.CameraSys("badName"), 

151 cameraGeom.CameraSys("pixels", "badDetectorName") 

152 ): 

153 self.assertFalse(detector.hasTransform(badCamSys)) 

154 self.assertTrue(detector.hasTransform(cameraGeom.PIXELS)) 

155 with self.assertRaises(lsst.pex.exceptions.Exception): 

156 detector.getTransform(cameraGeom.PIXELS, badCamSys) 

157 

158 def testMakeCameraSys(self): 

159 """Test the makeCameraSys method 

160 """ 

161 dw = DetectorWrapper() 

162 for sysName in ("csys1", "csys2"): 

163 for detectorName in ("", dw.name, "a different detector"): 

164 inCamSys = cameraGeom.CameraSys(sysName, detectorName) 

165 outCamSys = dw.detector.makeCameraSys(inCamSys) 

166 self.assertEqual(inCamSys, outCamSys) 

167 

168 inCamSysPrefix = cameraGeom.CameraSysPrefix(sysName) 

169 outCamSys2 = dw.detector.makeCameraSys(inCamSysPrefix) 

170 self.assertEqual( 

171 outCamSys2, cameraGeom.CameraSys(sysName, dw.name)) 

172 

173 def testGetCorners(self): 

174 """Test the getCorners method 

175 """ 

176 dw = DetectorWrapper() 

177 for cameraSys in (cameraGeom.FOCAL_PLANE, cameraGeom.PIXELS): 

178 # positions of corners in specified camera system 

179 cornerList = dw.detector.getCorners(cameraSys) 

180 for posPixels, posCameraSys in zip(lsst.geom.Box2D(dw.bbox).getCorners(), cornerList): 

181 pixelsToCameraSys = dw.detector.getTransform(cameraGeom.PIXELS, cameraSys) 

182 predPosCameraSys = pixelsToCameraSys.applyForward(posPixels) 

183 self.assertPairsAlmostEqual(predPosCameraSys, posCameraSys) 

184 if cameraSys == cameraGeom.PIXELS: 

185 self.assertPairsAlmostEqual(posPixels, predPosCameraSys) 

186 

187 def testGetCenter(self): 

188 """Test the getCenter method 

189 """ 

190 dw = DetectorWrapper() 

191 ctrPixPoint = lsst.geom.Box2D(dw.detector.getBBox()).getCenter() 

192 for cameraSys in (cameraGeom.FOCAL_PLANE, cameraGeom.PIXELS): 

193 ctrPoint = dw.detector.getCenter(cameraSys) 

194 transform = dw.detector.getTransform(cameraGeom.PIXELS, cameraSys) 

195 predCtrPoint = transform.applyForward(ctrPixPoint) 

196 self.assertPairsAlmostEqual(predCtrPoint, ctrPoint) 

197 

198 def testDetectorRebuild(self): 

199 """Test Detector.rebuild() method 

200 """ 

201 # 

202 # Make a copy without any modifications 

203 # 

204 detector = DetectorWrapper().detector 

205 ndetector = detector.rebuild().finish() 

206 

207 self.assertEqual(detector.getName(), ndetector.getName()) 

208 self.assertEqual(detector.getBBox(), ndetector.getBBox()) 

209 self.assertEqual(detector.getPhysicalType(), ndetector.getPhysicalType()) 

210 for amp, namp in zip(detector, ndetector): 

211 self.assertEqual(amp.getBBox(), namp.getBBox()) 

212 self.assertEqual(amp.getRawXYOffset(), namp.getRawXYOffset()) 

213 # 

214 # Now make a copy with a hacked-up set of amps 

215 # 

216 builder = detector.rebuild() 

217 for i, amp in enumerate(builder, 1): 

218 amp.setRawXYOffset(i*lsst.geom.ExtentI(1, 1)) 

219 

220 ndetector = builder.finish() 

221 

222 self.assertEqual(detector.getName(), ndetector.getName()) 

223 self.assertEqual(detector.getBBox(), ndetector.getBBox()) 

224 for i, (amp, namp) in enumerate(zip(detector, ndetector), 1): 

225 self.assertEqual(amp.getBBox(), namp.getBBox()) 

226 self.assertNotEqual(amp.getRawXYOffset(), namp.getRawXYOffset()) 

227 self.assertEqual(namp.getRawXYOffset()[0], i) 

228 

229 def testPersistence(self): 

230 """Test round-tripping a Detector through FITS I/O. 

231 """ 

232 dw = DetectorWrapper() 

233 detectorIn = dw.detector 

234 with lsst.utils.tests.getTempFilePath("*.fits") as filename: 

235 detectorIn.writeFits(filename) 

236 detectorOut = cameraGeom.Detector.readFits(filename) 

237 self.assertDetectorsEqual(detectorIn, detectorOut) 

238 

239 

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

241 pass 

242 

243 

244def setup_module(module): 

245 lsst.utils.tests.init() 

246 

247 

248if __name__ == "__main__": 248 ↛ 249line 248 didn't jump to line 249, because the condition on line 248 was never true

249 lsst.utils.tests.init() 

250 unittest.main()