CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-fitsio

A full featured python library to read from and write to FITS files

Pending
Overview
Eval results
Files

image-operations.mddocs/

Image Operations

FITS image data handling functionality providing efficient reading, writing, and manipulation of image HDUs with support for subsets, compression, various data types, and numpy-style array operations.

Capabilities

ImageHDU Class

Handler for FITS image extensions with support for reading, writing, compression, and array-like access patterns.

class ImageHDU:
    def read(self, **kwargs):
        """
        Read image data.

        Parameters:
        - **kwargs: additional read options

        Returns:
        numpy array, image data
        """
    
    def write(self, img, start=0):
        """
        Write image data.

        Parameters:
        - img: array-like, image data to write
        - start: int/tuple, starting position for writing subset
        """
    
    def get_dims(self):
        """
        Get image dimensions.

        Returns:
        tuple of int, image dimensions (NAXIS1, NAXIS2, ...)
        """
    
    def reshape(self, dims):
        """
        Change image dimensions on disk.

        Parameters:
        - dims: tuple of int, new dimensions
        """
    
    def is_compressed(self):
        """
        Check if image is tile-compressed.

        Returns:
        bool, True if tile-compressed
        """
    
    def get_comptype(self):
        """
        Get compression type.

        Returns:
        str, compression algorithm name
        """
    
    def has_data(self):
        """
        Check if HDU contains image data.

        Returns:
        bool, True if HDU has data
        """
    
    def __getitem__(self, key):
        """
        Access image data using numpy-style slicing.

        Parameters:
        - key: slice/tuple, numpy-style slice notation

        Returns:
        numpy array, image subset
        """
    
    # Inherited from HDUBase
    def get_info(self):
        """Get complete HDU information."""
    
    def get_offsets(self):
        """Get byte offsets (header_start, data_start, data_end)."""
    
    def get_extnum(self):
        """Get extension number."""
    
    def get_extname(self):
        """Get extension name."""
    
    def get_extver(self):
        """Get extension version."""
    
    def get_exttype(self, num=False):
        """Get extension type."""
    
    def read_header(self):
        """Read header as FITSHDR object."""
    
    def write_key(self, name, value, comment=""):
        """Write single header keyword."""
    
    def write_keys(self, records, clean=True):
        """Write multiple header keywords."""
    
    def write_checksum(self):
        """Write DATASUM/CHECKSUM keywords."""
    
    def verify_checksum(self):
        """Verify data integrity."""

Image Writing with Compression

def write(filename, data, compress=None, qlevel=None, qmethod=None, 
          hcomp_scale=None, **kwargs):
    """
    Write image with compression options.

    Parameters:
    - filename: str, output file path
    - data: array-like, image data
    - compress: str, compression type ('rice', 'gzip', 'plio', 'hcompress')
    - qlevel: float, quantization level (for lossy compression)
    - qmethod: str, quantization method
    - hcomp_scale: float, HCOMPRESS scale parameter
    - **kwargs: additional options
    """

Image Data Types

# Supported numpy data types for images:
# - np.uint8, np.int8
# - np.uint16, np.int16  
# - np.uint32, np.int32
# - np.uint64, np.int64
# - np.float32 (BITPIX = -32)
# - np.float64 (BITPIX = -64)
# - np.complex64, np.complex128

Compression Constants

NOCOMPRESS = 0
RICE_1 = 11        # Rice compression
GZIP_1 = 21        # GZIP compression level 1
GZIP_2 = 22        # GZIP compression level 2
PLIO_1 = 31        # PLIO compression
HCOMPRESS_1 = 41   # HCOMPRESS compression

# Quantization methods for lossy compression
NO_DITHER = -1
SUBTRACTIVE_DITHER_1 = 1
SUBTRACTIVE_DITHER_2 = 2

# Default compression parameters
DEFAULT_QLEVEL = 4.0
DEFAULT_QMETHOD = 'SUBTRACTIVE_DITHER_1'
DEFAULT_HCOMP_SCALE = 0.0

Usage Examples

Reading Images

import fitsio
import numpy as np

# Read entire image
image = fitsio.read('image.fits')
print(f"Image shape: {image.shape}")

# Read specific HDU
image = fitsio.read('multi.fits', ext=1)

# Read with FITS object for more control
with fitsio.FITS('image.fits') as fits:
    # Get image information
    hdu = fits[0]
    dims = hdu.get_dims()
    is_compressed = hdu.is_compressed()
    
    print(f"Dimensions: {dims}")
    print(f"Compressed: {is_compressed}")
    
    # Read entire image
    full_image = hdu.read()
    
    # Read image subsets using slicing
    subset = hdu[100:200, 50:150]  # 100x100 subset
    row = hdu[500, :]              # Single row
    column = hdu[:, 300]           # Single column
    
    # Advanced slicing
    every_other = hdu[::2, ::2]    # Every other pixel
    flipped = hdu[::-1, :]         # Vertically flipped

Writing Images

import fitsio
import numpy as np

# Create sample image
image = np.random.random((512, 512)).astype(np.float32)

