Coverage for tests/test_assemble.py: 31%

83 statements  

« prev     ^ index     » next       coverage.py v7.2.5, created at 2023-05-07 09:12 +0000

1# This file is part of obs_lsst. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (http://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 <http://www.gnu.org/licenses/>. 

21 

22import numpy 

23import os 

24import sys 

25import unittest 

26 

27import lsst.utils.tests 

28from lsst.utils import getPackageDir 

29from lsst.daf.butler import Butler 

30from lsst.afw.cameraGeom import Detector 

31from lsst.afw.image import ImageFitsReader 

32import lsst.obs.base.yamlCamera as yamlCamera 

33from lsst.ip.isr import AssembleCcdTask 

34 

35from lsst.obs.lsst.utils import readRawFile 

36 

37PACKAGE_DIR = getPackageDir("obs_lsst") 

38TESTDIR = os.path.dirname(__file__) 

39LATISS_DATA_ROOT = os.path.join(PACKAGE_DIR, 'data', 'input', 'latiss') 

40BOT_DATA_ROOT = os.path.join(TESTDIR, 'data', 'input') 

41E2V_DATA_ID = {'raft': 'R22', 'name_in_raft': 'S11', 'exposure': 3019103101985, 'instrument': 'LSSTCam'} 

42ITL_DATA_ID = {'raft': 'R02', 'name_in_raft': 'S02', 'exposure': 3019110102212, 'instrument': 'LSSTCam'} 

43TESTDATA_ROOT = os.path.join(TESTDIR, "data") 

44 

45 

46class RawAssemblyTestCase(lsst.utils.tests.TestCase): 

47 """Test assembly of each of data from each of the two 

48 manufacturers. Data come from BOT spot data runs. 

49 """ 

50 

51 def setUp(self): 

52 # E2V and ITL detecotrs and expected assembled images 

53 self.e2v = {'detector': Detector.readFits(os.path.join(TESTDATA_ROOT, 'e2v_detector.fits')), 

54 'expected': ImageFitsReader(os.path.join(TESTDATA_ROOT, 

55 'e2v_expected_assembled.fits.gz'))} 

56 self.itl = {'detector': Detector.readFits(os.path.join(TESTDATA_ROOT, 'itl_detector.fits')), 

57 'expected': ImageFitsReader(os.path.join(TESTDATA_ROOT, 

58 'itl_expected_assembled.fits.gz'))} 

59 self.roots = [BOT_DATA_ROOT, BOT_DATA_ROOT] 

60 self.ids = [E2V_DATA_ID, ITL_DATA_ID] 

61 self.expecteds = [self.e2v, self.itl] 

62 

63 def assertAmpRawBBoxesEqual(self, amp1, amp2): 

64 """Check that Raw bounding boxes match between amps. 

65 

66 Parameters 

67 ---------- 

68 amp1 : `~lsst.afw.cameraGeom.Amplifier` 

69 First amplifier. 

70 amp2 : `~lsst.afw.cameraGeom.Amplifier` 

71 Second amplifier. 

72 """ 

73 self.assertEqual(amp1.getRawBBox(), amp2.getRawBBox()) 

74 self.assertEqual(amp1.getRawHorizontalOverscanBBox(), amp2.getRawHorizontalOverscanBBox()) 

75 self.assertEqual(amp1.getRawVerticalOverscanBBox(), amp2.getRawVerticalOverscanBBox()) 

76 

77 def assertAmpRawBBoxesFlippablyEqual(self, amp1, amp2): 

78 """Check that amp1 can be self-consistently transformed to match amp2. 

79 

80 This method compares amplifier bounding boxes by confirming 

81 that they represent the same segment of the detector image. 

82 If the offsets or amplifier flips differ between the 

83 amplifiers, this method will pass even if the raw bounding 

84 boxes returned by the amplifier accessors are not equal. 

85 

86 Parameters 

87 ---------- 

88 amp1 : `~lsst.afw.cameraGeom.Amplifier` 

89 Amplifier to transform. 

90 amp2 : `~lsst.afw.cameraGeom.Amplifier` 

91 Reference amplifier. 

92 

93 """ 

94 xFlip = amp1.getRawFlipX() ^ amp2.getRawFlipX() 

95 yFlip = amp1.getRawFlipY() ^ amp2.getRawFlipY() 

96 XYOffset = amp1.getRawXYOffset() - amp2.getRawXYOffset() 

97 

98 testRawBox = amp1.getRawBBox() 

99 testHOSBox = amp1.getRawHorizontalOverscanBBox() 

100 testVOSBox = amp1.getRawVerticalOverscanBBox() 

101 

102 if xFlip: 

103 size = amp1.getRawBBox().getWidth() 

104 testRawBox.flipLR(size) 

105 testHOSBox.flipLR(size) 

106 testVOSBox.flipLR(size) 

107 if yFlip: 

108 size = amp1.getRawBBox().getHeight() 

109 testRawBox.flipTB(size) 

110 testHOSBox.flipTB(size) 

111 testVOSBox.flipTB(size) 

112 

113 testRawBox.shift(XYOffset) 

114 testHOSBox.shift(XYOffset) 

115 testVOSBox.shift(XYOffset) 

116 

117 self.assertEqual(testRawBox, amp2.getRawBBox()) 

118 self.assertEqual(testHOSBox, amp2.getRawHorizontalOverscanBBox()) 

119 self.assertEqual(testVOSBox, amp2.getRawVerticalOverscanBBox()) 

120 

121 def testDetectors(self): 

122 """Test that the detector returned by the butler is the same 

123 as the expected one. 

124 """ 

125 for root, did, expected in zip(self.roots, self.ids, self.expecteds): 

126 butler = Butler(root) 

127 raw = butler.get("raw", dataId=did, collections="LSSTCam/raw/all") 

128 for amp1, amp2 in zip(expected['detector'], raw.getDetector()): 

129 with self.subTest(amp=amp1.getName()): 

130 self.assertEqual(amp1.getName(), amp2.getName()) 

131 self.assertAmpRawBBoxesEqual(amp1, amp2) 

132 

133 def testAssemble(self): 

134 """Test the assembly of E2V and ITL sensors 

135 """ 

136 task = AssembleCcdTask() 

137 # exclude LATISS for this test since we don't have an expected output 

138 for root, did, expected in zip(self.roots, self.ids, self.expecteds): 

139 butler = Butler(root) 

140 raw = butler.get("raw", dataId=did, collections="LSSTCam/raw/all") 

141 assembled = task.assembleCcd(raw) 

142 count = numpy.sum(expected['expected'].read().array - assembled.getImage().array) 

143 self.assertEqual(count, 0) 

144 

145 

146class ReadRawFileTestCase(lsst.utils.tests.TestCase): 

147 def testReadRawLatissFile(self): 

148 fileName = os.path.join(LATISS_DATA_ROOT, "raw/2018-09-20/3018092000065-det000.fits") 

149 policy = os.path.join(PACKAGE_DIR, "policy", "latiss.yaml") 

150 camera = yamlCamera.makeCamera(policy) 

151 exposure = readRawFile(fileName, camera[0], dataId={"file": fileName}) 

152 self.assertIsInstance(exposure, lsst.afw.image.Exposure) 

153 md = exposure.getMetadata() 

154 self.assertIn("INSTRUME", md) 

155 

156 

157def setup_module(module): 

158 lsst.utils.tests.init() 

159 

160 

161if __name__ == "__main__": 161 ↛ 162line 161 didn't jump to line 162, because the condition on line 161 was never true

162 setup_module(sys.modules[__name__]) 

163 unittest.main()