Coverage for tests/test_ndf_starlink_ingest.py: 94%

34 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-06-23 01:52 -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_starlink 

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_starlink()`` 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_starlink(Image, EXAMPLE) 

42 self.assertIsInstance(result, Image) 

43 self.assertEqual(result.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 image = read_starlink(Image, EXAMPLE) 

48 self.assertIsNotNone(image.sky_projection) 

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

50 sky = image.sky_projection.pixel_to_sky_transform.apply_forward( 

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

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

53 ) 

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

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

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

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

58 

59 def test_opaque_fits_metadata_recovered(self): 

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

61 image = read_starlink(Image, EXAMPLE) 

62 opaque = image._opaque_metadata 

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

64 primary = opaque.headers[ExtensionKey()] 

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

66 # FITS dimension keywords regardless of any later processing. 

67 self.assertIn("NAXIS", primary) 

68 self.assertIn("NAXIS1", primary) 

69 self.assertIn("NAXIS2", primary) 

70 

71 

72if __name__ == "__main__": 

73 unittest.main()