Example #1
0
    def build_polygon(self):
        if self.edges_ra is None:
            self.get_edges_sky()

        self.polygon = SphericalPolygon.from_radec(self.edges_ra,
                                                   self.edges_dec,
                                                   self.meta_wcs.wcs.crval)
Example #2
0
    def build_polygon(self):

        inner_pix = self.wcs.pixel_to_world_values(2, 2)
        # define polygon on the sky
        self.polygon = SphericalPolygon.from_radec(self.corners[:, 0],
                                                   self.corners[:,
                                                                1], inner_pix)
Example #3
0
    def build_polygon(self, member='total'):
        if self.edges_ra is None:
            self.get_edges_sky(member=member)

        self.polygon = SphericalPolygon.from_radec(self.edges_ra,
                                                   self.edges_dec,
                                                   self.meta_wcs.wcs.crval)
Example #4
0
def getWcsRegion(imageRow):
    region = None
    stcs = imageRow["regionSTCS"]
    if (stcs is not None):
        a = stcs.split(' ')
        if len(a) == 10:
            ras = [
                float(a[2]),
                float(a[4]),
                float(a[6]),
                float(a[8]),
                float(a[2])
            ]
            decs = [
                float(a[3]),
                float(a[5]),
                float(a[7]),
                float(a[9]),
                float(a[3])
            ]
            print ras
            print decs
            region = SphericalPolygon.from_radec(ras, decs)

    return region
Example #5
0
def getWcsRegion(imageRow):
    region = None
    stcs = imageRow["regionSTCS"]
    if stcs is not None:
        a = stcs.split(" ")
        if len(a) == 10:
            ras = [float(a[2]), float(a[4]), float(a[6]), float(a[8]), float(a[2])]
            decs = [float(a[3]), float(a[5]), float(a[7]), float(a[9]), float(a[3])]
            print ras
            print decs
            region = SphericalPolygon.from_radec(ras, decs)

    return region
Example #6
0
def quad_to_poly(ra, dec, **kwargs):
    p = SphericalPolygon.from_radec(ra, dec, degrees=True)

    points = p.polygons[0]._points
    _ra, _dec = [], []
    for A, B in zip(points[0:-1], points[1:]):
        length = great_circle_arc.length(A, B, degrees=True)
        if not np.isfinite(length):
            length = 2
        interpolated = great_circle_arc.interpolate(A, B, length * 4)
        lon, lat = vector.vector_to_lonlat(interpolated[:, 0],
                                           interpolated[:, 1],
                                           interpolated[:, 2],
                                           degrees=True)
        for lon0, lat0, lon1, lat1 in zip(lon[0:-1], lat[0:-1], lon[1:],
                                          lat[1:]):
            _ra.append(lon0)
            _dec.append(lat0)

    _ra.append(lon1)
    _dec.append(lat1)
    return PolyCollection([np.c_[_ra, _dec]], **kwargs)
Example #7
0
    def _calc_sky_orig(self, overlap=None, delta=True):
        """
        Compute sky background value.

        Parameters
        ----------
        overlap : SkyImage, SkyGroup, SphericalPolygon, list of tuples, \
None, optional
            Another `SkyImage`, `SkyGroup`,
            :py:class:`spherical_geometry.polygons.SphericalPolygon`, or
            a list of tuples of (RA, DEC) of vertices of a spherical
            polygon. This parameter is used to indicate that sky statistics
            should computed only in the region of intersection of *this*
            image with the polygon indicated by `overlap`. When `overlap` is
            `None`, sky statistics will be computed over the entire image.

        delta : bool, optional
            Should this function return absolute sky value or the difference
            between the computed value and the value of the sky stored in the
            `sky` property.

        Returns
        -------
        skyval : float, None
            Computed sky value (absolute or relative to the `sky` attribute).
            If there are no valid data to perform this computations (e.g.,
            because this image does not overlap with the image indicated by
            `overlap`), `skyval` will be set to `None`.

        npix : int
            Number of pixels used to compute sky statistics.

        polyarea : float
            Area (in srad) of the polygon that bounds data used to compute
            sky statistics.

        """

        if overlap is None:

            if self.mask is None:
                data = self.image
            else:
                data = self.image[self.mask]

            polyarea = self.poly_area

        else:
            fill_mask = np.zeros(self.image.shape, dtype=bool)

            if isinstance(overlap, (SkyImage, SkyGroup, SphericalPolygon)):
                intersection = self.intersection(overlap)
                polyarea = np.fabs(intersection.area())
                radec = intersection.to_radec()

            else:  # assume a list of (ra, dec) tuples:
                radec = []
                polyarea = 0.0
                for r, d in overlap:
                    poly = SphericalPolygon.from_radec(r, d)
                    polyarea1 = np.fabs(poly.area())
                    if polyarea1 == 0.0 or len(r) < 4:
                        continue
                    polyarea += polyarea1
                    radec.append(self.intersection(poly).to_radec())

            if polyarea == 0.0:
                return (None, 0, 0.0)

            for ra, dec in radec:
                if len(ra) < 4:
                    continue

                # set pixels in 'fill_mask' that are inside a polygon to True:
                x, y = self.wcs_inv(ra, dec)
                poly_vert = list(zip(*[x, y]))

                polygon = region.Polygon(True, poly_vert)
                fill_mask = polygon.scan(fill_mask)

            if self.mask is not None:
                fill_mask &= self.mask

            data = self.image[fill_mask]

            if data.size < 1:
                return (None, 0, 0.0)

        # Calculate sky
        try:

            skyval, npix = self._skystat(data)

        except ValueError:

            return (None, 0, 0.0)

        if delta:
            skyval -= self._sky

        return skyval, npix, polyarea
