Coverage for tests/test_schema_v1_legacy_fixtures.py: 27%

48 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-06-03 01:09 -0700

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 

12"""Read-back tests for the legacy-derived v1 fixtures. 

13 

14The fixtures under ``tests/data/schema_v1/legacy/`` are derived from real 

15files (converted from legacy formats) by ``_minify_for_fixtures``. Their 

16whole point is to prove that we can still read real-data serializations back 

17in -- so these tests just read each fixture and check its structure. 

18 

19These tests do not require ``lsst.cell_coadds`` (the ``CellCoadd`` fixture is 

20read purely through ``lsst.images``). They also do not require ``piff``: a 

21``VisitImage`` whose PSF cannot be deserialized still reads successfully, with 

22the error deferred until the PSF is actually accessed. We assert that 

23deferred behaviour directly, and only dereference the PSF when ``piff`` is 

24importable. 

25""" 

26 

27from __future__ import annotations 

28 

29import unittest 

30from pathlib import Path 

31 

32from lsst.images import VisitImage 

33from lsst.images.cells import CellCoadd 

34from lsst.images.json import read 

35from lsst.images.serialization import ArchiveReadError 

36 

37SCHEMA_DIR = Path(__file__).parent / "data" / "schema_v1" 

38LEGACY_DIR = SCHEMA_DIR / "legacy" 

39 

40try: 

41 import piff # noqa: F401 

42 

43 HAVE_PIFF = True 

44except ImportError: 

45 HAVE_PIFF = False 

46 

47 

48class LegacyFixtureReadBackTestCase(unittest.TestCase): 

49 """Read each legacy-derived fixture back in and check its structure.""" 

50 

51 def test_cell_coadd(self): 

52 """The CellCoadd fixture reads back as a multi-cell coadd and can be 

53 subset down to a single cell. 

54 """ 

55 path = LEGACY_DIR / "cell_coadd.json" 

56 if not path.exists(): 

57 self.skipTest(f"{path} not present") 

58 

59 coadd, _, _ = read(CellCoadd, str(path)) 

60 

61 self.assertIsInstance(coadd.band, str) 

62 self.assertIsNotNone(coadd.image.unit) 

63 # The fixture deliberately keeps more than one cell so it is a useful 

64 # test, and includes a missing cell to exercise the sparse-grid path. 

65 present = list(coadd.bounds.cell_indices()) 

66 self.assertGreaterEqual(len(present), 2) 

67 self.assertTrue(coadd.bounds.missing, "fixture should retain a missing cell") 

68 # Provenance survived the minify and has the expected two-table shape. 

69 self.assertGreater(len(coadd.provenance.inputs), 0) 

70 self.assertGreater(len(coadd.provenance.contributions), 0) 

71 self.assertIn("polygon", coadd.provenance.inputs.colnames) 

72 

73 # Subsetting to a single present cell still works on the morphed grid. 

74 cell_bbox = coadd.grid.bbox_of(present[0]) 

75 single = coadd[cell_bbox] 

76 self.assertEqual(list(single.bounds.cell_indices()), [present[0]]) 

77 

78 def test_visit_images(self): 

79 """Each VisitImage fixture reads back with its real detector and a 

80 deferred PSF (raised only on access when piff is unavailable). 

81 """ 

82 for name in ("visit_image_dp1.json", "visit_image_dp2.json"): 

83 with self.subTest(name=name): 

84 path = LEGACY_DIR / name 

85 if not path.exists(): 

86 self.skipTest(f"{path} not present") 

87 

88 visit_image, _, _ = read(VisitImage, str(path)) 

89 

90 # Pixel planes were cropped to a small corner. 

91 self.assertEqual(visit_image.image.array.ndim, 2) 

92 self.assertLessEqual(max(visit_image.image.array.shape), 16) 

93 self.assertIsInstance(visit_image.band, str) 

94 self.assertIsNotNone(visit_image.image.unit) 

95 # The real detector (with trimmed amplifiers) round-tripped. 

96 self.assertGreaterEqual(len(visit_image.detector.amplifiers), 1) 

97 self.assertGreater(len(visit_image.aperture_corrections), 0) 

98 

99 if HAVE_PIFF: 

100 self.assertIsNotNone(visit_image.psf) 

101 else: 

102 # Reading succeeded above; the PSF error is deferred to 

103 # the point of access. 

104 with self.assertRaises(ArchiveReadError): 

105 visit_image.psf 

106 

107 

108if __name__ == "__main__": 

109 unittest.main()