GitHunt
FE

FerreolS/AstroFITS.jl

An easy way to handle FITS files in Julia

Easy reading/writing of FITS files in Julia

Doc
License
Build Status
Build status
Coverage
Aqua QA

AstroFITS is a Julia package designed to make it easier to read
and write data in FITS format without
sacrificing performances, flexibility, or readability.

A few examples

The full documentation is available on-line.

The Flexible Image Transport System (or
FITS for short) is a file format widely
used in Astronomy to store many kinds of data (images, tables, etc.) and metadata. FITS
files consist in a concatenation of Header Data Units (HDUs) which each have a header part
(with textual metadata) followed by a data part.

The following example demonstrates how to write a FITS file with 3 HDUs, an Image
Extension
and two Table Extensions:

using Dates, AstroFITS
filename = "/tmp/test.fits";
arr = rand(Float32, (3,4,5));
nrows = 20;
inds = 1:nrows;
speed = rand(Float64, nrows);
mass = rand(Float32, nrows);
position = rand(Float32, 3, nrows);
phase = (1:7) .// 3;
amplitude = exp.(-1:-1:-7);
x = amplitude.*cos.(phase);
y = amplitude.*sin.(phase);
writefits(filename,
          #-----------------------------------------------------------------
          # First HDU must be a FITS "image", but data may be empty.
          #
          # Header part as a vector of `key=>val` or `key=>(val,com)` pairs:
          ["DATE"    => (now(), "date of creation"),
           "HISTORY" => "This file has been produced by AstroFITS",
           "USER"    => ENV["USER"]],
          # Data part as an array:
          arr,
          #-----------------------------------------------------------------
          # Second HDU, here a FITS "table".
          #
          # Header part of 2nd HDU as a tuple of pairs:
          ("EXTNAME" => ("MY-EXTENSION", "Name of this extension"),
           "EXTVER"  => (1, "Version of this extension")),
          # Data part is a table in the form of a named tuple:
          (Speed    = (speed, "km/s"),  # this column has units
           Indices  = inds,             # not this one
           Mass     = (mass, "kg"),
           Position = (position, "cm")),
          #-----------------------------------------------------------------
          # Third HDU, another FITS "table".
          #
          # Header part of 3rd HDU as a named tuple (note that keywords must
          # be in uppercase letters):
          (EXTNAME = ("MY-OTHER-EXTENSION", "Name of this other extension"),
           EXTVER  = (1, "Version of this other extension"),
           COMMENT = "This is an interesting comment"),
          # Data part is a table in the form of a vector of pairs (column names
          # can be strings or symbols but not a mixture):
          [:phase => ((180/π).*phase, "deg"),
           :amplitude => (amplitude, "V"),
           :xy => (hcat(x,y)', "V")])

Each HDU has a header part (the metadata) and a data part which is reflected by the pairs of
arguments afterfilename, the name of the file, in the above call to writefits. The
headers are provided by collections (a vector for the 1st one, a tuple for the 2nd one) of
pairs or by a named tuples (3rd one) associating a keyword with a value and a comment (both
optional). In a FITS Image Extension, the data can be any real-valued Julia array. In a
FITS Table Extension , the data part is provided by a collection of column names
associated with columns values and optional units. The columns in a FITS table must have the
same trailing dimension (interpreted as the rows of the table) but may have different
leading dimensions corresponding to the sizes of the column cells. In the above example, the
"Position" column has 3 values per cell (presumably the 3D coordinates), while other
columns have a single value per cell. Note that the 1st HDU, so-called Primary HDU, of a
FITS file must be a Fits Image (possibly empty), not a FITS Table.

To read the headers of the 1st and 2nd HDU of the file:

hdr1 = readfits(FitsHeader, filename) 
hdr2 = readfits(FitsHeader, filename, ext=2)

yield two instance of FitsHeader. Reading the data parts is very easy:

dat1 = readfits(filename)
dat2 = readfits(filename, ext=2)

will yield an array dat1 equal to arr and a dictionary dat2 indexed by the column
names (in uppercase letters by default). For example:

dat2["SPEED"] == speed

should hold.

The FITSIO package is another alternative to
read/write FITS files. AstroFITS is no longer based on FITSIO and now directly call the
functions of the CFITSIO library as provided by CFITSIO_jll artifact and uses
FITSHeaders to parse metadata (FITS header
cards).

Languages

Julia99.6%Shell0.3%Emacs Lisp0.1%

Contributors

Other
Created February 16, 2026
Updated March 12, 2026
FerreolS/AstroFITS.jl | GitHunt