Coverage for tests / test_cameras.py: 33%

49 statements  

« prev     ^ index     » next       coverage.py v7.14.0, created at 2026-05-20 08:26 +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. 

11 

12from __future__ import annotations 

13 

14import os 

15import unittest 

16 

17from lsst.images.cameras import AmplifierRawGeometry, Detector 

18from lsst.images.tests import DP2_VISIT_DETECTOR_DATA_ID, RoundtripFits, compare_detector_to_legacy 

19 

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 

28 

29DATA_DIR = os.environ.get("TESTDATA_IMAGES_DIR", None) 

30 

31 

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

36 

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() 

43 

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) 

58 

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) 

81 

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) 

105 

106 

107if __name__ == "__main__": 

108 unittest.main()