Coverage for tests/test_jointcal_hsc.py: 22%
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
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
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/>.
22import unittest
23import os
25from astropy import units as u
26import numpy as np
28from lsst.daf.butler import Butler
29import lsst.geom
30import lsst.pex.config
31import lsst.utils
32import lsst.pex.exceptions
34import jointcalTestBase
37# for MemoryTestCase
38def setup_module(module):
39 lsst.utils.tests.init()
42class JointcalTestHSC(jointcalTestBase.JointcalTestBase, lsst.utils.tests.TestCase):
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")
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
60 do_plot = False
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
66 input_dir = os.path.join(self.data_dir, 'hsc')
67 all_visits = [34648, 34690, 34714, 34674, 34670, 36140, 35892, 36192, 36260, 36236]
69 self.setUp_base(center, radius,
70 input_dir=input_dir,
71 all_visits=all_visits,
72 do_plot=do_plot)
74 test_config = os.path.join(lsst.utils.getPackageDir('jointcal'), 'tests/config/hsc-config.py')
75 self.configfiles.append(test_config)
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"
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)
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'])
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}
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)
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)
129 check_output(34648, [51, 59, 67])
130 check_output(34690, [48, 56, 64])
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 """
137 self.config = lsst.jointcal.jointcal.JointcalConfig()
138 self.config.astrometryModel = "simple"
139 self.config.doPhotometry = False
140 self.jointcalStatistics.do_photometry = False
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': 10225.31,
152 'astrometry_final_ndof': 18576,
153 }
154 self._testJointcalTask(10, dist_rms_relative, dist_rms_absolute, pa1, metrics=metrics)
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
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
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)
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
187 self._testJointcalTask(2, None, None, pa1, metrics=metrics)
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)
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
204 self._testJointcalTask(2, None, None, pa1, metrics=metrics)
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)
213 with self.assertRaises(lsst.pex.config.FieldValidationError):
214 self._testJointcalTask(2, None, None, pa1)
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
231 data_refs = self._testJointcalTask(2, self.dist_rms_relative, self.dist_rms_absolute,
232 None, metrics=metrics)
234 for data_ref in data_refs:
235 with self.assertRaises(lsst.daf.persistence.butlerExceptions.NoResults):
236 data_ref.get('jointcal_photoCalib')
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
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)
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
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)
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
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.433,
303 'astrometry_final_ndof': 1286,
304 }
305 pa1 = None
306 self._testJointcalTask(3, dist_rms_relative, dist_rms_absolute, pa1, metrics=metrics)
309class MemoryTester(lsst.utils.tests.MemoryTestCase):
310 pass
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()