FITS structure
Introduction
The Application Programming Interface (API) for CamiFITS is based on 6 FITS-object structs with dedicated object-casting procedures to enforce the FITS standard . The API elements are typically called internally by one of the Basic tools but is made available in the documentation to provide insight in the structure of CamiFITS.
FITS-objects
CamiFITS.FITS
— TypeFITS
Object to hold a single .fits
file.
The fields are
.filnam:
: the.fits
filename (:String
).hdu: the collection of header-data-unit objects (
::Vector{FITS_HDU}`)
CamiFITS.FITS_filnam
— TypeFITS_filnam
mutable FITS object to hold the decomposed name of a .fits
file.
The fields are: " .value
: for p#.fits
this is p#.fits
(::String
)
.name
: forp#.fits
this isp#
(::String
).prefix
: forp#.fits
this isp
(::String
).numerator
: forp#.fits
this is#
, a serial number (e.g., '3') or a range (e.g., '3-7') (::String
).extension
: forp#.fits
this is.fits
(::String
)
CamiFITS.FITS_HDU
— TypeFITS_HDU
Object to hold a single "Header and Data Unit" (HDU).
The fields are
.hduindex:
: identifier (a file may contain more than one HDU) (:Int
).header
: the header object (::FITS_header
).dataobject
: the data object (::FITS_dataobject
)
NB. An empty data block (.dataobject = nothing
) conforms to the standard.
CamiFITS.FITS_header
— TypeFITS_header
Object to hold the header information of a FITS_HDU
.
The fields are:
.card
: the array ofcards
(::Vector{FITS_card}
).map
: Dictionarykeyword => recordindex
(::Dict{String, Int}
).size
: length in bytes (::Int
)
CamiFITS.FITS_card
— TypeFITS_card
Object to hold the card information of the FITS_header
object.
The fields are:
.cardindex
: identifier of the header record (::Int
).record
: the full record on the card (::String
).keyword
: name of the corresponding header record (::String
).val
: value of the corresponding header record (::Any
).comment
: comment on the corresponding header record (::String
)
CamiFITS.FITS_dataobject
— TypeFITS_dataobject
Object to hold the data of the FITS_HDU
of given hdutype
.
The fields are:
.hdutype
: accepted types are 'PRIMARY', 'IMAGE' and 'TABLE' (::String
).data
: in the from appropriate for thehdutype
(::Any)
CamiFITS.Ptrs
— TypePtrs
Pointer object holding start
and
stop`values for reading/writing
IOStream`.
The fields are:
.start
: startofIOStream (::Int
).stop
: endofIOStream (::Int
)
CamiFITS.HDU_ptr
— TypeHDU_ptr
Object holding header
and data
Ptrs
objects.
The fields are:
.header
: IO pointing object (::Ptrs
).data
: IO data object (::Ptrs
)
CamiFITS.FITS_pointer
— TypeFITS_pointer
Object holding an array of HDU_ptr
objects.
The fields are:
.nblock
: block count (::Int
).nhdu
: hdu count (::Int
).block_start
: start-of-block pointers: (::Tuple(Vector{Int})
).block_stop
: end-of-block pointers: (::Tuple(Vector{Int})
).hdu_start
: start-of-hdu pointers: (::Tuple(Vector{Int})
).hdu_stop
: end-of-hdu pointers: (::Tuple(Vector{Int})
).hdr_start
: start-of-header pointers: (::Tuple(Vector{Int})
).hdr_stop
: end-of-header pointers: (::Tuple(Vector{Int}))
).data_start
: start-of-data pointers: (::Tuple(Vector{Int})
).data_stop
: end-of-data pointers: (::Tuple(Vector{Int})
)
CamiFITS.FITS_ptr
— TypeFITS_ptr
Object holding an array of HDU_ptr
objects.
It has a single field:
.hdu
: IO pointing object (::Vector{HDU_ptr}
)
FITS-object casting
The ordering of the FITS-object casting procedures is illustrated in the flow diagram below.
The use of the casting procedures is recommended over direct application of the FITS-object strucs to ensure conformance to the FITS standard .
CamiFITS.cast_FITS_filnam
— Methodcast_FITS_filnam(filnam::String)
Create the FITS_filnam
object to decompose filnam
into its name
, prefix
, numerator
and extension
.
Example:
julia> filnam = "T23.01.fits";
julia> n = cast_FITS_filnam(filnam);
julia> n.name, n.prefix, n.numerator, n.extension
("T23.01", "T23.", "01", ".fits")
CamiFITS.cast_FITS_dataobject
— Methodcast_FITS_dataobject(hdutype::String, data)
Create the FITS_dataobject
object for given hduindex
constructed from the data
in accordance to the specified hdutype
: PRIMARY, IMAGE, ARRAY, TABLE (ASCII table) or BINTABLE (binary table).
Example:
julia> data = [11,21,31,12,22,23,13,23,33];
julia> data = reshape(data,(3,3));
julia> d = cast_FITS_dataobject("image", data)
FITS_dataobject("'IMAGE '", [11 12 13; 21 22 23; 31 23 33])
julia> d.data
3×3 Matrix{Int64}:
11 12 13
21 22 23
31 23 33
julia> d.hdutype
"'IMAGE '"
CamiFITS.cast_FITS_header
— Methodcast_FITS_header(dataobject::FITS_dataobject)
Create the FITS_header
object from the dataobject. The dataobject-input mode is used by fits_create
to ceate the header object as part of creating the FITS
object starting from Julia data input.
Example:
julia> data = [11 21 31; 12 22 23; 13 23 33];
julia> d = cast_FITS_dataobject("image", data);
julia> h = cast_FITS_header(d);
julia> h.map
Dict{String, Int64} with 7 entries:
"BITPIX" => 2
"NAXIS2" => 5
"XTENSION" => 1
"NAXIS1" => 4
"" => 36
"NAXIS" => 3
"END" => 6
cast_FITS_header(record::Vector{String})
Create the FITS_header
object from a block of (a multiple of) 36 single-record strings (of 80 printable ASCII characters). The record-input mode is used by fits_read
after reading the header records from disk (see casting diagram above).
Example:
julia> record = [rpad("KEYWORD$i",8) * "'" * rpad("$i",70) * "'" for i=1:3];
julia> blanks = [repeat(' ', 80) for i = 1:36-length(record)];
julia> append!(record, blanks); # to conform to the FITS standard
julia> h = cast_FITS_header(record);
julia> h.map
Dict{String, Int64} with 4 entries:
"KEYWORD3" => 3
"KEYWORD2" => 2
"KEYWORD1" => 144
"" => 36
CamiFITS.cast_FITS_card
— Methodcast_FITS_card(cardindex::Int, record::String)
Create the FITS_card
object for record
with index cardindex
.
Example:
julia> record = "SIMPLE = T / file does conform to FITS standard ";
julia> card = cast_FITS_card(1, record);
julia> card.cardindex, card.keyword, card.value, card.comment
(1, "SIMPLE", true, "file does conform to FITS standard ")
CamiFITS.cast_FITS_HDU
— Methodcast_FITS_HDU(hduindex::Int, header::FITS_header, data::FITS_dataobject)
Create the FITS_HDU
object for given hduindex
, header
and data
.
Example:
julia> data = [11 21 31; 12 22 23; 13 23 33];
julia> d = cast_FITS_dataobject("image", data);
julia> h = cast_FITS_header(d);
julia> hdu = cast_FITS_HDU(1, h, d);
julia> hdu.dataobject.data
3×3 Matrix{Int64}:
11 21 31
12 22 23
13 23 33
CamiFITS.cast_FITS
— MethodFITS(filnam::String, hdu::Vector{FITS_HDU})
Object to hold a single .fits
file.
The fields are
.filnam
: filename of the corresponding.fits
file (::String
).hdu
: array ofFITS_HDU
s (::Vector{FITS_HDU}
)
Example:
julia> data = [11 21 31; 12 22 23; 13 23 33];
julia> d = cast_FITS_dataobject("image", data);
julia> h = cast_FITS_header(d);
julia> hdu = cast_FITS_HDU(1, h, d);
julia> f = cast_FITS("test.fits", [hdu]);
julia> f.hdu[1].dataobject.data
3×3 Matrix{Int64}:
11 21 31
12 22 23
13 23 33
CamiFITS.cast_FITS_pointer
— Methodcast_FITS_pointer(o::IO)
Prefered method to construct a FITS_pointer
object.
Example:
julia> filnam = "foo.fits";
julia> data = [0x0000043e, 0x0000040c, 0x0000041f];
julia> f = fits_create(filnam, data; protect=false);
julia> fits_extend(f, data; hdutype="'IMAGE '");
julia> fits_extend(f, data; hdutype="'IMAGE '");
julia> o = IORead(filnam);
julia> p = cast_FITS_pointer(o);
julia> p.nblock, p.nhdu, p.block_start, p.block_stop, p.hdu_start, p.hdr_stop
(6, 3, (0, 2880, 5760, 8640, 11520, 14400), (2880, 5760, 8640, 11520, 14400, 17280), (0, 5760, 11520), (2880, 8640, 14400))
julia> p.hdr_start, p.hdr_stop, p.data_start, p.data_stop
((0, 5760, 11520), (2880, 8640, 14400), (2880, 8640, 14400), (8640, 14400, 17280))
CamiFITS.cast_FITS_ptr
— Methodcast_FITS_ptr(o::IO [; msg=false])
cast_FITS_ptr(p::FITS_pointer)
Prefered method to construct a FITS_ptr
object.
Example:
julia> filnam = "foo.fits";
julia> data = [0x0000043e, 0x0000040c, 0x0000041f];
julia> f = fits_create(filnam, data; protect=false);
julia> fits_extend(f, data; hdutype="'IMAGE '");
julia> fits_extend(f, data; hdutype="'IMAGE '");
julia> o = IORead(filnam);
julia> ptr = cast_FITS_ptr(o; msg=true)
block count: 6
hdu count: 3
start-of-block pointers: [0, 2880, 5760, 8640, 11520, 14400]
end-of-block pointers: [2880, 5760, 8640, 11520, 14400, 17280]
start-of-hdu pointers: [0, 5760, 11520]
end-of-hdu pointers: [5760, 11520, 17280]
start-of-header pointers: [0, 5760, 11520]
end-of-header pointers: [2880, 8640, 14400]
start-of-data pointers: [2880, 8640, 14400]
end-of-data pointers: [8640, 14400, 17280]
FITS_ptr(HDU_ptr[HDU_ptr(Ptrs(0, 2880), Ptrs(2880, 8640)), HDU_ptr(Ptrs(5760, 8640), Ptrs(8640, 14400)), HDU_ptr(Ptrs(11520, 14400), Ptrs(14400, 17280))])
julia> p.hdu[2].header.start, p.hdu[2].data.start
(5760, 8640)
FITS methods
CamiFITS.fits_pointer
— Methodfits_pointer(filnam::String)
fits_pointer(f::FITS)
FITS_pointer
object of the file filnam
or its FITS
object f
.
Examples:
julia> filnam = "foo.fits";
julia> f = fits_create(filnam, data; protect=false);
julia> fits_extend(f; hdutype="'IMAGE '");
julia> fits_extend(filnam, data; hdutype="'IMAGE '");
julia> p = fits_pointer(f);
julia> p.nblock
5
CamiFITS.fits_pointers
— Methodfits_pointers(filnam::String)
fits_pointers(f::FITS)
summary of the pointers internally used by CamiFITS
Examples:
julia> filnam = "foo.fits";
julia> data = [0x0000043e, 0x0000040c, 0x0000041f];
julia> f = fits_create(filnam, data; protect=false);
julia> fits_extend(f);
julia> fits_extend(filnam, data; hdutype="'IMAGE '");
julia> foreach(println, fits_pointers(filnam))
block count: 5
hdu count: 3
start-of-block pointers: (0, 2880, 5760, 8640, 11520)
end-of-block pointers: (2880, 5760, 8640, 11520, 14400)
start-of-hdu pointers: (0, 5760, 8640)
end-of-hdu pointers: (2880, 8640, 11520)
start-of-header pointers: (0, 5760, 8640)
end-of-header pointers: (2880, 8640, 11520)
start-of-data pointers: (2880, 8640, 11520)
end-of-data pointers: (5760, 8640, 14400)
CamiFITS.fits_zero_offset
— Methodfits_zero_offset(T::Type)
Zero offset a
as used in linear scaling equation
f(x) = a + b x,
where b
is the scaling factor.
The default value is a = 0.0
for Real
numeric types. For non-real types a = nothing
.
Example:
julia> T = Type[Any, Bool, Int8, UInt8, Int16, UInt16, Int32, UInt32,
Int64, UInt64, Float16, Float32, Float64];
julia> o = (0.0, 0.0, -128, 0.0, 0.0, 32768,
0.0, 2147483648, 0.0, 9223372036854775808, 0.0, 0.0, 0.0);
julia> sum([fits_zero_offset(T[i]) == o[i] for i ∈ eachindex(T)]) == 13
true
CamiFITS.fits_apply_zero_offset
— Methodfits_apply_zero_offset(data)
Shift the UInt
range of values onto the Int
range by substracting from the data
the appropriate integer offset value as specified by the BZERO
keyword.
NB. Since the FITS format does not support a native unsigned integer data type (except UInt8
), unsigned values of the types UInt16
, UInt32
and UInt64
, are stored as native signed integers of the types Int16
, Int32
and Int64
, respectively, after substracting the appropriate integer offset specified by the (positive) BZERO
keyword value. For the byte data type (UInt8
), the converse technique can be used to store signed byte values (Int8
) as native unsigned values (UInt
) after subtracting the (negative) BZERO
offset value.
This method is included and used in storing of data to ensure backward compatibility with software not supporting native values of the types Int8
, UInt16
, UInt32
and UInt64
.
Example:
julia> fits_apply_zero_offset(UInt32[0])
1-element Vector{Int32}:
-2147483648
julia> fits_apply_zero_offset(Int8[0])
1-element Vector{UInt8}:
0x80
julia> Int(0x80)
128
CamiFITS.fits_remove_zero_offset
— Methodfits_remove_zero_offset(data)
Shift the Int
range of values onto the UInt
range by adding to the data
the appropriate integer offset value as specified by the BZERO
keyword.
NB. Since the FITS format does not support a native unsigned integer data type (except UInt8
), unsigned values of the types UInt16
, UInt32
and UInt64
, are recovered from stored native signed integers of the types Int16
, Int32
and Int64
, respectively, by adding the appropriate integer offset specified by the (positive) BZERO
keyword value. For the byte data type (UInt8
), the converse technique can be used to recover the signed byte values (Int8
) from the stored native unsigned values (UInt
) by adding the (negative) BZERO
offset value.
This method is included and used in reading stored data to ensure backward compatibility with software not supporting native values of the types Int8
, UInt16
, UInt32
and UInt64
.
Example:
julia> fits_remove_zero_offset(Int32[-2147483648])
1-element Vector{UInt32}:
0x00000000
julia> Int(0x00000000)
0
julia> fits_remove_zero_offset(UInt8[128])
1-element Vector{Int8}:
0
Fortran objects
CamiFITS.FORTRAN_format
— TypeFORTRAN_format
Object to hold a FORTRAN format specifier decomposed in its fields.
Accepted datatype specifiers are: Aw
, Iw
, Fw.d
, Ew.d
, Dw.d
Accepted output formating specifiers are: Aw
, Iw.m
, Bw.m
, Ow.m
, Zw.m
, Fw.d
, Ew.dEe
, ENw.d
, ESw.d
, Gw.dEe
, Dw.dEe
. Notation: w
- width, m
(optional) - minimum number of digits, d
- number of digits to right of decimal, e
- number of digits in exponent N
/S
(optional) indicates engineering/scientific formating of the E
type.
The fields are:
.datatype
: primary FORTRAN datatype (::String
).char
: primary FORTRAN datatype character (::Char
).EngSci
: secundary datatype character - N for engineering/ S for scientific (::Union{Char,Nothing}
).width
: width of numeric field (::Int
).nmin
: minimum number of digits displayed (::Int
).ndec
: number of digits to right of decimal (::Int
).nexp
: number of digits in exponent (::Int
)
Fortran-object casting
CamiFITS.cast_FORTRAN_format
— Methodcast_FORTRAN_format(format::String)
Decompose the format specifier format
into its fields and cast this into the FORTRAN_format
object. Allowed format specifiers are of the types: Aw
, Iw.m
, Bw.m
, Ow.m
, Zw.m
, Fw.d
, Ew.dEe
, ENw.d
, ESw.d
, Gw.dEe
, Dw.dEe
, with: w
- width, m
(optional) - minimum number of digits, d
- number of digits to right of decimal, e
- number of digits in exponent; N
/S
(optional) indicates engineering/scientific formating of the E
type.
Examples:
julia> cast_FORTRAN_format("I10")
FORTRAN_format("Iw", 'I', nothing, 10, 0, 0, 0)
julia> cast_FORTRAN_format("I10.12")
FORTRAN_format("Iw.m", 'I', nothing, 10, 12, 0, 0)
julia> F = cast_FORTRAN_format("E10.5E3")
FORTRAN_format("Ew.dEe", 'E', nothing, 10, 0, 5, 3)
julia> F.Type, F.TypeChar, F.EngSci, F.width, F.nmin, F.ndec, F.nexp
("Ew.dEe", 'E', nothing, 10, 0, 5, 3)
FORTRAN-related methods
CamiFITS.FORTRAN_eltype_char
— MethodFORTRAN_eltype_char(T::Type)
FORTRAN datatype description character for julia type T
:
Bool => 'L', UInt8 => 'B', Int16 => 'I', UInt16 => 'I', Int32 => 'J', UInt32 => 'J', Int64 => 'K', UInt64 => 'K', Float32 => 'E', Float64 => 'D', ComplexF32 => 'C', ComplexF64 => 'M'
The character '-' is returned for non-primitive FORTRAN datatypes and for primitive datatypes not included in the FITS standard.
Examples:
julia> T = Type[Bool, Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64];
julia> print([FORTRAN_eltype_char(T[i]) for i ∈ eachindex(T)])
Int8: datatype not part of the FITS standard
['L', '-', 'B', 'I', 'I', 'J', 'J', 'K', 'K']
julia> T = [Float16, Float32, Float64, ComplexF32, ComplexF64];
julia> print([FORTRAN_eltype_char(T[i]) for i ∈ eachindex(T)])
Float16: datatype not part of the FITS standard
['-', 'E', 'D', 'C', 'M']
julia> T = [String, Vector{Char}, FITS];
julia> print([FORTRAN_eltype_char(T[i]) for i ∈ eachindex(T)])
Vector{Char}: not a FORTRAN datatype
FITS: not a FORTRAN datatype
['A', 'A', '-', '-']
Plotting
CamiFITS.step125
— Methodstep125(x)
Step used for deviding the number x in steps according to 1-2-5 scheme
Examples:
step125.([5,10,21.3,50,100.1])
5-element Vector{Int64}:
1
2
5
10
20
CamiFITS.select125
— Methodselect125(x)
Select elements of the collection x by index according to 1-2-5 scheme
Examples:
x = [1,2,4,6,8,10,13,16,18,20,40,60,80,100]
select125(x)
[2, 6, 10, 16, 20, 60, 100]
x = string.(x)
select125(x)
["2", "6", "10", "16", "20", "60", "100"]
x = 1:100
select125(x)
[20, 40, 60, 80, 100]
CamiFITS.steps
— Methodsteps(x)
Heatmap range transformation for steplength specification vector x
Examples:
x = [4,2,6]
steps(x)
[0, 4, 6, 12]
CamiFITS.stepcenters
— Methodstepcenters(x)
Stepcenter positions for steplength specification vector x
Examples:
x = [4,2,6]
stepcenters(x)
[2.0, 5.0, 9.0]
CamiFITS.stepedges
— Methodstepedges(x)
Stepedges for steplength specification vector x
Examples:
x = [4,2,6]
stepedges(x)
[0, 4, 6, 12]
CamiFITS.edges
— Functionedges(px [, Δx[, x0]])
Heatmap range transformation from pixel coordinates to physical coordinates, with pixelsize Δx and offset x0, both in physical units.
Examples:
px = 1:5
Δx = 2.5
x0 = 2.5
edges(px)
[0.5, 1.5, 2.5, 3.5, 4.5]
edges(px, Δx)
[1.25, 3.75, 6.25, 8.75, 11.25]
edges(px, Δx, x0)
[-1.25, 1.25, 3.75, 6.25, 8.75]