Coverage for python/lsst/obs/base/camera_tests.py: 26%

Shortcuts on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

39 statements  

1# This file is part of obs_base. 

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/>. 

21 

22import abc 

23import collections 

24import math 

25 

26import lsst.geom 

27from lsst.afw.cameraGeom import FOCAL_PLANE, FIELD_ANGLE 

28 

29__all__ = ["CameraTests"] 

30 

31 

32class CameraTests(metaclass=abc.ABCMeta): 

33 """Tests that the butler returns a useable Camera. 

34 

35 In the subclasses's setUp(): 

36 * Call setUp_camera() to fill in required parameters. 

37 """ 

38 

39 def setUp_camera(self, 

40 camera_name=None, 

41 n_detectors=None, 

42 first_detector_name=None, 

43 plate_scale=None, 

44 ): 

45 """Set up the necessary variables for camera tests. 

46 

47 Parameters 

48 ---------- 

49 

50 camera_name : `str` 

51 name of this camera 

52 n_detectors : `int` 

53 number of detectors in this camera 

54 first_detector_name : `str` 

55 name of the first detector in this camera 

56 plate_scale : `lsst.geom.Angle` 

57 plate scale at center of focal plane, as angle-on-sky/mm 

58 """ 

59 fields = ['camera_name', 

60 'n_detectors', 

61 'first_detector_name', 

62 'plate_scale', 

63 ] 

64 CameraData = collections.namedtuple("CameraData", fields) 

65 self.camera_data = CameraData(camera_name=camera_name, 

66 n_detectors=n_detectors, 

67 first_detector_name=first_detector_name, 

68 plate_scale=plate_scale, 

69 ) 

70 

71 def test_iterable(self): 

72 """Simplest camera test: can we get a Camera instance, and does 

73 iterating return Detectors?""" 

74 camera = self.butler.get('camera', immediate=True) 

75 self.assertIsInstance(camera, lsst.afw.cameraGeom.Camera) 

76 for detector in camera: 

77 msg = "Failed for detector={}".format(detector) 

78 self.assertIsInstance(detector, lsst.afw.cameraGeom.Detector, msg=msg) 

79 

80 def test_camera_butler(self): 

81 """Check that the butler returns the right type of camera.""" 

82 camera = self.butler.get('camera', immediate=True) 

83 self.assertEqual(camera.getName(), self.camera_data.camera_name) 

84 self.assertEqual(len(camera), self.camera_data.n_detectors) 

85 self.assertEqual(next(iter(camera)).getName(), self.camera_data.first_detector_name) 

86 

87 def test_plate_scale(self): 

88 """Check the plate scale at center of focal plane 

89 

90 Check plate_scale using the FOCAL_PLANE to FIELD_ANGLE transform 

91 from the camera. 

92 """ 

93 plate_scale = self.camera_data.plate_scale 

94 self.assertIsNotNone(plate_scale) 

95 camera = self.butler.get('camera', immediate=True) 

96 focalPlaneToFieldAngle = camera.getTransformMap().getTransform(FOCAL_PLANE, FIELD_ANGLE) 

97 focalPlaneRadiusMm = 0.001 # an offset small enough to be in the linear regime 

98 for offsetAngleRad in (0.0, 0.65, 1.3): # direction of offset; a few arbitrary angles 

99 cosAng = math.cos(offsetAngleRad) 

100 sinAng = math.sin(offsetAngleRad) 

101 fieldAngleRadians = focalPlaneToFieldAngle.applyForward( 

102 lsst.geom.Point2D(cosAng * focalPlaneRadiusMm, sinAng * focalPlaneRadiusMm)) 

103 fieldAngleRadius = math.hypot(*fieldAngleRadians) * lsst.geom.radians 

104 measuredScale1 = fieldAngleRadius / focalPlaneRadiusMm 

105 self.assertAnglesAlmostEqual(measuredScale1, plate_scale) 

106 

107 focalPlanePos = focalPlaneToFieldAngle.applyInverse( 

108 lsst.geom.Point2D(fieldAngleRadius.asRadians() * cosAng, 

109 fieldAngleRadius.asRadians() * sinAng)) 

110 focalPlaneRadiusMm2 = math.hypot(*focalPlanePos) 

111 measureScale2 = fieldAngleRadius / focalPlaneRadiusMm2 

112 self.assertAnglesAlmostEqual(measureScale2, plate_scale)