Coverage for tests/test_jointcal_cfht_minimal.py: 24%

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

104 statements  

1# This file is part of jointcal. 

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

21 

22"""Test with a minimal catalog extracted from cfht.""" 

23import unittest 

24import os 

25 

26import lsst.geom 

27import lsst.utils 

28import lsst.pex.exceptions 

29 

30import jointcalTestBase 

31from lsst.jointcal import jointcal 

32import lsst.jointcal.testUtils 

33 

34 

35# for MemoryTestCase 

36def setup_module(module): 

37 lsst.utils.tests.init() 

38 

39 

40@unittest.skipUnless(lsst.jointcal.testUtils.canRunTests(), "obs_cfht not available to use cfht_minimal.") 

41class JointcalTestCFHTMinimal(jointcalTestBase.JointcalTestBase, lsst.utils.tests.TestCase): 

42 """ 

43 Test with a stripped down CFHT dataset containing 3 stars, so by-hand 

44 calculation of metrics is possible. 

45 

46 See `notebooks/cfht_minimal_direct_calculation.ipynb` for numpy-based 

47 computations of chi2, etc. using this dataset. 

48 """ 

49 @classmethod 

50 def setUpClass(cls): 

51 cls.data_dir = os.path.join(lsst.utils.getPackageDir('jointcal'), 'tests/data') 

52 

53 def setUp(self): 

54 do_plot = False 

55 

56 # center of the cfht validation_data catalog 

57 center = lsst.geom.SpherePoint(214.884832, 52.6622199, lsst.geom.degrees) 

58 radius = 3*lsst.geom.degrees 

59 

60 input_dir = os.path.join(self.data_dir, 'cfht_minimal') 

61 all_visits = [849375, 850587] 

62 other_args = ['ccd=12'] 

63 

64 self.setUp_base(center, radius, 

65 input_dir=input_dir, 

66 all_visits=all_visits, 

67 other_args=other_args, 

68 do_plot=do_plot, log_level="debug") 

69 test_config = os.path.join(os.path.dirname(__file__), 'config/cfht_minimal-config.py') 

70 self.configfiles.append(test_config) 

71 

72 def test_jointcalTask_2_visits_photometry(self): 

73 self.config = lsst.jointcal.jointcal.JointcalConfig() 

74 self.config.photometryModel = "simpleFlux" 

75 self.config.doAstrometry = False 

76 self.config.writeInitMatrix = True # write Hessian/gradient files 

77 self.jointcalStatistics.do_astrometry = False 

78 

79 # NOTE: ndof==1 from 4 fit parameters (2 model, 2 fittedStar), and 

80 # 5 degrees-of-freedom (3 star measurements, with 2 reference stars). 

81 metrics = {'collected_photometry_refStars': 346, 

82 'selected_photometry_refStars': 2, 

83 'associated_photometry_fittedStars': 2, 

84 'selected_photometry_fittedStars': 2, 

85 'selected_photometry_ccdImages': 2, 

86 'photometry_final_chi2': 2.336915, 

87 'photometry_final_ndof': 1 

88 } 

89 

90 # we use _runJointcalTask instead of _test here because we aren't doing 

91 # full calulation of PA1: the above chi2 is exact. 

92 self._runJointcalTask(2, metrics=metrics) 

93 

94 # Check that the Hessian/gradient files were written. 

95 self.assertTrue(os.path.exists("photometry_preinit-0_r.MP9601-mat.txt")) 

96 os.remove("photometry_preinit-0_r.MP9601-mat.txt") 

97 self.assertTrue(os.path.exists("photometry_preinit-0_r.MP9601-grad.txt")) 

98 os.remove("photometry_preinit-0_r.MP9601-grad.txt") 

99 self.assertTrue(os.path.exists("photometry_postinit-0_r.MP9601-mat.txt")) 

100 os.remove("photometry_postinit-0_r.MP9601-mat.txt") 

101 self.assertTrue(os.path.exists("photometry_postinit-0_r.MP9601-grad.txt")) 

102 os.remove("photometry_postinit-0_r.MP9601-grad.txt") 

103 

104 # Check that the config was persisted, we can read it, and it matches the settings above 

105 self.assertTrue(os.path.exists(os.path.join(self.output_dir, 'config/jointcal.py'))) 

106 butler = lsst.daf.persistence.Butler(self.output_dir) 

107 config = butler.get('jointcal_config') 

108 self.assertEqual(config.photometryModel, self.config.photometryModel) 

109 self.assertEqual(config.doAstrometry, self.config.doAstrometry) 

110 self.assertEqual(config.writeInitMatrix, self.config.writeInitMatrix) 

111 

112 def test_jointcalTask_2_visits_photometry_magnitude(self): 

