fits

package module
v0.0.0-...-ad7800d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 2, 2020 License: MIT Imports: 7 Imported by: 0

README

Copyright 2014 Shahriar Iravanian (siravan@svtsim.com). All rights reserved. Use of this source code is governed by a MIT license that can be found in the LICENSE file.

Package fits reads and processes FITS files. It is written in pure golang and is not a wrapper around another library or a direct translation of another library to golang. The main purpose is to provide a native golang solution to reading FITS file and to assess the suitability of golang for scientific and numerical applications.

FITS is a common open-source format for storage and transmission of astronomical images and data. This package is based on version 3.0 of the FITS standard.

The following features are supported in the current version:

1. Images with all six different data format (byte, int16, int32, int64, float32, and float64)
2. Text and binary tables with atomic and fixed-size array elements

The following features are not yet implemented:

1. Automatic application of BSCALE/BZERO
2. Random group structure
3. Variable length arrays in binary tables
4. World coordinate system

Also note that currently this package provides only read capability and does not write/generate a FITS file.

The basic usage of the package is by calling Open function. It accepts a reader that should provide a valid FITS file. The output is a []*fits.Unit, where Unit represents a Header/Data Unit (i.e. a header with the corresponding data). Unit provides a set of variables and functions to access the HDU data.

Let 'test.fits' be a FITS file with two HDU. The first one is of type SIMPLE and contains a single two-dimensional image with the following parameters:

BITPIX  =  -32
NAXIS   =  2
NAXIS1  =  512
NAXIS2  =  256

The second HDU contains a binary table (XTENSION=BINTABLE):

BITPIX  =  8
NAXIS   =  2
NAXIS1  =  100
NASIX2  =  5
TFIELDS =  10
TFORM1  =  E
TTYPE   =  FLUX
TDISP1  =  F10.4

To read this file, we first call

units := fits.Open("test.fits")

Now, units[0] points to the first HDU. We can access the header keys by using units.Keys map. For example, units[0].Keys["BITPIX"].(int) returns -32. Note that Keys stores interface{} and appropriate type-assertion needs to be done. Unit.Naxis returns a slice of integers ([]int) containing all NAXIS data. For example, units[0].Naxis is equal to [512, 256]. We can access the image data points by using one of the three accessor functions: Unit.At, Unit.IntAt and Unit.FloatAt. Each function accepts NAXIS integer arguments and returns the pixel value at that location. Unit.At returns an interface{} and needs to be type-asserted before use. Unit.IntAt and Unit.FloatAt return int64 and float64, respectively.

For table data, we use two other accessor functions: Field and Format. Field accepts one argument, col, that define a field. It can be 0-based int or a string. For example, units[1].Field(0) and units[1].Field("FLUX") both points to the same column. The return value of Field is another function, which is the actual accessor function and accepts one int argument representing a row. For example, units[1].Field("Flux")(1) returns the value of column "FLUX" in the second row of the table as interface{}. The following code populates a slice of float with the value of the FLUX column (note that Naxis[0] is the number of bytes in a row and Naxis[1] is the number of rows):

fn := units[1].Field("FLUX")
x := make([]float32, units[1].Naxis[1])     
for row := range x {
    x[row] = fn(row).(float32)
}

Format function on the hand accepts two arguments, col (same as Field) and row and return a string formatted according to TDISP for the field. For example, if units[1].Field("Flux")(1) is equal to 987.654321, then units[1].Format("Flux", 1) returns "987.6543".

Documentation

Overview

Copyright 2014 Shahriar Iravanian (siravan@svtsim.com). All rights reserved. Use of this source code is governed by a MIT license that can be found in the LICENSE file.

Package fits reads and processes FITS files. It is written in pure golang and is not a wrapper around another library or a direct translation of another library to golang. The main purpose is to provide a native golang solution to reading FITS file and to assess the suitability of golang for scientific and numerical applications.

FITS is a common format for astronomical image and data. This package is based on version 3.0 of the FITS standard:

Pence W.D., Chiappetti L., Page C. G., Shaw R. A., Stobie E. Definition of the Flexible Image Transport System (FITS), version 3.0. A&A 524, A42 (2010)
http://www.aanda.org/articles/aa/abs/2010/16/aa15362-10/aa15362-10.html

