28from ._geom
import makeSkyWcs
31def makeHpxWcs(hips_order, pixel, shift_order=9):
33 Make a SkyWcs object with HEALPix grid projection (HPX).
35 The SkyWcs generated by this function
is suitable to be used
with a
36 Hierarchical Progressive Survey (HiPS) FITS image
as described
in
37 https://www.ivoa.net/documents/HiPS/20170519/REC-HIPS-1.0-20170519.pdf
39 A HiPS image covers one HEALPix cell,
with the HEALPix nside equal to
40 2**hips_order. Each cell
is 'shift_order' orders deeper than the HEALPix
41 cell,
with 2**shift_order x 2**shift_order sub-pixels on a side, which
42 defines the target resolution of the HiPS image. The IVOA recommends
43 shift_order=9,
for 2**9=512 pixels on a side. See Notes below to
44 convert
from hips_order to image resolution.
49 HiPS order, such that HEALPix nside=2**hips_order.
50 Must be a positive integer.
52 Pixel number
in the nest ordering scheme.
53 shift_order : `int`, optional
54 Shift order
for subpixels, such that there are 2**shift_order
55 sub-pixels on a side of the HiPS cell.
56 Must be a positive integer.
60 wcs : `lsst.geom.SkyWcs`
64 `ValueError`: Raise
if hips_order
is <=0,
or if shift_order
is <=0,
or
65 if pixel number
is out of range
for the given hips_order
66 (0 <= pixel < 12*nside*nside).
71 https://www.ivoa.net/documents/HiPS/20170519/REC-HIPS-1.0-20170519.pdf
72 shows the relationship between hips_order, number of tiles (full
73 sky coverage), cell size,
and sub-pixel size/image resolution (
with
74 the default shift_order=9):
76 +------------+-----------------+--------------+------------------+
77 | hips_order | Number of Tiles | Cell Size | Image Resolution |
78 +============+=================+==============+==================+
79 | 0 | 12 | 58.63 deg | 6.871 arcmin |
80 | 1 | 48 | 29.32 deg | 3.435 arcmin |
81 | 2 | 192 | 14.66 deg | 1.718 arcmin |
82 | 3 | 768 | 7.329 deg | 51.53 arcsec |
83 | 4 | 3072 | 3.665 deg | 25.77 arcsec |
84 | 5 | 12288 | 1.832 deg | 12.88 arcsec |
85 | 6 | 49152 | 54.97 arcmin | 6.442 arcsec |
86 | 7 | 196608 | 27.48 arcmin | 3.221 arcsec |
87 | 8 | 786432 | 13.74 arcmin | 1.61 arcsec |
88 | 9 | 3145728 | 6.871 arcmin | 805.2mas |
89 | 10 | 12582912 | 3.435 arcmin | 402.6mas |
90 | 11 | 50331648 | 1.718 arcmin | 201.3mas |
91 | 12 | 201326592 | 51.53 arcsec | 100.6mas |
92 | 13 | 805306368 | 25.77 arcsec | 50.32mas |
93 +------------+-----------------+--------------+------------------+
96 raise ValueError(f
"shift_order {shift_order} must be positive.")
97 hips_tilepix = 2**shift_order
100 raise ValueError(f
"order {hips_order} must be positive.")
101 nside_cell = 2**hips_order
103 if pixel < 0
or pixel >= 12*nside_cell*nside_cell:
104 raise ValueError(f
"pixel value {pixel} out of range.")
122 nside_pix = nside_cell*hips_tilepix
124 cos45 = np.sqrt(2.0)/2.0
126 scale = 90.0/nside_pix/np.sqrt(2.0)
127 cos45_scale = cos45*scale
132 cent_ra_proj, cent_dec_proj = _hpx_projected_center(hips_order, pixel)
135 md[
'CD1_1'] = -cos45_scale
136 md[
'CD1_2'] = -cos45_scale
137 md[
'CD2_1'] = cos45_scale
138 md[
'CD2_2'] = -cos45_scale
139 md[
'CTYPE1'] =
'RA---HPX'
140 md[
'CTYPE2'] =
'DEC--HPX'
145 md[
'CRPIX1'] = ((hips_tilepix + 1)/2.0) - 0.5*(-cent_ra_proj/cos45_scale + cent_dec_proj/cos45_scale)
146 md[
'CRPIX2'] = ((hips_tilepix + 1)/2.0) - 0.5*(-cent_ra_proj/cos45_scale - cent_dec_proj/cos45_scale)
148 return makeSkyWcs(md)
151def _hpx_projected_center(hips_order, pixel):
153 Compute the projected center for use
in HPX WCS headers.
155 The values of cent_ra_proj, cent_dec_proj computed by this function are
156 typically outside of the cell pixel itself,
and are
not the same
as
157 the values computed
from HEALPix `pix2ang()
'.
159 Code is adapted
from AladinSrc.jar version 11.024, Tile2HPX.java.
160 AladinSrc.jar
is licensed
with GPLv3, see
161 http://aladin.u-strasbg.fr/COPYING
166 HiPS order, such that HEALPix nside=2**hips_order.
168 Pixel number
in the nest ordering scheme.
172 cent_ra_proj, cent_dec_proj : `float`
173 Projected center ra/dec
in degrees.
177 `ValueError`: Raised
if hips_order
is <=0,
or if pixel number
is out of
178 range
for the given order (0 < 12*nside*nside).
181 raise ValueError(f
"hips_order {hips_order} must be positive.")
182 nside_cell = 2**hips_order
184 if pixel < 0
or pixel >= 12*nside_cell*nside_cell:
185 raise ValueError(f
"pixel value {pixel} out of range.")
187 twice_depth = np.left_shift(hips_order, 1)
188 xy_mask = np.left_shift(1, twice_depth) - 1
191 d0h = np.int32(np.right_shift(pixel, twice_depth))
192 _hash = fc.hash2ij(pixel & xy_mask)
193 i_in_d0h = fc.ij2i(_hash)
194 j_in_d0h = fc.ij2j(_hash)
197 l_in_d0h = i_in_d0h - j_in_d0h
198 h_in_d0h = i_in_d0h + j_in_d0h - (nside_cell - 1)
200 d0h_by_4_quotient = np.right_shift(d0h, 2)
201 d0h_mod_4 = d0h - np.left_shift(d0h_by_4_quotient, 2)
202 h_d0h = 1 - d0h_by_4_quotient
203 l_d0h = np.left_shift(d0h_mod_4, 1)
204 if ((h_d0h == 0)
and ((l_d0h == 6)
or ((l_d0h == 4)
and (l_in_d0h > 0)))):
213 return (np.rad2deg((np.pi/4.)*(l_d0h + l_in_d0h/float(nside_cell))),
214 np.rad2deg((np.pi/4.)*(h_d0h + h_in_d0h/float(nside_cell))))
219 Z-Order 2D curve for 32-bit integer values.
221 Code
is ported
from AladinSrc.jar version 11.024,
222 ZOrderCurve2DImpls.java.
223 AladinSrc.jar
is licensed
with GPLv3, see
224 http://aladin.u-strasbg.fr/COPYING
226 From the original documentation:
227 "Z-Order Curve (ZOC) implementation in which the vertical coordinate
228 carry the most significant bit (VMSB). This implementation is based
229 on a lookup table (LOOKUP). We assume that each discritized
230 coordinates
is coded on maximum 32 bits (INT).
"
232 LUPT_TO_HASH = np.array([
233 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044,
234 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111,
235 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400,
236 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445,
237 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514,
238 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001,
239 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050,
240 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115,
241 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404,
242 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451,
243 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540,
244 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005,
245 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054,
246 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141,
247 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410,
248 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455,
249 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544,
250 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011,
251 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100,
252 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145,
253 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414,
254 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501,
255 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550,
256 0x5551, 0x5554, 0x5555], dtype=np.int16)
258 LUPT_TO_IJ_INT = np.array([
259 0x000000000, 0x000000001, 0x100000000, 0x100000001, 0x000000002, 0x000000003,
260 0x100000002, 0x100000003, 0x200000000, 0x200000001, 0x300000000, 0x300000001,
261 0x200000002, 0x200000003, 0x300000002, 0x300000003, 0x000000004, 0x000000005,
262 0x100000004, 0x100000005, 0x000000006, 0x000000007, 0x100000006, 0x100000007,
263 0x200000004, 0x200000005, 0x300000004, 0x300000005, 0x200000006, 0x200000007,
264 0x300000006, 0x300000007, 0x400000000, 0x400000001, 0x500000000, 0x500000001,
265 0x400000002, 0x400000003, 0x500000002, 0x500000003, 0x600000000, 0x600000001,
266 0x700000000, 0x700000001, 0x600000002, 0x600000003, 0x700000002, 0x700000003,
267 0x400000004, 0x400000005, 0x500000004, 0x500000005, 0x400000006, 0x400000007,
268 0x500000006, 0x500000007, 0x600000004, 0x600000005, 0x700000004, 0x700000005,
269 0x600000006, 0x600000007, 0x700000006, 0x700000007, 0x000000008, 0x000000009,
270 0x100000008, 0x100000009, 0x00000000A, 0x00000000B, 0x10000000A, 0x10000000B,
271 0x200000008, 0x200000009, 0x300000008, 0x300000009, 0x20000000A, 0x20000000B,
272 0x30000000A, 0x30000000B, 0x00000000C, 0x00000000D, 0x10000000C, 0x10000000D,
273 0x00000000E, 0x00000000F, 0x10000000E, 0x10000000F, 0x20000000C, 0x20000000D,
274 0x30000000C, 0x30000000D, 0x20000000E, 0x20000000F, 0x30000000E, 0x30000000F,
275 0x400000008, 0x400000009, 0x500000008, 0x500000009, 0x40000000A, 0x40000000B,
276 0x50000000A, 0x50000000B, 0x600000008, 0x600000009, 0x700000008, 0x700000009,
277 0x60000000A, 0x60000000B, 0x70000000A, 0x70000000B, 0x40000000C, 0x40000000D,
278 0x50000000C, 0x50000000D, 0x40000000E, 0x40000000F, 0x50000000E, 0x50000000F,
279 0x60000000C, 0x60000000D, 0x70000000C, 0x70000000D, 0x60000000E, 0x60000000F,
280 0x70000000E, 0x70000000F, 0x800000000, 0x800000001, 0x900000000, 0x900000001,
281 0x800000002, 0x800000003, 0x900000002, 0x900000003, 0xA00000000, 0xA00000001,
282 0xB00000000, 0xB00000001, 0xA00000002, 0xA00000003, 0xB00000002, 0xB00000003,
283 0x800000004, 0x800000005, 0x900000004, 0x900000005, 0x800000006, 0x800000007,
284 0x900000006, 0x900000007, 0xA00000004, 0xA00000005, 0xB00000004, 0xB00000005,
285 0xA00000006, 0xA00000007, 0xB00000006, 0xB00000007, 0xC00000000, 0xC00000001,
286 0xD00000000, 0xD00000001, 0xC00000002, 0xC00000003, 0xD00000002, 0xD00000003,
287 0xE00000000, 0xE00000001, 0xF00000000, 0xF00000001, 0xE00000002, 0xE00000003,
288 0xF00000002, 0xF00000003, 0xC00000004, 0xC00000005, 0xD00000004, 0xD00000005,
289 0xC00000006, 0xC00000007, 0xD00000006, 0xD00000007, 0xE00000004, 0xE00000005,
290 0xF00000004, 0xF00000005, 0xE00000006, 0xE00000007, 0xF00000006, 0xF00000007,
291 0x800000008, 0x800000009, 0x900000008, 0x900000009, 0x80000000A, 0x80000000B,
292 0x90000000A, 0x90000000B, 0xA00000008, 0xA00000009, 0xB00000008, 0xB00000009,
293 0xA0000000A, 0xA0000000B, 0xB0000000A, 0xB0000000B, 0x80000000C, 0x80000000D,
294 0x90000000C, 0x90000000D, 0x80000000E, 0x80000000F, 0x90000000E, 0x90000000F,
295 0xA0000000C, 0xA0000000D, 0xB0000000C, 0xB0000000D, 0xA0000000E, 0xA0000000F,
296 0xB0000000E, 0xB0000000F, 0xC00000008, 0xC00000009, 0xD00000008, 0xD00000009,
297 0xC0000000A, 0xC0000000B, 0xD0000000A, 0xD0000000B, 0xE00000008, 0xE00000009,
298 0xF00000008, 0xF00000009, 0xE0000000A, 0xE0000000B, 0xF0000000A, 0xF0000000B,
299 0xC0000000C, 0xC0000000D, 0xD0000000C, 0xD0000000D, 0xC0000000E, 0xC0000000F,
300 0xD0000000E, 0xD0000000F, 0xE0000000C, 0xE0000000D, 0xF0000000C, 0xF0000000D,
301 0xE0000000E, 0xE0000000F, 0xF0000000E, 0xF0000000F], dtype=np.int64)
308 Compute the hash value from x/y.
313 x coordinate along the horizontal axis.
314 Must fit within the 32-bit integer range.
316 y coordinate along the vertical axis.
317 Must fit within the 32-bit integer range.
322 The space-filling hash value associated
with the
325 return self.ij2hash(np.int32(x), np.int32(y))
329 Compute the hash value from discretized i, j.
334 i discretized coordinate along the horizontal axis.
335 Must fit within the 32-bit integer range.
337 j discretized coordinate along the vertical axis.
338 Must fit within the 32-bit integer range.
343 The space-filling hash value associated
with the
346 return (self.
i02hash(np.int32(j)) << 1) | self.
i02hash(np.int32(i))
350 Special case of ij2hash in which the discretized coordinate along
351 the vertical axis equals zero.
356 i discretized coordinate along the horizontal axis.
357 Must fit within the 32-bit integer range.
362 The space-filling hash value associated
with the
365 val1 = np.int64(self.LUPT_TO_HASH[np.uint32(i) >> np.uint32(24)] << np.int64(48))
366 val2 = np.int64(self.LUPT_TO_HASH[(np.uint32(i) & 0x00FF0000) >> np.uint32(16)] << np.uint64(32))
367 val3 = np.int64(self.LUPT_TO_HASH[(np.uint32(i) & 0x0000FF00) >> np.uint32(8)] << np.uint64(16))
368 val4 = np.int64(self.LUPT_TO_HASH[np.uint32(i) & 0x000000FF])
369 return val1 | val2 | val3 | val4
373 Transforms the given space-filling hash value into a single value
374 from which the 2d coordinates can be extracted using ij2i
and ij2j.
379 Space-filling hash value
384 Single value
from which 2d coordinates can be extracted.
387 np.int32((np.uint64(h)
388 & np.uint64(0xFF00000000000000)) >> np.uint64(56))] << np.int64(28)
390 np.int32((np.uint64(h)
391 & np.uint64(0x00FF000000000000)) >> np.uint64(48))] << np.int64(24)
393 np.int32((np.uint64(h)
394 & np.uint64(0x0000FF0000000000)) >> np.uint64(40))] << np.int64(20)
396 np.int32((np.uint64(h)
397 & np.uint64(0x000000FF00000000)) >> np.uint64(32))] << np.int64(16)
399 np.int32((np.uint64(h)
400 & np.uint64(0x00000000FF000000)) >> np.uint64(24))] << np.int64(12)
402 np.int32((np.uint64(h)
403 & np.uint64(0x0000000000FF0000)) >> np.uint64(16))] << np.int64(8)
405 np.int32((np.uint64(h)
406 & np.uint64(0x000000000000FF00)) >> np.uint64(8))] << np.int64(4)
408 np.int32((np.uint64(h)
409 & np.uint64(0x00000000000000FF)))]
410 return val1 | val2 | val3 | val4 | val5 | val6 | val7 | val8
414 Special case of hash2ij in which the discretized coordinate along
415 the vertical axis
is zero.
420 Space-filling hash value.
425 Single value
from which 2d coordinates can be extracted.
427 assert((0xFFFFFFFF33333333 & np.int64(_hash)) == 0)
432 Extract the discretized horizontal coordinate from hash2ij.
437 The ij result of hash2ij.
442 Discretized horizontal coordinate stored
in ij.
448 Extract the discretized vertical coordinate from hash2ij.
453 The ij result of hash2ij.
458 Discretized vertical coordinate stored
in ij.
460 return np.int32(np.uint64(ij) >> np.uint64(32))
Class for storing generic metadata.