Pixel functions

In this section we document the functions that convert from a direction in the sky into a pixel index, and vice versa.

First of all, Healpix.jl implements the most basic functions to convert between spherical and Cartesian coordinates. Note that Healpix uses co-latitude instead of latitude:


julia> ang2vec(0.0, 0.0)(0.0, 0.0, 1.0)
julia> vec2ang(0.0, 0.0, 1.0)(0.0, 0.0)

More interesting functions return the index of the pixel on a Healpix-tessellated sphere. For these functions to work, you have to provide a Resolution object:

julia> res = Resolution(16)Healpix resolution(NSIDE = 16)
julia> ang2pixRing(res, π/2, 0)1441
julia> ang2pixNest(res, π/2, 0)1217

Ring functions

The Healpix projection has the advantage of storing pixels along iso-latitude rings; this allows to implement efficient spherical-transform functions. Healpix.jl provides a number of functions that manage rings. Many of them use the RingInfo structure, which encodes details about a ring.

Healpix.RingInfoType
RingInfo

Information about a ring of pixels, i.e., the set of pixels on a Healpix map which have the same colatitude. The type is "mutable", so that one object can begin reused many times without further memory allocations.

The list of fields defined in this structure is the following:

  • ring: an integer index, running from

  • firstPixIdx: index of the first pixel (using the RING scheme) belonging to this ring

  • numOfPixels: number of consecutive pixels within the ring

  • colatitude_rad: value of the colatitude for this ring (in radians)

  • shifted: Boolean flag; it is true if the longitude of the first pixel in the ring is not zero.

References

See also getringinfo! and getringinfo.

Example

import Healpix
res = Healpix.Resolution(256)

# Show information about ring #10
print(getringinfo(res, 10))
source
Healpix.getringinfoFunction
getringinfo(resol::Resolution, ring; kwargs...) :: RingInfo

Return a RingInfo structure containing information about the specified ring. For the list of accepted keyword arguments, see getringinfo!.

source
Healpix.getringinfo!Function
getringinfo!(resol::Resolution, ring, ringinfo::RingInfo; full=true) :: RingInfo

Fill the RingInfo structure with information about the specified ring. If full is false, the field colatitude_rad (the most expensive in terms of computation) is set to NaN.

source
Healpix.getinterpolRingFunction
getinterpolRing(resol::Resolution, θ, ϕ) -> (Array{Int,1}, Array{Float64, 1})
getinterpolRing!(resol::Resolution, θ, ϕ, pix, weights) -> (Array{Int,1}, Array{Float64, 1})

Return the indices and the weights of the four neighbour pixels for the given direction (θ, ϕ) in a map with the specified resolution.

If provided, the parameters pix and weights should point to two 4-element arrays of integers and floating-points, respectively. They can be reused in multiple calls to avoid heap allocations and speed up the code.

source

Pixel boundaries

It is sometimes useful to be able to trace the border of a pixel: this can be useful for plotting purposes. Healpix.jl implements the boundariesRing! and boundariesRing functions for this purpose. They calculate a set of $N$ vectors pointing to a number of points along the border of a given pixel and return them as a $N\times 3$ matrix.

Here is a visual example:

using Plots
pyplot() # hide
using Healpix # hide

pointsperside = 10
matr = boundariesRing(Resolution(2), 3, pointsperside, Float32)
scatter(matr[:, 1], matr[:, 2], matr[:, 3])
savefig(joinpath("images", "pixelboundaries1.png")) # hide

We can cycle this over all the pixels in a map; however, using boundariesRing will require the result matrix to be allocated again and again for each pixel. Here boundariesRing! comes to the rescue, as we can pre-allocate the matrix and then pass it to each call within the for loop:

using Plots
pyplot() # hide
using Healpix # hide

pointsperside = 10
matr = Matrix{Float32}(undef, 4pointsperside, 3)
resol = Resolution(2)

scatter()
for pixidx in 1:resol.numOfPixels
    boundariesRing!(resol, pixidx, pointsperside, matr)
    scatter!(matr[:, 1], matr[:, 2], matr[:, 3], label="")
end
savefig(joinpath("images", "pixelboundariesall.png")) # hide

Reference

Healpix.ang2vecMethod
ang2vec(theta, phi) -> Array{Float64}

Given a direction in the sky with colatitude theta and longitude phi (in radians), return an array of 3 elements containing the x, y, and z components of the one-length vector pointing to that direction.

source
Healpix.vec2angMethod
vec2ang(x, y, z) -> (Number, Number)

Given a vector (not necessarily normalized) whose Cartesian components are x, y, and z, return a pair (theta, phi) containing the colatitude theta and the longitude phi (in radians) of the direction in the sky the vector is pointing at.

source
Healpix.ang2pixNestMethod
ang2pixNest(resol::Resolution, theta, phi) -> Integer

Return the index of the pixel which contains the point with coordinates (theta, the colatitude, and phi, the longitude), in radians, for a Healpix map with pixels in nested order. Note that pixel indexes are 1-based (this is Julia)!

source
Healpix.zphi2pixRingMethod
zphi2pixRing(resol::Resolution, theta, phi) -> Integer

Return the index of the pixel which contains the point with coordinates (theta, the colatitude, and phi, the longitude), in radians, for a Healpix map with pixels in ring order. Note that pixel indexes are 1-based (this is Julia)!

source
Healpix.ang2pixRingMethod
ang2pixRing(resol::Resolution, theta, phi) -> Integer

Return the index of the pixel which contains the point with coordinates (theta, the colatitude, and phi, the longitude), in radians, for a Healpix map with pixels in ring order. Note that pixel indexes are 1-based (this is Julia)!

source
Healpix.pix2angNestMethod
pix2angNest(resol::Resolution, pixel) -> (Float64, Float64)

