Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HDU and header copy functions #17

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "CFITSIO"
uuid = "3b1b4be9-1499-4b22-8d78-7db3344d1961"
authors = ["Miles Lucas <[email protected]> and contributors"]
version = "1.4.0"
version = "1.5.0"

[deps]
CFITSIO_jll = "b3e40c51-02ae-5482-8a39-3ace5868dcf4"
Expand Down
4 changes: 4 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ fits_get_num_hdus
fits_movabs_hdu
fits_movrel_hdu
fits_movnam_hdu
fits_copy_file
fits_copy_hdu
fits_copy_data
fits_delete_hdu
```

Expand All @@ -132,6 +135,7 @@ fits_write_record
fits_delete_record
fits_delete_key
fits_hdr2str
fits_copy_header
```

## Image HDU Routines
Expand Down
128 changes: 128 additions & 0 deletions src/CFITSIO.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ export FITSFile,
fits_assert_open,
fits_clobber_file,
fits_close_file,
fits_copy_data,
fits_copy_image_section,
fits_copy_file,
fits_copy_hdu,
fits_copy_header,
fits_create_ascii_tbl,
fits_create_binary_tbl,
fits_create_diskfile,
Expand Down Expand Up @@ -891,6 +895,27 @@ function fits_hdr2str(f::FITSFile, nocomments::Bool = false)
result
end

"""
fits_copy_header(fin::FITSFile, fout::FITSFile)

Copy the header (not the data) associated with the current HDU from `fin` to `fout`.
If the current HDU in `fout` is not empty, it will be closed and a new HDU will be appended.
An empty output HDU will be created with the header but no data.
"""
function fits_copy_header(fin::FITSFile, fout::FITSFile)
fits_assert_open(fin)
fits_assert_open(fout)
status = Ref{Cint}(0)
ccall(
(:ffcphd, libcfitsio),
Cint,
(Ptr{Cvoid}, Ptr{Cvoid}, Ref{Cint}),
fin.ptr,
fout.ptr,
status,
)
fits_assert_ok(status[])
end

# -----------------------------------------------------------------------------
# HDU info functions and moving the current HDU
Expand Down Expand Up @@ -1165,6 +1190,109 @@ end

fits_insert_img(f::FITSFile, a::AbstractArray) = fits_insert_img(f, eltype(a), size(a))

"""
fits_copy_file(fin::FITSFile, fout::FITSFile, previous::Bool, current::Bool, following::Bool)

Copy all or a part of the HDUs from the input file `fin`,
and append them to the output file `fout`.
The flags `previous`, `current` and `following` specify which HDUs are to be copied.

* If `previous` is true, all the HDUs prior to the current input HDU are copied.
* If `current` is true, the current input HDU is copied.
* If `following` is true, all the HDUs following the current input HDU are copied.

These flags may be combined, so if all are set to `true` then all the HDUs are copied from
`fin` to `fout`.

On exit, the input is unchanged, and the last HDU in the output is set as the current HDU.
"""
function fits_copy_file(fin::FITSFile, fout::FITSFile,
previous::Bool, current::Bool, following::Bool,
)

fits_assert_open(fin)
fits_assert_open(fout)

status = Ref{Cint}(0)

ccall(
(:ffcpfl, libcfitsio),
Cint,
(
Ptr{Cvoid},
Ptr{Cvoid},
Cint,
Cint,
Cint,
Ref{Cint},
),
fin.ptr,
fout.ptr,
previous,
current,
following,
status,
)
fits_assert_ok(status[])
end

"""
fits_copy_hdu(fin::FITSFile, fout::FITSFile[, morekeys::Integer = 0])

Copy the current HDU from the input file `fin` and append it to the output file `fout`.
Space may be reserved for `morekeys` additional keywords in the output header.
"""
function fits_copy_hdu(fin::FITSFile, fout::FITSFile, morekeys::Integer = 0)

fits_assert_open(fin)
fits_assert_open(fout)

status = Ref{Cint}(0)

ccall(
(:ffcopy, libcfitsio),
Cint,
(
Ptr{Cvoid},
Ptr{Cvoid},
Cint,
Ref{Cint},
),
fin.ptr,
fout.ptr,
morekeys,
status,
)
fits_assert_ok(status[])
end

"""
fits_copy_data(fin::FITSFile, fout::FITSFile)

Copy the data (not the header) from the current HDU in `fin` to the current HDU in `fout`.
This will overwrite pre-existing data in the output HDU.
"""
function fits_copy_data(fin::FITSFile, fout::FITSFile)
fits_assert_open(fin)
fits_assert_open(fout)

status = Ref{Cint}(0)

