Coverage for tests/test_ingest.py: 61%

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

90 statements  

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 

22"""Unit tests for LSST raw data ingest. 

23""" 

24 

25import unittest 

26import os 

27import lsst.utils.tests 

28 

29from lsst.afw.math import flipImage 

30from lsst.afw.cameraGeom import AmplifierGeometryComparison 

31from lsst.daf.butler import Butler 

32from lsst.daf.butler.cli.butler import cli as butlerCli 

33from lsst.daf.butler.cli.utils import LogCliRunner 

34from lsst.obs.base.ingest_tests import IngestTestBase 

35from lsst.ip.isr import PhotodiodeCalib 

36import lsst.afw.cameraGeom.testUtils # for injected test asserts 

37import lsst.obs.lsst 

38 

39TESTDIR = os.path.abspath(os.path.dirname(__file__)) 

40DATAROOT = os.path.join(TESTDIR, os.path.pardir, "data", "input") 

41 

42 

43class LatissIngestTestCase(IngestTestBase, lsst.utils.tests.TestCase): 

44 

45 curatedCalibrationDatasetTypes = ("camera", "defects") 

46 instrumentClassName = "lsst.obs.lsst.Latiss" 

47 ingestDir = TESTDIR 

48 file = os.path.join(DATAROOT, "latiss", "raw", "2018-09-20", "3018092000065-det000.fits") 

49 dataIds = [dict(instrument="LATISS", exposure=3018092000065, detector=0)] 

50 filterLabel = lsst.afw.image.FilterLabel(band="unknown", physical="unknown~unknown") 

51 

52 def checkRepo(self, files=None): 

53 # Test amp parameter implementation for the LSST raw formatter. This 

54 # is the same for all instruments, so repeating it in other test cases 

55 # is wasteful. 

56 butler = Butler(self.root, run=self.outputRun) 

57 ref = butler.registry.findDataset("raw", self.dataIds[0]) 

58 full_assembled = butler.getDirect(ref) 

59 unassembled_detector = self.instrumentClass().getCamera()[ref.dataId["detector"]] 

60 assembled_detector = full_assembled.getDetector() 

61 for unassembled_amp, assembled_amp in zip(unassembled_detector, assembled_detector): 

62 # Check that we're testing what we think we're testing: these 

63 # amps should differ in assembly state (offsets, flips), and they 

64 # _may_ differ in fundamental geometry if we had to patch the 

65 # overscan region sizes. 

66 comparison = unassembled_amp.compareGeometry(assembled_amp) 

67 self.assertTrue(comparison & AmplifierGeometryComparison.ASSEMBLY_DIFFERS) 

68 assembled_subimage = butler.getDirect(ref, parameters={"amp": assembled_amp}) 

69 unassembled_subimage = butler.getDirect(ref, parameters={"amp": unassembled_amp.getName()}) 

70 self.assertEqual(len(assembled_subimage.getDetector()), 1) 

71 self.assertEqual(len(unassembled_subimage.getDetector()), 1) 

72 self.assertEqual(len(assembled_subimage.getDetector()), 1) 

73 self.assertEqual(len(unassembled_subimage.getDetector()), 1) 

74 self.assertImagesEqual(assembled_subimage.image, full_assembled.image[assembled_amp.getRawBBox()]) 

75 self.assertImagesEqual( 

76 unassembled_subimage.image, 

77 flipImage( 

78 full_assembled.image[assembled_amp.getRawBBox()], 

79 flipLR=unassembled_amp.getRawFlipX(), 

80 flipTB=unassembled_amp.getRawFlipY(), 

81 ), 

82 ) 

83 self.assertAmplifiersEqual(assembled_subimage.getDetector()[0], assembled_amp) 

84 if comparison & comparison.REGIONS_DIFFER: 

85 # We needed to patch overscans, but unassembled_amp (which 

86 # comes straight from the camera) won't have those patches, so 

87 # we can't compare it to the amp attached to 

88 # unassembled_subimage (which does have those patches). 

89 comparison2 = unassembled_subimage.getDetector()[0].compareGeometry(unassembled_amp) 

90 

91 self.assertTrue(comparison2 & AmplifierGeometryComparison.REGIONS_DIFFER) 

