Coverage for tests/test_calibrateImage.py: 17%
230 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-20 12:29 +0000
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-20 12:29 +0000
1# This file is part of pipe_tasks.
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 tempfile
25import astropy.units as u
26from astropy.coordinates import SkyCoord
27import numpy as np
29import lsst.afw.image as afwImage
30import lsst.afw.table as afwTable
31import lsst.daf.base
32import lsst.daf.butler.tests as butlerTests
33import lsst.geom
34import lsst.meas.algorithms
35from lsst.meas.algorithms import testUtils
36import lsst.meas.extensions.psfex
37import lsst.meas.base.tests
38import lsst.pipe.base.testUtils
39from lsst.pipe.tasks.calibrateImage import CalibrateImageTask
40import lsst.utils.tests
43class CalibrateImageTaskTests(lsst.utils.tests.TestCase):
45 def setUp(self):
46 # Different x/y dimensions so they're easy to distinguish in a plot,
47 # and non-zero minimum, to help catch xy0 errors.
48 bbox = lsst.geom.Box2I(lsst.geom.Point2I(5, 4), lsst.geom.Point2I(205, 184))
49 self.sky_center = lsst.geom.SpherePoint(245.0, -45.0, lsst.geom.degrees)
50 self.photo_calib = 12.3
51 dataset = lsst.meas.base.tests.TestDataset(bbox, crval=self.sky_center, calibration=self.photo_calib)
52 # sqrt of area of a normalized 2d gaussian
53 psf_scale = np.sqrt(4*np.pi*(dataset.psfShape.getDeterminantRadius())**2)
54 noise = 10.0 # stddev of noise per pixel
55 # Sources ordered from faintest to brightest.
56 self.fluxes = np.array((6*noise*psf_scale,
57 12*noise*psf_scale,
58 45*noise*psf_scale,
59 150*noise*psf_scale,
60 400*noise*psf_scale,
61 1000*noise*psf_scale))
62 self.centroids = np.array(((162, 22),
63 (40, 70),
64 (100, 160),
65 (50, 120),
66 (92, 35),
67 (175, 154)), dtype=np.float32)
68 for flux, centroid in zip(self.fluxes, self.centroids):
69 dataset.addSource(instFlux=flux, centroid=lsst.geom.Point2D(centroid[0], centroid[1]))
71 # Bright extended source in the center of the image: should not appear
72 # in any of the output catalogs.
73 center = lsst.geom.Point2D(100, 100)
74 shape = lsst.afw.geom.Quadrupole(8, 9, 3)
75 dataset.addSource(instFlux=500*noise*psf_scale, centroid=center, shape=shape)
77 schema = dataset.makeMinimalSchema()
78 self.truth_exposure, self.truth_cat = dataset.realize(noise=noise, schema=schema)
79 # To make it look like a version=1 (nJy fluxes) refcat
80 self.truth_cat = self.truth_exposure.photoCalib.calibrateCatalog(self.truth_cat)
81 self.ref_loader = testUtils.MockReferenceObjectLoaderFromMemory([self.truth_cat])
82 metadata = lsst.daf.base.PropertyList()
83 metadata.set("REFCAT_FORMAT_VERSION", 1)
84 self.truth_cat.setMetadata(metadata)
86 # TODO: a cosmic ray (need to figure out how to insert a fake-CR)
87 # self.truth_exposure.image.array[10, 10] = 100000
88 # self.truth_exposure.variance.array[10, 10] = 100000/noise
90 # Copy the truth exposure, because CalibrateImage modifies the input.
91 # Post-ISR ccds only contain: initial WCS, VisitInfo, filter
92 self.exposure = afwImage.ExposureF(self.truth_exposure.maskedImage)
93 self.exposure.setWcs(self.truth_exposure.wcs)
94 self.exposure.info.setVisitInfo(self.truth_exposure.visitInfo)
95 # "truth" filter, to match the "truth" refcat.
96 self.exposure.setFilter(lsst.afw.image.FilterLabel(physical='truth', band="truth"))
98 # Test-specific configuration:
99 self.config = CalibrateImageTask.ConfigClass()
100 # We don't have many sources, so have to fit simpler models.
101 self.config.psf_detection.background.approxOrderX = 1
102 self.config.star_detection.background.approxOrderX = 1
103 # Only insert 2 sky sources, for simplicity.
104 self.config.star_sky_sources.nSources = 2
105 # Use PCA psf fitter, as psfex fails if there are only 4 stars.
106 self.config.psf_measure_psf.psfDeterminer = 'pca'
107 # We don't have many test points, so can't match on complicated shapes.
108 self.config.astrometry.matcher.numPointsForShape = 3
109 # ApFlux has more noise than PsfFlux (the latter unrealistically small
110 # in this test data), so we need to do magnitude rejection at higher
111 # sigma, otherwise we can lose otherwise good sources.
112 # TODO DM-39203: Once we are using Compensated Gaussian Fluxes, we
113 # will use those fluxes here, and hopefully can remove this.
114 self.config.astrometry.magnitudeOutlierRejectionNSigma = 9.0
116 # find_stars needs an id generator.
117 self.id_generator = lsst.meas.base.IdGenerator()
119 # Something about this test dataset prefers the older fluxRatio here.
120 self.config.star_catalog_calculation.plugins['base_ClassificationExtendedness'].fluxRatio = 0.925
122 def _check_run(self, calibrate, result, *, photo_calib):
123 """Test the result of CalibrateImage.run().
125 Parameters
126 ----------
127 calibrate : `lsst.pipe.tasks.calibrateImage.CalibrateImageTask`
128 Configured task that had `run` called on it.
129 result : `lsst.pipe.base.Struct`
130 Result of calling calibrate.run().
131 photo_calib : `float`
132 Expected value of the PhotoCalib mean.
133 """
134 # Background should have 4 elements: 3 from compute_psf and one from
135 # re-estimation during source detection.
136 self.assertEqual(len(result.background), 4)
138 # Check that the summary statistics are reasonable.
139 summary = result.output_exposure.info.getSummaryStats()
140 self.assertFloatsAlmostEqual(summary.psfSigma, 2.0, rtol=1e-2)
141 self.assertFloatsAlmostEqual(summary.ra, self.sky_center.getRa().asDegrees(), rtol=1e-7)
142 self.assertFloatsAlmostEqual(summary.dec, self.sky_center.getDec().asDegrees(), rtol=1e-7)
144 # Returned photoCalib should be the applied value, not the ==1 one on the exposure.
145 self.assertFloatsAlmostEqual(result.applied_photo_calib.getCalibrationMean(),
146 photo_calib, rtol=2e-3)
147 # Should have flux/magnitudes in the catalog.
148 self.assertIn("slot_PsfFlux_flux", result.stars.schema)
149 self.assertIn("slot_PsfFlux_mag", result.stars.schema)
151 # Check that all necessary fields are in the output.
152 lsst.pipe.base.testUtils.assertValidOutput(calibrate, result)
154 def test_run(self):
155 """Test that run() returns reasonable values to be butler put.
156 """
157 calibrate = CalibrateImageTask(config=self.config)
158 calibrate.astrometry.setRefObjLoader(self.ref_loader)
159 calibrate.photometry.match.setRefObjLoader(self.ref_loader)
160 result = calibrate.run(exposures=self.exposure)
162 self._check_run(calibrate, result, photo_calib=self.photo_calib)
164 def test_run_2_snaps(self):
165 """Test that run() returns reasonable values to be butler put, when
166 passed two exposures to combine as snaps.
167 """
168 calibrate = CalibrateImageTask(config=self.config)
169 calibrate.astrometry.setRefObjLoader(self.ref_loader)
170 calibrate.photometry.match.setRefObjLoader(self.ref_loader)
171 result = calibrate.run(exposures=[self.exposure, self.exposure])
173 self._check_run(calibrate, result, photo_calib=self.photo_calib/2)
175 def test_handle_snaps(self):
176 calibrate = CalibrateImageTask(config=self.config)
177 self.assertEqual(calibrate._handle_snaps(self.exposure), self.exposure)
178 self.assertEqual(calibrate._handle_snaps((self.exposure, )), self.exposure)
179 self.assertEqual(calibrate._handle_snaps(self.exposure), self.exposure)
180 with self.assertRaisesRegex(RuntimeError, "Can only process 1 or 2 snaps, not 0."):
181 calibrate._handle_snaps([])
182 with self.assertRaisesRegex(RuntimeError, "Can only process 1 or 2 snaps, not 3."):
183 calibrate._handle_snaps(3*[self.exposure])
185 def test_compute_psf(self):
186 """Test that our brightest sources are found by _compute_psf(),
187 that a PSF is assigned to the expopsure.
188 """
189 calibrate = CalibrateImageTask(config=self.config)
190 psf_stars, background, candidates = calibrate._compute_psf(self.exposure)
192 # Background should have 3 elements: initial subtraction, and two from
193 # re-estimation during the two detection passes.
194 self.assertEqual(len(background), 3)
196 # Only the point-sources with S/N > 50 should be in this output.
197 self.assertEqual(psf_stars["calib_psf_used"].sum(), 3)
198 # Sort in order of brightness, to easily compare with expected positions.
199 psf_stars.sort(psf_stars.getPsfFluxSlot().getMeasKey())
200 for record, flux, center in zip(psf_stars[::-1], self.fluxes, self.centroids[self.fluxes > 50]):
201 self.assertFloatsAlmostEqual(record.getX(), center[0], rtol=0.01)
202 self.assertFloatsAlmostEqual(record.getY(), center[1], rtol=0.01)
203 # PsfFlux should match the values inserted.
204 self.assertFloatsAlmostEqual(record["slot_PsfFlux_instFlux"], flux, rtol=0.01)
206 # TODO: While debugging DM-32701, we're using PCA instead of psfex.
207 # Check that we got a useable PSF.
208 # self.assertIsInstance(self.exposure.psf, lsst.meas.extensions.psfex.PsfexPsf)
209 self.assertIsInstance(self.exposure.psf, lsst.meas.algorithms.PcaPsf)
210 # TestDataset sources have PSF radius=2 pixels.
211 radius = self.exposure.psf.computeShape(self.exposure.psf.getAveragePosition()).getDeterminantRadius()
212 self.assertFloatsAlmostEqual(radius, 2.0, rtol=1e-2)
214 # To look at images for debugging (`setup display_ds9` and run ds9):
215 # import lsst.afw.display
216 # display = lsst.afw.display.getDisplay()
217 # display.mtv(self.exposure)
219 def test_measure_aperture_correction(self):
220 """Test that _measure_aperture_correction() assigns an ApCorrMap to the
221 exposure.
222 """
223 calibrate = CalibrateImageTask(config=self.config)
224 psf_stars, background, candidates = calibrate._compute_psf(self.exposure)
226 # First check that the exposure doesn't have an ApCorrMap.
227 self.assertIsNone(self.exposure.apCorrMap)
228 calibrate._measure_aperture_correction(self.exposure, psf_stars)
229 self.assertIsInstance(self.exposure.apCorrMap, afwImage.ApCorrMap)
231 def test_find_stars(self):
232 """Test that _find_stars() correctly identifies the S/N>10 stars
233 in the image and returns them in the output catalog.
234 """
235 calibrate = CalibrateImageTask(config=self.config)
236 psf_stars, background, candidates = calibrate._compute_psf(self.exposure)
237 calibrate._measure_aperture_correction(self.exposure, psf_stars)
239 stars = calibrate._find_stars(self.exposure, background, self.id_generator)
241 # Background should have 4 elements: 3 from compute_psf and one from
242 # re-estimation during source detection.
243 self.assertEqual(len(background), 4)
245 # Only 5 psf-like sources with S/N>10 should be in the output catalog,
246 # plus two sky sources.
247 self.assertEqual(len(stars), 7)
248 self.assertTrue(stars.isContiguous())
249 # Sort in order of brightness, to easily compare with expected positions.
250 stars.sort(stars.getPsfFluxSlot().getMeasKey())
251 for record, flux, center in zip(stars[::-1], self.fluxes, self.centroids[self.fluxes > 50]):
252 self.assertFloatsAlmostEqual(record.getX(), center[0], rtol=0.01)
253 self.assertFloatsAlmostEqual(record.getY(), center[1], rtol=0.01)
254 self.assertFloatsAlmostEqual(record["slot_PsfFlux_instFlux"], flux, rtol=0.01)
256 def test_astrometry(self):
257 """Test that the fitted WCS gives good catalog coordinates.
258 """
259 calibrate = CalibrateImageTask(config=self.config)
260 calibrate.astrometry.setRefObjLoader(self.ref_loader)
261 psf_stars, background, candidates = calibrate._compute_psf(self.exposure)
262 calibrate._measure_aperture_correction(self.exposure, psf_stars)
263 stars = calibrate._find_stars(self.exposure, background, self.id_generator)
265 calibrate._fit_astrometry(self.exposure, stars)
267 # Check that we got reliable matches with the truth coordinates.
268 sky = stars["sky_source"]
269 fitted = SkyCoord(stars[~sky]['coord_ra'], stars[~sky]['coord_dec'], unit="radian")
270 truth = SkyCoord(self.truth_cat['coord_ra'], self.truth_cat['coord_dec'], unit="radian")
271 idx, d2d, _ = fitted.match_to_catalog_sky(truth)
272 np.testing.assert_array_less(d2d.to_value(u.milliarcsecond), 35.0)
274 def test_photometry(self):
275 """Test that the fitted photoCalib matches the one we generated,
276 and that the exposure is calibrated.
277 """
278 calibrate = CalibrateImageTask(config=self.config)
279 calibrate.astrometry.setRefObjLoader(self.ref_loader)
280 calibrate.photometry.match.setRefObjLoader(self.ref_loader)
281 psf_stars, background, candidates = calibrate._compute_psf(self.exposure)
282 calibrate._measure_aperture_correction(self.exposure, psf_stars)
283 stars = calibrate._find_stars(self.exposure, background, self.id_generator)
284 calibrate._fit_astrometry(self.exposure, stars)
286 stars, matches, meta, photoCalib = calibrate._fit_photometry(self.exposure, stars)
288 # NOTE: With this test data, PhotoCalTask returns calibrationErr==0,
289 # so we can't check that the photoCal error has been set.
290 self.assertFloatsAlmostEqual(photoCalib.getCalibrationMean(), self.photo_calib, rtol=2e-3)
291 # The exposure should be calibrated by the applied photoCalib.
292 self.assertFloatsAlmostEqual(self.exposure.image.array/self.truth_exposure.image.array,
293 self.photo_calib, rtol=2e-3)
294 # PhotoCalib on the exposure must be identically 1.
295 self.assertEqual(self.exposure.photoCalib.getCalibrationMean(), 1.0)
297 # Check that we got reliable magnitudes and fluxes vs. truth, ignoring
298 # sky sources.
299 sky = stars["sky_source"]
300 fitted = SkyCoord(stars[~sky]['coord_ra'], stars[~sky]['coord_dec'], unit="radian")
301 truth = SkyCoord(self.truth_cat['coord_ra'], self.truth_cat['coord_dec'], unit="radian")
302 idx, _, _ = fitted.match_to_catalog_sky(truth)
303 # Because the input variance image does not include contributions from
304 # the sources, we can't use fluxErr as a bound on the measurement
305 # quality here.
306 self.assertFloatsAlmostEqual(stars[~sky]['slot_PsfFlux_flux'],
307 self.truth_cat['truth_flux'][idx],
308 rtol=0.1)
309 self.assertFloatsAlmostEqual(stars[~sky]['slot_PsfFlux_mag'],
310 self.truth_cat['truth_mag'][idx],
311 rtol=0.01)
313 def test_match_psf_stars(self):
314 """Test that _match_psf_stars() flags the correct stars as psf stars
315 and candidates.
316 """
317 calibrate = CalibrateImageTask(config=self.config)
318 psf_stars, background, candidates = calibrate._compute_psf(self.exposure)
319 calibrate._measure_aperture_correction(self.exposure, psf_stars)
320 stars = calibrate._find_stars(self.exposure, background, self.id_generator)
322 # There should be no psf-related flags set at first.
323 self.assertEqual(stars["calib_psf_candidate"].sum(), 0)
324 self.assertEqual(stars["calib_psf_used"].sum(), 0)
325 self.assertEqual(stars["calib_psf_reserved"].sum(), 0)
327 calibrate._match_psf_stars(psf_stars, stars)
329 # Sort in order of brightness; the psf stars are the 3 brightest, with
330 # two sky sources as the faintest.
331 stars.sort(stars.getPsfFluxSlot().getMeasKey())
332 # sort() above leaves the catalog non-contiguous.
333 stars = stars.copy(deep=True)
334 np.testing.assert_array_equal(stars["calib_psf_candidate"],
335 [False, False, False, False, True, True, True])
336 np.testing.assert_array_equal(stars["calib_psf_used"], [False, False, False, False, True, True, True])
337 # Too few sources to reserve any in these tests.
338 self.assertEqual(stars["calib_psf_reserved"].sum(), 0)
341class CalibrateImageTaskRunQuantumTests(lsst.utils.tests.TestCase):
342 """Tests of ``CalibrateImageTask.runQuantum``, which need a test butler,
343 but do not need real images.
344 """
345 def setUp(self):
346 instrument = "testCam"
347 exposure0 = 101
348 exposure1 = 101
349 visit = 100101
350 detector = 42
352 # Create a and populate a test butler for runQuantum tests.
353 self.repo_path = tempfile.TemporaryDirectory(ignore_cleanup_errors=True)
354 self.repo = butlerTests.makeTestRepo(self.repo_path.name)
356 # A complete instrument record is necessary for the id generator.
357 instrumentRecord = self.repo.dimensions["instrument"].RecordClass(
358 name=instrument, visit_max=1e6, exposure_max=1e6, detector_max=128,
359 class_name="lsst.obs.base.instrument_tests.DummyCam",
360 )
361 self.repo.registry.syncDimensionData("instrument", instrumentRecord)
363 # dataIds for fake data
364 butlerTests.addDataIdValue(self.repo, "exposure", exposure0)
365 butlerTests.addDataIdValue(self.repo, "exposure", exposure1)
366 butlerTests.addDataIdValue(self.repo, "visit", visit)
367 butlerTests.addDataIdValue(self.repo, "detector", detector)
369 # inputs
370 butlerTests.addDatasetType(self.repo, "postISRCCD", {"instrument", "exposure", "detector"},
371 "ExposureF")
372 butlerTests.addDatasetType(self.repo, "gaia_dr3_20230707", {"htm7"}, "SimpleCatalog")
373 butlerTests.addDatasetType(self.repo, "ps1_pv3_3pi_20170110", {"htm7"}, "SimpleCatalog")
375 # outputs
376 butlerTests.addDatasetType(self.repo, "initial_pvi", {"instrument", "visit", "detector"},
377 "ExposureF")
378 butlerTests.addDatasetType(self.repo, "initial_stars_footprints_detector",
379 {"instrument", "visit", "detector"},
380 "SourceCatalog")
381 butlerTests.addDatasetType(self.repo, "initial_photoCalib_detector",
382 {"instrument", "visit", "detector"},
383 "PhotoCalib")
384 # optional outputs
385 butlerTests.addDatasetType(self.repo, "initial_pvi_background", {"instrument", "visit", "detector"},
386 "Background")
387 butlerTests.addDatasetType(self.repo, "initial_psf_stars_footprints",
388 {"instrument", "visit", "detector"},
389 "SourceCatalog")
390 butlerTests.addDatasetType(self.repo,
391 "initial_astrometry_match_detector",
392 {"instrument", "visit", "detector"},
393 "Catalog")
394 butlerTests.addDatasetType(self.repo,
395 "initial_photometry_match_detector",
396 {"instrument", "visit", "detector"},
397 "Catalog")
399 # dataIds
400 self.exposure0_id = self.repo.registry.expandDataId(
401 {"instrument": instrument, "exposure": exposure0, "detector": detector})
402 self.exposure1_id = self.repo.registry.expandDataId(
403 {"instrument": instrument, "exposure": exposure1, "detector": detector})
404 self.visit_id = self.repo.registry.expandDataId(
405 {"instrument": instrument, "visit": visit, "detector": detector})
406 self.htm_id = self.repo.registry.expandDataId({"htm7": 42})
408 # put empty data
409 self.butler = butlerTests.makeTestCollection(self.repo)
410 self.butler.put(afwImage.ExposureF(), "postISRCCD", self.exposure0_id)
411 self.butler.put(afwTable.SimpleCatalog(), "gaia_dr3_20230707", self.htm_id)
412 self.butler.put(afwTable.SimpleCatalog(), "ps1_pv3_3pi_20170110", self.htm_id)
414 def tearDown(self):
415 self.repo_path.cleanup()
417 def test_runQuantum(self):
418 task = CalibrateImageTask()
419 lsst.pipe.base.testUtils.assertValidInitOutput(task)
421 quantum = lsst.pipe.base.testUtils.makeQuantum(
422 task, self.butler, self.visit_id,
423 {"exposures": [self.exposure0_id],
424 "astrometry_ref_cat": [self.htm_id],
425 "photometry_ref_cat": [self.htm_id],
426 # outputs
427 "output_exposure": self.visit_id,
428 "stars": self.visit_id,
429 "background": self.visit_id,
430 "psf_stars": self.visit_id,
431 "applied_photo_calib": self.visit_id,
432 "initial_pvi_background": self.visit_id,
433 "astrometry_matches": self.visit_id,
434 "photometry_matches": self.visit_id,
435 })
436 mock_run = lsst.pipe.base.testUtils.runTestQuantum(task, self.butler, quantum)
438 # Ensure the reference loaders have been configured.
439 self.assertEqual(task.astrometry.refObjLoader.name, "gaia_dr3_20230707")
440 self.assertEqual(task.photometry.match.refObjLoader.name, "ps1_pv3_3pi_20170110")
441 # Check that the proper kwargs are passed to run().
442 self.assertEqual(mock_run.call_args.kwargs.keys(), {"exposures", "id_generator"})
444 def test_runQuantum_2_snaps(self):
445 task = CalibrateImageTask()
446 lsst.pipe.base.testUtils.assertValidInitOutput(task)
448 quantum = lsst.pipe.base.testUtils.makeQuantum(
449 task, self.butler, self.visit_id,
450 {"exposures": [self.exposure0_id, self.exposure1_id],
451 "astrometry_ref_cat": [self.htm_id],
452 "photometry_ref_cat": [self.htm_id],
453 # outputs
454 "output_exposure": self.visit_id,
455 "stars": self.visit_id,
456 "background": self.visit_id,
457 "psf_stars": self.visit_id,
458 "applied_photo_calib": self.visit_id,
459 "initial_pvi_background": self.visit_id,
460 "astrometry_matches": self.visit_id,
461 "photometry_matches": self.visit_id,
462 })
463 mock_run = lsst.pipe.base.testUtils.runTestQuantum(task, self.butler, quantum)
465 # Ensure the reference loaders have been configured.
466 self.assertEqual(task.astrometry.refObjLoader.name, "gaia_dr3_20230707")
467 self.assertEqual(task.photometry.match.refObjLoader.name, "ps1_pv3_3pi_20170110")
468 # Check that the proper kwargs are passed to run().
469 self.assertEqual(mock_run.call_args.kwargs.keys(), {"exposures", "id_generator"})
471 def test_runQuantum_no_optional_outputs(self):
472 config = CalibrateImageTask.ConfigClass()
473 config.optional_outputs = None
474 task = CalibrateImageTask(config=config)
475 lsst.pipe.base.testUtils.assertValidInitOutput(task)
477 quantum = lsst.pipe.base.testUtils.makeQuantum(
478 task, self.butler, self.visit_id,
479 {"exposures": [self.exposure0_id],
480 "astrometry_ref_cat": [self.htm_id],
481 "photometry_ref_cat": [self.htm_id],
482 # outputs
483 "output_exposure": self.visit_id,
484 "stars": self.visit_id,
485 "applied_photo_calib": self.visit_id,
486 "background": self.visit_id,
487 })
488 mock_run = lsst.pipe.base.testUtils.runTestQuantum(task, self.butler, quantum)
490 # Ensure the reference loaders have been configured.
491 self.assertEqual(task.astrometry.refObjLoader.name, "gaia_dr3_20230707")
492 self.assertEqual(task.photometry.match.refObjLoader.name, "ps1_pv3_3pi_20170110")
493 # Check that the proper kwargs are passed to run().
494 self.assertEqual(mock_run.call_args.kwargs.keys(), {"exposures", "id_generator"})
496 def test_lintConnections(self):
497 """Check that the connections are self-consistent.
498 """
499 Connections = CalibrateImageTask.ConfigClass.ConnectionsClass
500 lsst.pipe.base.testUtils.lintConnections(Connections)
503def setup_module(module):
504 lsst.utils.tests.init()
507class MemoryTestCase(lsst.utils.tests.MemoryTestCase):
508 pass
511if __name__ == "__main__": 511 ↛ 512line 511 didn't jump to line 512, because the condition on line 511 was never true
512 lsst.utils.tests.init()
513 unittest.main()