Coverage for tests / test_psfs.py: 24%
49 statements
« prev ^ index » next coverage.py v7.13.2, created at 2026-02-26 12:40 -0800
« prev ^ index » next coverage.py v7.13.2, created at 2026-02-26 12:40 -0800
1# This file is part of lsst-images.
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# Use of this source code is governed by a 3-clause BSD-style
10# license that can be found in the LICENSE file.
12from __future__ import annotations
14import os
15import unittest
17from lsst.images import Box
18from lsst.images.psfs import (
19 PiffWrapper,
20 PointSpreadFunction,
21 PSFExWrapper,
22)
23from lsst.images.tests import RoundtripFits, compare_psf_to_legacy
25DATA_DIR = os.environ.get("TESTDATA_IMAGES_DIR", None)
28class PointSpreadFunctionTestCase(unittest.TestCase):
29 """Tests for the PointSpreadFunction classes."""
31 @unittest.skipUnless(DATA_DIR is not None, "TESTDATA_IMAGES_DIR is not in the environment.")
32 def test_piff(self) -> None:
33 """Test that we can:
35 - read a legacy Piff PSF with afw;
36 - convert it to the new `PiffWrapper` class;
37 - get consistent behavior from the two;
38 - round-trip the new PSF through a FITS archive;
39 - still get consistent behavior with the round-tripped PSF.
41 This test is skipped if legacy modules cannot be imported.
42 """
43 try:
44 from piff import PSF
46 from lsst.afw.image import ExposureFitsReader
47 except ImportError:
48 raise unittest.SkipTest("'lsst.afw.image' could not be imported.") from None
49 assert DATA_DIR is not None, "Guaranteed by decorator."
50 filename = os.path.join(DATA_DIR, "dp2", "legacy", "visit_image.fits")
51 reader = ExposureFitsReader(filename)
52 legacy_psf = reader.readPsf()
53 bounds = Box.from_legacy(reader.readBBox())
54 psf = PointSpreadFunction.from_legacy(legacy_psf, bounds)
55 self.assertIsInstance(psf, PiffWrapper)
56 self.assertEqual(psf.bounds, bounds)
57 self.assertIsInstance(psf.piff_psf, PSF)
58 compare_psf_to_legacy(self, psf, legacy_psf)
59 with RoundtripFits(self, psf) as roundtrip:
60 pass
61 compare_psf_to_legacy(self, roundtrip.result, legacy_psf)
63 @unittest.skipUnless(DATA_DIR is not None, "TESTDATA_IMAGES_DIR is not in the environment.")
64 def test_psfex(self) -> None:
65 """Test that we can:
67 - read a legacy PSFEX PSF with afw;
68 - wrap it inthe new `LegacyPointSpreadFunction` class;
69 - get consistent behavior from the two.
71 This test is skipped if legacy modules cannot be imported.
72 """
73 try:
74 from lsst.afw.image import ExposureFitsReader
75 from lsst.meas.extensions.psfex import PsfexPsf
76 except ImportError:
77 raise unittest.SkipTest("'lsst.afw.image' could not be imported.") from None
78 assert DATA_DIR is not None, "Guaranteed by decorator."
79 filename = os.path.join(DATA_DIR, "dp2", "legacy", "preliminary_visit_image.fits")
80 reader = ExposureFitsReader(filename)
81 legacy_psf = reader.readPsf()
82 bounds = Box.from_legacy(reader.readBBox())
83 psf = PointSpreadFunction.from_legacy(legacy_psf, bounds)
84 self.assertIsInstance(psf, PSFExWrapper)
85 self.assertEqual(psf.bounds, bounds)
86 self.assertIsInstance(psf.legacy_psf, PsfexPsf)
87 compare_psf_to_legacy(self, psf, legacy_psf)
88 compare_psf_to_legacy(self, psf, legacy_psf)
89 with RoundtripFits(self, psf) as roundtrip:
90 pass
91 compare_psf_to_legacy(self, roundtrip.result, legacy_psf)
94if __name__ == "__main__":
95 unittest.main()