Comparing files¶
fitsy.diff() compares two FITS files HDU-by-HDU and returns a
fitsy.FitsDiff object that is falsy when the files are
identical and stringifies into a human-readable report.
Tunables:
rtol/atol– relative and absolute tolerance for every floating-point comparison: header card values, image pixels, and table cells. Combined as|a - b| <= atol + rtol * |b|(thenumpy.iscloseform). Both default to0.0, i.e. exact equality.rtolalone cannot reconcile values straddling zero, which is whatatolis for.max_diffs– cap on per-HDU difference reports.ignore_keywords– header keywords to skip (e.g."CHECKSUM","DATASUM","DATE").
What gets compared¶
Image pixels, numerically and in physical units –
BZERO/BSCALEapplied,BLANKmapped to NaN. Reported indices are pixel numbers and reported values are decoded pixels, so two files that store the same physical image with differentBSCALEcompare equal on data.Tile-compressed images, on their decompressed pixels, so re-compressing a file with different tile bytes is not a data difference.
Table cells, per column, in decoded (post-
TSCAL/TZERO) values. Differences are reported asCOLUMN[row].Random-groups HDUs, and HDUs whose
XTENSIONfitsy does not recognize, are the gap: they have no decoded form and report a single byte-level “differs” verdict.
Byte-identical data whose scaling cards also match short-circuits
before any decoding – the common case for files that match.
Otherwise both data sections are decoded, which costs rather more
than reading the files: image pixels decode to float64, so
comparing two BITPIX = 16 images holds four times the on-disk
size in memory per side.
Example¶
"""Compare two FITS files with `fitsy.diff`.
Run from the repository root:
python examples/python/diff.py
"""
import os
import tempfile
import fitsy
import numpy as np
with tempfile.TemporaryDirectory() as td:
a = os.path.join(td, "a.fits")
b = os.path.join(td, "b.fits")
img = np.arange(64, dtype="f4").reshape(8, 8)
fitsy.write(a, [fitsy.image(img, header={"OBJECT": "before"})])
img2 = img.copy()
img2[0, 0] = 99.0
fitsy.write(b, [fitsy.image(img2, header={"OBJECT": "after"})])
d = fitsy.diff(a, b, rtol=0.0, max_diffs=10)
print("identical?", d.identical)
print("hdu_counts:", d.hdu_counts)
print(d) # multi-line human-readable summary
# Ignore non-physical keyword churn (e.g. CHECKSUM) for round-trip
# comparisons of independently-written files.
d2 = fitsy.diff(a, b, ignore_keywords=["OBJECT"])
print("after ignoring OBJECT:", d2.identical)