Package cds.healpix

# Class Healpix

java.lang.Object
cds.healpix.Healpix

All Implemented Interfaces:
  `Projection`

public final class Healpix extends Object implements Projection
Utility class containing HEALPix constants and operations which are independent of the depth. We replace the term "norder" used in HEALPix documents by the more generic "depth" usually used in tree-datastructures. We consider each base-resolution cell as been part of the root so that their depth equals 0.

Author:
  F.-X. Pineau

## Field Summary

Fields
Modifier and Type
Field
Description
`static final FillingCurve2DType`
`DEFAULT_FCTYPE`
Default implementation of the z-order curve.
`static final int`
`DEPTH_MAX`
29, largest possible depth we can store on a signed positive long (4 bits for base cells + 2 bits per depth + 2 remaining bits (1 use in the unique notation).
`static final double`
`LAT_OF_SQUARE_CELL`
Latitude, in the equatorial region, for which the distance from the cell center to its four vertices is equal on the sky (i.e.
`static double[]`
`SMALLER_EDGE2OPEDGE_DIST`
For each HEALPix depth, stores the smallest distance from an edge of a cell to the opposite edge of the same cell.
`static final double`
`TRANSITION_LATITUDE`
Limit on the |latitude (in radians)| between the equatorial region and the polar caps.
`static final double`
`TRANSITION_Z`
Limit on |z|=|sin(lat)| between the equatorial region and the polar caps.
`static final Healpix`
`UI`
Unique instance of this class (needed to implement the `Projection` interface).

### Fields inherited from interface cds.healpix.Projection

`LAT_INDEX, LON_INDEX, X_INDEX, Y_INDEX`

## Method Summary

Modifier and Type
Method
Description
`static void`
`checkLatitude(double latRad)`
Throws an IllegalArgumentException if the given latitude is not in [-pi/2, pi/2].
`static int`
`depth(int nside)`
Returns the number of subdivision of a base-resolution pixel at the given nside.
`static int`
`getBestStartingDepth(double distMaxInRad)`
Returns the the smallest depth (in [0, 29]) at which a shape having the given largest distance from its center to a border overlaps a maximum of 9 cells (the cell containing the center of the shape plus the 8 neighbouring cells).
Info: internally, unrolled binary search loop on 30 pre-computed values (one by depth).
`static double`
`getLargestCenterToCellVertexDistance(double lonRad, double latRad, int depth)`
For a given position on the unit sphere and a given depth, returns an upper limit on the distance between the center of a cell and its farthest vertex.
`static HealpixNested`
`getNested(int depth)`
Lazy instantiation of unique instances of `HealpixNested` for each required depth.
`static HealpixNested`
`getNested(int depth, FillingCurve2DType fillingCurveType)`
Same as `getNested(int)` except that we have here a given instance per depth and z-order curve implementation `DEFAULT_FCTYPE`.
`static HealpixNestedFast`
`getNestedFast(int depth)`
Same as `getNested(int)` for `HealpixNestedFast`, i.e.
`static HealpixNestedFast`
`getNestedFast(int depth, FillingCurve2DType fillingCurveType)`
Same as `getNested(int, FillingCurve2DType)` for `HealpixNestedFast`, i.e.
`static boolean`
`isLatInNorthPolarCap(double latRad)`
Returns `true` if the given latitude is in the North polar cap
`static boolean`
`isLatInSouthPolarCap(double latRad)`
Returns `true` if the given latitude is in the South polar cap
`static void`
`main(String[] args)`
`static long`
`nHash(int depth)`
Returns the number of cells (so the number of distinct hash value) the unit sphere is divided in at the given depth.
`static int`
`nIsolatitudeRings(int depth)`
Returns the number of isolatitude rings at the given depth, i.e.
`static int`
`nside(int depth)`
Returns the number of cells along both axis of a base-resolution cell at the given depth.
`double[]`
`project(double lonRad, double latRad)`
Project the given spherical coordinates into the Euclidean plane, following the HPX WCS projection (see Calabretta2007).
`void`
`project(double lonRad, double latRad, double[] resultXY)`
See `Projection.project(double, double)` with the result stored in the given array.
`static long`
`uniq(int depth, long hash)`
Create the unique representation of the given hash at the given depth.
`static int`
`uniq2depth(long uniqedHash)`
Extract the depth from the unique representation of the hash.
`static long`
`uniq2hash(long uniqedHash)`
Extract the hash from the the unique representation of the hash.
`static long`
`uniq2hash(long uniqdHash, int depth)`
Faster version of `uniq2hash(long)` in case we know (or have already extracted) the depth.
`double[]`
`unproject(double x, double y)`
Reverse projection: we look for spherical coordinates from their projected coordinates (`Projection.project(double, double)`.
`void`
`unproject(double x, double y, double[] resultLonLat)`
See `Projection.unproject(double, double)` with the result stored in the given array.

### Methods inherited from class java.lang.Object

`equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

## Field Details

### DEPTH_MAX

public static final int DEPTH_MAX
29, largest possible depth we can store on a signed positive long (4 bits for base cells + 2 bits per depth + 2 remaining bits (1 use in the unique notation).

See Also:
  - Constant Field Values

### TRANSITION_Z

public static final double TRANSITION_Z
Limit on |z|=|sin(lat)| between the equatorial region and the polar caps. Equals 2/3, see Eq. (1) in Gorsky2005.

See Also:
  - Constant Field Values

### TRANSITION_LATITUDE

public static final double TRANSITION_LATITUDE
Limit on the |latitude (in radians)| between the equatorial region and the polar caps. Equals asin(2/3) = 0.7297276562269663 radians ~= 41,81 degrees. Written \theta_X in Calabretta2007.

### SMALLER_EDGE2OPEDGE_DIST

public static double[] SMALLER_EDGE2OPEDGE_DIST
For each HEALPix depth, stores the smallest distance from an edge of a cell to the opposite edge of the same cell. If the radius of a cone is smaller than this distance, we know that it will overlap maximum 9 pixels (the pixel containing the center of the cone plus the 8 neighbours). In practice, this distance is the distance between the point of coordinate (0, `TRANSITION_LATITUDE`) and its nearest point on the Northeast edge of the cell of base hash 0 and coordinates in the base hash (x=0, y=nside-1). IMPORTANT REMARK: - this value is larger than the smallest center to vertex distance - this value x2 is larger than the smallest diagonal (NS or EW) - this value x2 is larger than the smallest edge - BUT there is no case in which the value is larger than the four center-to-vertex distance - BUT there is no case in which the value x2 is larger than both diagonals => this radius is smaller than the smaller circumcircle radius (=> no cone having the smaller -edge-to-opposite-edge-radius radius can contains the 4 vertices of a cell (but 3 is ok) vertices

### LAT_OF_SQUARE_CELL

public static final double LAT_OF_SQUARE_CELL
Latitude, in the equatorial region, for which the distance from the cell center to its four vertices is equal on the sky (i.e. the shape of the cell on the sky is similar to a square): dX = dY = 1 / nside (center to vertex distance) X = 4/pi * lon => dX = 4/pi dlon Y = 3/2 * sin(lat) => dY = 3/2 * cos(lat) dlat dlon * cos(lat) = dlat (same distance on the sky) => cos^2(lat) = 2/3 * 4/pi => lat = arccos(sqrt(2/3 * 4/pi)) = 22.88050802005781976715 deg = 0.39934019947897773410 rad

See Also:
  - Constant Field Values

### DEFAULT_FCTYPE

public static final FillingCurve2DType DEFAULT_FCTYPE
Default implementation of the z-order curve. Set to the look-up table implementation because it is the one showing the best performances in simple tests.
For an application requiring a lot of CPU cache, you may try the Z_ORDER_XOR implementation.

### UI

public static final Healpix UI
Unique instance of this class (needed to implement the `Projection` interface).

## Method Details

### getLargestCenterToCellVertexDistance

public static double getLargestCenterToCellVertexDistance(double lonRad, double latRad, int depth)
For a given position on the unit sphere and a given depth, returns an upper limit on the distance between the center of a cell and its farthest vertex.

Parameters:
  `lonRad` - longitude in radians.
  `latRad` - latitude in radians.
  `depth` - HEALPix depth.
Returns:
  2/3 * 1/nside * cos(LAT_OF_SQUARE_CELL)

### getNested

public static HealpixNested getNested(int depth)
Lazy instantiation of unique instances of `HealpixNested` for each required depth. Uses internally a double-checked lock.

Parameters:
  `depth` - the depth of the wanted `HealpixNested` instance
Returns:
  a `HealpixNested` instance at the given depth

### getNested

public static HealpixNested getNested(int depth, FillingCurve2DType fillingCurveType)
Same as `getNested(int)` except that we have here a given instance per depth and z-order curve implementation `DEFAULT_FCTYPE`.

Parameters:
  `depth` - the depth of the wanted `HealpixNested` instance
  `fillingCurveType` - the wanted z-order curve implementation
Returns:
  a `HealpixNested` instance at the given depth, with the given z-order curve implementation

### getNestedFast

public static HealpixNestedFast getNestedFast(int depth)
Same as `getNested(int)` for `HealpixNestedFast`, i.e. faster but less readable version of `HealpixNested`.

Parameters:
  `depth` - the depth of the wanted `HealpixNestedFast` instance
Returns:
  a `HealpixNestedFast` instance at the given depth

### getNestedFast

public static HealpixNestedFast getNestedFast(int depth, FillingCurve2DType fillingCurveType)
Same as `getNested(int, FillingCurve2DType)` for `HealpixNestedFast`, i.e. faster but less readable version of `HealpixNested`.

Parameters:
  `depth` - he depth of the wanted `HealpixNestedFast` instance
  `fillingCurveType` - the wanted z-order curve implementation
Returns:
  a `HealpixNestedFast` instance at the given depth, with the given z-order curve implementation

### nside

public static int nside(int depth)
Returns the number of cells along both axis of a base-resolution cell at the given depth.

Parameters:
  `depth` - (or order) number of subdivision of a base-resolution cell, from 0 to `DEPTH_MAX`.
Returns:
  2^depth.

### checkLatitude

public static void checkLatitude(double latRad)
Throws an IllegalArgumentException if the given latitude is not in [-pi/2, pi/2].

Parameters:
  `latRad` - latittude, in radians

### depth

public static int depth(int nside)
Returns the number of subdivision of a base-resolution pixel at the given nside.

Parameters:
  `nside` - number of pixels along both axis of a base-resolution pixel, from 1 to 2 power `DEPTH_MAX`.
Returns:
  log2(nside)

### nHash

public static long nHash(int depth)
Returns the number of cells (so the number of distinct hash value) the unit sphere is divided in at the given depth.

Parameters:
  `depth` - (or order) number of subdivision of a base-resolution cell, from 0 to `DEPTH_MAX`.
Returns:
  12 * nside^2

### nIsolatitudeRings

public static int nIsolatitudeRings(int depth)
Returns the number of isolatitude rings at the given depth, i.e. the number of small circles parallel to the equator containing HEALPix cell centers

Parameters:
  `depth` - (or order) number of subdivision of a base-resolution cell, from 0 to `DEPTH_MAX`.
Returns:
  4 * nside - 1

### isLatInNorthPolarCap

public static boolean isLatInNorthPolarCap(double latRad)
Returns `true` if the given latitude is in the North polar cap

Parameters:
  `latRad` - latitude, in radians
Returns:
  `true` if `latRad >` `TRANSITION_LATITUDE`

### isLatInSouthPolarCap

public static boolean isLatInSouthPolarCap(double latRad)
Returns `true` if the given latitude is in the South polar cap

Parameters:
  `latRad` - latitude, in radians
Returns:
  `true` if `latRad < -``TRANSITION_LATITUDE`

### getBestStartingDepth

public static int getBestStartingDepth(double distMaxInRad)
Returns the the smallest depth (in [0, 29]) at which a shape having the given largest distance from its center to a border overlaps a maximum of 9 cells (the cell containing the center of the shape plus the 8 neighbouring cells).
Info: internally, unrolled binary search loop on 30 pre-computed values (one by depth).

Parameters:
  `distMaxInRad` - largest possible distance, in radians, between the center and the border of a shape.
Returns:
  -1 if the given distance is very large (> ~48deg), else returns the smallest depth (in [0, 29]) at which a shape having the given largest distance from its center to a border overlaps a maximum of 9 cells (the cell containing the center of the shape plus the 8 neighbouring cells).

### project

public double[] project(double lonRad, double latRad)
Project the given spherical coordinates into the Euclidean plane, following the HPX WCS projection (see Calabretta2007). Remark: this method is thread safe

Specified by:
  `project` in interface `Projection`
Parameters:
  `lonRad` - longitude in radians, support positive and negative reasonably large values with a naive approach (no Cody-Waite nor Payne Hanek range reduction).
  `latRad` - latitude, must be in [-pi/2, pi/2] radians
Returns:
  x in [-PI, PI] radians, y in [-PI/2, PI/2] radians.

### project

public void project(double lonRad, double latRad, double[] resultXY)
Description copied from interface: `Projection`
See `Projection.project(double, double)` with the result stored in the given array.

Specified by:
  `project` in interface `Projection`
Parameters:
  `lonRad` - see `Projection.project(double, double)`
  `latRad` - see `Projection.project(double, double)`
  `resultXY` - array used to store the result. Must be of size >= 2.

### unproject

public double[] unproject(double x, double y)
Description copied from interface: `Projection`
Reverse projection: we look for spherical coordinates from their projected coordinates (`Projection.project(double, double)`.

Specified by:
  `unproject` in interface `Projection`
Parameters:
  `x` - the x coordinate of the projected spherical point we are looking for, the accepted value range is implementation dependent
  `y` - the y coordinate of the projected spherical point we are looking for, must be in [-2, 2].
Returns:
  the spherical coordinates leading to the given projection coordinates. The lon and lat coordinate are stored in the returned array at indices `Projection.LON_INDEX` and `Projection.LAT_INDEX` respectively. Lat is in [-pi/2, pi/2] radians, lon is also in radians but it possible value range is implementation dependent).

### unproject

public void unproject(double x, double y, double[] resultLonLat)
Description copied from interface: `Projection`
See `Projection.unproject(double, double)` with the result stored in the given array.

Specified by:
  `unproject` in interface `Projection`
Parameters:
  `x` - `Projection.unproject(double, double)`
  `y` - `Projection.unproject(double, double)`
  `resultLonLat` - array used to store the result. Must be of size >= 2.

### uniq

public static long uniq(int depth, long hash)
Create the unique representation of the given hash at the given depth. The unique representation encode the depth together with the hash value such that each possible (deph, hash) pair is unique.
To do so, the unique representation uses a sentinel bit to code the depth. The sentinel bit is the (1 +4 + 2*depth)^th most significant bit.
The encoding in the case of the nested scheme is thus
0...0sbbbb112233...
With

- 0...0: unused bits
- s: sentinel bit
- bbbb: the 4 bits coding the base cell
- 11: the 2 bits coding depth 1
- 22: the 2 bits coding depth 2
- 33: the 2 bits coding depth 3
- ...

WARNING: this is not compliant with the IVOA definition!!

Parameters:
  `depth` - the depth of the wanted unique hash
  `hash` - the hash we want the unique representation
Returns:
  the unique representation of the given hash at the given depth.

### uniq2depth

public static int uniq2depth(long uniqedHash)
Extract the depth from the unique representation of the hash. See `uniq(int, long)` to know more about the uniq encoding.

Parameters:
  `uniqedHash` - the uniq nested hash value we want to extract the depth
Returns:
  the depth from the unique representation of the hash.

### uniq2hash

public static long uniq2hash(long uniqedHash)
Extract the hash from the the unique representation of the hash. See `uniq(int, long)` to know more about the uniq encoding. WARNING: this is not compliant with the IVOA definition!!

Parameters:
  `uniqedHash` - the uniq nested hash value we want to extract the hash value
Returns:
  the hash from the the unique representation of the hash.

### uniq2hash

public static long uniq2hash(long uniqdHash, int depth)
Faster version of `uniq2hash(long)` in case we know (or have already extracted) the depth.

Parameters:
  `uniqdHash` - the uniq hash value we want to extract the hash value
  `depth` - the known depth encoded in the given uniq hash
Returns:
  the hash from the the unique representation of the hash, knowing the depth.

### main

public static void main(String[] args)