Coverage for tests / test_psfs.py: 24%

49 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-05 02:32 -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. 

11 

12from __future__ import annotations 

13 

14import os 

15import unittest 

16 

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 

24 

25DATA_DIR = os.environ.get("TESTDATA_IMAGES_DIR", None) 

26 

27 

28class PointSpreadFunctionTestCase(unittest.TestCase): 

29 """Tests for the PointSpreadFunction classes.""" 

30 

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: 

34 

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. 

40 

41 This test is skipped if legacy modules cannot be imported. 

42 """ 

43 try: 

44 from piff import PSF 

45 

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) 

62 

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: 

66 

67 - read a legacy PSFEX PSF with afw; 

68 - wrap it inthe new `LegacyPointSpreadFunction` class; 

69 - get consistent behavior from the two. 

70 

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) 

92 

93 

94if __name__ == "__main__": 

95 unittest.main()