The following features are supported in the current version:

  1. Images with all six different data format (byte, int16, int32, int64, float32, and float64)
  2. Text and binary tables with atomic and fixed-size array elements

The following features are not yet implemented:

  1. Automatic application of BSCALE/BZERO
  2. Random group structure
  3. Variable length arrays in binary tables
  4. World coordinate system

Also note that currently this package provides only read capability and does not write/generate a FITS file.

The basic usage of the package is by calling Open function. It accepts a reader that should provide a valid FITS file. The output is a []*fits.Unit, where Unit represents a Header/Data Unit (i.e. a header with the corresponding data). Unit provides a set of variables and functions to access the HDU data.

Let 'test.fits' be a FITS file with two HDU. The first one is of type SIMPLE and contains a single two-dimensional image with the following parameters:

BITPIX  =  -32
NAXIS   =  2
NAXIS1  =  512
NAXIS2  =  256

The second HDU contains a binary table (XTENSION=BINTABLE):

BITPIX  =  8
NAXIS   =  2
NAXIS1  =  100
NASIX2  =  5
TFIELDS =  10
TFORM1  =  E
TTYPE   =  FLUX
TDISP1  =  F10.4

To read this file, we first call

units := fits.Open("test.fits")

Now, units[0] points to the first HDU. We can access the header keys by using units.Keys map. For example, units[0].Keys["BITPIX"].(int) returns -32. Note that Keys stores interface{} and appropriate type-assertion needs to be done. Unit.Naxis returns a slice of integers ([]int) containing all NAXIS data. For example, units[0].Naxis is equal to [512, 256]. We can access the image data points by using one of the three accessor functions: Unit.At, Unit.IntAt and Unit.FloatAt. Each function accepts NAXIS integer arguments and returns the pixel value at that location. Unit.At returns an interface{} and needs to be type-asserted before use. Unit.IntAt and Unit.FloatAt return int64 and float64, respectively.

For table data, we use two other accessor functions: Field and Format. Field accepts one argument, col, that define a field. It can be 0-based int or a string. For example, units[1].Field(0) and units[1].Field("FLUX") both points to the same column. The return value of Field is another function, which is the actual accessor function and accepts one int argument representing a row. For example, units[1].Field("Flux")(1) returns the value of column "FLUX" in the second row of the table as interface{}. The following code populates a slice of float with the value of the FLUX column:

fn := units[1].Field("FLUX")
x := make([]float32, units[1].Naxis[1])     // note Naxis[0]=NAXIS1=length of a row, Naxis[1]=NAXIS2=number of rows
for row := range x {
    x[row] = fn(row).(float32)
}

Format function on the hand accepts two arguments, col (same as Field) and row and return a string formatted according to TDISP for the field. For example, if units[1].Field("Flux")(1) is equal to 987.654321, then units[1].Format("Flux", 1) returns "987.6543".

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Nth

func Nth(prefix string, n int) string

Nth returns a string resulted from concatenation of prefix and n in string form it is a stateless helper function

Types

type FieldFunc

type FieldFunc func(row int) interface{}

FieldFunc are the type of accessor functions returned by Unit.Field() FieldFunc is used to access the value of cells in a text or binary table (XTENSION=TABLE or XTENSION=BINTABLE)

type Reader

type Reader struct {
	// contains filtered or unexported fields
}

Reader is a buffered Reader implementation that works based on the FITS block structure (each 2880 bytes long)

func NewReader

func NewReader(reader io.Reader) *Reader

NewReader generates a new fits.Reader that wraps the given reader 2880 is the standard FITS file block size

func (*Reader) IsEOF

func (b *Reader) IsEOF() bool

IsEOF returns if b is finished

func (*Reader) NewHeader

func (b *Reader) NewHeader() (h *Unit, err error)

NewHeader reads and processes the next header from the a the reader stream its main function is to populate Keys and setups Naxis

func (*Reader) NextPage

func (b *Reader) NextPage() (buf []byte, err error)

