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 

71 def test_jointcalTask_2_visits_photometry(self): 

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

73 self.config.photometryModel = "simpleFlux" 

74 self.config.doAstrometry = False 

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

76 self.jointcalStatistics.do_astrometry = False 

77 

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

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

80 metrics = {'collected_photometry_refStars': 346, 

81 'selected_photometry_refStars': 2, 

82 'associated_photometry_fittedStars': 2, 

83 'selected_photometry_fittedStars': 2, 

84 'selected_photometry_ccdImages': 2, 

85 'photometry_final_chi2': 2.336915, 

86 'photometry_final_ndof': 1 

87 } 

88 

89 # The output repo is named after this method. 

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

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

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

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

94 

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

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

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

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

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

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

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

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

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

104 

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

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

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

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

109 config = butler.get('jointcal_config') 

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

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

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

113 

114 def test_jointcalTask_2_visits_photometry_magnitude(self): 

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

116 self.config.photometryModel = "simpleMagnitude" 

117 self.config.doAstrometry = False 

118 self.jointcalStatistics.do_astrometry = False 

119 

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

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

122 metrics = {'collected_photometry_refStars': 346, 

123 'selected_photometry_refStars': 2, 

124 'associated_photometry_fittedStars': 2, 

125 'selected_photometry_fittedStars': 2, 

126 'selected_photometry_ccdImages': 2, 

127 'photometry_final_chi2': 2.23008, 

128 'photometry_final_ndof': 1 

129 } 

130 

131 # The output repo is named after this method. 

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

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

134 

135 def test_jointcalTask_fails_raise(self): 

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

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

138 self.config.setDefaults() 

139 self.config.photometryModel = "simpleFlux" 

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

141 self.config.doAstrometry = False 

142 

143 # The output repo is named after this method. 

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

145 nCatalogs = 2 

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

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

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

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

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

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

152 '--doraise', 

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

154 args.extend(self.other_args) 

155 with self.assertRaises(RuntimeError): 

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

157 

158 def test_jointcalTask_fails_no_raise(self): 

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

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

161 self.config.setDefaults() 

162 self.config.photometryModel = "simpleFlux" 

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

164 self.config.doAstrometry = False 

165 

166 # The output repo is named after this method. 

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

168 nCatalogs = 2 

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

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

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

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

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

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

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

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

177 args.extend(self.other_args) 

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

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

180 

181 def test_jointcalTask_fails_no_raise_no_return_results(self): 

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

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

184 self.config.setDefaults() 

185 self.config.photometryModel = "simpleFlux" 

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

187 self.config.doAstrometry = False 

188 

189 # The output repo is named after this method. 

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

191 nCatalogs = 2 

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

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

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

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

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

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

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

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

200 args.extend(self.other_args) 

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

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

203 

204 

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

206 pass 

207 

208 

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

210 lsst.utils.tests.init() 

211 unittest.main()