ccall(
(:ffcpdt, libcfitsio),
Cint,
(
Ptr{Cvoid},
Ptr{Cvoid},
Ref{Cint},
),
fin.ptr,
fout.ptr,
status,
)
fits_assert_ok(status[])
end

"""
fits_write_pix(f::FITSFile, fpixel::Union{Vector{<:Integer}, Tuple{Vararg{Integer}}}, nelements::Integer, data::StridedArray)

Expand Down
116 changes: 116 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,122 @@ end
end
end

@testset "copy from one file to another" begin
tempfitsfile() do fin
for a in [ones(1,1), ones(2,2), ones(3,3)]
fits_create_img(fin, a)
fits_write_pix(fin, a)
end

@testset "copy file" begin
tempfitsfile() do fout
fits_movabs_hdu(fin, 1)
fits_copy_file(fin, fout, false, false, false)
@test fits_get_num_hdus(fout) == 0

fits_copy_file(fin, fout, true, true, false)
@test fits_get_num_hdus(fout) == 1
sz = fits_get_img_size(fout)
@test sz == [1,1]

# prev makes no difference when we're on the first HDU of the input
for (ind, prev) in enumerate([false, true])
fits_copy_file(fin, fout, prev, true, true)
@test fits_get_num_hdus(fout) == 1 + 3ind
sz = fits_get_img_size(fout)
@test sz == [3,3]
end

fits_movabs_hdu(fin, 2)
fits_copy_file(fin, fout, false, false, false)
@test fits_get_num_hdus(fout) == 7
fits_copy_file(fin, fout, false, true, false)
@test fits_get_num_hdus(fout) == 8
sz = fits_get_img_size(fout)
@test sz == [2,2]
fits_copy_file(fin, fout, true, true, false)
@test fits_get_num_hdus(fout) == 10
sz = fits_get_img_size(fout)
@test sz == [2,2]
fits_copy_file(fin, fout, true, true, true)
@test fits_get_num_hdus(fout) == 13
sz = fits_get_img_size(fout)
@test sz == [3,3]
fits_copy_file(fin, fout, false, false, true)
@test fits_get_num_hdus(fout) == 14
sz = fits_get_img_size(fout)
@test sz == [3,3]

fits_movabs_hdu(fin, 3)
fits_copy_file(fin, fout, false, false, false)
@test fits_get_num_hdus(fout) == 14
fits_copy_file(fin, fout, false, true, false)
@test fits_get_num_hdus(fout) == 15
sz = fits_get_img_size(fout)
@test sz == [3,3]
fits_copy_file(fin, fout, true, true, false)
@test fits_get_num_hdus(fout) == 18
sz = fits_get_img_size(fout)
@test sz == [3,3]
fits_copy_file(fin, fout, true, true, true)
@test fits_get_num_hdus(fout) == 21
sz = fits_get_img_size(fout)
@test sz == [3,3]
fits_copy_file(fin, fout, true, false, false)
@test fits_get_num_hdus(fout) == 23
sz = fits_get_img_size(fout)
@test sz == [2,2]
end
end
@testset "copy hdu" begin
tempfitsfile() do fout
fits_movabs_hdu(fin, 2)
fits_copy_hdu(fin, fout)
@test fits_get_num_hdus(fout) == 1
@test fits_get_img_size(fout) == [2,2]

fits_movabs_hdu(fin, 1)
fits_copy_hdu(fin, fout, 3)
@test fits_get_num_hdus(fout) == 2
@test fits_get_img_size(fout) == [1,1]
end
end
@testset "copy header" begin
tempfitsfile() do fout
fits_movabs_hdu(fin, 2)
fits_copy_header(fin, fout)
@test fits_get_img_size(fout) == [2,2]
@test fits_get_num_hdus(fout) == 1
fits_copy_hdu(fin, fout)
fits_movabs_hdu(fin, 1)
fits_copy_header(fin, fout)
@test fits_get_img_size(fout) == [1,1]
@test fits_get_num_hdus(fout) == 3
# test that we write to the same HDU
@test fits_get_hdu_num(fout) == 3
bout = ones(1,1)*3
fits_write_pix(fout, bout)
b = zero(bout)
fits_read_pix(fout, b)
@test b == bout
@test fits_get_num_hdus(fout) == 3
end
end
@testset "copy data" begin
tempfitsfile() do fout
fits_movabs_hdu(fin, 2)
# copy header first
fits_copy_header(fin, fout)
fits_copy_data(fin, fout)
@show fits_get_num_hdus(fout)
b = zeros(2,2)
fits_read_pix(fout, b)
@test all(x -> x == 1, b)
end
end
end
end

@testset "image type/size" begin
tempfitsfile() do f
a = ones(2,2)
Expand Down