A full featured python library to read from and write to FITS files
—
Core FITS file handling functionality providing both high-level convenience functions for simple operations and the FITS class for complete control over file operations, HDU management, and advanced workflows.
The primary interface for reading and writing FITS files with full control over HDU operations, file modes, and advanced features.
class FITS:
def __init__(self, filename, mode='r', lower=False, upper=False,
trim_strings=False, vstorage='fixed', case_sensitive=False,
iter_row_buffer=1, write_bitcols=False, ignore_empty=False,
verbose=False, clobber=False):
"""
Open a FITS file for reading and/or writing.
Parameters:
- filename: str, path to FITS file
- mode: str, file access mode ('r', 'rw', 'r+')
- lower: bool, convert column names to lowercase
- upper: bool, convert column names to uppercase
- trim_strings: bool, remove trailing whitespace from strings
- vstorage: str, variable length storage ('fixed' or 'object')
- case_sensitive: bool, case sensitive column name matching
- iter_row_buffer: int, rows to buffer during iteration
- write_bitcols: bool, write bit columns as FITS bit type
- ignore_empty: bool, ignore empty HDUs
- verbose: bool, print verbose information
- clobber: bool, overwrite existing file
"""
def close(self):
"""Close the FITS file and free resources."""
def write(self, data, extname=None, header=None, **kwargs):
"""
Write data to a new HDU.
Parameters:
- data: array-like, image or table data to write
- extname: str, extension name
- header: dict/list/FITSHDR, header keywords
- **kwargs: additional write options
"""
def write_image(self, img, extname=None, header=None, **kwargs):
"""Write image data to new image HDU."""
def write_table(self, data, extname=None, header=None, **kwargs):
"""Write table data to new table HDU."""
def create_image_hdu(self, **kwargs):
"""Create empty image HDU."""
def create_table_hdu(self, **kwargs):
"""Create empty table HDU."""
def reopen(self):
"""Reopen a closed FITS file."""
def movabs_ext(self, ext):
"""
Move to HDU by absolute extension number.
Parameters:
- ext: int, extension number (0-based)
"""
def movabs_hdu(self, hdunum):
"""
Move to HDU by HDU number.
Parameters:
- hdunum: int, HDU number (0-based)
"""
def movnam_ext(self, extname, hdutype=-1, extver=0):
"""
Move to HDU by extension name.
Parameters:
- extname: str, extension name
- hdutype: int, HDU type filter (default: ANY_HDU)
- extver: int, extension version
"""
def movnam_hdu(self, extname, hdutype=-1, extver=0):
"""
Move to HDU by name.
Parameters:
- extname: str, extension name
- hdutype: int, HDU type filter (default: ANY_HDU)
- extver: int, extension version
"""
def read_raw(self):
"""
Read raw FITS file data.
Returns:
bytes, raw file content
"""
def __getitem__(self, key):
"""
Access HDU by index or name.
Parameters:
- key: int/str/(str,int), HDU index, name, or (name, version)
Returns:
HDU object (ImageHDU, TableHDU, or AsciiTableHDU)
"""
def __contains__(self, key):
"""Check if HDU exists in file."""
def __len__(self):
"""Number of HDUs in file."""
def __iter__(self):
"""Iterate over all HDUs."""
def __enter__(self):
"""Context manager entry."""
def __exit__(self, exc_type, exc_val, exc_tb):
"""Context manager exit with automatic file closure."""High-level functions for common FITS operations without requiring explicit FITS object creation.
def read(filename, ext=None, extver=None, columns=None, rows=None,
header=False, case_sensitive=False, upper=False, lower=False,
vstorage='fixed', verbose=False, trim_strings=False, **kwargs):
"""
Read data from FITS file.
Parameters:
- filename: str, path to FITS file
- ext: int/str, extension number or name (default: first with data)
- extver: int, extension version for duplicate names
- columns: list, column names to read (tables only)
- rows: list/array, specific rows to read (tables only)
- header: bool, return (data, header) tuple if True
- case_sensitive: bool, case sensitive column matching
- upper: bool, convert column names to uppercase
- lower: bool, convert column names to lowercase
- vstorage: str, variable length storage method
- verbose: bool, print verbose information
- trim_strings: bool, remove trailing whitespace
Returns:
numpy array (images) or structured array (tables), optionally with header
"""
def write(filename, data, extname=None, header=None, clobber=False,
compress=None, **kwargs):
"""
Write data to FITS file.
Parameters:
- filename: str, output file path
- data: array-like, data to write
- extname: str, extension name
- header: dict/list/FITSHDR, header keywords
- clobber: bool, overwrite existing file
- compress: str, compression type ('rice', 'gzip', 'plio', 'hcompress')
- **kwargs: additional write options
"""
def read_header(filename, ext=0, extver=None):
"""
Read FITS header without data.
Parameters:
- filename: str, path to FITS file
- ext: int/str, extension number or name
- extver: int, extension version
Returns:
FITSHDR object
"""
def read_scamp_head(filename, header=None):
"""
Read SCAMP .head file format.
Parameters:
- filename: str, path to .head file
- header: FITSHDR, existing header to update
Returns:
FITSHDR object
"""import fitsio
# Open file for reading
with fitsio.FITS('data.fits') as fits:
print(f"File has {len(fits)} HDUs")
# Check what's in the file
for i, hdu in enumerate(fits):
print(f"HDU {i}: {hdu.get_exttype()}")
# Read data using convenience function
data = fitsio.read('data.fits', ext=1)
header = fitsio.read_header('data.fits', ext=1)
# Read with header
data, header = fitsio.read('data.fits', ext=1, header=True)import numpy as np
import fitsio
# Create sample data
image = np.random.random((100, 100))
table_data = np.zeros(50, dtype=[('x', 'f8'), ('y', 'f8'), ('flux', 'f4')])
# Write using convenience function
fitsio.write('output.fits', image, clobber=True)
# Write with compression
fitsio.write('compressed.fits', image, compress='rice', clobber=True)
# Write multiple HDUs
with fitsio.FITS('multi.fits', 'rw', clobber=True) as fits:
fits.write(image, extname='IMAGE')
fits.write(table_data, extname='CATALOG')# Open for read-write to modify existing file
with fitsio.FITS('data.fits', 'rw') as fits:
# Read existing data
old_data = fits[1].read()
# Append new rows to table
new_rows = np.zeros(10, dtype=old_data.dtype)
fits[1].append(new_rows)
# Write new HDU
fits.write(np.random.random((50, 50)), extname='NEW_IMAGE')with fitsio.FITS('data.fits') as fits:
# Access by index
primary = fits[0]
table = fits[1]
# Access by name
if 'CATALOG' in fits:
catalog = fits['CATALOG']
# Access with version
if ('SCI', 2) in fits:
science = fits['SCI', 2]
# Iterate over all HDUs
for hdu in fits:
if hdu.has_data():
print(f"HDU has {hdu.get_exttype()} data")Install with Tessl CLI
npx tessl i tessl/pypi-fitsio