예제 #1
0
파일: moc.py 프로젝트: tboch/mocpy
    def plot(self, title='MOC', frame=None):
        """
        Plot the MOC object using a mollweide projection.

        **Deprecated**: New `fill` and `border` methods produce more reliable results and allow you to specify additional 
        matplotlib style parameters.

        Parameters
        ----------
        title : str
            The title of the plot
        frame : `astropy.coordinates.BaseCoordinateFrame`, optional
            Describes the coordinate system the plot will be (ICRS, Galactic are the only coordinate systems supported).
        """
        frame = ICRS() if frame is None else frame

        from matplotlib.colors import LinearSegmentedColormap
        import matplotlib.pyplot as plt

        plot_order = 8
        if self.max_order > plot_order:
            plotted_moc = self.degrade_to_order(plot_order)
        else:
            plotted_moc = self

        num_pixels_map = 1024
        delta = 2. * np.pi / num_pixels_map

        x = np.arange(-np.pi, np.pi, delta)
        y = np.arange(-np.pi/2, np.pi/2, delta)
        lon_rad, lat_rad = np.meshgrid(x, y)
        hp = HEALPix(nside=(1 << plotted_moc.max_order), order='nested')

        if frame and not isinstance(frame, BaseCoordinateFrame):
            raise ValueError("Only Galactic/ICRS coordinate systems are supported."
                             "Please set `coord` to either 'C' or 'G'.")

        pix_map = hp.lonlat_to_healpix(lon_rad * u.rad, lat_rad * u.rad)

        m = np.zeros(nside2npix(1 << plotted_moc.max_order))
        pix_id = plotted_moc._best_res_pixels()

        # change the HEALPix cells if the frame of the MOC is not the same as the one associated with the plot method.
        if isinstance(frame, Galactic):
            lon, lat = hp.boundaries_lonlat(pix_id, step=2)
            sky_crd = SkyCoord(lon, lat, unit='deg')
            pix_id = hp.lonlat_to_healpix(sky_crd.galactic.l, sky_crd.galactic.b)

        m[pix_id] = 1

        z = np.flip(m[pix_map], axis=1)

        plt.figure(figsize=(10, 10))

        ax = plt.subplot(111, projection="mollweide")
        ax.set_xticklabels(['150°', '120°', '90°', '60°', '30°', '0°', '330°', '300°', '270°', '240°', '210°', '180°'])

        color_map = LinearSegmentedColormap.from_list('w2r', ['#eeeeee', '#aa0000'])
        color_map.set_under('w')
        color_map.set_bad('gray')

        ax.pcolormesh(x, y, z, cmap=color_map, vmin=0, vmax=1)
        ax.tick_params(labelsize=14, labelcolor='#000000')
        plt.title(title)
        plt.grid(True, linestyle='--', linewidth=1, color='#555555')

        plt.show()
