Coverage for tests/test_pipelineLoadSubset.py: 22%

57 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-11-18 10:50 +0000

1# This file is part of pipe_base. 

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 software is dual licensed under the GNU General Public License and also 

10# under a 3-clause BSD license. Recipients may choose which of these licenses 

11# to use; please see the files gpl-3.0.txt and/or bsd_license.txt, 

12# respectively. If you choose the GPL option then the following text applies 

13# (but note that there is still no warranty even if you opt for BSD instead): 

14# 

15# This program is free software: you can redistribute it and/or modify 

16# it under the terms of the GNU General Public License as published by 

17# the Free Software Foundation, either version 3 of the License, or 

18# (at your option) any later version. 

19# 

20# This program is distributed in the hope that it will be useful, 

21# but WITHOUT ANY WARRANTY; without even the implied warranty of 

22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

23# GNU General Public License for more details. 

24# 

25# You should have received a copy of the GNU General Public License 

26# along with this program. If not, see <http://www.gnu.org/licenses/>. 

27 

28import os 

29import unittest 

30from tempfile import NamedTemporaryFile 

31from textwrap import dedent 

32 

33import lsst.pipe.base as pipeBase 

34 

35 

36class PipelineLoadSubsetTest(unittest.TestCase): 

37 """Tests for loading subsets of pipelines from YAML files.""" 

38 

39 def setUp(self): 

40 frozen_pipeline = dedent( 

41 """ 

42 description: Frozen Pipeline 

43 tasks: 

44 isr: 

45 class: lsst.pipe.base.tests.mocks.DynamicTestPipelineTask 

46 config: 

47 python: | 

48 from lsst.pipe.base.tests.mocks import DynamicConnectionConfig 

49 config.dimensions = ['exposure', 'detector'] 

50 config.inputs['input_image'] = DynamicConnectionConfig( 

51 dataset_type_name='raw', 

52 dimensions={'exposure', 'detector'}, 

53 ) 

54 config.outputs['output_image'] = DynamicConnectionConfig( 

55 dataset_type_name='detrended', 

56 dimensions={'exposure', 'detector'}, 

57 ) 

58 calibrate: 

59 class: lsst.pipe.base.tests.mocks.DynamicTestPipelineTask 

60 config: 

61 python: | 

62 from lsst.pipe.base.tests.mocks import DynamicConnectionConfig 

63 config.dimensions = ['visit', 'detector'] 

64 config.inputs['input_image'] = DynamicConnectionConfig( 

65 dataset_type_name='detrended', 

66 dimensions={'exposure', 'detector'}, 

67 ) 

68 config.outputs['output_image'] = DynamicConnectionConfig( 

69 dataset_type_name='pvi', 

70 dimensions={'visit', 'detector'}, 

71 ) 

72 makeWarp: 

73 class: lsst.pipe.base.tests.mocks.DynamicTestPipelineTask 

74 config: 

75 python: | 

76 from lsst.pipe.base.tests.mocks import DynamicConnectionConfig 

77 config.dimensions = ['patch', 'visit'] 

78 config.inputs['input_image'] = DynamicConnectionConfig( 

79 dataset_type_name='pvi', 

80 dimensions={'visit', 'detector'}, 

81 ) 

82 config.outputs['output_image'] = DynamicConnectionConfig( 

83 dataset_type_name='warp', 

84 dimensions={'visit', 'patch'}, 

85 ) 

86 assembleCoadd: 

87 class: lsst.pipe.base.tests.mocks.DynamicTestPipelineTask 

88 config: 

89 python: | 

90 from lsst.pipe.base.tests.mocks import DynamicConnectionConfig 

91 config.dimensions = ['patch', 'band'] 

92 config.inputs['input_image'] = DynamicConnectionConfig( 

93 dataset_type_name='warp', 

94 dimensions={'visit', 'patch'}, 

95 ) 

96 config.outputs['output_image'] = DynamicConnectionConfig( 

97 dataset_type_name='coadd', 

98 dimensions={'patch', 'band'}, 

99 ) 

100 """ 

101 ) 