# Write uncompressed image
fitsio.write('output.fits', image)

# Write with compression
fitsio.write('compressed.fits', image, compress='rice')

# Write with compression options
fitsio.write('lossy.fits', image, compress='rice', 
             qlevel=8.0, qmethod='SUBTRACTIVE_DITHER_2')

# Write integer data with GZIP
int_image = (image * 1000).astype(np.int16)
fitsio.write('int_compressed.fits', int_image, compress='gzip')

# Write to specific HDU
with fitsio.FITS('multi.fits', 'rw', clobber=True) as fits:
    fits.write(image, extname='IMAGE1')
    fits.write(image * 2, extname='IMAGE2', compress='plio')

Working with Large Images

import fitsio
import numpy as np

# Create large image file
large_image = np.random.random((4096, 4096)).astype(np.float32)
fitsio.write('large.fits', large_image)

with fitsio.FITS('large.fits', 'rw') as fits:
    hdu = fits[0]
    
    # Read small regions without loading entire image
    corner = hdu[0:100, 0:100]
    center = hdu[2000:2100, 2000:2100]
    
    # Write to subset of existing image
    new_data = np.ones((50, 50), dtype=np.float32)
    hdu.write(new_data, start=[1000, 1000])
    
    # Modify image dimensions
    hdu.reshape([2048, 8192])  # Reshape to different aspect ratio

Image Compression Examples

import fitsio
import numpy as np

# Test different compression methods
image = np.random.random((1024, 1024)).astype(np.float32)

# Lossless compression
fitsio.write('lossless_rice.fits', image, compress='rice', qlevel=None)
fitsio.write('lossless_gzip.fits', image, compress='gzip', qlevel=None)

# Lossy compression with quality control
fitsio.write('lossy_rice.fits', image, compress='rice', 
             qlevel=4.0, qmethod='SUBTRACTIVE_DITHER_1')

# HCOMPRESS for smooth images
smooth = np.outer(np.linspace(0, 1, 1024), np.linspace(0, 1, 1024))
fitsio.write('hcompress.fits', smooth, compress='hcompress', 
             hcomp_scale=2.0)

# Check compression ratios
import os
original_size = os.path.getsize('uncompressed.fits')
compressed_size = os.path.getsize('lossless_rice.fits')
ratio = original_size / compressed_size
print(f"Compression ratio: {ratio:.2f}")

Data Type Handling

import fitsio
import numpy as np

# Different data types
uint8_data = np.random.randint(0, 256, (100, 100), dtype=np.uint8)
int16_data = np.random.randint(-32768, 32767, (100, 100), dtype=np.int16)
float32_data = np.random.random((100, 100)).astype(np.float32)
float64_data = np.random.random((100, 100)).astype(np.float64)

# Write each type
fitsio.write('uint8.fits', uint8_data)
fitsio.write('int16.fits', int16_data) 
fitsio.write('float32.fits', float32_data)
fitsio.write('float64.fits', float64_data)

# Read back and check types
data = fitsio.read('uint8.fits')
print(f"Data type: {data.dtype}")  # Should be uint8

# Handle scaling (BSCALE/BZERO)
with fitsio.FITS('scaled.fits') as fits:
    # Check for scaling keywords
    header = fits[0].read_header()
    if 'BSCALE' in header:
        print(f"BSCALE: {header['BSCALE']}")
        print(f"BZERO: {header.get('BZERO', 0.0)}")
    
    # Data is automatically scaled on read
    scaled_data = fits[0].read()

Working with Multi-dimensional Images

import fitsio
import numpy as np

# 3D data cube
cube = np.random.random((50, 256, 256)).astype(np.float32)
fitsio.write('cube.fits', cube)

with fitsio.FITS('cube.fits') as fits:
    hdu = fits[0]
    dims = hdu.get_dims()
    print(f"Cube dimensions: {dims}")  # (256, 256, 50) - FITS order
    
    # Access slices
    first_plane = hdu[:, :, 0]        # First image plane
    middle_plane = hdu[:, :, 25]      # Middle plane
    spectrum = hdu[128, 128, :]       # Spectrum at center pixel
    
    # 4D hypercube
    hypercube = np.random.random((10, 20, 100, 100)).astype(np.float32)
    fitsio.write('hypercube.fits', hypercube)

Image Metadata and Information

import fitsio

with fitsio.FITS('image.fits') as fits:
    hdu = fits[0]
    
    # Get complete HDU information
    info = hdu.get_info()
    print(f"HDU info: {info}")
    
    # Check basic properties
    has_data = hdu.has_data()
    is_compressed = hdu.is_compressed()
    comp_type = hdu.get_comptype() if is_compressed else None
    
    # Get file offsets
    offsets = hdu.get_offsets()
    header_start, data_start, data_end = offsets
    
    print(f"Header starts at byte: {header_start}")
    print(f"Data starts at byte: {data_start}")
    print(f"Data ends at byte: {data_end}")

Install with Tessl CLI

npx tessl i tessl/pypi-fitsio

docs

file-operations.md

header-operations.md

image-operations.md

index.md

table-operations.md

tile.json