NextPage skips the rest of the current 2880-byte block and reads the next block

func (*Reader) Read

func (b *Reader) Read(p []byte) (n int, err error)

Read populates p while taking care of the FITS file block structure

func (*Reader) ReadBool

func (b *Reader) ReadBool() bool

func (*Reader) ReadByte

func (b *Reader) ReadByte() byte

func (*Reader) ReadFloat32

func (b *Reader) ReadFloat32() float32

ReadInt16 reads a float32 encoded in big-endian binary

func (*Reader) ReadFloat64

func (b *Reader) ReadFloat64() float64

ReadInt16 reads a float64 encoded in big-endian binary

func (*Reader) ReadInt16

func (b *Reader) ReadInt16() int16

ReadInt16 reads an int16 encoded in big-endian binary Note that the FITS standard supports only big-endian binaries

func (*Reader) ReadInt32

func (b *Reader) ReadInt32() int32

ReadInt16 reads an int32 encoded in big-endian binary

func (*Reader) ReadInt64

func (b *Reader) ReadInt64() int64

ReadInt16 reads an int64 encoded in big-endian binary

func (*Reader) ReadString

func (b *Reader) ReadString(n int) string

type Unit

type Unit struct {
	Keys  map[string]interface{}
	Naxis []int // len(Naxis) is equal to the value of NASIX in the header
	// Naxis[k] is equal to NAXIS{k+1} in the header
	Data interface{}

	At func(a ...int) interface{} // Accessor function that returns the value of a pixel based on its coordinates
	// a... represents NAXIS integers corresponding to NAXIS1, NAXIS2,...
	// The return result type is interface{}. The concrete type is determined by BITPIX
	IntAt   func(a ...int) int64   // A helper accessor function that returns the pixel value as int64
	FloatAt func(a ...int) float64 // A helper accessor function that returns the pixel value as float64
	Blank   func(a ...int) bool    // returns true if pixel type is integral and the pixel pointed by a... is equal to blank,
	// contains filtered or unexported fields
}

Unit stored the header and data of a single HDU (Header Data Unit) as defined by FITS standard Data points to a flat array holding the HDU data Its type is []byte for tables and is determined by BITPIX for images:

BITPIX  Data
8       []byte
16      []int16
32      []int32
64      []int64
-32     []float32
-64     []float64

func Open

func Open(reader io.Reader) (fits []*Unit, err error)

Open processes a FITS file provided as an io.Reader and returns a list of HDUs in the FITS file It is the main entry point of the fits package

func (*Unit) Bitpix

func (h *Unit) Bitpix() int

Bitpix is a helper function the simply returns BITPIX value in the header

func (*Unit) Field

func (h *Unit) Field(col interface{}) FieldFunc

Field returns a FieldFunc corresponding to col If col is int, the col'th field is returned (note: col is 0 based, so col=1 means TFORM2) If col a string, the field with TDISP equal to col is returned Fields are held in a map (Unit.fields) based on their name (TDISP). In addition, for each field, an entry with key "#name" is added to Unit.fields to facilitate the search for TDISP based on the name

Note: this function returns an accessor function, that needs to be called to obtain the actual cell value For example, assume h is a table. One of its column is named "ID" of type "J" (int32) To obtain the value of the cell located at the intersection of the third row (row=2) and column "ID", we write

fn := h.Field("ID")
val := fn(2).(int32)

func (*Unit) Format

func (h *Unit) Format(col interface{}, row int) string

Format returns a formatted string based on the given col and row and TDISP of the col col can be an int or a string (same as Field) The return value is a string, which is obtained by

  1. Finding the FieldFunc based on col
  2. Running the FieldFunc by passing row as an argument
  3. Applying format to the result

func (*Unit) HasImage

func (h *Unit) HasImage() bool

HasImage returns true is the Unit is either SIMPLE or IMAGE and has the data for an actual image

func (*Unit) HasTable

func (h *Unit) HasTable() bool

HasImage returns true is the Unit is either TABLE or BINTABLE and has the data for an actual table

func (*Unit) Stats

func (h *Unit) Stats() (min float64, max float64)

Stats returns the minimum and maximum values in the image data

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL