Import
import { createScientificLibrary, renderScientificPlane } from 'purejsimage/scientific'
import { fitsReader } from 'purejsimage/scientific/readers/fits'Minimal Node.js example
import { createScientificLibrary, renderScientificPlane } from 'purejsimage/scientific'
import { createScientificPathContext } from 'purejsimage/scientific/node'
import { fitsReader } from 'purejsimage/scientific/readers/fits'
const science = createScientificLibrary({ readers: [fitsReader] })
const document = await science.open(await createScientificPathContext('observation.fits'))
console.log(document.datasets)
const dataset = await document.openDataset(document.datasets[0].id)
const display = await renderScientificPlane(dataset, {
plane: { displayAxes: ['x', 'y'], fixedIndices: [{ axisId: 'axis-3', index: 0 }] },
range: { mode: 'percentile', low: 1, high: 99 },
palette: 'magma',
})
for await (const pixels of display.pixels) console.log(pixels.data)Minimal browser example
import { createScientificLibrary } from 'purejsimage/scientific'
import { createScientificFileContext } from 'purejsimage/scientific/browser'
import { fitsReader } from 'purejsimage/scientific/readers/fits'
const input = document.querySelector<HTMLInputElement>('#fits')
const file = input?.files?.[0]
if (!file) throw new Error('Choose a FITS file')
const science = createScientificLibrary({ readers: [fitsReader] })
const document = await science.open(createScientificFileContext(file))
const imageHdu = document.datasets[0]
if (!imageHdu) throw new Error('No supported FITS image array')
const dataset = await document.openDataset(imageHdu.id)
for await (const block of dataset.readPlane({
displayAxes: ['x', 'y'], fixedIndices: [{ axisId: 'axis-3', index: 2 }],
x: 100, y: 100, width: 256, height: 256,
})) console.log(block.data)Supported features
| Feature | Support |
|---|---|
| HDU inspection | Primary and extensions |
| Image arrays | Primary arrays and XTENSION='IMAGE' |
| Axes | NAXIS 1, 2, and 3 |
| BITPIX | 8, 16, 32, -32, -64 |
| Physical values | BSCALE, BZERO, integer BLANK |
| Headers | Typed cards, repeated COMMENT and HISTORY, unknown cards |
Dataset mapping
NAXIS1 maps to labeled axis x, NAXIS2 to y, and higher ranks to stable axis-N IDs with FITS coordinate metadata when present. A one-dimensional array has a synthetic height-1 Y axis. Identity scaling preserves the stored sample type. Standard unsigned 16-bit and 32-bit BZERO conventions use uint16 and uint32 output. Other scaling and integer BLANK conversion use float64 physical values.
Bounded reads
The FITS reader reads aligned 2880-byte header blocks for every HDU, then leaves image data lazy. A selected higher-axis plane uses its direct array offset. A spatial ROI reads the selected contiguous row ranges. Blob, file, memory, HTTP range, and custom ImageSource inputs use the same reader.
Display rendering
renderScientificPlane() maps one selected quantitative plane into display RGB. Percentile calculation is approximate when bounded sampling is used. Display transfers are applied after mapping the selected range to 0 through 1. They do not compute a logarithm, square root, or asinh of the original measurement before range selection.
Unsupported features
ASCII tables, binary tables, random groups, tile-compressed images, Rice compression, gzip wrappers, FITS writing, celestial WCS projection math, SIP distortion, spectral-coordinate interpretation, NAXIS greater than 3, and BITPIX=64 raster samples are not supported. Unsupported HDUs remain inspectable but cannot be opened as rasters.
Official specification
NASA/GSFC FITS Standard · FITS Primer · Official FITS samples
Scientific Raster Explorer · ENVI guide · GSF guide · API · TIFF and OME-TIFF · Whole-slide viewer