예제 #2
0
파일: moc.py 프로젝트: marxide/mocpy
    def plot(self, title='MOC', frame=None):
        """
        Plot the MOC object using a mollweide projection.

        **Deprecated**: New `fill` and `border` methods produce more reliable results and allow you to specify additional 
        matplotlib style parameters.

        Parameters
        ----------
        title : str
            The title of the plot
        frame : `astropy.coordinates.BaseCoordinateFrame`, optional
            Describes the coordinate system the plot will be (ICRS, Galactic are the only coordinate systems supported).
        """
        import warnings
        warnings.warn('This method is deprecated and is no longer tested.'
                      'Please refer to this documentation page for plotting MOCs using'
                      'matplotlib: https://mocpy.readthedocs.io/en/latest/examples/examples.html#loading-and-plotting-the-moc-of-sdss', DeprecationWarning)

        frame = ICRS() if frame is None else frame

        from matplotlib.colors import LinearSegmentedColormap
        import matplotlib.pyplot as plt

        plot_order = 8
        if self.max_order > plot_order:
            plotted_moc = self.degrade_to_order(plot_order)
        else:
            plotted_moc = self

        num_pixels_map = 1024
        delta = 2. * np.pi / num_pixels_map

        x = np.arange(-np.pi, np.pi, delta)
        y = np.arange(-np.pi/2, np.pi/2, delta)
        lon_rad, lat_rad = np.meshgrid(x, y)
        hp = HEALPix(nside=(1 << plotted_moc.max_order), order='nested')

        if frame and not isinstance(frame, BaseCoordinateFrame):
            raise ValueError("Only Galactic/ICRS coordinate systems are supported."
                             "Please set `coord` to either 'C' or 'G'.")

        pix_map = hp.lonlat_to_healpix(lon_rad * u.rad, lat_rad * u.rad)

        m = np.zeros(12*4**(plotted_moc.max_order))
        pix_id = core.flatten_pixels(plotted_moc._interval_set._intervals, plotted_moc.max_order)

        # change the HEALPix cells if the frame of the MOC is not the same as the one associated with the plot method.
        if isinstance(frame, Galactic):
            lon, lat = hp.boundaries_lonlat(pix_id, step=2)
            sky_crd = SkyCoord(lon, lat, unit='deg')
            pix_id = hp.lonlat_to_healpix(sky_crd.galactic.l, sky_crd.galactic.b)

        m[pix_id] = 1

        z = np.flip(m[pix_map], axis=1)

        plt.figure(figsize=(10, 10))

        ax = plt.subplot(111, projection="mollweide")
        ax.set_xticklabels(['150°', '120°', '90°', '60°', '30°', '0°', '330°', '300°', '270°', '240°', '210°', '180°'])

        color_map = LinearSegmentedColormap.from_list('w2r', ['#eeeeee', '#aa0000'])
        color_map.set_under('w')
        color_map.set_bad('gray')

        ax.pcolormesh(x, y, z, cmap=color_map, vmin=0, vmax=1)
        ax.tick_params(labelsize=14, labelcolor='#000000')
        plt.title(title)
        plt.grid(True, linestyle='--', linewidth=1, color='#555555')

        plt.show()
