header

package
v1.2.1 Latest Latest
Warning

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

Go to latest
Published: Apr 14, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package header implements FITS header-card parsing and serialization.

A FITS header is a sequence of fixed-width 80-byte "cards" grouped into 2880-byte blocks. Every card has a keyword in columns 1–8 (or the extended HIERARCH form in columns 1–8 + columns 9..), optionally followed by the value indicator "= " in columns 9–10 and a value field that may carry a string, logical, integer, floating-point, or complex value, followed by an optional "/ comment" field.

Reference: FITS Standard v4.0 §4.1, §4.2, Appendix A.

Index

Constants

View Source
const (
	KeySimple   = "SIMPLE"
	KeyBitpix   = "BITPIX"
	KeyNaxis    = "NAXIS"
	KeyXtension = "XTENSION"
	KeyEnd      = "END"
	KeyExtname  = "EXTNAME"
	KeyExtver   = "EXTVER"
	KeyExtlevel = "EXTLEVEL"
	KeyPcount   = "PCOUNT"
	KeyGcount   = "GCOUNT"
	KeyTfields  = "TFIELDS"
)

Mandatory structural keywords.

View Source
const (
	KeyComment = "COMMENT"
	KeyHistory = "HISTORY"
	KeyBlank   = "" // blank keyword
)

Commentary keywords.

View Source
const (
	KeyBscale = "BSCALE"
	KeyBzero  = "BZERO"
	KeyBlankV = "BLANK" // "BLANK" keyword (distinct from blank keyword constant)
	KeyBunit  = "BUNIT"
)

Scaling keywords.

View Source
const (
	XtensionImage    = "IMAGE"
	XtensionBinTable = "BINTABLE"
	XtensionTable    = "TABLE"
)

XTENSION values.

View Source
const (
	KeyChecksum = "CHECKSUM"
	KeyDatasum  = "DATASUM"
)

Checksum keywords.

View Source
const CardWidth = 80

CardWidth is the fixed width of a header card, in bytes.

Variables

View Source
var ErrBadCard = errors.New("fits/header: malformed card")

ErrBadCard is returned when a card's 80 bytes cannot be parsed. The error text includes the keyword and a short description of the problem.

View Source
var ErrKeyNotFound = errors.New("fits/header: key not found")

ErrKeyNotFound is returned by typed getters when a keyword is absent.

View Source
var ErrNoEnd = errors.New("fits/header: no END card found")

ErrNoEnd is returned when a header byte slice does not contain an END keyword.

View Source
var ErrWrongType = errors.New("fits/header: wrong value type")

ErrWrongType is returned when a typed getter is called on a card whose value type does not match.

Functions

func BlockCountFor

func BlockCountFor(nCards int) int

BlockCountFor returns the number of 2880-byte blocks required to hold the given number of cards plus a terminating END card.

func Encode

func Encode(h *Header) ([]byte, error)

Encode serializes a full Header into one or more 2880-byte blocks, terminated by an END card and padded with spaces to the next block boundary.

func EncodeCard

func EncodeCard(c Card) ([CardWidth]byte, error)

EncodeCard serializes a single Card into its 80-byte on-disk form.

If the card's Raw field is non-zero (i.e. it was parsed from disk and never mutated through Set/Add), the raw bytes are returned as-is to guarantee byte-for-byte round-trip fidelity for unchanged cards.

For strings that exceed the 68-character fixed-format value field, this function returns an error — callers that need CONTINUE splitting must use EncodeCardWithContinuation, which returns one or more 80-byte cards.

func EncodeCardWithContinuation

func EncodeCardWithContinuation(c Card) ([][CardWidth]byte, error)

EncodeCardWithContinuation serializes c into one or more 80-byte cards, applying the CONTINUE convention (§4.2.1.2) if the string value is too long for a single card.

The caller's comment is placed on the LAST emitted card per convention (cfitsio ffmkky); leading cards carry an empty comment.

Types

type Card

type Card struct {
	Key     string
	Value   any
	Comment string
	Type    ValueType
	Raw     [CardWidth]byte
}

Card is a single parsed FITS header card.

Key holds the keyword in uppercase for normal cards, or the full HIERARCH keyword path ("HIERARCH ESO DET NAME") for HIERARCH cards.

Value holds the typed value. For commentary cards (COMMENT, HISTORY, blank) Value is nil and Comment carries the text. For keyword cards without a value (i.e. badly-formed user cards that still contain "= "), Value is nil and Type is TypeEmpty.

Raw preserves the original 80 bytes read from disk so that unmodified cards can be round-tripped bit-for-bit through Encode() without re-serialization. Raw is zero for cards built in memory.

func DecodeCard

func DecodeCard(raw []byte) (Card, error)

DecodeCard parses one 80-byte FITS header card and returns the typed Card. The caller guarantees len(raw) == CardWidth.

Layout (§4.1, §4.2):

columns 1..8  : keyword (left-justified, space-padded)
columns 9..10 : value indicator "= " (present iff a value follows)
columns 11..80: value + comment field, or free-text for commentary cards

HIERARCH cards use "HIERARCH" in columns 1..8 followed by a dotted/space keyword path and "= " elsewhere on the card (§4.1.2.2).

func ParseCards

func ParseCards(buf []byte) (cards []Card, endIndex int, err error)

ParseCards parses a header byte slice (one or more 2880-byte blocks) into an ordered slice of Cards. The returned slice includes every keyword, commentary, and COMMENT/HISTORY card but NOT the terminating END (the END position is returned separately as endIndex, counted in 80-byte units from the start of the input). If no END is found ErrNoEnd is returned.

