Hide keyboard shortcuts

Hot-keys 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

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 inspect 

24import unittest 

25import os 

26 

27import lsst.geom 

28import lsst.utils 

29import lsst.pex.exceptions 

30 

31import jointcalTestBase 

32from lsst.jointcal import jointcal 

33import lsst.jointcal.testUtils 

34 

35 

36# for MemoryTestCase 

37def setup_module(module): 

38 lsst.utils.tests.init() 

39 

40 

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

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

43 """ 

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

45 calculation of metrics is possible. 

46 

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

48 computations of chi2, etc. using this dataset. 

49 """ 

50 @classmethod 

51 def setUpClass(cls): 

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

53 

54 def setUp(self): 

55 do_plot = False 

56 

57 # center of the cfht validation_data catalog 

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

59 radius = 3*lsst.geom.degrees 

60 

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

62 all_visits = [849375, 850587] 

63 other_args = ['ccd=12'] 

64 

65 self.setUp_base(center, radius, 

66 input_dir=input_dir, 

67 all_visits=all_visits, 

68 other_args=other_args, 

69 do_plot=do_plot, log_level="debug") 

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

71 self.configfiles.append(test_config) 

72 

73 def test_jointcalTask_2_visits_photometry(self): 

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

75 self.config.photometryModel = "simpleFlux" 

76 self.config.doAstrometry = False 

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

78 self.jointcalStatistics.do_astrometry = False 

79 

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

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

82 metrics = {'collected_photometry_refStars': 346, 

83 'selected_photometry_refStars': 2, 

84 'associated_photometry_fittedStars': 2, 

85 'selected_photometry_fittedStars': 2, 

86 'selected_photometry_ccdImages': 2, 

87 'photometry_final_chi2': 2.336915, 

88 'photometry_final_ndof': 1 

89 } 

90 

91 # The output repo is named after this method. 

92 caller = inspect.stack()[0].function 

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

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

95 self._runJointcalTask(2, caller, metrics=metrics) 

96 

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

98 self.assertTrue(os.path.exists("photometry_preinit-mat.txt")) 

99 os.remove("photometry_preinit-mat.txt") 

100 self.assertTrue(os.path.exists("photometry_preinit-grad.txt")) 

101 os.remove("photometry_preinit-grad.txt") 

102 self.assertTrue(os.path.exists("photometry_postinit-mat.txt")) 

103 os.remove("photometry_postinit-mat.txt") 

104 self.assertTrue(os.path.exists("photometry_postinit-grad.txt")) 

105 os.remove("photometry_postinit-grad.txt") 

106 

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

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

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

110 butler = lsst.daf.persistence.Butler(output_dir) 

111 config = butler.get('jointcal_config') 

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

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

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

115 

116 def test_jointcalTask_2_visits_photometry_magnitude(self): 

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

118 self.config.photometryModel = "simpleMagnitude" 

119 self.config.doAstrometry = False 

120 self.jointcalStatistics.do_astrometry = False 

121 

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

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

124 metrics = {'collected_photometry_refStars': 346, 

125 'selected_photometry_refStars': 2, 

126 'associated_photometry_fittedStars': 2, 

127 'selected_photometry_fittedStars': 2, 

128 'selected_photometry_ccdImages': 2, 

129 'photometry_final_chi2': 2.23008, 

130 'photometry_final_ndof': 1 

131 } 

132 

133 # The output repo is named after this method. 

134 caller = inspect.stack()[0].function 

135 self._runJointcalTask(2, caller, metrics=metrics) 

136 

137 def test_jointcalTask_fails_raise(self): 

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

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

140 self.config.setDefaults() 

141 self.config.photometryModel = "simpleFlux" 

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

143 self.config.doAstrometry = False 

144 

145 # The output repo is named after this method. 

146 caller = inspect.stack()[0].function 

147 nCatalogs = 2 

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

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

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

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

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

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

154 '--doraise', 

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

156 args.extend(self.other_args) 

157 with self.assertRaises(RuntimeError): 

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

159 

160 def test_jointcalTask_fails_no_raise(self): 

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

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

163 self.config.setDefaults() 

164 self.config.photometryModel = "simpleFlux" 

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

166 self.config.doAstrometry = False 

167 

168 # The output repo is named after this method. 

169 caller = inspect.stack()[0].function 

170 nCatalogs = 2 

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

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

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

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

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

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

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

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

179 args.extend(self.other_args) 

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

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

182 

183 def test_jointcalTask_fails_no_raise_no_return_results(self): 

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

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

186 self.config.setDefaults() 

187 self.config.photometryModel = "simpleFlux" 

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

189 self.config.doAstrometry = False 

190 

191 # The output repo is named after this method. 

192 caller = inspect.stack()[0].function 

193 nCatalogs = 2 

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

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

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

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

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

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

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

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

202 args.extend(self.other_args) 

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

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

205 

206 

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

208 pass 

209 

210 

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

212 lsst.utils.tests.init() 

213 unittest.main()