Apertures
All apertures will rely on a position and the shape parameters.
aperture = Aperture(x0, y0, shape_params...)
The position can be pixels or sky coordinates. The sky coordinate positions utilize SkyCoords.jl and WCS.jl for conversion.
Sky coordinates are not supported yet.
See Pixel Convention - The origin is the bottom-left with (1, 1)
being the center of the pixel.
API/Reference
Photometry.Aperture.AbstractAperture
— TypeAbstractAperture{T} <: AbstractMatrix{T}
The abstract super-type for Apertures.
Apertures can be thought of as a cutout or stamp of a geometric shape with shading applied. For example, a circular aperture with a diameter of 3 pixels will require a 5x5 pixel grid (when perfectly on-grid) to represent.
julia> ap = CircularAperture(3, 3, 2.5)
5×5 CircularAperture{Float64} with indices 1:5×1:5:
0.136857 0.769325 0.983232 0.769325 0.136857
0.769325 1.0 1.0 1.0 0.769325
0.983232 1.0 1.0 1.0 0.983232
0.769325 1.0 1.0 1.0 0.769325
0.136857 0.769325 0.983232 0.769325 0.136857
This is a useful way of thinking about apertures: if we have some data, we can weight the data with the aperture
julia> data = fill(2, 5, 5);
julia> idxs = map(intersect, axes(ap), axes(data)) |> CartesianIndices;
julia> weighted_cutout = data[idxs] .* ap[idxs]
5×5 Matrix{Float64}:
0.273713 1.53865 1.96646 1.53865 0.273713
1.53865 2.0 2.0 2.0 1.53865
1.96646 2.0 2.0 2.0 1.96646
1.53865 2.0 2.0 2.0 1.53865
0.273713 1.53865 1.96646 1.53865 0.273713
Performing aperture photometry is merely summing the weighted cutout shown above.
julia> flux = sum(weighted_cutout)
39.269908169872416
julia> flux ≈ (π * 2.5^2) * 2 # area of circle times intensity of 2
true
What's interesting about the implementation of apertures, though, is they are lazy. This means there is no stored matrix of aperture values; rather, they are calculated on the fly as needed.
julia> axes(ap)
(1:5, 1:5)
julia> ap[-10, -10] # out-of-bounds, but calculated on the fly
0.0
julia> ap .* ones(5, 7) # broadcasts to eachindex(data), regardless of ap bound
5×7 Matrix{Float64}:
0.136857 0.769325 0.983232 0.769325 0.136857 0.0 0.0
0.769325 1.0 1.0 1.0 0.769325 0.0 0.0
0.983232 1.0 1.0 1.0 0.983232 0.0 0.0
0.769325 1.0 1.0 1.0 0.769325 0.0 0.0
0.136857 0.769325 0.983232 0.769325 0.136857 0.0 0.0
This allows extremely efficient computation of aperture photometry from small to medium sized apertures.
julia> using BenchmarkTools
julia> @btime sum(idx -> $ap[idx] * $data[idx], $idxs)
1.097 μs (0 allocations: 0 bytes)
39.26990816987243
This is essentially the full implementation of photometry
, save for the packing of additional information into a tabular form.
Photometry.Aperture.Subpixel
— TypeSubpixel(ap, N=1) <: AbstractAperture
Use a subpixel quadrature approximation for pixel shading instead of exact geometric methods.
For any pixel laying on the border of ap
, this alters the shading algorithm by breaking the border pixel up into (N, N)
subpixels. The shading value is the fraction of these subpixels within the geometric border of ap
.
Using a subpixel shading method is sometimes faster than exact methods at the cost of accuracy. For CircularAperture
the subpixel method is only faster than the exact method for N
~ 7. for EllipticalAperture
the cutoff is N
~ 12, and for RectangularAperture
the cutoff is N
~ 20.
Examples
julia> ap = CircularAperture(3, 3, 2.5)
5×5 CircularAperture{Float64} with indices 1:5×1:5:
0.136857 0.769325 0.983232 0.769325 0.136857
0.769325 1.0 1.0 1.0 0.769325
0.983232 1.0 1.0 1.0 0.983232
0.769325 1.0 1.0 1.0 0.769325
0.136857 0.769325 0.983232 0.769325 0.136857
julia> sub_ap = Subpixel(ap, 5)
5×5 Subpixel{Float64, CircularAperture{Float64}} with indices 1:5×1:5:
0.12 0.76 1.0 0.76 0.12
0.76 1.0 1.0 1.0 0.76
1.0 1.0 1.0 1.0 1.0
0.76 1.0 1.0 1.0 0.76
0.12 0.76 1.0 0.76 0.12
photutils
offers a center
shading method which is equivalent to using the Subpixel
method with 1 subpixel. To avoid unneccessary namespace cluttering, we simply instruct users to use Subpixel(ap)
instead.
Circular Apertures
These apertures are parameterized by radius.
Photometry.Aperture.CircularAperture
— TypeCircularAperture(x, y, r)
CircularAperture(position, r)
A circular aperture.
A circular aperture with radius r
. r
must be greater than or equal to 0.
Examples
julia> ap = CircularAperture(0, 0, 10)
21×21 CircularAperture{Int64} with indices -10:10×-10:10:
0 0 0 … 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0.00571026 0.00571026 0 0
0 0 0.491844 0.491844 0 0
0 0.170878 0.982952 … 0.982952 0.170878 0
0 0.659735 1 1 0.659735 0
0.0590655 0.975524 1 1 0.975524 0.0590655
0.293527 1 1 1 1 0.293527
0.445643 1 1 1 1 0.445643
⋮ ⋱ ⋮
0.293527 1 1 1 1 0.293527
0.0590655 0.975524 1 1 0.975524 0.0590655
0 0.659735 1 1 0.659735 0
0 0.170878 0.982952 … 0.982952 0.170878 0
0 0 0.491844 0.491844 0 0
0 0 0.00571026 0.00571026 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 … 0 0 0
Photometry.Aperture.CircularAnnulus
— TypeCircularAnnulus(x, y, r_in, r_out)
CircularAnnulus(position, r_in, r_out)
A circular annulus with inner radius r_in
and outer radius r_out
. 0 ≤ r_in
≤ r_out
.
Examples
julia> ap = CircularAnnulus(0, 0, 5, 10)
21×21 CircularAnnulus{Int64} with indices -10:10×-10:10:
0 0 0 … 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0.00571026 0.00571026 0 0
0 0 0.491844 0.491844 0 0
0 0.170878 0.982952 … 0.982952 0.170878 0
0 0.659735 1 1 0.659735 0
0.0590655 0.975524 1 1 0.975524 0.0590655
0.293527 1 1 1 1 0.293527
0.445643 1 1 1 1 0.445643
⋮ ⋱ ⋮
0.293527 1 1 1 1 0.293527
0.0590655 0.975524 1 1 0.975524 0.0590655
0 0.659735 1 1 0.659735 0
0 0.170878 0.982952 … 0.982952 0.170878 0
0 0 0.491844 0.491844 0 0
0 0 0.00571026 0.00571026 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 … 0 0 0
Elliptical Apertures
These apertures are parameterized by the semi-major axis a
, semi-minor axis b
and position angle in degrees counter-clockwise from the positive x-axis θ
Photometry.Aperture.EllipticalAperture
— TypeEllipticalAperture(x, y, a, b, θ=0)
EllipticalAperture(position, a, b, θ=0)
An elliptical aperture with semi-major axis a
, semi-minor axis b
, and position angle θ
. a
and b
must be ≥ 0, θ
is measured in degrees counter-clockwise the standard x-axis.
Examples
julia> ap = EllipticalAperture(0, 0, 4, 2, 35)
7×5 EllipticalAperture{Int64} with indices -3:3×-2:2:
0.873382 0.844185 0.324917 0 0
1 1 0.997821 0.435284 0
1 1 1 0.990119 0.23968
0.796137 1 1 1 0.796137
0.23968 0.990119 1 1 1
0 0.435284 0.997821 1 1
0 0 0.324917 0.844185 0.873382
Photometry.Aperture.EllipticalAnnulus
— TypeEllipticalAnnulus(x, y, a_in, a_out, b_out, θ=0)
EllipticalAnnulus(position, a_in, a_out, b_out, θ=0)
An elliptical annulus with inner semi-major axis a_in
, outer semi-major axis a_out
, outer semi-minor axis b_out
, and position angle θ
. a_out
≥ a_in
≥ 0 and b_out
must be ≥ 0, θ
is measured in degrees counter-clockwise the standard x-axis.
b_in
will automatically be calculated from (a_in / a_out) * b_out
. Note this may cause a type instability.
Examples
julia> ap = EllipticalAnnulus(0, 0, 4, 10, 5, 45)
15×15 EllipticalAnnulus{Float64} with indices -7:7×-7:7:
0.594853 1.0 1.0 1.0 … 0.0 0.0 0.0
1.0 1.0 1.0 1.0 0.0 0.0 0.0
1.0 1.0 1.0 1.0 0.0 0.0 0.0
1.0 1.0 1.0 1.0 0.0 0.0 0.0
1.0 1.0 1.0 1.0 0.0 0.0 0.0
0.814163 1.0 1.0 1.0 … 0.414163 0.0 0.0
0.369432 1.0 1.0 1.0 0.975704 0.193728 0.0
0.0112571 0.809079 1.0 1.0 1.0 0.809079 0.0112571
0.0 0.193728 0.975704 1.0 1.0 1.0 0.369432
0.0 0.0 0.414163 1.0 1.0 1.0 0.814163
0.0 0.0 0.0 0.546165 … 1.0 1.0 1.0
0.0 0.0 0.0 0.00252321 1.0 1.0 1.0
0.0 0.0 0.0 0.0 1.0 1.0 1.0
0.0 0.0 0.0 0.0 1.0 1.0 1.0
0.0 0.0 0.0 0.0 1.0 1.0 0.594853
Rectangular Apertures
These apertures are parameterized by width w
, height h
, and position angle in degrees counter-clockwise from the positive x-axis θ
.
Photometry.Aperture.RectangularAperture
— TypeRectangularAperture(x, y, w, h, θ=0)
RectangularAperture(position, w, h, θ=0)
A rectangular aperture.
A rectangular aperture with width w
, height h
, and position angle θ
in degrees.
Examples
julia> ap = RectangularAperture(0, 0, 10, 4, 0)
11×5 RectangularAperture{Int64} with indices -5:5×-2:2:
0.25 0.5 0.5 0.5 0.25
0.5 1 1 1 0.5
0.5 1 1 1 0.5
0.5 1 1 1 0.5
0.5 1 1 1 0.5
0.5 1 1 1 0.5
0.5 1 1 1 0.5
0.5 1 1 1 0.5
0.5 1 1 1 0.5
0.5 1 1 1 0.5
0.25 0.5 0.5 0.5 0.25
Photometry.Aperture.RectangularAnnulus
— TypeRectangularAnnulus(x, y, w_in, w_out, h_out, θ=0)
RectangularAnnulus(position, w_in, w_out, h_out, θ=0)
A rectangular annulus with inner width w_in
, outer width w_out
, outer height h_out
, and position angle θ
in degrees. h_in
is automatically calculated from w_in / w_out * h_out
. Note that w_out ≥ w_in > 0
.
Examples
julia> ap = RectangularAnnulus(0, 0, 5, 10, 8, 45)
13×13 RectangularAnnulus{Float64} with indices -6:6×-6:6:
0.0 0.0 0.0 … 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.00252532 0.0 0.0 0.0
0.0 0.0 0.568542 0.0 0.0 0.0
0.0 0.568542 1.0 0.215729 0.0 0.0
0.528175 1.0 1.0 … 1.0 0.215729 0.0
0.215729 1.0 1.0 1.0 1.0 0.215729
0.0 0.215729 1.0 1.0 1.0 0.528175
0.0 0.0 0.215729 1.0 0.568542 0.0
0.0 0.0 0.0 0.568542 0.0 0.0
0.0 0.0 0.0 … 0.00252532 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0