def remove_neighbours(self): """ Removes from the MOC instance the HEALPix cells located at its border. The depth of the HEALPix cells removed is equal to the maximum depth of the MOC instance. Returns ------- moc : `~mocpy.moc.MOC` self minus its HEALPix cells located at its border. """ max_depth = self.max_order # Get the HEALPix cells of the MOC at its max depth ipix = core.flatten_pixels(self._interval_set._intervals, max_depth) # Get the HEALPix array containing the neighbors of ``ipix``. # This array "extends" ``ipix`` by one degree of neighbors. ipix_extended = cdshealpix.neighbours(ipix, max_depth) ipix_extended = ipix_extended[ipix_extended >= 0] ipix_extended = ipix_extended.astype(np.uint64) # Get only the max depth HEALPix cells lying at the border of the MOC ipix_neighbors = np.setxor1d(ipix_extended, ipix) # Remove these pixels from ``ipix`` ipix_around_border = cdshealpix.neighbours(ipix_neighbors, max_depth) ipix_around_border = ipix_around_border[ipix_around_border >= 0] ipix_around_border = ipix_around_border.astype(np.uint64) final_ipix = np.setdiff1d(ipix, ipix_around_border) final_depth = np.full(shape=final_ipix.shape, fill_value=max_depth, dtype=np.int8) # Build the reduced MOC, i.e. MOC without its pixels which were located at its border. final = MOC.from_healpix_cells(final_ipix, final_depth) self._interval_set = final._interval_set return self
def add_neighbours(self): """ Extends the MOC instance so that it includes the HEALPix cells touching its border. The depth of the HEALPix cells added at the border is equal to the maximum depth of the MOC instance. Returns ------- moc : `~mocpy.moc.MOC` self extended by one degree of neighbours. """ max_depth = self.max_order # Get the pixels array of the MOC at the its max order. ipix = core.flatten_pixels(self._interval_set._intervals, max_depth) # Get the HEALPix array containing the neighbors of ``ipix``. # This array "extends" ``ipix`` by one degree of neighbors. ipix_extended = cdshealpix.neighbours(ipix, max_depth) ipix_extended = ipix_extended[ipix_extended >= 0] ipix_extended = ipix_extended.astype(np.uint64) # Compute the difference between ``extend_ipix`` and ``ipix`` to get only the neighboring pixels # located at the border of the MOC. ipix_neighbors = np.setdiff1d(ipix_extended, ipix) depth_neighbors = np.full(shape=ipix_neighbors.shape, fill_value=max_depth, dtype=np.int8) #intervals_neighbors = core.from_healpix_cells(ipix_neighbors, depth_neighbors) moc_neighbors = MOC.from_healpix_cells(ipix_neighbors, depth_neighbors) # This array of HEALPix neighbors are added to the MOC to get an ``extended`` MOC #self._interval_set._intervals = core.coverage_union(self._interval_set._intervals, moc_neighbors._interval_set._intervals) final = self.union(moc_neighbors) self._interval_set = final._interval_set return self
def border(moc, ax, wcs, **kw_mpl_pathpatch): from .utils import build_plotting_moc moc_to_plot = build_plotting_moc(moc, wcs) if moc_to_plot.empty(): return max_order = moc_to_plot.max_order ipixels_open = mocpy.flatten_pixels(moc_to_plot._interval_set._intervals, moc_to_plot.max_order) # Take the complement if the MOC covers more than half of the sky num_ipixels = 3 << (2*(max_order + 1)) sky_fraction = ipixels_open.shape[0] / float(num_ipixels) if sky_fraction > 0.5: ipixels_all = np.arange(num_ipixels) ipixels_open = np.setdiff1d(ipixels_all, ipixels_open, assume_unique=True) neighbors = cdshealpix.neighbours(ipixels_open, max_order).T # Select the direct neighbors (i.e. those in WEST, NORTH, EAST and SOUTH directions) neighbors = neighbors[[3, 7, 5, 1], :] ipix_moc = np.isin(neighbors, ipixels_open) west_edge = ipix_moc[0, :] south_edge = ipix_moc[1, :] east_edge = ipix_moc[2, :] north_edge = ipix_moc[3, :] num_ipix_moc = ipix_moc.sum(axis=0) ipixels_border_id = (num_ipix_moc < 4) # The border of each HEALPix cells is drawn one at a time path_vertices_l = [] codes = [] west_border = west_edge[ipixels_border_id] south_border = south_edge[ipixels_border_id] east_border = east_edge[ipixels_border_id] north_border = north_edge[ipixels_border_id] ipixels_border = ipixels_open[ipixels_border_id] ipix_lon_boundaries, ipix_lat_boundaries = cdshealpix.vertices(ipixels_border, max_order) ipix_boundaries = SkyCoord(ipix_lon_boundaries, ipix_lat_boundaries, frame=ICRS()) # Projection on the given WCS xp, yp = skycoord_to_pixel(coords=ipix_boundaries, wcs=wcs) from . import culling_backfacing_cells xp, yp, frontface_id = culling_backfacing_cells.backface_culling(xp, yp) west_border = west_border[frontface_id] south_border = south_border[frontface_id] east_border = east_border[frontface_id] north_border = north_border[frontface_id] for i in range(xp.shape[0]): vx = xp[i] vy = yp[i] if not north_border[i]: path_vertices_l += [(vx[0], vy[0]), (vx[1], vy[1]), (0, 0)] codes += [Path.MOVETO] + [Path.LINETO] + [Path.CLOSEPOLY] if not east_border[i]: path_vertices_l += [(vx[1], vy[1]), (vx[2], vy[2]), (0, 0)] codes += [Path.MOVETO] + [Path.LINETO] + [Path.CLOSEPOLY] if not south_border[i]: path_vertices_l += [(vx[2], vy[2]), (vx[3], vy[3]), (0, 0)] codes += [Path.MOVETO] + [Path.LINETO] + [Path.CLOSEPOLY] if not west_border[i]: path_vertices_l += [(vx[3], vy[3]), (vx[0], vy[0]), (0, 0)] codes += [Path.MOVETO] + [Path.LINETO] + [Path.CLOSEPOLY] path = Path(path_vertices_l, codes) perimeter_patch = PathPatch(path, **kw_mpl_pathpatch) ax.add_patch(perimeter_patch) from . import axis_viewport axis_viewport.set(ax, wcs)