113 self.config = lsst.jointcal.jointcal.JointcalConfig() 

114 self.config.photometryModel = "simpleMagnitude" 

115 self.config.doAstrometry = False 

116 self.jointcalStatistics.do_astrometry = False 

117 

118 # NOTE: ndof==1 from 4 fit parameters (2 model, 2 fittedStar), and 

119 # 5 degrees-of-freedom (3 star measurements, with 2 reference stars). 

120 metrics = {'collected_photometry_refStars': 346, 

121 'selected_photometry_refStars': 2, 

122 'associated_photometry_fittedStars': 2, 

123 'selected_photometry_fittedStars': 2, 

124 'selected_photometry_ccdImages': 2, 

125 'photometry_final_chi2': 2.23008, 

126 'photometry_final_ndof': 1 

127 } 

128 

129 self._runJointcalTask(2, metrics=metrics) 

130 

131 def test_jointcalTask_fails_raise(self): 

132 """Raise an exception if there is no data to process.""" 

133 self.config = lsst.jointcal.jointcal.JointcalConfig() 

134 self.config.setDefaults() 

135 self.config.photometryModel = "simpleFlux" 

136 self.config.sourceSelector['astrometry'].minSnr = 10000 

137 self.config.doAstrometry = False 

138 

139 # The output repo is named after this method. 

140 caller = self.id() 

141 nCatalogs = 2 

142 visits = '^'.join(str(v) for v in self.all_visits[:nCatalogs]) 

143 output_dir = os.path.join('.test', self.__class__.__name__, caller) 

144 test_config = os.path.join(lsst.utils.getPackageDir('jointcal'), 'tests/config/config.py') 

145 self.configfiles = [test_config] + self.configfiles 

146 args = [self.input_dir, '--output', output_dir, 

147 '--clobber-versions', '--clobber-config', '--configfile', *self.configfiles, 

148 '--doraise', 

149 '--id', 'visit=%s'%visits] 

150 args.extend(self.other_args) 

151 with self.assertRaisesRegex(RuntimeError, "No data to process"): 

152 jointcal.JointcalTask.parseAndRun(args=args, doReturnResults=True, config=self.config) 

153 

154 def test_jointcalTask_fails_no_raise(self): 

155 """exitStatus=1 if there is no data to process.""" 

156 self.config = lsst.jointcal.jointcal.JointcalConfig() 

157 self.config.setDefaults() 

158 self.config.photometryModel = "simpleFlux" 

159 self.config.sourceSelector['astrometry'].minSnr = 10000 

160 self.config.doAstrometry = False 

161 

162 nCatalogs = 2 

163 visits = '^'.join(str(v) for v in self.all_visits[:nCatalogs]) 

164 test_config = os.path.join(lsst.utils.getPackageDir('jointcal'), 'tests/config/config.py') 

165 self.configfiles = [test_config] + self.configfiles 

166 args = [self.input_dir, '--output', self.output_dir, 

167 '--clobber-versions', '--clobber-config', '--configfile', *self.configfiles, 

168 '--noExit', # have to specify noExit, otherwise the test quits 

169 '--id', 'visit=%s'%visits] 

170 args.extend(self.other_args) 

171 result = jointcal.JointcalTask.parseAndRun(args=args, doReturnResults=True, config=self.config) 

172 self.assertEqual(result.resultList[0].exitStatus, 1) 

173 

174 def test_jointcalTask_fails_no_raise_no_return_results(self): 

175 """exitStatus=1 if there is no data to process.""" 

176 self.config = lsst.jointcal.jointcal.JointcalConfig() 

177 self.config.setDefaults() 

178 self.config.photometryModel = "simpleFlux" 

179 self.config.sourceSelector['astrometry'].minSnr = 10000 

180 self.config.doAstrometry = False 

181 

182 nCatalogs = 2 

183 visits = '^'.join(str(v) for v in self.all_visits[:nCatalogs]) 

184 test_config = os.path.join(lsst.utils.getPackageDir('jointcal'), 'tests/config/config.py') 

185 self.configfiles = [test_config] + self.configfiles 

186 args = [self.input_dir, '--output', self.output_dir, 

187 '--clobber-versions', '--clobber-config', '--configfile', *self.configfiles, 

188 '--noExit', # have to specify noExit, otherwise the test quits 

189 '--id', 'visit=%s'%visits] 

190 args.extend(self.other_args) 

191 result = jointcal.JointcalTask.parseAndRun(args=args, config=self.config) 

192 self.assertEqual(result.resultList[0].exitStatus, 1) 

193 

194 

195class MemoryTester(lsst.utils.tests.MemoryTestCase): 

196 pass 

197 

198 

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

200 lsst.utils.tests.init() 

201 unittest.main()