예제 #3
0
파일: boundaries.py 프로젝트: marxide/mocpy
    def _compute_graph_HEALPix_boundaries(depth, ipixels):
        def insert_edge(G, l1, l2, p1_lon, p1_lat, p2_lon, p2_lat):
            # Nodes are indexed by str(skycoord). When getting ordered nodes, one can retrieve back the skycoord instance
            # by accessing the python dict `pts_d`.
            try:
                # Avoid the special case where holes are touching to each other
                # 'x' belongs to the MOC
                # ' ' is part of the holes in the MOC
                #    |xxx
                #    |xxx
                # ---A---
                # xxx|
                # xxx|
                #
                # If this case occurs we split the node A into 2. One is attached to the bottom left graph and the other to the
                # top right one. When computing the MST (minimal spanning tree) from a graph, we need our graphs to have
                # only nodes of degrees 1 or 2 (i.e. to be lines).
                if G.degree[l1] >= 2:
                    l1 += '_'
            except:
                pass

            try:
                if G.degree[l2] >= 2:
                    l2 += '_'
            except:
                pass
            # Set the skycoord instance as an attribute of the nodes
            G.add_node(l1, ra=p1_lon, dec=p1_lat)
            G.add_node(l2, ra=p2_lon, dec=p2_lat)
            G.add_edge(l1, l2)

        # Phase 1: Retrieve the ipixels located at the border of
        # this connexe MOC component
        ipixels = ipixels.astype(np.int)
        hp = HEALPix(nside=(1 << depth), order='nested', frame=ICRS())
        neighbours = hp.neighbours(ipixels)[[0, 2, 4, 6], :]
        ipixels = ipixels.astype(np.uint64)

        neighbours = neighbours.astype(np.uint64)

        isin = np.isin(neighbours, ipixels)
        border = isin.sum(axis=0) < 4

        ipixels_border = ipixels[border]
        isin_border = isin[:, border]

        # Phase 2: Build the graph from the positions of the ipixels boundaries
        #import cdshealpix as healpix
        #ipix_lon, ipix_lat = healpix.vertices(ipixels_border, depth)
        #ipix_lon[:, [1, 3]] = ipix_lon[:, [3, 1]]
        #ipix_lat[:, [1, 3]] = ipix_lat[:, [3, 1]]
        ipix_lon, ipix_lat = hp.boundaries_lonlat(ipixels_border, step=1)

        ipix_lon_deg = ipix_lon.to_value(u.deg)
        ipix_lat_deg = ipix_lat.to_value(u.deg)

        ipix_lon_repr = \
         np.around(np.asarray(ipix_lon.reshape((1, -1))[0]), decimals=3).tolist()
        ipix_lat_repr = \
         np.around(np.asarray(ipix_lat.reshape((1, -1))[0]), decimals=3).tolist()
        
        west_border = ~isin_border[0, :]
        south_border = ~isin_border[1, :]
        east_border = ~isin_border[2, :]
        north_border = ~isin_border[3, :]

        E = nx.Graph()

        for i in range(ipixels_border.shape[0]):
            lon_deg = ipix_lon_deg[i]
            lat_deg = ipix_lat_deg[i]

            p0_lon = lon_deg[0]
            p1_lon = lon_deg[1]
            p2_lon = lon_deg[2]
            p3_lon = lon_deg[3]

            p0_lat = lat_deg[0]
            p1_lat = lat_deg[1]
            p2_lat = lat_deg[2]
            p3_lat = lat_deg[3]

            off = 4*i
            off2 = 4*(i + 1)
            repr_lon = ipix_lon_repr[off:off2]
            repr_lat = ipix_lat_repr[off:off2]

            s0 = str(repr_lon[0]) + ' ' + str(repr_lat[0])
            s1 = str(repr_lon[1]) + ' ' + str(repr_lat[1])
            s2 = str(repr_lon[2]) + ' ' + str(repr_lat[2])
            s3 = str(repr_lon[3]) + ' ' + str(repr_lat[3])

            # WEST border
            if west_border[i]:
                insert_edge(E, s1, s2, p1_lon, p1_lat, p2_lon, p2_lat)

            # NORTH border
            if north_border[i]:
                insert_edge(E, s2, s3, p2_lon, p2_lat, p3_lon, p3_lat)

            # EAST border
            if east_border[i]:
                insert_edge(E, s3, s0, p3_lon, p3_lat, p0_lon, p0_lat)

            # SOUTH border
            if south_border[i]:
                insert_edge(E, s0, s1, p0_lon, p0_lat, p1_lon, p1_lat)

        return E
