diff --git a/Project.toml b/Project.toml index e9ef717..3604482 100644 --- a/Project.toml +++ b/Project.toml @@ -3,6 +3,10 @@ uuid = "d1dcc2e6-806e-11e9-2897-3f99785db2ae" authors = ["Mosè Giordano"] version = "0.1.0" +[deps] +FITSIO = "525bcba6-941b-5504-bd06-fd0dc1a4d2eb" +WCS = "15f3aee2-9e10-537f-b834-a6fb8bdb944d" + [compat] julia = "^1.0.0" diff --git a/src/Reproject.jl b/src/Reproject.jl index 875b927..d2cb43b 100644 --- a/src/Reproject.jl +++ b/src/Reproject.jl @@ -1,5 +1,7 @@ module Reproject -greet() = print("Hello World!") +using FITSIO, WCS + +include("parsers.jl") end # module diff --git a/src/parsers.jl b/src/parsers.jl new file mode 100644 index 0000000..dcc8472 --- /dev/null +++ b/src/parsers.jl @@ -0,0 +1,77 @@ +""" + parse_input_data(input_data::ImageHDU) + parse_input_data(input_data::String, hdu_in) + parse_input_data(input_data::FITS, hdu_in) + +Parse input data and returns an Array and WCS object. + +# Arguments +- `input_data`: image to reproject which can be name of a FITS file, + an ImageHDU or a FITS file. +- `hdu_in`: used to set HDU to use when more than one HDU is present. +""" +function parse_input_data(input_data::ImageHDU) + return read(input_data), WCS.from_header(read_header(input_data, String))[1] +end + +function parse_input_data(input_data::String, hdu_in) + return parse_input_data(FITS(input_data), hdu_in) +end + +function parse_input_data(input_data::FITS, hdu_in) + return parse_input_data(input_data[hdu_in]) +end + + +# TODO: extend support for passing FITSHeader when FITSHeader to WCSTransform support is possible. + + +""" + parse_output_projection(output_projection::WCSTransform, shape_out) + parse_output_projection(output_projection::ImageHDU; shape_out) + parse_output_projection(output_projection::String, hdu_number) + parse_output_projection(output_projection::FITS, hdu_number) + +Parse output projection and returns a WCS object and shape of output. + +# Arguments +- `output_projection`: WCS information about the image to be reprojected which can be + name of a FITS file, an ImageHDU or WCSTransform. +- `shape_out`: shape of the output image. +- `hdu_number`: specifies HDU number when file name is given as input. +""" +function parse_output_projection(output_projection::WCSTransform, shape_out) + if length(shape_out) == 0 + throw(DomainError(shape_out, "The shape of the output image should not be an empty tuple")) + end + + return output_projection, shape_out +end + +function parse_output_projection(output_projection::ImageHDU, shape_out) + wcs_out = WCS.from_header(read_header(output_projection, String))[1] + if shape_out === nothing + shape_out = size(output_projection) + end + if length(shape_out) == 0 + throw(DomainError(shape_out, "The shape of the output image should not be an empty tuple")) + end + return wcs_out, shape_out +end + +function parse_output_projection(output_projection::String, hdu_number) + parse_output_projection(FITS(output_projection), hdu_number) +end + +function parse_output_projection(output_projection::FITS, hdu_number) + wcs_out = WCS.from_header(read_header(output_projection[hdu_number], String))[1] + + if output_projection[hdu_number] isa ImageHDU + shape_out = size(output_projection[hdu_number]) + else + throw(ArgumentError("Given FITS file doesn't have ImageHDU")) + end + + return wcs_out, shape_out +end + diff --git a/test/parsers.jl b/test/parsers.jl new file mode 100644 index 0000000..73f89ce --- /dev/null +++ b/test/parsers.jl @@ -0,0 +1,97 @@ +using Reproject: parse_input_data, parse_output_projection +@testset "input parser" begin + fname = tempname() * ".fits" + f = FITS(fname, "w") + inhdr = FITSHeader(["FLTKEY", "INTKEY", "BOOLKEY", "STRKEY", "COMMENT", + "HISTORY"], + [1.0, 1, true, "string value", nothing, nothing], + ["floating point keyword", + "", + "boolean keyword", + "string value", + "this is a comment", + "this is a history"]) + + indata = reshape(Float32[1:100;], 5, 20) + write(f, indata; header=inhdr) + + @testset "ImageHDU type" begin + result = parse_input_data(f[1]) + @test result[1] isa Array + @test result[2] isa WCSTransform + end + + @testset "Single HDU FITS file" begin + result = parse_input_data(f, 1) + @test result[1] isa Array + @test result[2] isa WCSTransform + end + close(f) + + @testset "String filename input" begin + result = parse_input_data(fname, 1) + @test result[1] isa Array + @test result[2] isa WCSTransform + end + + f = FITS(fname, "w") + write(f, indata; header=inhdr) + write(f, indata; header=inhdr) + + @testset "Multiple HDU FITS file" begin + result = parse_input_data(f, 2) + @test result[1] isa Array + @test result[2] isa WCSTransform + + close(f) + result = parse_input_data(fname, 1) + @test result[1] isa Array + @test result[2] isa WCSTransform + end +end + +@testset "output parser" begin + fname = tempname() * ".fits" + f = FITS(fname, "w") + inhdr = FITSHeader(["FLTKEY", "INTKEY", "BOOLKEY", "STRKEY", "COMMENT", + "HISTORY"], + [1.0, 1, true, "string value", nothing, nothing], + ["floating point keyword", + "", + "boolean keyword", + "string value", + "this is a comment", + "this is a history"]) + + indata = reshape(Float32[1:100;], 5, 20) + write(f, indata; header=inhdr) + + @testset "ImageHDU type" begin + result = parse_output_projection(f[1], (12,12)) + @test result[1] isa WCSTransform + @test result[2] isa Tuple + @test_throws DomainError parse_output_projection(f[1], ()) + end + close(f) + + @testset "String filename" begin + result = parse_output_projection(fname, 1) + @test result[1] isa WCSTransform + @test result[2] isa Tuple + end + + wcs = WCSTransform(2; + cdelt = [-0.066667, 0.066667], + ctype = ["RA---AIR", "DEC--AIR"], + crpix = [-234.75, 8.3393], + crval = [0., -90], + pv = [(2, 1, 45.0)]) + + @testset "WCSTransform input" begin + result = parse_output_projection(wcs, (12,12)) + @test result[1] isa WCSTransform + @test result[2] isa Tuple + @test_throws DomainError parse_output_projection(wcs, ()) + end +end + diff --git a/test/runtests.jl b/test/runtests.jl index 515282e..1809d4d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,7 @@ using Reproject using Test using Conda, PyCall +using FITSIO, WCS ENV["PYTHON"]="" Conda.add_channel("astropy") @@ -8,5 +9,5 @@ Conda.add("reproject") rp = pyimport("reproject") @testset "Reproject.jl" begin - # Write your own tests here. + include("parsers.jl") end