Coverage for tests/test_cameraGeom.py: 23%
48 statements
« prev ^ index » next coverage.py v6.5.0, created at 2022-10-27 03:05 -0700
« prev ^ index » next coverage.py v6.5.0, created at 2022-10-27 03:05 -0700
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
29from lsst.obs.subaru import HyperSuprimeCam
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 hsc = HyperSuprimeCam()
55 self.camera = hsc.getCamera()
56 self.maxFocalPlaneRadius = self.camera.computeMaxFocalPlaneRadius()
58 def testComputeDetectorPixelScale(self):
59 """Test CameraModel._computeDetectorPixelScale by comparing two
60 detectors from the same visit: they should have near identical pixel
61 scale variation.
62 """
63 # don't need the wcs or detector lists for this test
64 model = lsst.jointcal.cameraGeometry.CameraModel([], [], self.camera)
65 angle1, radial1, tangential1 = model._computeDetectorPixelScale(self.detector1,
66 self.wcs1)
67 angle2, radial2, tangential2 = model._computeDetectorPixelScale(self.detector2,
68 self.wcs2)
69 # The angles really should be identical: this value is independent of distortion.
70 self.assertFloatsEqual(angle1, angle2)
71 # These should be identical, but we allow for machine-precision errors
72 # due to possible complexity in the distortion model.
73 self.assertFloatsAlmostEqual(radial1, radial2)
74 self.assertFloatsAlmostEqual(tangential1, tangential2)
75 # Check that the HSC pixel scale is approximately correct at the boresight.
76 self.assertFloatsAlmostEqual(radial1[0], 0.168, rtol=1e-2)
77 self.assertFloatsAlmostEqual(tangential1[0], 0.168, rtol=1e-2)
79 def testComputeCameraPixelScale(self):
80 """Test CameraModel.computeCameraPixelScale by comparing two
81 detectors: they should have near identical pixel scale variation.
82 """
83 # don't need the wcs or detector lists for this test
84 model = lsst.jointcal.cameraGeometry.CameraModel([], [], self.camera)
85 angle1, radial1, tangential1 = model.computeCameraPixelScale(self.detector1)
86 angle2, radial2, tangential2 = model.computeCameraPixelScale(self.detector2)
87 # For the camera calculation, there can be machine-precision
88 # differences between different detectors, so "almost" here.
89 self.assertFloatsAlmostEqual(angle1, angle2)
90 self.assertFloatsAlmostEqual(radial1, radial2)
91 self.assertFloatsAlmostEqual(tangential1, tangential2)
92 # Check that the HSC pixel scale is approximately correct at the boresight.
93 self.assertFloatsAlmostEqual(radial1[0], 0.168, rtol=1e-3)
94 self.assertFloatsAlmostEqual(tangential1[0], 0.168, rtol=1e-3)
96 def testComputePixelScale(self):
97 """Test that the pixel scale calculation produces something sensible.
98 """
99 model = lsst.jointcal.cameraGeometry.CameraModel(self.wcsList, self.detectors, self.camera)
100 model.computePixelScale()
101 angle2, radial2, tangential2 = model._computeDetectorPixelScale(self.detector2,
102 self.wcs2)
103 # TOOD: If we ever go with a more careful approach to the mean
104 # fieldAngle question, this may have to change.
105 self.assertFloatsAlmostEqual(model.fieldAngle, angle2, rtol=1e-4)
107 # spot check the second array elements
108 self.assertFloatsEqual(model.fieldAngles[1], angle2)
109 self.assertFloatsEqual(model.radialScales[1], radial2)
110 self.assertFloatsEqual(model.tangentialScales[1], tangential2)