Coverage for tests/test_fits_date_header.py: 100%
37 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-16 15:24 -0700
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-16 15:24 -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
14from pathlib import Path
16import astropy.io.fits
17import astropy.time
19from lsst.images import Image
20from lsst.images.fits import ExtensionKey, FitsInputArchive
23def _simple_image() -> Image:
24 return Image(0.0, shape=(4, 4), dtype="float32")
27def test_every_hdu_has_a_fits_compliant_date(tmp_path: Path) -> None:
28 """Test that each HDU carries a DATE card recording approximately when
29 the file was written.
30 """
31 before = astropy.time.Time.now()
32 path = tmp_path / "x.fits"
33 _simple_image().write(path)
34 after = astropy.time.Time.now()
35 with astropy.io.fits.open(path) as hdul:
36 assert len(hdul) > 1
37 for index, hdu in enumerate(hdul):
38 extname = hdu.header.get("EXTNAME", "PRIMARY")
39 assert "DATE" in hdu.header, f"hdu={index} ({extname}): no DATE header"
40 # The value must parse in the FITS time format.
41 date = astropy.time.Time(hdu.header["DATE"], format="fits")
42 # And it must reflect this write, not a stale value.
43 assert date.jd >= before.jd, f"hdu={index} ({extname}): DATE before write started"
44 assert date.jd <= after.jd, f"hdu={index} ({extname}): DATE after write finished"
47def test_update_header_cannot_set_a_stale_primary_date(tmp_path: Path) -> None:
48 """Test that an ``update_header`` callback cannot leave a stale DATE in
49 the primary header.
50 """
51 before = astropy.time.Time.now()
52 path = tmp_path / "x.fits"
53 _simple_image().write(path, update_header=lambda h: h.set("DATE", "1999-01-01T00:00:00"))
54 after = astropy.time.Time.now()
55 with astropy.io.fits.open(path) as hdul:
56 date = astropy.time.Time(hdul[0].header["DATE"], format="fits")
57 assert date.jd >= before.jd
58 assert date.jd <= after.jd
61def test_date_is_not_captured_as_opaque_metadata(tmp_path: Path) -> None:
62 """Test that DATE is not stored in opaque metadata.
64 DATE is regenerated on every write, so the value read back must not
65 be carried in opaque metadata (which would propagate a stale date to
66 the next write).
67 """
68 path = tmp_path / "x.fits"
69 _simple_image().write(path)
70 with FitsInputArchive.open(path) as archive:
71 opaque = archive.get_opaque_metadata()
72 primary_header = opaque.headers[ExtensionKey()]
73 assert "DATE" not in primary_header