Coverage for tests / test_ndf_starlink_ingest.py: 43%

35 statements  

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

12from __future__ import annotations 

13 

14import os 

15import unittest 

16 

17import numpy as np 

18 

19from lsst.images import Image 

20from lsst.images.fits._common import ExtensionKey 

21 

22try: 

23 from lsst.images.ndf import read 

24 

25 HAVE_H5PY = True 

26except ImportError: 

27 HAVE_H5PY = False 

28 

29# Starlink-generated NDF fixture (M57 image, hds-v5 HDF5). 

30EXAMPLE = os.path.join(os.path.dirname(__file__), "data", "example-ndf.sdf") 

31 

32 

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

34class StarlinkIngestTestCase(unittest.TestCase): 

35 """Integration tests that read a real Starlink-produced NDF via the 

36 auto-detect ``ndf.read()`` path. 

37 """ 

38 

39 def test_round_trips_to_image(self): 

40 """Auto-detect path returns an Image with the correct array shape.""" 

41 result = read(Image, EXAMPLE) 

42 self.assertIsInstance(result.deserialized, Image) 

43 self.assertEqual(result.deserialized.array.shape, (611, 609)) 

44 

45 def test_wcs_produces_projection(self): 

46 """Auto-detect path builds a Projection from the NDF WCS component.""" 

47 result = read(Image, EXAMPLE) 

48 image = result.deserialized 

49 self.assertIsNotNone(image.projection) 

50 # M57 (Ring Nebula) is near RA~283.4 deg, Dec~33.0 deg. 

51 sky = image.projection.pixel_to_sky_transform.apply_forward( 

52 x=np.array([300.0]), 

53 y=np.array([300.0]), 

54 ) 

55 ra_deg = float(np.degrees(sky.x[0])) 

56 dec_deg = float(np.degrees(sky.y[0])) 

57 self.assertAlmostEqual(ra_deg, 283.4, delta=0.5) 

58 self.assertAlmostEqual(dec_deg, 33.0, delta=0.5) 

59 

60 def test_opaque_fits_metadata_recovered(self): 

61 """MORE/FITS cards are surfaced in ``_opaque_metadata``.""" 

62 result = read(Image, EXAMPLE) 

63 opaque = result.deserialized._opaque_metadata 

64 self.assertIn(ExtensionKey(), opaque.headers) 

65 primary = opaque.headers[ExtensionKey()] 

66 # The fixture is a real Starlink M57 NDF; MORE/FITS carries standard 

67 # FITS dimension keywords regardless of any later processing. 

68 self.assertIn("NAXIS", primary) 

69 self.assertIn("NAXIS1", primary) 

70 self.assertIn("NAXIS2", primary) 

71 

72 

73if __name__ == "__main__": 

74 unittest.main()