Coverage for tests/test_ndf_model.py: 22%

62 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-06-03 08:08 +0000

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 tempfile 

15import unittest 

16 

17import numpy as np 

18 

19try: 

20 import h5py 

21 

22 from lsst.images.ndf import _hds 

23 from lsst.images.ndf._model import HdsPrimitive, Ndf, NdfArray, NdfDocument, NdfQuality, NdfWcs 

24 

25 HAVE_H5PY = True 

26except ImportError: 

27 HAVE_H5PY = False 

28 

29 

30def _attr_str(value: object) -> str: 

31 if isinstance(value, bytes): 

32 return value.decode("ascii") 

33 return str(value) 

34 

35 

36@unittest.skipUnless(HAVE_H5PY, "h5py is not installed") 

37class NdfModelTestCase(unittest.TestCase): 

38 """Tests for the Python NDF intermediate representation.""" 

39 

40 def test_ndf_document_writes_standard_components(self) -> None: 

41 image = np.arange(6, dtype=np.float32).reshape(2, 3) 

42 quality = np.array([[0, 1, 0], [1, 0, 0]], dtype=np.uint8) 

43 wcs_lines = [" Begin FrameSet", " End FrameSet"] 

44 document = NdfDocument(root=Ndf(), root_name="TEST") 

45 document.root.set_array_component("DATA_ARRAY", image, origin=(20, 10)) 

46 document.root.set_quality( 

47 NdfQuality( 

48 NdfArray( 

49 quality, 

50 origin=np.array([20, 10], dtype=np.int32), 

51 bad_pixel=False, 

52 ) 

53 ) 

54 ) 

55 document.root.set_wcs(NdfWcs(wcs_lines)) 

56 document.root.set_units("adu") 

57 lsst = document.root.ensure_lsst_extension() 

58 lsst.children["JSON"] = HdsPrimitive.char_array(['{"kind":"image"}'], width=80) 

59 

60 with tempfile.NamedTemporaryFile(suffix=".sdf") as tmp: 

61 with h5py.File(tmp.name, "w") as f: 

62 document.write_to_hdf5(f) 

63 with h5py.File(tmp.name, "r") as f: 

64 self.assertEqual(_attr_str(f["/"].attrs[_hds.ATTR_CLASS]), "NDF") 

65 self.assertEqual(_attr_str(f["/"].attrs[_hds.ATTR_ROOT_NAME]), "TEST") 

66 self.assertEqual(_attr_str(f["/DATA_ARRAY"].attrs[_hds.ATTR_CLASS]), "ARRAY") 

67 np.testing.assert_array_equal(f["/DATA_ARRAY/DATA"][()], image) 

68 np.testing.assert_array_equal(f["/DATA_ARRAY/ORIGIN"][()], np.array([20, 10])) 

69 self.assertEqual(_attr_str(f["/QUALITY"].attrs[_hds.ATTR_CLASS]), "QUALITY") 

70 self.assertEqual(f["/QUALITY/BADBITS"][()], 255) 

71 np.testing.assert_array_equal(f["/QUALITY/QUALITY/DATA"][()], quality) 

72 self.assertEqual(f["/QUALITY/QUALITY/BAD_PIXEL"].id.get_type().get_class(), h5py.h5t.BITFIELD) 

73 self.assertEqual(_attr_str(f["/WCS"].attrs[_hds.ATTR_CLASS]), "WCS") 

74 self.assertEqual(_hds.read_char_array(f["/WCS/DATA"]), wcs_lines) 

75 self.assertEqual(f["/UNITS"].shape, ()) 

76 self.assertEqual(f["/UNITS"][()].decode("ascii").rstrip(" "), "adu") 

77 self.assertEqual(_hds.read_char_array(f["/MORE/LSST/JSON"]), ['{"kind":"image"}']) 

78 

79 def test_document_read_preserves_typed_ndf_components(self) -> None: 

80 image = np.arange(4, dtype=np.int16).reshape(2, 2) 

81 with tempfile.NamedTemporaryFile(suffix=".sdf") as tmp: 

82 with h5py.File(tmp.name, "w") as f: 

83 document = NdfDocument(root=Ndf(), root_name="READ") 

84 document.root.set_array_component("DATA_ARRAY", image, origin=(5, 6)) 

85 document.root.set_units("count") 

86 document.write_to_hdf5(f) 

87 with h5py.File(tmp.name, "r") as f: 

88 recovered = NdfDocument.from_hdf5(f) 

89 self.assertIsInstance(recovered.root, Ndf) 

90 self.assertEqual(recovered.root_name, "READ") 

91 self.assertEqual(recovered.root.get_units(), "count") 

92 data = recovered.get("/DATA_ARRAY/DATA") 

93 self.assertIsInstance(data, HdsPrimitive) 

94 np.testing.assert_array_equal(data.read_array(), image) 

95 

96 

97if __name__ == "__main__": 

98 unittest.main()