July 1, 2019

Grinder - FITS files

These can be extremely simple. In the simple case you have a header unit, followed by a data unit. The header unit is a series of 80 byte "card image" records (no newlines) as a quaint reminder of card-decks and yesteryear. This is followed, at the next 2880 byte boundary, by the data unit, which is simply image data. One 2880 byte block can hold 36 card records, and is usually plenty. It is padded with blanks.

Each header record is a KEY = value / comment type thing, so you can use your favorite text file viewer (I use od -x) to look at a FITS file and see the headers. The last header says "END".

If you have more than one HDU (header and data unit), the additional ones are called "Extension" HDU's. The simple files I deal with don't have these.

If you write short files, they will almost certainly be 5760 bytes in size. The header section will be a 2880 byte block, padded at the end with blanks. The data section will have your data at the front, and be padded with zeros to the end of the file.

Libraries to read and write FITS files

There are lots of these, for various languages. If you plan to use C, the CFITSIO library is the reference library, and is a likely choice.

Arrays and indexes

If you intend to use a 2-dimensional C array to hold your image, you will need to get that straight. Let us say you want to have 100 rows, each with 4 columns. You would declare:
int image[100][4];
There are two ways to think about this. One is that this is an array of 100 items, and each of those items is an array of 4 elements. This is the reverse of FORTRAN, by the way, if you have any mental logjams involving how FORTRAN handled multidimensional arrays. If the idea of rows and columns appeals to your mind, think of this as 100 rows and 4 columns. In memory, this is all linear of course, and the order is:
image[0][0], image[0][1], image[0][2], image[0][3], image[1][0], image[1][1],
image[1][2], image[1][3], ....
If you have such an array, and pass it to CFITSIO, the order is maintained just as in memory.

My files

Here is the header from a completed file:
SIMPLE  =                    T  /  FITS STANDARD
BITPIX  =                  -32  /  FITS BITS/PIXEL
NAXIS   =                    2  /  NUMBER OF AXES
NAXIS1  =                   66  /
NAXIS2  =                 1440  /
OBJECT  = 'adcv181001'          /
ORIGIN  = 'KPNO-IRAF'           /
DATE    = '2019-06-03T18:31:35'
IRAFNAME= 'adcv181001'          /  NAME OF IRAF IMAGE FILE
IRAF-MAX=           0.000000E0  /  DATA MAX
IRAF-MIN=           0.000000E0  /  DATA MIN
IRAF-BPX=                   32  /  DATA BITS/PIXEL
IRAFTYPE= 'REAL    '            /  PIXEL TYPE
FIRSTCOL=                    1
LASTCOL =                 1440
END
Here is the header from a file in progress:
SIMPLE  =                    T  /  FITS STANDARD
BITPIX  =                  -32  /  FITS BITS/PIXEL
NAXIS   =                    2  /  NUMBER OF AXES
NAXIS1  =                   66  /
NAXIS2  =                 1440  /
OBJECT  = 'adcv190603'          /
ORIGIN  = 'KPNO-IRAF'           /
DATE    = '2019-06-03T18:27:34'
IRAFNAME= 'adcv190603'          /  NAME OF IRAF IMAGE FILE
IRAF-MAX=           0.000000E0  /  DATA MAX
IRAF-MIN=           0.000000E0  /  DATA MIN
IRAF-BPX=                   32  /  DATA BITS/PIXEL
IRAFTYPE= 'REAL    '            /  PIXEL TYPE
FIRSTCOL=                    1
LASTCOL =                  685
END
Note the setting for LASTCOL. The following statements come from SPP code in lgdata.x. Usually FIRSTCOL gets set to 1, but when the logger first starts up, this is not so (so the first file for a Casting will start somewhere into the day). When the first record is written, LASTCOL = FIRSTCOL and usually these are both 1. As new records arrive, their index in the image is derived from the time of day!
x = TM_HOUR(tm)*60 + TM_MIN(tm)+1
call imaddi (im, "FIRSTCOL", x)
call imaddi (im, "LASTCOL", x)
The largest data file is the TTMP file, which is 4150080 bytes. This has records (rows) that have 720 values, so the "image" size is 4*720*1440 = 4147200 bytes


Have any comments? Questions? Drop me a line!

Tom's home page / tom@mmto.org