예제 #4
0
파일: polygon.py 프로젝트: tboch/mocpy
    def __init__(self, ra, dec, inside=None, max_depth=10):
        ra = ra.to(u.rad).value
        dec = dec.to(u.rad).value
        # Check if the vertices form a closed polygon
        if ra[0] != ra[-1] or dec[0] != dec[-1]:
            # If not, append the first vertex to ``vertices``
            ra = np.append(ra, ra[0])
            dec = np.append(dec, dec[0])
            vertices = SkyCoord(ra=ra, dec=dec, unit="rad", frame="icrs")

        if inside:
            # Convert it to (x, y, z) cartesian coordinates on the sphere
            inside = (inside.icrs.ra.rad, inside.icrs.dec.rad)

        self.polygon = SphericalPolygon.from_lonlat(lon=ra, lat=dec, center=inside, degrees=False)

        start_depth, ipixels = self._get_starting_depth()
        end_depth = max_depth

        # When the start depth returned is > to the depth requested
        # For that specific case, we only do one iteration at start_depth
        # Thus the MOC will contain the partially intersecting cells with the
        # contained ones at start_depth

        # And we degrade the MOC to the max_depth
        self.degrade_to_max_depth = False
        if start_depth > end_depth:
            end_depth = start_depth
            self.degrade_to_max_depth = True

        self.ipix_d = {str(order): [] for order in range(start_depth, end_depth + 1)}

        ## Iterative version of the algorithm: seems a bit faster than the recursive one
        for depth in range(start_depth, end_depth + 1):
            # Define a HEALPix at the current depth
            hp = HEALPix(nside=(1 << depth), order='nested', frame=ICRS())

            # Get the lon and lat of the corners of the pixels
            # intersecting the polygon
            lon, lat = hp.boundaries_lonlat(ipixels, step=1)
            lon = lon.to(u.rad).value
            lat = lat.to(u.rad).value

            # closes the lon and lat array so that their first and last value matches
            lon = self._closes_numpy_2d_array(lon)
            lat = self._closes_numpy_2d_array(lat)

            num_ipix_inter_poly = ipixels.shape[0]

            # Define a 3d numpy array containing the corners coordinates of the intersecting pixels
            # The first dim is the num of ipixels
            # The second is the number of coordinates (5 as it defines the closed polygon of a HEALPix cell)
            # The last is of size 2 (lon and lat)
            shapes = np.vstack((lon.ravel(), lat.ravel())).T.reshape(num_ipix_inter_poly, 5, -1)

            ipix_in_polygon_l = []
            ipix_inter_polygon_l = []

            for i in range(num_ipix_inter_poly):
                shape = shapes[i]
                # Definition of a SphericalPolygon from the border coordinates of a HEALPix cell
                ipix_shape = SphericalPolygon.from_radec(lon=shape[:, 0], lat=shape[:, 1], degrees=False)
                ipix = ipixels[i]

                if self.polygon.intersects_poly(ipix_shape):
                    # If we are at the max depth then we direcly add to the MOC the intersecting ipixels
                    if depth == end_depth:
                        ipix_in_polygon_l.append(ipix)
                    else:
                        # Check whether polygon contains ipix or not
                        if self.polygon_contains_ipix(ipix_shape):
                            ipix_in_polygon_l.append(ipix)
                        else:
                            # The ipix is just intersecting without being contained in the polygon
                            # We split it in its 4 children
                            child_ipix = ipix << 2
                            ipix_inter_polygon_l.extend([child_ipix,
                                                        child_ipix + 1,
                                                        child_ipix + 2,
                                                        child_ipix + 3])

            self.ipix_d.update({str(depth): ipix_in_polygon_l})
            ipixels = np.asarray(ipix_inter_polygon_l)
예제 #5
0
    def plot(self, title='MOC', frame=None):
        """
        Plot the MOC object in a mollweide view

        This method uses matplotlib.

        Parameters
        ----------
        title : str
            the title of the plot
        frame : `astropy.coordinates.BaseCoordinateFrame`, optional
            Describes the coordinate system the plot will be (ICRS, Galactic are the only coordinate systems supported).
        """
        frame = ICRS() if frame is None else frame

        from matplotlib.colors import LinearSegmentedColormap
        import matplotlib.pyplot as plt

        plot_order = 8
        if self.max_order > plot_order:
            plotted_moc = self.degrade_to_order(plot_order)
        else:
            plotted_moc = self

        num_pixels_map = 1024
        delta = 2 * np.pi / num_pixels_map

        x = np.arange(-np.pi, np.pi, delta)
        y = np.arange(-np.pi / 2, np.pi / 2, delta)
        lon_rad, lat_rad = np.meshgrid(x, y)
        hp = HEALPix(nside=(1 << plotted_moc.max_order), order='nested')

        if frame and not isinstance(frame, BaseCoordinateFrame):
            raise ValueError(
                "Only Galactic/ICRS coordinate systems are supported."
                "Please set `coord` to either 'C' or 'G'.")

        pix_map = hp.lonlat_to_healpix(lon_rad * u.rad, lat_rad * u.rad)

        m = np.zeros(nside2npix(1 << plotted_moc.max_order))
        pix_id_arr = plotted_moc._best_res_pixels()

        # change the HEALPix cells if the frame of the MOC is not the same as the one associated with the plot method.
        if isinstance(frame, Galactic):
            lon, lat = hp.boundaries_lonlat(pix_id_arr, step=2)
            sky_crd = SkyCoord(lon, lat, unit='deg')
            pix_id_arr = hp.lonlat_to_healpix(sky_crd.galactic.l,
                                              sky_crd.galactic.b)

        m[pix_id_arr] = 1

        z = np.flip(m[pix_map], axis=1)

        plt.figure(figsize=(10, 10))

        ax = plt.subplot(111, projection="mollweide")
        ax.set_xticklabels([
            '150°', '120°', '90°', '60°', '30°', '0°', '330°', '300°', '270°',
            '240°', '210°', '180°'
        ])

        color_map = LinearSegmentedColormap.from_list('w2r',
                                                      ['#eeeeee', '#aa0000'])
        color_map.set_under('w')
        color_map.set_bad('gray')

        ax.pcolormesh(x, y, z, cmap=color_map, vmin=0, vmax=1)
        ax.tick_params(labelsize=14, labelcolor='#000000')
        plt.title(title)
        plt.grid(True, linestyle='--', linewidth=1, color='#555555')

        plt.show()