ParseCards applies the CONTINUE long-string convention (§4.2.1.2): when a string value ends in "&" and is immediately followed by a CONTINUE card, the string is joined and the pair emitted as one logical Card. The joined card retains the original bytes of the first card in Card.Raw; subsequent CONTINUE cards are consumed and do not appear separately in the output. Callers that need to round-trip continuation intact must re-serialize via Encode, which re-emits CONTINUE cards as needed.

func (*Card) IsCommentary

func (c *Card) IsCommentary() bool

IsCommentary reports whether c is a commentary card (COMMENT, HISTORY, or a blank keyword). Commentary cards never carry a typed value.

func (*Card) IsEnd

func (c *Card) IsEnd() bool

IsEnd reports whether c is the END card that terminates the header.

func (*Card) IsHierarch

func (c *Card) IsHierarch() bool

IsHierarch reports whether c uses the ESO HIERARCH long-keyword convention.

type Complex

type Complex struct {
	Re, Im float64
}

Complex is the in-memory representation of a FITS complex value. The real and imaginary parts are stored as float64 regardless of whether the card wrote them as integer or floating literals — callers that need the original textual form can inspect Card.Raw.

func (Complex) String

func (v Complex) String() string

String formats v for diagnostic output; the canonical serializer lives in encoder.go.

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

Header is an ordered, case-insensitive collection of FITS header cards.

Insertion order is preserved. Lookups are case-insensitive (§4.1.2.1 states all keywords are uppercase). Duplicate keys are allowed for commentary keywords (COMMENT, HISTORY, blank) which have "last wins" semantics only in the sense that Set() updates the first occurrence; Add() always appends.

A Header is safe to mutate directly; persistence back to disk is the caller's responsibility (via *fits.File in edit mode).

func FromCards

func FromCards(cards []Card) *Header

FromCards returns a Header initialized with the given cards. Card order is preserved.

func New

func New() *Header

New returns an empty Header.

func (*Header) Add

func (h *Header) Add(name string, value any, comment string) error

Add appends a new card. For commentary keys this is the normal path; for other keys it permits duplicates (use with care — only HISTORY/COMMENT are expected to appear more than once).

func (*Header) Bool

func (h *Header) Bool(name string) (bool, error)

Bool returns the logical value of name.

func (*Header) Cards

func (h *Header) Cards() []Card

Cards returns the underlying card slice in insertion order. The returned slice must not be modified in place; use Set/Add/Delete to mutate.

func (*Header) Clone

func (h *Header) Clone() *Header

Clone returns a deep copy of h that is safe to mutate independently.

func (*Header) Comments

func (h *Header) Comments() []string

Comments returns the text of every COMMENT card in insertion order.

func (*Header) Delete

func (h *Header) Delete(name string) error

Delete removes the first card matching name. Returns ErrKeyNotFound if the card is absent.

func (*Header) Float

func (h *Header) Float(name string) (float64, error)

Float returns the floating-point value of name. Integer-typed cards are promoted to float64 here (no loss for values that fit in a float64 mantissa exactly).

func (*Header) Get

func (h *Header) Get(name string) (Card, bool)

Get returns the first card matching name, or ok=false.

func (*Header) Has

func (h *Header) Has(name string) bool

Has reports whether a keyword is present (case-insensitive).

func (*Header) History

func (h *Header) History() []string

History returns the text of every HISTORY card in insertion order.

func (*Header) Int

func (h *Header) Int(name string) (int64, error)

Int returns the integer-typed value of name. Float-typed cards that represent exact integers are not coerced.

func (*Header) Len

func (h *Header) Len() int

Len returns the number of cards.

func (*Header) NAXIS

func (h *Header) NAXIS() (int, error)

NAXIS returns NAXIS (number of axes) — convenience.

func (*Header) NAXISn

func (h *Header) NAXISn(i int) (int64, error)

NAXISn returns NAXISi for 1-based axis index. NAXIS1..NAXIS999 are supported.

func (*Header) Set

func (h *Header) Set(name string, value any, comment string) error

Set updates the value (and optionally comment) of name. If the keyword does not exist, Set appends a new card — equivalent to Add in that case. For commentary keywords Set is equivalent to Add.

func (*Header) String

func (h *Header) String(name string) (string, error)

String returns the string-typed value of name.

type ParseError

type ParseError struct {
	Offset int    // byte offset inside the input where the problem was detected
	Msg    string // human-readable description
}

ParseError describes a failure while parsing a header byte stream.

func (*ParseError) Error

func (e *ParseError) Error() string

type ValueType

type ValueType int

ValueType enumerates the distinct value types a parsed card can carry.

const (
	// TypeEmpty is a card with no value (COMMENT, HISTORY, blank, END, or a
	// commentary card with no "= " indicator).
	TypeEmpty ValueType = iota
	// TypeString — single-quoted string value (§4.2.1).
	TypeString
	// TypeLogical — "T" or "F" (§4.2.2).
	TypeLogical
	// TypeInt — integer value (§4.2.3).
	TypeInt
	// TypeFloat — floating-point value including D-exponent form (§4.2.4).
	TypeFloat
	// TypeComplexInt — integer complex "(re,im)" (§4.2.5).
	TypeComplexInt
	// TypeComplexFloat — floating complex "(re,im)" (§4.2.6).
	TypeComplexFloat
)

Jump to

Keyboard shortcuts

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