Example #8
0
    def calc_bounding_polygon(self, stepsize=None):
        """ Compute image's bounding polygon.

        Parameters
        ----------
        stepsize : int, None, optional
            Indicates the maximum separation between two adjacent vertices
            of the bounding polygon along each side of the image. Corners
            of the image are included automatically. If `stepsize` is `None`,
            bounding polygon will contain only vertices of the image.

        """
        ny, nx = self.image.shape

        if stepsize is None:
            nintx = 2
            ninty = 2
        else:
            nintx = max(2, int(np.ceil((nx + 1.0) / stepsize)))
            ninty = max(2, int(np.ceil((ny + 1.0) / stepsize)))

        xs = np.linspace(-0.5, nx - 0.5, nintx, dtype=np.float)
        ys = np.linspace(-0.5, ny - 0.5, ninty, dtype=np.float)[1:-1]
        nptx = xs.size
        npty = ys.size

        npts = 2 * (nptx + npty)

        borderx = np.empty((npts + 1, ), dtype=np.float)
        bordery = np.empty((npts + 1, ), dtype=np.float)

        # "bottom" points:
        borderx[:nptx] = xs
        bordery[:nptx] = -0.5
        # "right"
        sl = np.s_[nptx:nptx + npty]
        borderx[sl] = nx - 0.5
        bordery[sl] = ys
        # "top"
        sl = np.s_[nptx + npty:2 * nptx + npty]
        borderx[sl] = xs[::-1]
        bordery[sl] = ny - 0.5
        # "left"
        sl = np.s_[2 * nptx + npty:-1]
        borderx[sl] = -0.5
        bordery[sl] = ys[::-1]

        # close polygon:
        borderx[-1] = borderx[0]
        bordery[-1] = bordery[0]

        ra, dec = self.wcs_fwd(borderx, bordery, with_bounding_box=False)
        # TODO: for strange reasons, occasionally ra[0] != ra[-1] and/or
        #       dec[0] != dec[-1] (even though we close the polygon in the
        #       previous two lines). Then SphericalPolygon fails because
        #       points are not closed. Threfore we force it to be closed:
        ra[-1] = ra[0]
        dec[-1] = dec[0]

        self._radec = [(ra, dec)]
        self._polygon = SphericalPolygon.from_radec(ra, dec)
        self._poly_area = np.fabs(self._polygon.area())
Example #9
0
def _skycoord_to_spherical_polygon(skycoord):
    return SphericalPolygon.from_radec(skycoord.spherical.lon.degree,
                                       skycoord.spherical.lat.degree,
                                       degrees=True)