예제 #6
0
파일: boundaries.py 프로젝트: tboch/mocpy
    def _compute_graph_HEALPix_boundaries(depth, ipixels):
        def insert_edge(G, l1, l2, p1_lon, p1_lat, p2_lon, p2_lat):
            # Nodes are indexed by str(skycoord). When getting ordered nodes, one can retrieve back the skycoord instance
            # by accessing the python dict `pts_d`.
            try:
                # Avoid the special case where holes are touching to each other
                # 'x' belongs to the MOC
                # ' ' is part of the holes in the MOC
                #    |xxx
                #    |xxx
                # ---A---
                # xxx|
                # xxx|
                #
                # If this case occurs we split the node A into 2. One is attached to the bottom left graph and the other to the
                # top right one. When computing the MST (minimal spanning tree) from a graph, we need our graphs to have
                # only nodes of degrees 1 or 2 (i.e. to be lines).
                if G.degree[l1] >= 2:
                    l1 += '_'
            except:
                pass

            try:
                if G.degree[l2] >= 2:
                    l2 += '_'
            except:
                pass
            # Set the skycoord instance as an attribute of the nodes
            G.add_node(l1, ra=p1_lon, dec=p1_lat)
            G.add_node(l2, ra=p2_lon, dec=p2_lat)
            G.add_edge(l1, l2)

        # Phase 1: Retrieve the ipixels located at the border of
        # this connexe MOC component
        ipixels = ipixels.astype(np.int)
        hp = HEALPix(nside=(1 << depth), order='nested', frame=ICRS())
        neighbours = hp.neighbours(ipixels)[[0, 2, 4, 6], :]
        ipixels = ipixels.astype(np.uint64)

        neighbours = neighbours.astype(np.uint64)

        isin = np.isin(neighbours, ipixels)
        border = isin.sum(axis=0) < 4

        ipixels_border = ipixels[border]
        isin_border = isin[:, border]

        # Phase 2: Build the graph from the positions of the ipixels boundaries
        #import cdshealpix as healpix
        #ipix_lon, ipix_lat = healpix.vertices(ipixels_border, depth)
        #ipix_lon[:, [1, 3]] = ipix_lon[:, [3, 1]]
        #ipix_lat[:, [1, 3]] = ipix_lat[:, [3, 1]]
        ipix_lon, ipix_lat = hp.boundaries_lonlat(ipixels_border, step=1)

        ipix_lon_deg = ipix_lon.to_value(u.deg)
        ipix_lat_deg = ipix_lat.to_value(u.deg)

        ipix_lon_repr = \
         np.around(np.asarray(ipix_lon.reshape((1, -1))[0]), decimals=3).tolist()
        ipix_lat_repr = \
         np.around(np.asarray(ipix_lat.reshape((1, -1))[0]), decimals=3).tolist()
        
        west_border = ~isin_border[0, :]
        south_border = ~isin_border[1, :]
        east_border = ~isin_border[2, :]
        north_border = ~isin_border[3, :]

        E = nx.Graph()

        for i in range(ipixels_border.shape[0]):
            lon_deg = ipix_lon_deg[i]
            lat_deg = ipix_lat_deg[i]

            p0_lon = lon_deg[0]
            p1_lon = lon_deg[1]
            p2_lon = lon_deg[2]
            p3_lon = lon_deg[3]

            p0_lat = lat_deg[0]
            p1_lat = lat_deg[1]
            p2_lat = lat_deg[2]
            p3_lat = lat_deg[3]

            off = 4*i
            off2 = 4*(i + 1)
            repr_lon = ipix_lon_repr[off:off2]
            repr_lat = ipix_lat_repr[off:off2]

            s0 = str(repr_lon[0]) + ' ' + str(repr_lat[0])
            s1 = str(repr_lon[1]) + ' ' + str(repr_lat[1])
            s2 = str(repr_lon[2]) + ' ' + str(repr_lat[2])
            s3 = str(repr_lon[3]) + ' ' + str(repr_lat[3])

            # WEST border
            if west_border[i]:
                insert_edge(E, s1, s2, p1_lon, p1_lat, p2_lon, p2_lat)

            # NORTH border
            if north_border[i]:
                insert_edge(E, s2, s3, p2_lon, p2_lat, p3_lon, p3_lat)

            # EAST border
            if east_border[i]:
                insert_edge(E, s3, s0, p3_lon, p3_lat, p0_lon, p0_lat)

            # SOUTH border
            if south_border[i]:
                insert_edge(E, s0, s1, p0_lon, p0_lat, p1_lon, p1_lat)

        return E
