Coverage for tests/test_ndf_model.py: 22%
62 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-05-30 02:13 -0700
« prev ^ index » next coverage.py v7.14.1, created at 2026-05-30 02:13 -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.
12from __future__ import annotations
14import tempfile
15import unittest
17import numpy as np
19try:
20 import h5py
22 from lsst.images.ndf import _hds
23 from lsst.images.ndf._model import HdsPrimitive, Ndf, NdfArray, NdfDocument, NdfQuality, NdfWcs
25 HAVE_H5PY = True
26except ImportError:
27 HAVE_H5PY = False
30def _attr_str(value: object) -> str:
31 if isinstance(value, bytes):
32 return value.decode("ascii")
33 return str(value)
36@unittest.skipUnless(HAVE_H5PY, "h5py is not installed")
37class NdfModelTestCase(unittest.TestCase):
38 """Tests for the Python NDF intermediate representation."""
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)
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"}'])
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)
97if __name__ == "__main__":
98 unittest.main()