Package cds.healpix
Class Healpix
- java.lang.Object
-
- cds.healpix.Healpix
-
- All Implemented Interfaces:
Projection
public final class Healpix extends java.lang.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 FillingCurve2DType
DEFAULT_FCTYPE
Default implementation of the z-order curve.static 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 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 double
TRANSITION_LATITUDE
Limit on the |latitude (in radians)| between the equatorial region and the polar caps.static double
TRANSITION_Z
Limit on |z|=|sin(lat)| between the equatorial region and the polar caps.static Healpix
UI
Unique instance of this class (needed to implement theProjection
interface).-
Fields inherited from interface cds.healpix.Projection
LAT_INDEX, LON_INDEX, X_INDEX, Y_INDEX
-
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods 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 ofHealpixNested
for each required depth.static HealpixNested
getNested(int depth, FillingCurve2DType fillingCurveType)
Same asgetNested(int)
except that we have here a given instance per depth and z-order curve implementationDEFAULT_FCTYPE
.static HealpixNestedFast
getNestedFast(int depth)
Same asgetNested(int)
forHealpixNestedFast
, i.e.static HealpixNestedFast
getNestedFast(int depth, FillingCurve2DType fillingCurveType)
Same asgetNested(int, FillingCurve2DType)
forHealpixNestedFast
, i.e.static boolean
isLatInNorthPolarCap(double latRad)
Returnstrue
if the given latitude is in the North polar capstatic boolean
isLatInSouthPolarCap(double latRad)
Returnstrue
if the given latitude is in the South polar capstatic 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)
SeeProjection.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 ofuniq2hash(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)
SeeProjection.unproject(double, double)
with the result stored in the given array.
-
-
-
Field Detail
-
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 theProjection
interface).
-
-
Method Detail
-
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 ofHealpixNested
for each required depth. Uses internally a double-checked lock.- Parameters:
depth
- the depth of the wantedHealpixNested
instance- Returns:
- a
HealpixNested
instance at the given depth
-
getNested
public static HealpixNested getNested(int depth, FillingCurve2DType fillingCurveType)
Same asgetNested(int)
except that we have here a given instance per depth and z-order curve implementationDEFAULT_FCTYPE
.- Parameters:
depth
- the depth of the wantedHealpixNested
instancefillingCurveType
- 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 asgetNested(int)
forHealpixNestedFast
, i.e. faster but less readable version ofHealpixNested
.- Parameters:
depth
- the depth of the wantedHealpixNestedFast
instance- Returns:
- a
HealpixNestedFast
instance at the given depth
-
getNestedFast
public static HealpixNestedFast getNestedFast(int depth, FillingCurve2DType fillingCurveType)
Same asgetNested(int, FillingCurve2DType)
forHealpixNestedFast
, i.e. faster but less readable version ofHealpixNested
.- Parameters:
depth
- he depth of the wantedHealpixNestedFast
instancefillingCurveType
- 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 toDEPTH_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 powerDEPTH_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 toDEPTH_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 toDEPTH_MAX
.- Returns:
- 4 * nside - 1
-
isLatInNorthPolarCap
public static boolean isLatInNorthPolarCap(double latRad)
Returnstrue
if the given latitude is in the North polar cap- Parameters:
latRad
- latitude, in radians- Returns:
true
iflatRad >
TRANSITION_LATITUDE
-
isLatInSouthPolarCap
public static boolean isLatInSouthPolarCap(double latRad)
Returnstrue
if the given latitude is in the South polar cap- Parameters:
latRad
- latitude, in radians- Returns:
true
iflatRad < -
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 interfaceProjection
- 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
SeeProjection.project(double, double)
with the result stored in the given array.- Specified by:
project
in interfaceProjection
- Parameters:
lonRad
- seeProjection.project(double, double)
latRad
- seeProjection.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 interfaceProjection
- Parameters:
x
- the x coordinate of the projected spherical point we are looking for, the accepted value range is implementation dependenty
- 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
andProjection.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
SeeProjection.unproject(double, double)
with the result stored in the given array.- Specified by:
unproject
in interfaceProjection
- 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
- ...
- Parameters:
depth
- the depth of the wanted unique hashhash
- 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. Seeuniq(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. Seeuniq(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 ofuniq2hash(long)
in case we know (or have already extracted) the depth.- Parameters:
uniqdHash
- the uniq hash value we want to extract the hash valuedepth
- the known depth encoded in the given uniq hash- Returns:
- the hash from the the unique representation of the hash, knowing the depth.
-
-