Example #10
0
    def _calc_sky_orig(self, overlap=None, delta=True):
        """
        Compute sky background value.

        Parameters
        ----------
        overlap : SkyImage, SkyGroup, SphericalPolygon, list of tuples, \
None, optional
            Another `SkyImage`, `SkyGroup`,
            :py:class:`spherical_geometry.polygons.SphericalPolygon`, or
            a list of tuples of (RA, DEC) of vertices of a spherical
            polygon. This parameter is used to indicate that sky statistics
            should computed only in the region of intersection of *this*
            image with the polygon indicated by `overlap`. When `overlap` is
            `None`, sky statistics will be computed over the entire image.

        delta : bool, optional
            Should this function return absolute sky value or the difference
            between the computed value and the value of the sky stored in the
            `sky` property.

        Returns
        -------
        skyval : float, None
            Computed sky value (absolute or relative to the `sky` attribute).
            If there are no valid data to perform this computations (e.g.,
            because this image does not overlap with the image indicated by
            `overlap`), `skyval` will be set to `None`.

        npix : int
            Number of pixels used to compute sky statistics.

        polyarea : float
            Area (in srad) of the polygon that bounds data used to compute
            sky statistics.

        """

        if overlap is None:

            if self.mask is None:
                data = self.image
            else:
                data = self.image[self.mask]

            polyarea = self.poly_area

        else:
            fill_mask = np.zeros(self.image.shape, dtype=bool)

            if isinstance(overlap, (SkyImage, SkyGroup, SphericalPolygon)):
                intersection = self.intersection(overlap)
                polyarea = np.fabs(intersection.area())
                radec = intersection.to_radec()

            else: # assume a list of (ra, dec) tuples:
                radec = []
                polyarea = 0.0
                for r, d in overlap:
                    poly = SphericalPolygon.from_radec(r, d)
                    polyarea1 = np.fabs(poly.area())
                    if polyarea1 == 0.0 or len(r) < 4:
                        continue
                    polyarea += polyarea1
                    radec.append(self.intersection(poly).to_radec())

            if polyarea == 0.0:
                return (None, 0, 0.0)

            for ra, dec in radec:
                if len(ra) < 4:
                    continue

                # set pixels in 'fill_mask' that are inside a polygon to True:
                x, y = self.wcs_inv(ra, dec)
                poly_vert = list(zip(*[x, y]))

                polygon = region.Polygon(True, poly_vert)
                fill_mask = polygon.scan(fill_mask)

            if self.mask is not None:
                fill_mask &= self.mask

            data = self.image[fill_mask]

            if data.size < 1:
                return (None, 0, 0.0)

        # Calculate sky
        try:

            skyval, npix = self._skystat(data)

        except ValueError:

            return (None, 0, 0.0)

        if delta:
            skyval -= self._sky

        return skyval, npix, polyarea
Example #11
0
    def calc_bounding_polygon(self, stepsize=None):
        """ Compute image's bounding polygon.

        Parameters
        ----------
        stepsize : int, None, optional
            Indicates the maximum separation between two adjacent vertices
            of the bounding polygon along each side of the image. Corners
            of the image are included automatically. If `stepsize` is `None`,
            bounding polygon will contain only vertices of the image.

        """
        ny, nx = self.image.shape

        if stepsize is None:
            nintx = 2
            ninty = 2
        else:
            nintx = max(2, int(np.ceil((nx + 1.0) / stepsize)))
            ninty = max(2, int(np.ceil((ny + 1.0) / stepsize)))

        xs = np.linspace(-0.5, nx - 0.5, nintx, dtype=np.float)
        ys = np.linspace(-0.5, ny - 0.5, ninty, dtype=np.float)[1:-1]
        nptx = xs.size
        npty = ys.size

        npts = 2 * (nptx + npty)

        borderx = np.empty((npts + 1,), dtype=np.float)
        bordery = np.empty((npts + 1,), dtype=np.float)

        # "bottom" points:
        borderx[:nptx] = xs
        bordery[:nptx] = -0.5
        # "right"
        sl = np.s_[nptx:nptx + npty]
        borderx[sl] = nx - 0.5
        bordery[sl] = ys
        # "top"
        sl = np.s_[nptx + npty:2 * nptx + npty]
        borderx[sl] = xs[::-1]
        bordery[sl] = ny - 0.5
        # "left"
        sl = np.s_[2 * nptx + npty:-1]
        borderx[sl] = -0.5
        bordery[sl] = ys[::-1]

        # close polygon:
        borderx[-1] = borderx[0]
        bordery[-1] = bordery[0]

        ra, dec = self.wcs_fwd(borderx, bordery, with_bounding_box=False)
        # TODO: for strange reasons, occasionally ra[0] != ra[-1] and/or
        #       dec[0] != dec[-1] (even though we close the polygon in the
        #       previous two lines). Then SphericalPolygon fails because
        #       points are not closed. Threfore we force it to be closed:
        ra[-1] = ra[0]
        dec[-1] = dec[0]

        self._radec = [(ra, dec)]
        self._polygon = SphericalPolygon.from_radec(ra, dec)
        self._poly_area = np.fabs(self._polygon.area())
Example #12
0
    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)