|
| 1 | +""" |
| 2 | + reproject(input_data, output_projection; shape_out = nothing, order = 1, hdu_in = 1, hdu_out = 1) |
| 3 | +
|
| 4 | +Reprojects image data to a new projection using interpolation. |
| 5 | +
|
| 6 | +# Arguments |
| 7 | +- `input_data`: Image data which is being reprojected. |
| 8 | + It can be an ImageHDU, FITS object or name of a FITS file. |
| 9 | +- `output_projection`: Frame in which data is reprojected. |
| 10 | + Frame can be taken from WCSTransform object, ImageHDU, FITS or name of FITS file. |
| 11 | +- `shape_out`: Shape of image after reprojection. |
| 12 | +- `order`: Order of interpolation. |
| 13 | + 0: Nearest-neighbor |
| 14 | + 1: Linear |
| 15 | + 2: Quadratic |
| 16 | +- `hdu_in`: Used to specify HDU number when giving input as FITS or name of FITS file. |
| 17 | +- `hud_out:` Used to specify HDU number when giving output projection as FITS or name of FITS file. |
| 18 | +""" |
| 19 | +function reproject(input_data, output_projection; shape_out = nothing, order::Int = 1, hdu_in::Int = 1, hdu_out::Int = 1) |
| 20 | + if input_data isa ImageHDU |
| 21 | + array_in, wcs_out = parse_input_data(input_data) |
| 22 | + else |
| 23 | + array_in, wcs_out = parse_input_data(input_data, hdu_in) |
| 24 | + end |
| 25 | + |
| 26 | + if output_projection isa FITS || output_projection isa String |
| 27 | + wcs_in, shape_out = parse_output_projection(output_projection, hdu_out) |
| 28 | + else |
| 29 | + wcs_in, shape_out = parse_output_projection(output_projection, shape_out) |
| 30 | + end |
| 31 | + |
| 32 | + type_in = wcs_to_celestial_frame(wcs_in) |
| 33 | + type_out = wcs_to_celestial_frame(wcs_out) |
| 34 | + |
| 35 | + if type_in == type_out && shape_out === nothing |
| 36 | + return array_in |
| 37 | + end |
| 38 | + |
| 39 | + img_out = fill(NaN, shape_out) |
| 40 | + |
| 41 | + itp = interpolator(array_in, order) |
| 42 | + shape_in = size(array_in) |
| 43 | + |
| 44 | + for i in 1:shape_out[1] |
| 45 | + for j in 1:shape_out[2] |
| 46 | + pix_coord_in = [float(i), float(j)] |
| 47 | + world_coord_in = pix_to_world(wcs_in, pix_coord_in) |
| 48 | + |
| 49 | + if type_in == "ICRS" |
| 50 | + coord_in = ICRSCoords(deg2rad(world_coord_in[1]), deg2rad(world_coord_in[2])) |
| 51 | + elseif type_in == "Gal" |
| 52 | + coord_in = GalCoords(deg2rad(world_coord_in[1]), deg2rad(world_coord_in[2])) |
| 53 | + elseif type_in == "FK5" |
| 54 | + coord_in = FK5Coords{wcs_in.equinox}(deg2rad(world_coord_in[1]), deg2rad(world_coord_in[2])) |
| 55 | + else |
| 56 | + throw(ArgumentError("Unsupported output WCS coordinate type")) |
| 57 | + end |
| 58 | + |
| 59 | + if type_out == "ICRS" |
| 60 | + coord_out = convert(ICRSCoords, coord_in) |
| 61 | + elseif type_out == "Gal" |
| 62 | + coord_out = convert(GalCoords, coord_in) |
| 63 | + elseif type_out == "FK5" |
| 64 | + coord_out = convert(FK5Coords{wcs_out.equinox}, coord_in) |
| 65 | + else |
| 66 | + throw(ArgumentError("Unsupported input WCS coordinate type")) |
| 67 | + end |
| 68 | + |
| 69 | + pix_coord_out = world_to_pix(wcs_out, [rad2deg(lon(coord_out)), rad2deg(lat(coord_out))]) |
| 70 | + |
| 71 | + if 1 <= pix_coord_out[1] <= shape_in[1] && 1 <= pix_coord_out[2] <= shape_in[2] |
| 72 | + img_out[i,j] = itp(pix_coord_out[1], pix_coord_out[2]) |
| 73 | + end |
| 74 | + end |
| 75 | + end |
| 76 | + |
| 77 | + return img_out, (!isnan).(img_out) |
| 78 | +end |
| 79 | + |
| 80 | + |
| 81 | +""" |
| 82 | + interpolator(array_in, order::Int) |
| 83 | +
|
| 84 | +Returns an interpolator with the given array and order of interpolation. |
| 85 | +""" |
| 86 | +function interpolator(array_in::AbstractArray, order::Int) |
| 87 | + if order == 0 |
| 88 | + itp = interpolate(array_in, BSpline(Constant())) |
| 89 | + elseif order == 1 |
| 90 | + itp = interpolate(array_in, BSpline(Linear())) |
| 91 | + else |
| 92 | + itp = interpolate(array_in, BSpline(Quadratic(InPlace(OnCell())))) |
| 93 | + end |
| 94 | + |
| 95 | + return itp |
| 96 | +end |
0 commit comments