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 

22import unittest 

23import os 

24 

25from astropy import units as u 

26import numpy as np 

27 

28from lsst.daf.butler import Butler 

29import lsst.geom 

30import lsst.pex.config 

31import lsst.utils 

32import lsst.pex.exceptions 

33 

34import jointcalTestBase 

35 

36 

37# for MemoryTestCase 

38def setup_module(module): 

39 lsst.utils.tests.init() 

40 

41 

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

43 

44 @classmethod 

45 def setUpClass(cls): 

46 try: 

47 cls.data_dir = lsst.utils.getPackageDir('testdata_jointcal') 

48 except LookupError: 

49 raise unittest.SkipTest("testdata_jointcal not setup") 

50 try: 

51 lsst.utils.getPackageDir('obs_subaru') 

52 except LookupError: 

53 raise unittest.SkipTest("obs_subaru not setup") 

54 

55 def setUp(self): 

56 # See Readme for an explanation of these empirical values. 

57 self.dist_rms_absolute = 21e-3*u.arcsecond 

58 self.dist_rms_relative = 7e-3*u.arcsecond 

59 

60 do_plot = False 

61 

62 # center of the hsc validation_data catalog 

63 center = lsst.geom.SpherePoint(337.710899, +0.807006, lsst.geom.degrees) 

64 radius = 0.5*lsst.geom.degrees 

65 

66 input_dir = os.path.join(self.data_dir, 'hsc') 

67 all_visits = [34648, 34690, 34714, 34674, 34670, 36140, 35892, 36192, 36260, 36236] 

68 

69 self.setUp_base(center, radius, 

70 input_dir=input_dir, 

71 all_visits=all_visits, 

72 do_plot=do_plot) 

73 

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

75 self.configfiles.append(test_config) 

76 

77 def test_jointcalTask_2_visits_simple(self): 

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

79 self.config.astrometryModel = "simple" 

80 self.config.photometryModel = "simpleFlux" 

81 

82 # See Readme for an explanation of these empirical values. 

83 pa1 = 0.016 

84 metrics = {'collected_astrometry_refStars': 568, 

85 'collected_photometry_refStars': 6485, 

86 'selected_astrometry_refStars': 137, 

87 'selected_photometry_refStars': 1609, 

88 'associated_astrometry_fittedStars': 2070, 

89 'associated_photometry_fittedStars': 2070, 

90 'selected_astrometry_fittedStars': 989, 

91 'selected_photometry_fittedStars': 1731, 

92 'selected_astrometry_ccdImages': 6, 

93 'selected_photometry_ccdImages': 6, 

94 'astrometry_final_chi2': 835.473, 

95 'astrometry_final_ndof': 1918, 

96 'photometry_final_chi2': 4997.62, 

97 'photometry_final_ndof': 2188 

98 } 

99 self._testJointcalTask(2, self.dist_rms_relative, self.dist_rms_absolute, pa1, metrics=metrics) 

100 

101 def test_jointcalTask_2_visits_simple_gen3(self): 

102 """Test gen3 butler jointcal.""" 

103 queryString = "instrument='HSC' and tract=9697 and skymap='hsc_rings_v1' and band='r'" 

104 queryString += f" and visit in ({self.all_visits[0]},{self.all_visits[1]})" 

105 configOptions = ["astrometryModel=simple", "photometryModel=simpleFlux"] 

106 self._runGen3Jointcal("lsst.obs.subaru.HyperSuprimeCam", "HSC", queryString, 

107 configOptions=configOptions) 

108 # TODO DM-28863: this does not currently test anything other than the code 

109 # running without raising and that it writes non-empty output. 

110 butler = Butler(self.repo, collections=['HSC/testdata/jointcal']) 

111 

112 def check_output(visit, detectors): 

113 """Check that there is something for each detector, and only 

114 entries for the correct detectors.""" 

115 dataId = {'visit': visit, 'instrument': 'HSC', 'tract': 9697} 

116 

117 catalog = butler.get('jointcalPhotoCalibCatalog', dataId) 

118 for record in catalog: 

119 self.assertIsInstance(record.getPhotoCalib(), lsst.afw.image.PhotoCalib, 

120 msg=f"visit {visit}: {record}") 

121 np.testing.assert_array_equal(catalog['id'], detectors) 

122 

123 catalog = butler.get('jointcalSkyWcsCatalog', dataId) 

124 for record in catalog: 

125 self.assertIsInstance(record.getWcs(), lsst.afw.geom.SkyWcs, 

126 msg=f"visit {visit}: {record}") 