102 self.temp_pipeline_name = "" 

103 while not self.temp_pipeline_name: 

104 self.temp_pipeline = NamedTemporaryFile() 

105 self.temp_pipeline.write(frozen_pipeline.encode()) 

106 self.temp_pipeline.flush() 

107 if not os.path.exists(self.temp_pipeline.name): 

108 self.temp_pipeline.close() 

109 else: 

110 self.temp_pipeline_name = self.temp_pipeline.name 

111 

112 def tearDown(self): 

113 self.temp_pipeline.close() 

114 

115 def testLoadList(self): 

116 """Test loading a specific list of labels.""" 

117 labels = ("isr", "makeWarp") 

118 path = os.path.expandvars(f"{self.temp_pipeline_name}#{','.join(labels)}") 

119 pipeline = pipeBase.Pipeline.fromFile(path) 

120 self.assertEqual(set(labels), pipeline._pipelineIR.tasks.keys()) 

121 

122 def testLoadSingle(self): 

123 """Test loading a specific label.""" 

124 label = "calibrate" 

125 path = os.path.expandvars(f"{self.temp_pipeline_name}#{label}") 

126 pipeline = pipeBase.Pipeline.fromFile(path) 

127 self.assertEqual(set((label,)), pipeline._pipelineIR.tasks.keys()) 

128 

129 def testLoadBoundedRange(self): 

130 """Test loading a bounded range.""" 

131 path = os.path.expandvars(f"{self.temp_pipeline_name}#calibrate..assembleCoadd") 

132 pipeline = pipeBase.Pipeline.fromFile(path) 

133 self.assertEqual( 

134 {"calibrate", "makeWarp", "assembleCoadd"}, 

135 pipeline._pipelineIR.tasks.keys(), 

136 ) 

137 

138 def testLoadUpperBound(self): 

139 """Test loading a range that only has an upper bound.""" 

140 path = os.path.expandvars(f"{self.temp_pipeline_name}#..makeWarp") 

141 pipeline = pipeBase.Pipeline.fromFile(path) 

142 self.assertEqual( 

143 {"isr", "calibrate", "makeWarp"}, 

144 pipeline._pipelineIR.tasks.keys(), 

145 ) 

146 

147 def testLoadLowerBound(self): 

148 """Test loading a range that only has a lower bound.""" 

149 path = os.path.expandvars(f"{self.temp_pipeline_name}#makeWarp..") 

150 pipeline = pipeBase.Pipeline.fromFile(path) 

151 self.assertEqual( 

152 {"makeWarp", "assembleCoadd"}, 

153 pipeline._pipelineIR.tasks.keys(), 

154 ) 

155 

156 def testLabelChecks(self): 

157 # test a bad list 

158 path = os.path.expandvars(f"{self.temp_pipeline_name}#FakeLabel") 

159 with self.assertRaises(ValueError): 

160 pipeBase.Pipeline.fromFile(path) 

161 

162 # test a bad end label 

163 path = os.path.expandvars(f"{self.temp_pipeline_name}#..FakeEndLabel") 

164 with self.assertRaises(ValueError): 

165 pipeBase.Pipeline.fromFile(path) 

166 

167 # test a bad begin label 

168 path = os.path.expandvars(f"{self.temp_pipeline_name}#FakeBeginLabel..") 

169 with self.assertRaises(ValueError): 

170 pipeBase.Pipeline.fromFile(path) 

171 

172 def testContractRemoval(self): 

173 path = os.path.expandvars(f"{self.temp_pipeline_name}") 

174 pipeline = pipeBase.Pipeline.fromFile(path) 

175 contract = pipeBase.pipelineIR.ContractIR("'visit' in calibrate.dimensions", None) 

176 pipeline._pipelineIR.contracts.append(contract) 

177 pipeline = pipeline.subsetFromLabels(pipeBase.LabelSpecifier(labels={"isr"})) 

178 self.assertEqual(len(pipeline._pipelineIR.contracts), 0) 

179 

180 

181if __name__ == "__main__": 

182 unittest.main()