Coverage for tests/test_cameraGeom.py: 24%
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
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
1# This file is part of jointcal.
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/>.
22import os.path
24import lsst.utils
26from lsst.afw.geom import SkyWcs
27import lsst.afw.cameraGeom
28import lsst.jointcal.cameraGeometry
29import lsst.obs.hsc
32class TestCameraGeom(lsst.utils.tests.TestCase):
33 """Test jointcal's cameraGeom code on data from a jointcal HSC run.
34 """
35 def setUp(self):
36 path = os.path.join(os.path.dirname(__file__), "data/output/HSC-R/9615/")
37 # Two WCS from the same visit, which should produce near identical results.
38 # 49 is near the center of the focal plane
39 self.detector1 = 49
40 # 37 is on the west side of the focal plane
41 self.detector2 = 37
42 # 103 is on the NW edge of the focal plane and rotated 90 degrees
43 self.detector3 = 103
44 # 90 is on the NE corner of the focal plane
45 self.detector4 = 90
46 # a selection of WCSs to compare the calculations on
47 self.wcs1 = SkyWcs.readFits(os.path.join(path, f"jointcal_wcs-0028976-{self.detector1:03}.fits"))
48 self.wcs2 = SkyWcs.readFits(os.path.join(path, f"jointcal_wcs-0028976-{self.detector2:03}.fits"))
49 wcs3 = SkyWcs.readFits(os.path.join(path, f"jointcal_wcs-0023924-{self.detector3:03}.fits"))
50 wcs4 = SkyWcs.readFits(os.path.join(path, f"jointcal_wcs-0023900-{self.detector4:03}.fits"))
51 self.wcsList = [self.wcs1, self.wcs2, wcs3, wcs4]
52 self.detectors = [self.detector1, self.detector2, self.detector3, self.detector4]
54 cameraPath = os.path.join(lsst.utils.getPackageDir("obs_subaru"), "hsc/camera")
55 cameraConfig = lsst.afw.cameraGeom.CameraConfig()
56 cameraConfig.load(os.path.join(cameraPath, "camera.py"))
57 self.camera = lsst.afw.cameraGeom.makeCameraFromPath(cameraConfig, cameraPath, lambda x: x,
58 lsst.obs.hsc.HscPupilFactory)
59 self.maxFocalPlaneRadius = self.camera.computeMaxFocalPlaneRadius()
61 def testComputeDetectorPixelScale(self):
62 """Test CameraModel._computeDetectorPixelScale by comparing two
63 detectors from the same visit: they should have near identical pixel
64 scale variation.
65 """
66 # don't need the wcs or detector lists for this test
67 model = lsst.jointcal.cameraGeometry.CameraModel([], [], self.camera)
68 angle1, radial1, tangential1 = model._computeDetectorPixelScale(self.detector1,
69 self.wcs1)
70 angle2, radial2, tangential2 = model._computeDetectorPixelScale(self.detector2,
71 self.wcs2)
72 # The angles really should be identical: this value is independent of distortion.
73 self.assertFloatsEqual(angle1, angle2)
74 # These should be identical, but we allow for machine-precision errors
75 # due to possible complexity in the distortion model.
76 self.assertFloatsAlmostEqual(radial1, radial2)
77 self.assertFloatsAlmostEqual(tangential1, tangential2)
78 # Check that the HSC pixel scale is approximately correct at the boresight.
79 self.assertFloatsAlmostEqual(radial1[0], 0.168, rtol=1e-2)
80 self.assertFloatsAlmostEqual(tangential1[0], 0.168, rtol=1e-2)
82 def testComputeCameraPixelScale(self):
83 """Test CameraModel.computeCameraPixelScale by comparing two
84 detectors: they should have near identical pixel scale variation.
85 """
86 # don't need the wcs or detector lists for this test
87 model = lsst.jointcal.cameraGeometry.CameraModel([], [], self.camera)
88 angle1, radial1, tangential1 = model.computeCameraPixelScale(self.detector1)
89 angle2, radial2, tangential2 = model.computeCameraPixelScale(self.detector2)
90 # For the camera calculation, there can be machine-precision
91 # differences between different detectors, so "almost" here.
92 self.assertFloatsAlmostEqual(angle1, angle2)
93 self.assertFloatsAlmostEqual(radial1, radial2)
94 self.assertFloatsAlmostEqual(tangential1, tangential2)
95 # Check that the HSC pixel scale is approximately correct at the boresight.
96 self.assertFloatsAlmostEqual(radial1[0], 0.168, rtol=1e-3)
97 self.assertFloatsAlmostEqual(tangential1[0], 0.168, rtol=1e-3)
99 def testComputePixelScale(self):
100 """Test that the pixel scale calculation produces something sensible.
101 """
102 model = lsst.jointcal.cameraGeometry.CameraModel(self.wcsList, self.detectors, self.camera)
103 model.computePixelScale()
104 angle2, radial2, tangential2 = model._computeDetectorPixelScale(self.detector2,
105 self.wcs2)
106 # TOOD: If we ever go with a more careful approach to the mean
107 # fieldAngle question, this may have to change.
108 self.assertFloatsAlmostEqual(model.fieldAngle, angle2, rtol=1e-4)
110 # spot check the second array elements
111 self.assertFloatsEqual(model.fieldAngles[1], angle2)
112 self.assertFloatsEqual(model.radialScales[1], radial2)
113 self.assertFloatsEqual(model.tangentialScales[1], tangential2)