127 np.testing.assert_array_equal(catalog['id'], detectors) 

128 

129 check_output(34648, [51, 59, 67]) 

130 check_output(34690, [48, 56, 64]) 

131 

132 def test_jointcalTask_10_visits_simple_astrometry_no_photometry(self): 

133 """Test all 10 visits with different filters. 

134 Testing photometry doesn't make sense for this currently. 

135 """ 

136 

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

138 self.config.astrometryModel = "simple" 

139 self.config.doPhotometry = False 

140 self.jointcalStatistics.do_photometry = False 

141 

142 # See Readme for an explanation of these empirical values. 

143 dist_rms_absolute = 23e-3*u.arcsecond 

144 dist_rms_relative = 13e-3*u.arcsecond 

145 pa1 = None 

146 metrics = {'collected_astrometry_refStars': 1316, 

147 'selected_astrometry_refStars': 318, 

148 'associated_astrometry_fittedStars': 5860, 

149 'selected_astrometry_fittedStars': 3568, 

150 'selected_astrometry_ccdImages': 30, 

151 'astrometry_final_chi2': 10218.518, 

152 'astrometry_final_ndof': 18574, 

153 } 

154 self._testJointcalTask(10, dist_rms_relative, dist_rms_absolute, pa1, metrics=metrics) 

155 

156 def setup_jointcalTask_2_visits_simplePhotometry(self): 

157 """Set default values for the simplePhotometry tests, and make it so 

158 the differences between each test and the defaults are more obvious. 

159 """ 

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

161 self.config.photometryModel = "simpleFlux" 

162 self.config.doAstrometry = False 

163 self.jointcalStatistics.do_astrometry = False 

164 

165 # See Readme for an explanation of these empirical values. 

166 pa1 = 0.016 

167 metrics = {'collected_photometry_refStars': 6485, 

168 'selected_photometry_refStars': 1609, 

169 'associated_photometry_fittedStars': 2070, 

170 'selected_photometry_fittedStars': 1731, 

171 'selected_photometry_ccdImages': 6, 

172 'photometry_final_chi2': 4997.62, 

173 'photometry_final_ndof': 2188 

174 } 

175 return pa1, metrics 

176 

177 def test_jointcalTask_2_visits_simpleFlux(self): 

178 pa1, metrics = self.setup_jointcalTask_2_visits_simplePhotometry() 

179 self._testJointcalTask(2, None, None, pa1, metrics=metrics) 

180 

181 def test_jointcalTask_2_visits_simpleMagnitude(self): 

182 pa1, metrics = self.setup_jointcalTask_2_visits_simplePhotometry() 

183 self.config.photometryModel = "simpleMagnitude" 

184 metrics['photometry_final_chi2'] = 5236.91 

185 metrics['photometry_final_ndof'] = 2200 

186 

187 self._testJointcalTask(2, None, None, pa1, metrics=metrics) 

188 

189 def test_jointcalTask_2_visits_simpleMagnitude_colorterms(self): 

190 """Test that colorterms are applied and change the fit.""" 

191 pa1, metrics = self.setup_jointcalTask_2_visits_simplePhotometry() 

192 self.config.photometryModel = "simpleMagnitude" 

193 test_config = os.path.join(lsst.utils.getPackageDir('jointcal'), 

194 'tests/config/hsc-colorterms-config.py') 

195 self.configfiles.append(test_config) 

196 

197 # slightly fewer refstars because they each need the specific filters required by the colorterms 

198 metrics['collected_photometry_refStars'] = 6478 

199 # Final chi2 should be different, but I don't have an a-priori reason 

200 # to expect it to be larger or smaller. 

201 metrics['photometry_final_chi2'] = 5181.25 

202 metrics['photometry_final_ndof'] = 2197 

203 

204 self._testJointcalTask(2, None, None, pa1, metrics=metrics) 

205 

206 def test_jointcalTask_2_visits_simpleMagnitude_colorterms_no_library(self): 

207 """Fail Config validation if the color term library isn't defined.""" 

208 pa1, metrics = self.setup_jointcalTask_2_visits_simplePhotometry() 

209 test_config = os.path.join(lsst.utils.getPackageDir('jointcal'), 

210 'tests/config/hsc-colorterms_no_library-config.py') 

211 self.configfiles.append(test_config) 

212 

213 with self.assertRaises(lsst.pex.config.FieldValidationError): 

214 self._testJointcalTask(2, None, None, pa1) 

215 

216 def test_JointcalTask_2_visits_simple_astrometry_no_photometry(self): 

217 """Test turning off fitting photometry.""" 

