Writing FITS files¶
Three builder functions convert numpy / Python data into HDU specs:
fitsy.image()– image HDUs from a numpy arrayfitsy.bintable()– BINTABLE from a column dictfitsy.ascii_table()– ASCII TABLE from a column dict
Hand the resulting list to fitsy.write().
"""Write a new FITS file: image + binary table.
Run from the repo root:
python examples/python/writing_files.py
"""
import os
import tempfile
import fitsy
import numpy as np
img = np.random.default_rng(0).normal(size=(64, 64)).astype("f4")
tbl = {
"RA": np.array([10.0, 11.0, 12.0]),
"DEC": np.array([-5.0, -5.5, -6.0]),
"NAME": ["a", "bb", "ccc"],
}
with tempfile.TemporaryDirectory() as td:
path = os.path.join(td, "out.fits")
fitsy.write(
path,
[
fitsy.image(img, header={"OBJECT": "noise"}),
fitsy.bintable(tbl, extname="CATALOG"),
],
)
# Round-trip: read it back and check.
with fitsy.open(path) as f:
print("HDU count:", len(f))
print("primary axes:", f[0].axes)
print("table columns:", f[1].column_names)
By default fitsy.write() refuses to clobber an existing file.
Pass overwrite=True to replace it.
Headers¶
The header argument to fitsy.image() accepts a plain
dict. Values may be scalars or (value, comment) tuples.
Pixel scaling on write (BSCALE / BZERO)¶
fitsy.image() writes the supplied numpy array verbatim: the
buffer’s dtype determines BITPIX and the pixel bytes are emitted
without further transformation. fitsy does not invert
BSCALE / BZERO from physical units back to a raw integer
representation. This matches the behavior of astropy.io.fits.
Two consequences:
If the input header carries
BSCALEandBZERO, the values in the array are interpreted on read asphysical = BZERO + BSCALE * raw. Writing them back without changing the keywords means the new file’s “raw” pixels are your current array, not the original raw integers.To round-trip a scaled integer image (e.g. one that was opened with
hdu.datareturning floats), drop theBSCALE/BZEROcards from the new header and write the data as the intended dtype, or apply the inverse transform yourself before building the HDU.
Unsigned integer images (uint16, uint32, uint64) are
the one exception: both fitsy.image() and the Rust
ImageBuilder::from_u16 / from_u32 / from_u64
constructors offset-encode pixels into the matching signed
BITPIX and emit BSCALE = 1 with the standard BZERO
offset automatically (FITS Standard Sec.4.4.2.5). Round-tripping
uint* arrays through fitsy is lossless.
ASCII tables¶
For text-formatted TABLE extensions, use
fitsy.ascii_table(). formats overrides the per-column
TFORM; tnulls supplies a string sentinel for None cells
in integer columns.