LSST Applications 30.0.7,g0e76e35be5+e8e946ae08,g19811a7679+138f7293ba,g199a45376c+5e234f8357,g1fd858c14a+2f48dbc4c4,g262e1987ae+fb36cac54d,g29ae962dfc+d9108a0941,g2c21b0017a+4f59a27f16,g31e44d4a5c+b0138be388,g33ac35c1f1+28b9f72785,g35bb328faa+b0138be388,g40c9b15c53+823ad735c1,g47891489e3+bcc48a0b46,g53246c7159+b0138be388,g64539dfbff+e8e946ae08,g67b6fd64d1+bcc48a0b46,g74acd417e5+422380537a,g76965917b2+a5ca99c4d9,g786e29fd12+796b79145d,g7aefaa3e3d+dc0c200193,g86b635cae8+734fe384f0,g87389fa792+d8b5378923,g89139ef638+bcc48a0b46,g8bbb235e95+3f4f7f9447,g8ea07a8fe4+78a4c88802,g9290983e33+ffdc83c6f7,g92c671f44c+e8e946ae08,gaa753fd333+03f406da14,gbf99507273+b0138be388,gc49b57b85e+8df26ee1f0,gca7fc764a6+bcc48a0b46,gd7ef33dd92+bcc48a0b46,gdab6d2f7ff+422380537a,ge1c02a5578+b0138be388,ge410e46f29+bcc48a0b46,ge80df9fc40+e6db5413d1,geaed405ab2+1de65a85c6,gf5dcc679e7+35a0ce2edd,gf5f1c85443+e8e946ae08
LSST Data Management Base Package
Loading...
Searching...
No Matches
_hpxUtils.py
Go to the documentation of this file.
1# This file is part of afw.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <https://www.gnu.org/licenses/>.
21#
22# This code is partly based on AladinSrc.jar version 11.024.
23# AladinSrc.jar is licensed with GPLv3, see http://aladin.u-strasbg.fr/COPYING
24import numpy as np
25
26from lsst.daf.base import PropertySet
27
28from ._geom import makeSkyWcs
29
30
31def makeHpxWcs(hips_order, pixel, shift_order=9, validate_pixel_id=True):
32 """
33 Make a SkyWcs object with HEALPix grid projection (HPX).
34
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
38
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.
45
46 Parameters
47 ----------
48 hips_order : `int`
49 HiPS order, such that HEALPix nside=2**hips_order.
50 Must be a positive integer.
51 pixel : `int`
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.
57 validate_pixel_id : `bool`, optional
58 If true validate that the pixel number is in range for the given
59 hips_order.
60
61
62 Returns
63 -------
64 wcs : `lsst.geom.SkyWcs`
65
66 Raises
67 ------
68 `ValueError`: Raise if hips_order is <=0, or if shift_order is <=0, or
69 if pixel number is out of range for the given hips_order
70 (0 <= pixel < 12*nside*nside) and validate_pixel_id is True.
71
72 Notes
73 -----
74 Table 5 from
75 https://www.ivoa.net/documents/HiPS/20170519/REC-HIPS-1.0-20170519.pdf
76 shows the relationship between hips_order, number of tiles (full
77 sky coverage), cell size, and sub-pixel size/image resolution (with
78 the default shift_order=9):
79
80 +------------+-----------------+--------------+------------------+
81 | hips_order | Number of Tiles | Cell Size | Image Resolution |
82 +============+=================+==============+==================+
83 | 0 | 12 | 58.63 deg | 6.871 arcmin |
84 | 1 | 48 | 29.32 deg | 3.435 arcmin |
85 | 2 | 192 | 14.66 deg | 1.718 arcmin |
86 | 3 | 768 | 7.329 deg | 51.53 arcsec |
87 | 4 | 3072 | 3.665 deg | 25.77 arcsec |
88 | 5 | 12288 | 1.832 deg | 12.88 arcsec |
89 | 6 | 49152 | 54.97 arcmin | 6.442 arcsec |
90 | 7 | 196608 | 27.48 arcmin | 3.221 arcsec |
91 | 8 | 786432 | 13.74 arcmin | 1.61 arcsec |
92 | 9 | 3145728 | 6.871 arcmin | 805.2mas |
93 | 10 | 12582912 | 3.435 arcmin | 402.6mas |
94 | 11 | 50331648 | 1.718 arcmin | 201.3mas |
95 | 12 | 201326592 | 51.53 arcsec | 100.6mas |
96 | 13 | 805306368 | 25.77 arcsec | 50.32mas |
97 +------------+-----------------+--------------+------------------+
98 """
99 if shift_order <= 0:
100 raise ValueError(f"shift_order {shift_order} must be positive.")
101 hips_tilepix = 2**shift_order
102
103 if hips_order <= 0:
104 raise ValueError(f"order {hips_order} must be positive.")
105 nside_cell = 2**hips_order
106
107 if validate_pixel_id and pixel < 0 or pixel >= 12*nside_cell*nside_cell:
108 raise ValueError(f"pixel value {pixel} out of range.")
109
110 # The HEALPix grid projection (HPX) is defined in the FITS standard
111 # https://fits.gsfc.nasa.gov/standard40/fits_standard40aa-le.pdf
112 # from Calabretta & Roukema (2007)
113 # https://ui.adsabs.harvard.edu/abs/2007MNRAS.381..865C/abstract
114 # which defines the standard H = 4, K = 3 pixelization parameters
115 # encoded in PV2_1 = H, PV2_2 = K.
116 # The CRVAL1, CRVAL2 values should always be 0, 0 according to
117 # the FITS standard.
118 # The CD matrix is defined in wcslib HPXcvt.c.
119 # The Calabretta & Roukema (2007) paper and wcslib HPXcvt.c only
120 # define full-sky HPX projections. For single pixels we
121 # use the code from AladinSrc.jar Tile2HPX.java to compute
122 # CRPIX1, CRPIX2.
123
124 # The nside of the sub-pixels is the product of the tile nside
125 # and the number of sub-pixels on a side.
126 nside_pix = nside_cell*hips_tilepix
127 # All tiles are rotated 45 degrees.
128 cos45 = np.sqrt(2.0)/2.0
129 # This defines the pixel scale.
130 scale = 90.0/nside_pix/np.sqrt(2.0)
131 cos45_scale = cos45*scale
132 # The projected center of the pixel used for the HPX header is
133 # a non-trivial computation, and typically is outside of the
134 # tile pixel itself. Therefore, these values are not the same
135 # as the values computed from HEALPix `pix2ang()`.
136 cent_ra_proj, cent_dec_proj = _hpx_projected_center(hips_order, pixel, validate_pixel_id)
137
138 md = PropertySet()
139 md['CD1_1'] = -cos45_scale
140 md['CD1_2'] = -cos45_scale
141 md['CD2_1'] = cos45_scale
142 md['CD2_2'] = -cos45_scale
143 md['CTYPE1'] = 'RA---HPX'
144 md['CTYPE2'] = 'DEC--HPX'
145 md['CRVAL1'] = 0.0
146 md['CRVAL2'] = 0.0
147 md['PV2_1'] = 4
148 md['PV2_2'] = 3
149 md['CRPIX1'] = ((hips_tilepix + 1)/2.0) - 0.5*(-cent_ra_proj/cos45_scale + cent_dec_proj/cos45_scale)
150 md['CRPIX2'] = ((hips_tilepix + 1)/2.0) - 0.5*(-cent_ra_proj/cos45_scale - cent_dec_proj/cos45_scale)
151
152 return makeSkyWcs(md)
153
154
155def _hpx_projected_center(hips_order, pixel, validate_pixel_id):
156 """
157 Compute the projected center for use in HPX WCS headers.
158
159 The values of cent_ra_proj, cent_dec_proj computed by this function are
160 typically outside of the cell pixel itself, and are not the same as
161 the values computed from HEALPix `pix2ang()'.
162
163 Code is adapted from AladinSrc.jar version 11.024, Tile2HPX.java.
164 AladinSrc.jar is licensed with GPLv3, see
165 http://aladin.u-strasbg.fr/COPYING
166
167 Parameters
168 ----------
169 hips_order : `int`
170 HiPS order, such that HEALPix nside=2**hips_order.
171 pixel : `int`
172 Pixel number in the nest ordering scheme.
173 validate_pixel_id : `bool`, optional
174 If true validate that the pixel number is in range for the given
175 hips_order.
176
177
178 Returns
179 -------
180 cent_ra_proj, cent_dec_proj : `float`
181 Projected center ra/dec in degrees.
182
183 Raises
184 ------
185 `ValueError`: Raised if hips_order is <=0, or if pixel number is out of
186 range for the given order (0 < 12*nside*nside).
187 """
188 if hips_order <= 0:
189 raise ValueError(f"hips_order {hips_order} must be positive.")
190 nside_cell = 2**hips_order
191
192 if validate_pixel_id and pixel < 0 or pixel >= 12*nside_cell*nside_cell:
193 raise ValueError(f"pixel value {pixel} out of range.")
194
195 twice_depth = np.left_shift(hips_order, 1)
196 xy_mask = np.left_shift(1, twice_depth) - 1
197 fc = _ZOrderCurve2DInt()
198
199 d0h = np.int32(np.right_shift(pixel, twice_depth))
200 _hash = fc.hash2ij(pixel & xy_mask)
201 i_in_d0h = fc.ij2i(_hash)
202 j_in_d0h = fc.ij2j(_hash)
203 # Compute coordinates from the center of the base pixel
204 # with x-axis = W-->E, y-axis = S-->N
205 l_in_d0h = i_in_d0h - j_in_d0h
206 h_in_d0h = i_in_d0h + j_in_d0h - (nside_cell - 1)
207 # Compute coordinates of the base pixel in the projection plane
208 d0h_by_4_quotient = np.right_shift(d0h, 2)
209 d0h_mod_4 = d0h - np.left_shift(d0h_by_4_quotient, 2)
210 h_d0h = 1 - d0h_by_4_quotient
211 l_d0h = np.left_shift(d0h_mod_4, 1)
212 if ((h_d0h == 0) and ((l_d0h == 6) or ((l_d0h == 4) and (l_in_d0h > 0)))):
213 # Equatorial region
214 l_d0h -= 8
215 elif (h_d0h != 0):
216 # Polar caps regions
217 l_d0h += 1
218 if (l_d0h > 3):
219 l_d0h -= 8
220 # Finalize
221 return (np.rad2deg((np.pi/4.)*(l_d0h + l_in_d0h/float(nside_cell))),
222 np.rad2deg((np.pi/4.)*(h_d0h + h_in_d0h/float(nside_cell))))
223
224
225class _ZOrderCurve2DInt(object):
226 """
227 Z-Order 2D curve for 32-bit integer values.
228
229 Code is ported from AladinSrc.jar version 11.024,
230 ZOrderCurve2DImpls.java.
231 AladinSrc.jar is licensed with GPLv3, see
232 http://aladin.u-strasbg.fr/COPYING
233
234 From the original documentation:
235 "Z-Order Curve (ZOC) implementation in which the vertical coordinate
236 carry the most significant bit (VMSB). This implementation is based
237 on a lookup table (LOOKUP). We assume that each discritized
238 coordinates is coded on maximum 32 bits (INT)."
239 """
240 LUPT_TO_HASH = np.array([
241 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044,
242 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111,
243 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400,
244 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445,
245 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514,
246 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 0x1000, 0x1001,
247 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050,
248 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115,
249 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404,
250 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451,
251 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540,
252 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005,
253 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054,
254 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141,
255 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401, 0x4404, 0x4405, 0x4410,
256 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455,
257 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544,
258 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011,
259 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100,
260 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145,
261 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414,
262 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501,
263 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550,
264 0x5551, 0x5554, 0x5555], dtype=np.int16)
265
266 LUPT_TO_IJ_INT = np.array([
267 0x000000000, 0x000000001, 0x100000000, 0x100000001, 0x000000002, 0x000000003,
268 0x100000002, 0x100000003, 0x200000000, 0x200000001, 0x300000000, 0x300000001,
269 0x200000002, 0x200000003, 0x300000002, 0x300000003, 0x000000004, 0x000000005,
270 0x100000004, 0x100000005, 0x000000006, 0x000000007, 0x100000006, 0x100000007,
271 0x200000004, 0x200000005, 0x300000004, 0x300000005, 0x200000006, 0x200000007,
272 0x300000006, 0x300000007, 0x400000000, 0x400000001, 0x500000000, 0x500000001,
273 0x400000002, 0x400000003, 0x500000002, 0x500000003, 0x600000000, 0x600000001,
274 0x700000000, 0x700000001, 0x600000002, 0x600000003, 0x700000002, 0x700000003,
275 0x400000004, 0x400000005, 0x500000004, 0x500000005, 0x400000006, 0x400000007,
276 0x500000006, 0x500000007, 0x600000004, 0x600000005, 0x700000004, 0x700000005,
277 0x600000006, 0x600000007, 0x700000006, 0x700000007, 0x000000008, 0x000000009,
278 0x100000008, 0x100000009, 0x00000000A, 0x00000000B, 0x10000000A, 0x10000000B,
279 0x200000008, 0x200000009, 0x300000008, 0x300000009, 0x20000000A, 0x20000000B,
280 0x30000000A, 0x30000000B, 0x00000000C, 0x00000000D, 0x10000000C, 0x10000000D,
281 0x00000000E, 0x00000000F, 0x10000000E, 0x10000000F, 0x20000000C, 0x20000000D,
282 0x30000000C, 0x30000000D, 0x20000000E, 0x20000000F, 0x30000000E, 0x30000000F,
283 0x400000008, 0x400000009, 0x500000008, 0x500000009, 0x40000000A, 0x40000000B,
284 0x50000000A, 0x50000000B, 0x600000008, 0x600000009, 0x700000008, 0x700000009,
285 0x60000000A, 0x60000000B, 0x70000000A, 0x70000000B, 0x40000000C, 0x40000000D,
286 0x50000000C, 0x50000000D, 0x40000000E, 0x40000000F, 0x50000000E, 0x50000000F,
287 0x60000000C, 0x60000000D, 0x70000000C, 0x70000000D, 0x60000000E, 0x60000000F,
288 0x70000000E, 0x70000000F, 0x800000000, 0x800000001, 0x900000000, 0x900000001,
289 0x800000002, 0x800000003, 0x900000002, 0x900000003, 0xA00000000, 0xA00000001,
290 0xB00000000, 0xB00000001, 0xA00000002, 0xA00000003, 0xB00000002, 0xB00000003,
291 0x800000004, 0x800000005, 0x900000004, 0x900000005, 0x800000006, 0x800000007,
292 0x900000006, 0x900000007, 0xA00000004, 0xA00000005, 0xB00000004, 0xB00000005,
293 0xA00000006, 0xA00000007, 0xB00000006, 0xB00000007, 0xC00000000, 0xC00000001,
294 0xD00000000, 0xD00000001, 0xC00000002, 0xC00000003, 0xD00000002, 0xD00000003,
295 0xE00000000, 0xE00000001, 0xF00000000, 0xF00000001, 0xE00000002, 0xE00000003,
296 0xF00000002, 0xF00000003, 0xC00000004, 0xC00000005, 0xD00000004, 0xD00000005,
297 0xC00000006, 0xC00000007, 0xD00000006, 0xD00000007, 0xE00000004, 0xE00000005,
298 0xF00000004, 0xF00000005, 0xE00000006, 0xE00000007, 0xF00000006, 0xF00000007,
299 0x800000008, 0x800000009, 0x900000008, 0x900000009, 0x80000000A, 0x80000000B,
300 0x90000000A, 0x90000000B, 0xA00000008, 0xA00000009, 0xB00000008, 0xB00000009,
301 0xA0000000A, 0xA0000000B, 0xB0000000A, 0xB0000000B, 0x80000000C, 0x80000000D,
302 0x90000000C, 0x90000000D, 0x80000000E, 0x80000000F, 0x90000000E, 0x90000000F,
303 0xA0000000C, 0xA0000000D, 0xB0000000C, 0xB0000000D, 0xA0000000E, 0xA0000000F,
304 0xB0000000E, 0xB0000000F, 0xC00000008, 0xC00000009, 0xD00000008, 0xD00000009,
305 0xC0000000A, 0xC0000000B, 0xD0000000A, 0xD0000000B, 0xE00000008, 0xE00000009,
306 0xF00000008, 0xF00000009, 0xE0000000A, 0xE0000000B, 0xF0000000A, 0xF0000000B,
307 0xC0000000C, 0xC0000000D, 0xD0000000C, 0xD0000000D, 0xC0000000E, 0xC0000000F,
308 0xD0000000E, 0xD0000000F, 0xE0000000C, 0xE0000000D, 0xF0000000C, 0xF0000000D,
309 0xE0000000E, 0xE0000000F, 0xF0000000E, 0xF0000000F], dtype=np.int64)
310
311 def __init__(self):
312 pass
313
314 def xy2hash(self, x, y):
315 """
316 Compute the hash value from x/y.
317
318 Parameters
319 ----------
320 x : `float`
321 x coordinate along the horizontal axis.
322 Must fit within the 32-bit integer range.
323 y : `float`
324 y coordinate along the vertical axis.
325 Must fit within the 32-bit integer range.
326
327 Returns
328 -------
329 hash : `numpy.int64`
330 The space-filling hash value associated with the
331 given coordinates.
332 """
333 return self.ij2hash(np.int32(x), np.int32(y))
334
335 def ij2hash(self, i, j):
336 """
337 Compute the hash value from discretized i, j.
338
339 Parameters
340 ----------
341 i : `int`
342 i discretized coordinate along the horizontal axis.
343 Must fit within the 32-bit integer range.
344 j : `int`
345 j discretized coordinate along the vertical axis.
346 Must fit within the 32-bit integer range.
347
348 Returns
349 -------
350 hash : `numpy.int64`
351 The space-filling hash value associated with the
352 given coordinates.
353 """
354 return (self.i02hash(np.int32(j)) << 1) | self.i02hash(np.int32(i))
355
356 def i02hash(self, i):
357 """
358 Special case of ij2hash in which the discretized coordinate along
359 the vertical axis equals zero.
360
361 Parameters
362 ----------
363 i : `int`
364 i discretized coordinate along the horizontal axis.
365 Must fit within the 32-bit integer range.
366
367 Returns
368 -------
369 hash : `numpy.int64`
370 The space-filling hash value associated with the
371 given coordinate.
372 """
373 val1 = np.int64(self.LUPT_TO_HASH[np.uint32(i) >> np.uint32(24)] << np.int64(48))
374 val2 = np.int64(self.LUPT_TO_HASH[(np.uint32(i) & 0x00FF0000) >> np.uint32(16)] << np.uint64(32))
375 val3 = np.int64(self.LUPT_TO_HASH[(np.uint32(i) & 0x0000FF00) >> np.uint32(8)] << np.uint64(16))
376 val4 = np.int64(self.LUPT_TO_HASH[np.uint32(i) & 0x000000FF])
377 return val1 | val2 | val3 | val4
378
379 def hash2ij(self, h):
380 """
381 Transforms the given space-filling hash value into a single value
382 from which the 2d coordinates can be extracted using ij2i and ij2j.
383
384 Parameters
385 ----------
386 h : `int`
387 Space-filling hash value
388
389 Returns
390 -------
391 ij : `np.int64`
392 Single value from which 2d coordinates can be extracted.
393 """
394 val1 = self.LUPT_TO_IJ_INT[
395 np.int32((np.uint64(h)
396 & np.uint64(0xFF00000000000000)) >> np.uint64(56))] << np.int64(28)
397 val2 = self.LUPT_TO_IJ_INT[
398 np.int32((np.uint64(h)
399 & np.uint64(0x00FF000000000000)) >> np.uint64(48))] << np.int64(24)
400 val3 = self.LUPT_TO_IJ_INT[
401 np.int32((np.uint64(h)
402 & np.uint64(0x0000FF0000000000)) >> np.uint64(40))] << np.int64(20)
403 val4 = self.LUPT_TO_IJ_INT[
404 np.int32((np.uint64(h)
405 & np.uint64(0x000000FF00000000)) >> np.uint64(32))] << np.int64(16)
406 val5 = self.LUPT_TO_IJ_INT[
407 np.int32((np.uint64(h)
408 & np.uint64(0x00000000FF000000)) >> np.uint64(24))] << np.int64(12)
409 val6 = self.LUPT_TO_IJ_INT[
410 np.int32((np.uint64(h)
411 & np.uint64(0x0000000000FF0000)) >> np.uint64(16))] << np.int64(8)
412 val7 = self.LUPT_TO_IJ_INT[
413 np.int32((np.uint64(h)
414 & np.uint64(0x000000000000FF00)) >> np.uint64(8))] << np.int64(4)
415 val8 = self.LUPT_TO_IJ_INT[
416 np.int32((np.uint64(h)
417 & np.uint64(0x00000000000000FF)))]
418 return val1 | val2 | val3 | val4 | val5 | val6 | val7 | val8
419
420 def hash2i0(self, _hash):
421 """
422 Special case of hash2ij in which the discretized coordinate along
423 the vertical axis is zero.
424
425 Parameters
426 ----------
427 _hash : `int`
428 Space-filling hash value.
429
430 Returns
431 -------
432 ij : `np.int64`
433 Single value from which 2d coordinates can be extracted.
434 """
435 assert (0xFFFFFFFF33333333 & np.int64(_hash)) == 0
436 return self.hash2ij(_hash)
437
438 def ij2i(self, ij):
439 """
440 Extract the discretized horizontal coordinate from hash2ij.
441
442 Parameters
443 ----------
444 ij : `int`
445 The ij result of hash2ij.
446
447 Returns
448 -------
449 i : `np.int32`
450 Discretized horizontal coordinate stored in ij.
451 """
452 return np.int32(ij)
453
454 def ij2j(self, ij):
455 """
456 Extract the discretized vertical coordinate from hash2ij.
457
458 Parameters
459 ----------
460 ij : `int`
461 The ij result of hash2ij.
462
463 Returns
464 -------
465 j : `np.int32`
466 Discretized vertical coordinate stored in ij.
467 """
468 return np.int32(np.uint64(ij) >> np.uint64(32))
Class for storing generic metadata.
Definition PropertySet.h:67
_hpx_projected_center(hips_order, pixel, validate_pixel_id)
Definition _hpxUtils.py:155
makeHpxWcs(hips_order, pixel, shift_order=9, validate_pixel_id=True)
Definition _hpxUtils.py:31
std::shared_ptr< SkyWcs > makeSkyWcs(daf::base::PropertySet &metadata, bool strip=false)
Construct a SkyWcs from FITS keywords.
Definition SkyWcs.cc:560