README.md

fitsjs

A standalone JavaScript library for reading the astronomical file format – FITS. This library is built for modern browsers supporting the DataView API. These include at least Chrome 9, Firefox 15, and Safari 6.

To use the library copy lib/fits.js to your project and include it with a script tag. The FITS object is exposed under the astro namespace.

<script src="fits.js" type="text/javascript" charset="utf-8">
</script>

<script type="text/javascript">
  var FITS = astro.FITS;
</script>

This library may be used to read various forms of the FITS format. This implementation is under active development. Currently it supports:

  • Reading multiple header data units
  • Reading images
  • Reading data cubes
  • Reading binary tables
  • Reading ASCII Tables
  • Reading Rice compressed images

Please let me know if you incorporate this library in your project, and please share your application with the rest of the astronomy community.

API

FITS.File

fits.getHDU()

Returns the first HDU containing a data unit. An optional argument may be passed to retrieve a specific HDU.

fits.getHeader()

Returns the header associated with the first HDU containing a data unit. An optional argument may be passed to point to a specific HDU.

fits.getDataUnit()

Returns the data object associated with the first HDU containing a data unit. This method does not read from the array buffer. An optional argument may be passed to point to a specific HDU.

FITS.Header

hdr.get(key)

Returns the value of the key.

hdr.contains(key)

Checks if a key is contained in the header instance.

hdr.hasDataUnit()

Checks if the header has an associated data unit.

Examples

<script src="fits.js" type="text/javascript" charset="utf-8"></script>

<script type="text/javascript">
  var FITS = astro.FITS;

  // Define a callback function for when the FITS file is received
  var callback = function() {

    // Get the first header-dataunit containing a dataunit
    var hdu = this.getHDU();

    // Get the first header
    var header = this.getHeader();

    // or we can do
    var header = hdu.header;

    // Read a card from the header
    var bitpix = header.get('BITPIX');

    // Get the dataunit object
    var dataunit = hdu.data;

    // or we can do
    var dataunit = this.getDataUnit();

    // Do some wicked client side processing ...
  }

  // Set path to FITS file
  var url = "/some/FITS/file/on/your/server.fits";

  // Initialize a new FITS File object
  var fits = new FITS(url, callback);

  // Alternatively, the FITS object may be initialized using the HTML File API.
  var fits = new FITS.File(fileObj, callback);

</script>

TODOs

  • Create examples
  • Remove repeated code that currently implements methods spawning Web Workers
  • Open support for NodeJS
  • Literate CoffeeScript?

Decompression and Dithering Algorithm

Definitions

  • ZDITHER0 = value of the ZDITHER0 keyword
  • Ntile = tile number = row number in the compressed binary table in which that tile is stored ( = 1 for the first tile).
  • N_RANDOM = number of random numbers in the sequence = 10000
  • Rand[N_RANDOM] = 10000 element array of Real*4 random numbers with values that are evenly distributed in the range [0.0 - 1.0]
  • R_i = index to next Rand array value to use (range = 0 - 9999)
  • npix = number of image pixels in the tile
  • Itile[npix] = integer*4 array of scaled values of the pixels in the tile. This array is generated by using the Rice algorithm to uncompress the tile bytes.
  • Ftile[npix] = Real*4 array of values of the pixels in the tile. This array is generated by inverse scaling the Itile array, using the subtractive dithering method.
  • NULL_VALUE = special integer value used to flag null values in the Itile array = -2147483647. These pixels get translated into NaN values in the Ftile array.
  • ZERO_VALUE = special integer value used to flag pixels that had a value of 0.0 in the original Real*4 image = -2147483646. These pixels are not dithered and get set to exactly 0.0 in the Ftile array.
  • scale = scale factor that was used when linearly scaling this tile
  • zero = zero point that was used when linearly scaling this tile

Algorithm

iseed0 = Ntile + ZDITHER0 - 1
iseed1 = (iseed0 - 1) % N_RANDOM
/* set r_i to a random value between 0 - 499 */

r_i = (int) (Rand[iseed1] * 500.)

/* now unscale all the pixel values in the tile */
for (ii = 0; ii < npix; ii++) {
  if (Itile[ii] == NULL_VALUE) {
    /* special case; this is a null value */
    Ftile[ii] = NaN
 } else if (Itile[ii] == ZERO_VALUE) {
   /* special case; this pixel = 0.0 */
   Ftile[ii] = 0.0
 } else {
   /* unscale value using subtractive dithering */
   Ftile[ii] = (float) (((double) Itile[ii] - Rand[r_i] + 0.5) * scale + zero)
 }

 /* increment the index to next random value */
 r_i++
 if (r_i == N_RANDOM) {
   iseed1++
   if (iseed1 == N_RANDOM) iseed1 = 0
   r_i = (int) (Rand[iseed1] * 500.);
  }
}

References

Pence, W. D. Binary Table Extension To FITS.

Pence, W. D., L. Chiappetti, C. G. Page, R. a. Shaw, and E. Stobie. 2010. Definition of the Flexible Image Transport System ( FITS ), version 3.0. Astronomy & Astrophysics 524 (November 22): A42. doi:10.1051/0004-6361/201015362. http://www.aanda.org/10.1051/0004-6361/201015362.

Ponz, J.D., Thompson, R.W., Muñoz, J.R. The FITS Image Extension.

White, Richard L, Perry Greenfield, William Pence, Nasa Gsfc, Doug Tody, and Rob Seaman. 2011. Tiled Image Convention for Storing Compressed Images in FITS Binary Tables: 1-17.

Changes for fitsjs 0.5

Many changes have been made to the library to support large FITS files. Prior, the library attempted to copy an entire file into memory before parsing for information. Now it handles files more intelligently by only copying relevant portions into memory.

During the rewrite, API changes have been made. There is no longer a File object. Instances of FITS files are now initialized:

var f = new astro.FITS(path/to/remote/file, callback);

or using a native HTML5 File instance pointing to a local file.

var f = new astro.FITS(file-instance, callback);