Given the (1-based) index of a pixel in a Healpix map in nested order, return a pair containing the (colatitude, longitude) angles corresponding to its center, both expressed in radians.

source
Healpix.pix2angRingMethod
pix2angRing(resol::Resolution, pixel) -> (Float64, Float64)

Given the (1-based) index of a pixel in a Healpix map in ring order, return a pair containing the (colatitude, longitude) angles corresponding to its center, both expressed in radians.

source
Healpix.ring2nestMethod
ring2nest(resol::Resolution, ipix) :: Int

Convert the number of a pixel from RING to NESTED scheme.

source
Healpix.nest2ringMethod
nest2ring(resol::Resolution, ipix) :: Int

Convert the number of a pixel from NESTED to RING scheme.

source
Healpix.pix2ringposMethod
pix2ringpos(resol::Resolution, pixel)

Given the (1-based) index of a pixel in a Healpix map in ring order, return a pair of numbers (n, i, j) whose meaning is the following:

  • n can be one of the symbols :northcap, :equator, or :southcap, representing the region of the sky
  • i is the ring index, from 1 to 4NSIDE - 1
  • j is the pixel-in-ring index
source
Healpix.pix2xyfNestMethod
pix2xyfNest(resol::Resolution, ipix) :: (Int, Int, Int)

Convert a pixel number into (x, y, face), using NESTED ordering.

source
Healpix.pix2xyfRingMethod
pix2xyfRing(resol::Resolution, ipix) :: (Int, Int, Int)

Convert a pixel number into (x, y, face), using RING ordering.

source
Healpix.xyf2pixNestMethod
xyf2pixNest(resol::Resolution, ix, iy, facenum) :: Int

Convert (x, y, face) into a pixel number, using NESTED ordering.

source
Healpix.xyf2pixRingMethod
xyf2pixRing(resol::Resolution, ix, iy, facenum) :: Int

Convert (x, y, face) into a pixel number, using RING ordering.

source
Healpix.xyf2locFunction
xyf2loc(x, y, face) -> (z, phi, sintheta, have_sintheta)

Given a position encoded as XYF, return the tuple containing $z = cos(\theta)$, \phi, and optionally an accurate estimate for $sin(\theta)$ (if have_sintheta is true), where $\theta$ is the colatitude and $\phi$ is the longitude, both expressed in radians.

source
Healpix.pix2zphiRingMethod
pix2zphiRing(res::Resolution, pix) -> (z, phi)

Compute the angular coordinates z = cos(θ), ϕ of the center of the pixel with number pix, assuming the RING numbering scheme for pixels. Caution: this method is inaccurate near the poles at high resolutions.

source
Healpix.pix2zphiNestMethod
pix2zphiNest(res::Resolution, pix) -> (z, phi)

Compute the angular coordinates z = cos(θ), ϕ of the center of the pixel with number pix, assuming the NEST numbering scheme for pixels. Caution: this method is inaccurate near the poles at high resolutions.

source
Healpix.ringAboveFunction
ringAbove(res::Resolution, z) -> (ring_number)

Return the number of the next ring to the north of z = cos(θ). If z lies north of all rings, the function returns 0.

source
Healpix.ring2zFunction
ring2z(res::Resolution, ring) -> z

Return the value of z = \cos(\theta) for the given ring.

source
Healpix.numOfRingsFunction
numOfRings(resol::Resolution)
numOfRings(nside::Integer)

Return the number of horizontal rings in a Healpix map.

source
Healpix.max_pixradFunction
max_pixrad(res::Resolution, ring)
max_pixrad(res::Resolution)

Return the maximum angular distance (in radians) between a pixel center and any of its corners. If ring is specified, the result applies to all the pixels of the given ring; otherwise, all the pixels on the sphere are considered.

source
Healpix.boundariesRingFunction
boundariesRing(resol::Resolution, pix, step, T::Type{<:Real})
boundariesRing!(resol::Resolution, pix, step, buf::Matrix{T}) where {T <: Real}

Compute a set of directions (3D vectors) along the boundaries of a given pixel in the RING scheme at some resolution.

The function boundariesRing returns a $N \times 3$ matrix of type T containing $N$ vectors pointing towards the border of the pixel with index pix in RING scheme. Each edge of the pixel contains step points, and, as every pixel has a diamond-like shape with four edges, the number $N$ is equal to 4 * step.

If you plan to call this function again and again, you should allocate your own matrix with the results and call boundariesRing!, which accepts the parameter buf where the result will be stored. The shape of this matrix must be (4step, 3), for instance, and its element can be left undefined:

step = 10
buf = Matrix{Float64}(undef, 4step, 3)
boundariesRing!(res, pixidx, step, buf)  # This sets `buf`

Examples

Here we show how to use boundariesRing and boundariesRing! together to avoid allocating a matrix twice.

julia> matr = boundariesRing(Resolution(16), 534, 2, Float16)
8×3 Matrix{Float16}:
 0.3535  -0.6123  0.707
 0.3525  -0.6353  0.687
 0.3513  -0.657   0.6665
 0.3762  -0.664   0.646
 0.4014  -0.6694  0.625
 0.4084  -0.645   0.646
 0.414   -0.6196  0.6665
 0.3843  -0.6167  0.687

julia> boundariesRing!(Resolution(16), 535, 2, matr)  # Reuse `matr`

julia> matr
8×3 Matrix{Float16}:
 0.4158  -0.5723  0.707
 0.415   -0.596   0.687
 0.414   -0.6196  0.6665
 0.4397  -0.624   0.646
 0.465   -0.627   0.625
 0.4697  -0.602   0.646
 0.473   -0.576   0.6665
 0.4446  -0.5747  0.687
source