Why do the afw image FITS readers use 1-indexing?

afw::image::Image(str,hdu) and afw::image::Mask(str,hdu) both use 1-indexing for HDU counting when reading FITS, with “magic” treatment of hdu=0. This is entirely nonstandard (who 1-indexes FITS files?), and very confusing (specify 0 and you get data, specify 1 and you get an exception, because 0 is empty).

Why is it done this way, and can we please fix it?

See the docs:



I think when we originally decided to do it this way, it was because that’s how CFITSIO and most other FITS-reading software worked (and maybe what the language in the FITS standard used). Since then, the exception (PyFITS and hence AstroPy) has become the rule, at least within the growing community of astronomers that use Python, so I’d personally have no objection to changing this to 0-indexing.

Jim’s correct; remember that the F in FITS logically stands for “Fortran” – e.g. the 1-indexing that the standard uses, and the refusal to support U16 data types in the days that the BZERO/BSCALE hack was a significant computational burden (e.g. SDSS’s DAQ).

I have no objection to changing this.

An additional point: the cfitsio manual says this about HDU indexing:

For example, ’myfile.fits[4]’ opens the 5th HDU in the file (note that the numbering starts with 0), and ’my- file.fits[EVENTS] opens the HDU with the name ’EVENTS’ (as defined by the EXTNAME or HDUNAME keywords). If no HDU is specified then CFITSIO opens the first HDU (the primary array) by default.

Adding more fuel to the fire, apparently cfitsio internally (meaning, when you’re specifying an integer argument to a function instead of a filename string) uses 1 indexing:


Most of the CFITSIO functions which read or write keywords or data operate only on the currently opened HDU in the file. The first routine moves to the specified absolute HDU number in the FITS file (the first HDU = 1)

Also compare sections 4.2 (Current Header Data Unit) and 5.2 (FITS File Access Routines) with section 5.3 (HDU Access Routines), of the manual (cfitsio.pdf) which says:

The first routine moves to a specified absolute HDU number (starting with 1 for the primary array) in the FITS file…