92 # ...and that unassembled_subimage's amp has the same regions 

93 # (after accounting for assembly/orientation) as assembled_amp. 

94 comparison3 = unassembled_subimage.getDetector()[0].compareGeometry(assembled_amp) 

95 self.assertTrue(comparison3 & AmplifierGeometryComparison.ASSEMBLY_DIFFERS) 

96 self.assertFalse(comparison3 & AmplifierGeometryComparison.REGIONS_DIFFER) 

97 else: 

98 self.assertAmplifiersEqual(unassembled_subimage.getDetector()[0], unassembled_amp) 

99 

100 

101class Ts3IngestTestCase(IngestTestBase, lsst.utils.tests.TestCase): 

102 

103 curatedCalibrationDatasetTypes = ("camera",) 

104 instrumentClassName = "lsst.obs.lsst.LsstTS3" 

105 ingestDir = TESTDIR 

106 file = os.path.join(DATAROOT, "ts3", "raw", "2018-11-15", "201811151255111-R433-S00-det433.fits") 

107 dataIds = [dict(instrument="LSST-TS3", exposure=201811151255111, detector=433)] 

108 filterLabel = lsst.afw.image.FilterLabel(physical="550CutOn") 

109 

110 

111class ComCamIngestTestCase(IngestTestBase, lsst.utils.tests.TestCase): 

112 

113 curatedCalibrationDatasetTypes = ("camera",) 

114 instrumentClassName = "lsst.obs.lsst.LsstComCam" 

115 ingestDir = TESTDIR 

116 file = os.path.join(DATAROOT, "comCam", "raw", "2019-05-30", 

117 "3019053000001", "3019053000001-R22-S00-det000.fits") 

118 dataIds = [dict(instrument="LSSTComCam", exposure=3019053000001, detector=0)] 

119 filterLabel = lsst.afw.image.FilterLabel(physical="unknown", band="unknown") 

120 

121 

122class LSSTCamIngestTestCase(IngestTestBase, lsst.utils.tests.TestCase): 

123 

124 curatedCalibrationDatasetTypes = ("camera",) 

125 instrumentClassName = "lsst.obs.lsst.LsstCam" 

126 ingestDir = TESTDIR 

127 file = os.path.join(DATAROOT, "lsstCam", "raw", "2019-03-19", 

128 "3019031900001", "3019031900001-R10-S02-det029.fits") 

129 dataIds = [dict(instrument="LSSTCam", exposure=3019031900001, detector=29)] 

130 filterLabel = lsst.afw.image.FilterLabel(physical="unknown", band="unknown") 

131 

132 

133class LSSTCamPhotodiodeIngestTestCase(IngestTestBase, lsst.utils.tests.TestCase): 

134 

135 curatedCalibrationDatasetTypes = ("camera",) 

136 instrumentClassName = "lsst.obs.lsst.LsstCam" 

137 ingestDir = TESTDIR 

138 file = os.path.join(DATAROOT, "lsstCam", "raw", "2021-12-12", 

139 "30211212000310", "30211212000310-R22-S22-det098.fits") 

140 dataIds = [dict(instrument="LSSTCam", exposure=3021121200310, detector=98)] 

141 filterLabel = lsst.afw.image.FilterLabel(physical="SDSSi", band="i") 

142 pdPath = os.path.join(DATAROOT, "lsstCam", "raw") 

143 

144 def testPhotodiode(self, pdPath=None): 

145 if pdPath is None: 

146 pdPath = self.pdPath 

147 runner = LogCliRunner() 

148 result = runner.invoke( 

149 butlerCli, 

150 [ 

151 "ingest-photodiode", 

152 self.root, 

153 self.instrumentClassName, 

154 pdPath, 

155 ], 

156 ) 

157 self.assertEqual(result.exit_code, 0, f"output: {result.output} exception: {result.exception}") 

158 

159 butler = Butler(self.root, run="LSSTCam/calib/photodiode") 

160 getResult = butler.get('photodiode', dataId=self.dataIds[0]) 

161 self.assertIsInstance(getResult, PhotodiodeCalib) 

162 

163 

164def setup_module(module): 

165 lsst.utils.tests.init() 

166 

167 

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

169 lsst.utils.tests.init() 

170 unittest.main()