218 metrics = {'collected_astrometry_refStars': 568, 

219 'selected_astrometry_refStars': 137, 

220 'associated_astrometry_fittedStars': 2070, 

221 'selected_astrometry_fittedStars': 989, 

222 'selected_astrometry_ccdImages': 6, 

223 'astrometry_final_chi2': 835.473, 

224 'astrometry_final_ndof': 1918, 

225 } 

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

227 self.config.astrometryModel = "simple" 

228 self.config.doPhotometry = False 

229 self.jointcalStatistics.do_photometry = False 

230 

231 data_refs = self._testJointcalTask(2, self.dist_rms_relative, self.dist_rms_absolute, 

232 None, metrics=metrics) 

233 

234 for data_ref in data_refs: 

235 with self.assertRaises(lsst.daf.persistence.butlerExceptions.NoResults): 

236 data_ref.get('jointcal_photoCalib') 

237 

238 def test_jointcalTask_2_visits_simple_astrometry_no_photometry_match_cut_10(self): 

239 """A larger matching radius will result in more associated fittedStars, 

240 and a somewhat worse final fit because stars that should not have been 

241 associated, were. 

242 """ 

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

244 self.config.astrometryModel = "simple" 

245 self.config.matchCut = 10.0 # TODO: once DM-6885 is fixed, we need to put `*lsst.geom.arcseconds` 

246 self.config.doPhotometry = False 

247 self.jointcalStatistics.do_photometry = False 

248 

249 # Slightly larger absolute astrometry RMS because of the larger matching radius 

250 dist_rms_absolute = 23e-3*u.arcsecond 

251 metrics = {'collected_astrometry_refStars': 568, 

252 'selected_astrometry_refStars': 211, 

253 'associated_astrometry_fittedStars': 2070, 

254 'selected_astrometry_fittedStars': 1042, 

255 'selected_astrometry_ccdImages': 6, 

256 'astrometry_final_chi2': 819.608, 

257 'astrometry_final_ndof': 1872, 

258 } 

259 pa1 = None 

260 self._testJointcalTask(2, self.dist_rms_relative, dist_rms_absolute, pa1, metrics=metrics) 

261 

262 def test_jointcalTask_3_visits_simple_astrometry_no_photometry(self): 

263 """3 visit, default config to compare with min_measurements_3 test.""" 

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

265 self.config.astrometryModel = "simple" 

266 self.config.minMeasurements = 2 

267 self.config.doPhotometry = False 

268 self.jointcalStatistics.do_photometry = False 

269 

270 # More visits and slightly worse relative and absolute rms. 

271 dist_rms_relative = 8.3e-3*u.arcsecond 

272 dist_rms_absolute = 24e-3*u.arcsecond 

273 metrics = {'collected_astrometry_refStars': 1038, 

274 'selected_astrometry_refStars': 209, 

275 'associated_astrometry_fittedStars': 3199, 

276 'selected_astrometry_fittedStars': 1282, 

277 'selected_astrometry_ccdImages': 9, 

278 'astrometry_final_chi2': 1221.63, 

279 'astrometry_final_ndof': 2892, 

280 } 

281 pa1 = None 

282 self._testJointcalTask(3, dist_rms_relative, dist_rms_absolute, pa1, metrics=metrics) 

283 

284 def test_jointcalTask_3_visits_simple_astrometry_no_photometry_min_measurements_3(self): 

285 """Raising min_measurements to 3 will reduce the number of selected 

286 fitted stars (and thus the chisq and Ndof), but should not change the 

287 other values.""" 

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

289 self.config.minMeasurements = 3 

290 self.config.astrometryModel = "simple" 

291 self.config.doPhotometry = False 

292 self.jointcalStatistics.do_photometry = False 

293 

294 # More visits and slightly worse relative and absolute rms. 

295 dist_rms_relative = 11e-3*u.arcsecond 

296 dist_rms_absolute = 24e-3*u.arcsecond 

297 metrics = {'collected_astrometry_refStars': 1038, 

298 'selected_astrometry_refStars': 209, 

299 'associated_astrometry_fittedStars': 3199, 

300 'selected_astrometry_fittedStars': 432, 

301 'selected_astrometry_ccdImages': 9, 

302 'astrometry_final_chi2': 567.443, 

303 'astrometry_final_ndof': 1286, 

304 } 

305 pa1 = None 

306 self._testJointcalTask(3, dist_rms_relative, dist_rms_absolute, pa1, metrics=metrics) 

307 

308 

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

310 pass 

311 

312 

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

314 lsst.utils.tests.init() 

315 unittest.main()