def healpix_pixel_corners(order: int, ipix: int, frame: str) -> SkyCoord: """Returns an array containing the angle (theta and phi) in radians. This function calls `healpy.boundaries` to compute the four corners of a HiPS tile. It's not documented, but apparently the order of the corners is always as follows: 1. North (N) 2. West (W) 3. South (S) 4. East (E) Parameters ---------- order : int HEALPix ``order`` parameter ipix : int HEALPix pixel index frame : {'icrs', 'galactic', 'ecliptic'} Sky coordinate frame Returns ------- corners : `~astropy.coordinates.SkyCoord` Sky coordinates (array of length 4). """ frame = make_frame(frame) hp = HEALPix(nside=2 ** order, order='nested', frame=frame) return hp.boundaries_skycoord(ipix, step=1)[0]
def plot_hpix(self, hpix, nside, order='nested', color='blue', edgecolor='black', zorder=1, alpha=1): bounds = HEALPix(nside=nside, order=order, frame=ICRS()) corners = bounds.boundaries_skycoord(np.unique(hpix), step=1) poly = MultiPolygon(Polygon(np.array([-(corners[idx].ra.deg - 360 * (corners[idx].ra.deg > 180)), corners[idx].dec.deg]).T) \ for idx in range(len(corners.ra)) if not any(abs(corners[idx].ra.deg - 360 * (corners[idx].ra.deg > 180) - 180) == 0)) self.ax.add_geometries([poly], crs=ccrs.PlateCarree(), facecolor=color, alpha=alpha, edgecolor=edgecolor, zorder=zorder)
def from_moc(depth_ipix_d, wcs): # Create a new MOC that do not contain the HEALPix # cells that are backfacing the projection depths = [int(depth_str) for depth_str in depth_ipix_d.keys()] min_depth = min(depths) max_depth = max(depths) ipixels = np.asarray(depth_ipix_d[str(min_depth)]) # Split the cells located at the border of the projection # until at least the depth 7 max_split_depth = max(7, max_depth) ipix_d = {} for depth in range(min_depth, max_split_depth + 1): hp = HEALPix(nside=(1 << depth), order='nested', frame=ICRS()) ipix_boundaries = hp.boundaries_skycoord(ipixels, step=1) # Projection on the given WCS xp, yp = skycoord_to_pixel(coords=ipix_boundaries, wcs=wcs) _, _, frontface_id = backface_culling(xp, yp) # Get the pixels which are backfacing the projection backfacing_ipix = ipixels[~frontface_id] frontface_ipix = ipixels[frontface_id] depth_str = str(depth) ipix_d.update({depth_str: frontface_ipix}) next_depth = str(depth + 1) ipixels = [] if next_depth in depth_ipix_d: ipixels = depth_ipix_d[next_depth] for bf_ipix in backfacing_ipix: child_bf_ipix = bf_ipix << 2 ipixels.extend([child_bf_ipix, child_bf_ipix + 1, child_bf_ipix + 2, child_bf_ipix + 3]) ipixels = np.asarray(ipixels) return ipix_d
def compute_healpix_vertices(depth, ipix, wcs): path_vertices = np.array([]) codes = np.array([]) depth = int(depth) step = 1 if depth < 3: step = 2 hp = HEALPix(order="nested", nside=(1 << depth), frame=ICRS()) ipix_boundaries = hp.boundaries_skycoord(ipix, step=step) # Projection on the given WCS xp, yp = skycoord_to_pixel(ipix_boundaries, wcs=wcs) c1 = np.vstack((xp[:, 0], yp[:, 0])).T c2 = np.vstack((xp[:, 1], yp[:, 1])).T c3 = np.vstack((xp[:, 2], yp[:, 2])).T c4 = np.vstack((xp[:, 3], yp[:, 3])).T if depth < 3: c5 = np.vstack((xp[:, 4], yp[:, 4])).T c6 = np.vstack((xp[:, 5], yp[:, 5])).T c7 = np.vstack((xp[:, 6], yp[:, 6])).T c8 = np.vstack((xp[:, 7], yp[:, 7])).T cells = np.hstack((c1, c2, c3, c4, c5, c6, c7, c8, np.zeros((c1.shape[0], 2)))) path_vertices = cells.reshape((9*c1.shape[0], 2)) single_code = np.array([Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY]) else: cells = np.hstack((c1, c2, c3, c4, np.zeros((c1.shape[0], 2)))) path_vertices = cells.reshape((5*c1.shape[0], 2)) single_code = np.array([Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY]) codes = np.tile(single_code, c1.shape[0]) return path_vertices, codes