예제 #7
0
def my_plot(moc,
            frame=None,
            labels=False,
            title='',
            grid=False,
            save='',
            color='black',
            degrade=True):
    frame = Galactic() if frame is None else frame

    from matplotlib.colors import LinearSegmentedColormap
    import matplotlib.pyplot as plt

    plot_order = 8
    if moc.max_order > plot_order and degrade:
        plotted_moc = moc.degrade_to_order(plot_order)
    else:
        plotted_moc = moc

    num_pixels_map = 1024
    delta = 2. * np.pi / num_pixels_map

    x = np.arange(-np.pi, np.pi, delta)
    y = np.arange(-np.pi / 2, np.pi / 2, delta)
    lon_rad, lat_rad = np.meshgrid(x, y)
    hp = HEALPix(nside=(1 << plotted_moc.max_order), order='nested')

    if frame and not isinstance(frame, BaseCoordinateFrame):
        raise ValueError(
            "Only Galactic/ICRS coordinate systems are supported.")

    pix_map = hp.lonlat_to_healpix(lon_rad * u.rad, lat_rad * u.rad)

    m = np.zeros(12 * 4**(plotted_moc.max_order))
    pix_id = core.flatten_pixels(plotted_moc._interval_set._intervals,
                                 plotted_moc.max_order)

    # change the HEALPix cells if the frame of the MOC is not the same as the one associated with the plot method.
    if isinstance(frame, Galactic):
        lon, lat = hp.boundaries_lonlat(pix_id, step=2)
        sky_crd = SkyCoord(lon, lat, unit='deg')
        pix_id = hp.lonlat_to_healpix(sky_crd.galactic.l, sky_crd.galactic.b)

    m[pix_id] = 1

    z = np.flip(m[pix_map], axis=1)

    figsize = (12, 10)
    fig = plt.figure(figsize=figsize)
    ax = fig.add_subplot(111, projection="aitoff")

    color_map = LinearSegmentedColormap.from_list('w2r', ['white', color])
    color_map.set_under('w')
    color_map.set_bad('w')

    # Note I flip x
    ax.pcolormesh(x, y, z, cmap=color_map, vmin=0, vmax=1)
    if labels: ax.tick_params(labelsize=14, labelcolor='#000000')
    if title: plt.title(title)
    if grid: plt.grid(True, linestyle='--', linewidth=1, color='#555555')

    ax.set_xticklabels([
        '210', '240', '270', '300', '330', '0', '30', '60', '90', '120', '150'
    ])
    ax.grid(grid)

    plt.tight_layout()

    if not labels:  # disable tick labels
        ax.set_xticklabels([])
        ax.set_yticklabels([])

    if save:
        plt.savefig(save)
    else:
        plt.show()