Coverage for tests / test_cameras.py: 33%
49 statements
« prev ^ index » next coverage.py v7.14.0, created at 2026-05-21 08:52 +0000
« prev ^ index » next coverage.py v7.14.0, created at 2026-05-21 08:52 +0000
1# This file is part of lsst-images.
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# Use of this source code is governed by a 3-clause BSD-style
10# license that can be found in the LICENSE file.
12from __future__ import annotations
14import os
15import unittest
17from lsst.images.cameras import AmplifierRawGeometry, Detector
18from lsst.images.tests import DP2_VISIT_DETECTOR_DATA_ID, RoundtripFits, compare_detector_to_legacy
20try:
21 from lsst.afw.cameraGeom import Camera as LegacyCamera
22 from lsst.afw.cameraGeom import DetectorType as LegacyDetectorType
23 from lsst.afw.image import ExposureFitsReader
24except ImportError: # pragma: no cover
25 HAVE_AFW = False
26else: # pragma: no cover
27 HAVE_AFW = True
29DATA_DIR = os.environ.get("TESTDATA_IMAGES_DIR", None)
32@unittest.skipUnless(DATA_DIR is not None, "TESTDATA_IMAGES_DIR is not in the environment.")
33@unittest.skipUnless(HAVE_AFW, "lsst.afw could not be imported.")
34class CamerasTestCase(unittest.TestCase):
35 """Tests for the 'cameras' module."""
37 @classmethod
38 def setUpClass(cls):
39 cls.legacy_camera = LegacyCamera.readFits(os.path.join(DATA_DIR, "dp2", "legacy", "camera.fits"))
40 cls.legacy_detector = ExposureFitsReader(
41 os.path.join(DATA_DIR, "dp2", "legacy", "visit_image.fits")
42 ).readDetector()
44 def test_visit_image_detector_legacy_conversions(self) -> None:
45 """Test converting a detector attached to a visit image from its
46 legacy type and back, with serialization in between.
47 """
48 detector = Detector.from_legacy(
49 self.legacy_detector,
50 instrument=DP2_VISIT_DETECTOR_DATA_ID["instrument"],
51 visit=DP2_VISIT_DETECTOR_DATA_ID["visit"],
52 )
53 compare_detector_to_legacy(self, detector, self.legacy_detector, is_raw_assembled=True)
54 with RoundtripFits(self, detector) as roundtrip:
55 pass
56 compare_detector_to_legacy(self, roundtrip.result, self.legacy_detector, is_raw_assembled=True)
57 compare_detector_to_legacy(self, detector, roundtrip.result.to_legacy(), is_raw_assembled=True)
59 def test_camera_detector_legacy_conversions(self) -> None:
60 """Test converting a detector extracted from a camera from its
61 legacy type and back, with serialization in between.
62 """
63 # Test one detector of each type for a reasonable balance of
64 # completeness and test speed.
65 detector_types_seen: set[LegacyDetectorType] = set()
66 for legacy_detector_1 in self.legacy_camera:
67 if legacy_detector_1.getType() in detector_types_seen:
68 continue
69 detector_types_seen.add(legacy_detector_1.getType())
70 with self.subTest(detector_id=legacy_detector_1.getId()):
71 detector = Detector.from_legacy(
72 legacy_detector_1,
73 instrument=DP2_VISIT_DETECTOR_DATA_ID["instrument"],
74 )
75 compare_detector_to_legacy(self, detector, legacy_detector_1, is_raw_assembled=False)
76 with RoundtripFits(self, detector) as roundtrip:
77 pass
78 compare_detector_to_legacy(self, roundtrip.result, legacy_detector_1, is_raw_assembled=False)
79 legacy_detector_2 = roundtrip.result.to_legacy()
80 compare_detector_to_legacy(self, detector, legacy_detector_2, is_raw_assembled=False)
82 def test_expanded_detector_roundtrip(self) -> None:
83 """Test roudntripping a detector that holds both assembled and
84 unassembled raw amplifier geometry.
85 """
86 legacy_camera_detector = self.legacy_camera[DP2_VISIT_DETECTOR_DATA_ID["detector"]]
87 detector = Detector.from_legacy(
88 legacy_camera_detector,
89 instrument=DP2_VISIT_DETECTOR_DATA_ID["instrument"],
90 visit=DP2_VISIT_DETECTOR_DATA_ID["visit"],
91 is_raw_assembled=False,
92 )
93 for amplifier, legacy_assembled_amplifier in zip(
94 detector.amplifiers, self.legacy_detector.getAmplifiers(), strict=True
95 ):
96 assert amplifier.unassembled_raw_geometry is not None
97 assert amplifier.assembled_raw_geometry is None
98 amplifier.assembled_raw_geometry = AmplifierRawGeometry.from_legacy_amplifier(
99 legacy_assembled_amplifier
100 )
101 with RoundtripFits(self, detector) as roundtrip:
102 pass
103 compare_detector_to_legacy(self, roundtrip.result, legacy_camera_detector, is_raw_assembled=False)
104 compare_detector_to_legacy(self, roundtrip.result, self.legacy_detector, is_raw_assembled=True)
107if __name__ == "__main__":
108 unittest.main()