Coverage for tests / test_image.py: 28%

39 statements  

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

17import numpy as np 

18 

19from lsst.images import Box, Image 

20from lsst.images.tests import assert_close, assert_images_equal, compare_image_to_legacy 

21 

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

23 

24 

25class ImageTestCase(unittest.TestCase): 

26 """Tests for the Image class.""" 

27 

28 def test_basics(self): 

29 """Test basic constructor patterns.""" 

30 image = Image(42, shape=(5, 5), metadata={"three": 3}) 

31 assert_close(self, image.array, np.zeros([5, 5], dtype=np.int64) + 42) 

32 self.assertEqual(image.metadata["three"], 3) 

33 

34 data = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]) 

35 image = Image(data) 

36 subset = image[Box.factory[:3, 1:3]] 

37 subset2 = image.absolute[:3, 1:3] 

38 assert_images_equal(self, subset2, subset, expect_view=True) 

39 

40 assert_images_equal(self, image.copy(), image, expect_view=False) 

41 

42 # Add an explicit bounding box and then slice it. 

43 image = Image(data, bbox=Box.factory[-2:1, 10:14]) 

44 with self.assertRaises(IndexError): 

45 # Same slice no longer works in absolute slicing because we have 

46 # moved origin. 

47 image.absolute[:3, 1:3] 

48 # That slice does still work in local coordinates. 

49 assert_close(self, image.local[:3, 1:3].array, subset2.array) 

50 # And we can write an equivalent slice in absolute coordinates. 

51 assert_close(self, image.absolute[:0, 11:13].array, np.array([[2, 3], [6, 7]])) 

52 

53 @unittest.skipUnless(DATA_DIR is not None, "TESTDATA_IMAGES_DIR is not in the environment.") 

54 def test_legacy(self) -> None: 

55 """Test Image.read_legacy, Image.to_legacy, and Image.from_legacy.""" 

56 assert DATA_DIR is not None, "Guaranteed by decorator." 

57 filename = os.path.join(DATA_DIR, "dp2", "legacy", "visit_image.fits") 

58 image = Image.read_legacy(filename, preserve_quantization=True) 

59 try: 

60 from lsst.afw.image import MaskedImageFitsReader 

61 except ImportError: 

62 raise unittest.SkipTest("'lsst.afw.image' could not be imported.") from None 

63 reader = MaskedImageFitsReader(filename) 

64 legacy_image = reader.readImage() 

65 compare_image_to_legacy(self, image, legacy_image, expect_view=False) 

66 # Converting back to afw will not share memory, because 

67 # preserve_quantization=True makes the array read-only and to_legacy 

68 # has to copy in that case. 

69 compare_image_to_legacy(self, image, image.to_legacy(), expect_view=False) 

70 # Converting from afw will always share memory. 

71 image_view = Image.from_legacy(legacy_image) 

72 compare_image_to_legacy(self, image_view, legacy_image, expect_view=True) 

73 # Converting back to afw from the in-memory view will be another view. 

74 compare_image_to_legacy(self, image_view, image_view.to_legacy(), expect_view=True) 

75 

76 

77if __name__ == "__main__": 

78 unittest.main()