# 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.

Warning

Sky coordinates are not supported yet.

Note

See Pixel Convention - The origin is the bottom-left with (1, 1) being the center of the pixel.

## API/Reference

Photometry.Aperture.AbstractApertureType
AbstractAperture{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.

source
Photometry.Aperture.SubpixelType
Subpixel(ap, N=1) <: AbstractAperture

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
Note

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.

source

### Circular Apertures

These apertures are parameterized by radius.

Photometry.Aperture.CircularApertureType
CircularAperture(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
source
Photometry.Aperture.CircularAnnulusType
CircularAnnulus(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_inr_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
source

### 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.EllipticalApertureType
EllipticalAperture(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
source
Photometry.Aperture.EllipticalAnnulusType
EllipticalAnnulus(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_outa_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
source

### 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.RectangularApertureType
RectangularAperture(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
source
Photometry.Aperture.RectangularAnnulusType
RectangularAnnulus(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
source