示例#1
0
    def cutout_range(self,
                     rac,
                     decc,
                     xw,
                     yw,
                     units='pixels',
                     coordsys='galactic'):
        """
        computes the pixel range (min max) of a frame centered at (rac, decc) with width xw, yw (in arc seconds)

        :param rac:
        :param decc:
        :param xw:
        :param yw:
        :return:
        """
        head = self.header
        wcs = pywcs.WCS(head)
        if units == 'wcs':
            if coordsys == 'celestial' and wcs.wcs.lngtyp == 'GLON':
                rac, decc = coords.Position((rac, decc),
                                            system=coordsys).galactic()
            elif coordsys == 'galactic' and wcs.wcs.lngtyp == 'RA':
                rac, decc = coords.Position((rac, decc),
                                            system=coordsys).j2000()
            else:
                raise ValueError("problem with wcs instance.")
        xx, yy = wcs.all_world2pix(rac, decc, 0)
        xx = int(xx)
        yy = int(yy)
        print('the center of the image is at pixel coordinates %f, %f.' %
              (xx, yy))
        if units == 'pixels':
            xmin, xmax = np.max([0, xx - xw]), np.min([self.naxis1, xx + xw])
            ymin, ymax = np.max([0, yy - yw]), np.min([self.naxis2, yy + yw])
        elif units == 'arcseconds':
            cd1, cd2 = self.pixel_size
            xmin, xmax = np.max([0, xx - xw / np.abs(cd1)]), np.min(
                [self.naxis1, xx + xw / np.abs(cd1)])
            ymin, ymax = np.max([0, yy - yw / np.abs(cd2)]), np.min(
                [self.naxis2, yy + yw / np.abs(cd2)])
        else:
            raise Exception("Can't use units %s." % units)
        if xmax < 0 or ymax < 0:
            raise ValueError("Max Coordinate is outside of map: %f,%f." %
                             (xmax, ymax))
        if ymin >= head.get('NAXIS2') or xmin >= head.get('NAXIS1'):
            raise ValueError("Min Coordinate is outside of map: %f,%f." %
                             (xmin, ymin))
        return xmin, xmax, ymin, ymax
示例#2
0
def coords_in_image(fitsfile, lon, lat, system='galactic'):
    """
    Determine whether the coordinates are inside the image
    """
    if not isinstance(fitsfile, fits.HDUList):
        fitsfile = fits.open(fitsfile)

    wcs = pywcs.WCS(flatten_header(fitsfile[0].header))

    if 'RA' in wcs.wcs.ctype[0]:
        pos = coordinates.Position((lon, lat), system=system)
        lon, lat = pos.j2000()
    if 'GLON' in wcs.wcs.ctype[0]:
        pos = coordinates.Position((lon, lat), system=system)
        lon, lat = pos.galactic()

    x, y = wcs.wcs_world2pix(lon, lat, 0)
    #DEBUG print x,y,wcs.naxis1,wcs.naxis2
    if (0 < x < wcs.naxis1) and (0 < y < wcs.naxis2):
        return True
    else:
        return False
示例#3
0
    def _cutout(self,
                fits_filename,
                xc,
                yc,
                xw,
                yw,
                units='pixels',
                clobber=True,
                useMontage=False,
                coordsys='galactic',
                verbose=False,
                exposure_map=False):
        """
        Inputs:
            file  - pyfits HDUList (must be 2D)
            xc,yc - x and y coordinates in the fits files' coordinate system (CTYPE)
            xw,yw - x and y width (pixels or wcs)
            units - specify units to use: either pixels or wcs
            outfile - optional output file
        """
        # file = pyfits.open(fits_filename)
        # head = file['SCI'].header.copy()

        head = self.header.copy()
        wcs = pywcs.WCS(head)
        if units == 'wcs':
            if coordsys == 'celestial' and wcs.wcs.lngtyp == 'GLON':
                xc, yc = coords.Position((xc, yc), system=coordsys).galactic()
            elif coordsys == 'galactic' and wcs.wcs.lngtyp == 'RA':
                xc, yc = coords.Position((xc, yc), system=coordsys).j2000()
        xx, yy = wcs.all_world2pix(xc, yc, 0)
        print('the center of the image is at pixel coordinates %f, %f.' %
              (xx, yy))
        if units == 'pixels':
            xmin, xmax = np.max([0, xx - xw]), np.min([self.naxis1, xx + xw])
            ymin, ymax = np.max([0, yy - yw]), np.min([self.naxis2, yy + yw])
        elif units == 'wcs':
            xmin, xmax = np.max([0, xx - xw / np.abs(self.cd1)]), np.min(
                [self.naxis1, xx + xw / np.abs(self.cd1)])
            ymin, ymax = np.max([0, yy - yw / np.abs(self.cd2)]), np.min(
                [self.naxis2, yy + yw / np.abs(self.cd2)])
        else:
            raise Exception("Can't use units %s." % units)
        self._xmin_c, self._xmax_c = xmin, xmax
        self._ymin_c, self._ymax_c = ymin, ymax
        if xmax < 0 or ymax < 0:
            raise ValueError("Max Coordinate is outside of map: %f,%f." %
                             (xmax, ymax))
        if ymin >= head.get('NAXIS2') or xmin >= head.get('NAXIS1'):
            raise ValueError("Min Coordinate is outside of map: %f,%f." %
                             (xmin, ymin))

        head = self.change_header(head, xmin, xmax, ymin, ymax)
        img = self.image_full()[int(ymin):int(ymax),
                                int(xmin):int(xmax)].copy()
        # img = file['SCI'].data[ymin:ymax, xmin:xmax]
        if verbose:
            print("Cut image %s to %s. xrange: %f:%f, yrange: %f:%f" %
                  (fits_filename, img.shape, xmin, xmax, ymin, ymax))
        if exposure_map:
            exp_map = self.exposure_full()[int(ymin):int(ymax),
                                           int(xmin):int(xmax)].copy()
        else:
            exp_map = None
        ra_coord, dec_coord = self.get_coordinates(xmin, xmax, ymin, ymax, wcs)
        return img, head, exp_map, ra_coord, dec_coord
示例#4
0
    def rotcrop_cube(x1,
                     y1,
                     x2,
                     y2,
                     cubename,
                     outname,
                     xwidth=25,
                     ywidth=25,
                     in_system='galactic',
                     out_system='equatorial',
                     overwrite=True,
                     newheader=None,
                     xcen=None,
                     ycen=None):
        """
        Crop a data cube and then rotate it with montage

        """

        cubefile = fits.open(cubename)

        if xcen is None and ycen is None:
            pos1 = coordinates.Position([x1, y1], system=in_system)
            pos2 = coordinates.Position([x2, y2], system=in_system)

            if cubefile[0].header.get('CTYPE1')[:2] == 'RA':
                x1, y1 = pos1.j2000()
                x2, y2 = pos2.j2000()
                coord_system = 'celestial'
            elif cubefile[0].header.get('CTYPE1')[:4] == 'GLON':
                x1, y1 = pos1.galactic()
                x2, y2 = pos2.galactic()
                coord_system = 'galactic'

            xcen = (x1 + x2) / 2.0
            ycen = (y1 + y2) / 2.0
            print(xcen, ycen, xwidth, ywidth, coord_system)
        else:
            coord_system = in_system

        sc = subcube(cubefile[0].data,
                     xcen,
                     xwidth,
                     ycen,
                     ywidth,
                     widthunits='pixels',
                     units="wcs",
                     header=cubefile[0].header,
                     return_HDU=True)
        # note: there should be no security risk here because fits' writeto
        # will not overwrite by default
        tempcube = tempfile.mktemp(suffix='.fits')
        sc.writeto(tempcube)

        pa = posang.posang(x1, y1, x2, y2, system=coord_system) - 90

        if newheader is None:
            newheader = sc.header.copy()
            cd11 = newheader.get('CDELT1') if newheader.get(
                'CDELT1') else newheader.get('CD1_1')
            cd22 = newheader.get('CDELT2') if newheader.get(
                'CDELT2') else newheader.get('CD2_2')
            cd12 = newheader.get('CD1_2') if newheader.get('CD1_2') else 0.0
            cd21 = newheader.get('CD2_1') if newheader.get('CD2_1') else 0.0
            cdelt = numpy.sqrt(cd11**2 + cd12**2)

            tempheader = tempfile.mktemp(suffix='.hdr')
            ycensign = "+" if numpy.sign(ycen) >= 0 else "-"
            montage.mHdr("%s %1s%s" % (xcen, ycensign, numpy.abs(ycen)),
                         xwidth * cdelt,
                         tempheader,
                         system=out_system,
                         height=ywidth * cdelt,
                         pix_size=cdelt * 3600.0,
                         rotation=pa)
            os.system("sed -i bck '/END/d' %s" % (tempheader))
            newheader2 = fits.Header()
            newheader2.fromTxtFile(tempheader)
            #newheader2.fromtextfile(tempheader)
            for key in ('CRPIX3', 'CRVAL3', 'CDELT3', 'CD3_3', 'CUNIT3',
                        'WCSTYPE3', 'CTYPE3'):
                if newheader.get(key):
                    newheader2[key] = newheader.get(key)
            if newheader.get('CD3_3') and newheader2.get('CDELT3') is None:
                newheader2['CDELT3'] = newheader.get('CD3_3')
            if astropy.version.major >= 2 or (astropy.version.major == 1
                                              and astropy.version.minor >= 3):
                newheader2.toTxtFile(tempheader, overwrite=True)
            else:
                newheader2.toTxtFile(tempheader, clobber=True)
            #if newheader2.get('CDELT3') is None:
            #    raise Exception("No CD3_3 or CDELT3 in header.")
        else:
            if isinstance(newheader, str):
                newheader2 = fits.Header()
                newheader2.fromTxtFile(newheader)
            tempheader = tempfile.mktemp(suffix='.hdr')
            if astropy.version.major >= 2 or (astropy.version.major == 1
                                              and astropy.version.minor >= 3):
                newheader2.toTxtFile(tempheader, overwrite=True)
            else:
                newheader2.toTxtFile(tempheader, clobber=True)

        montage.wrappers.reproject_cube(tempcube,
                                        outname,
                                        header=tempheader,
                                        clobber=overwrite)
        #print "\n",outname
        #os.system('imhead %s | grep CDELT' % outname)

        # AWFUL hack because montage removes CDELT3
        tempcube = fits.open(outname)
        tempcube.header = newheader2
        #if tempcube.header.get('CDELT3') is None:
        #    raise Exception("No CD3_3 or CDELT3 in header.")
        #print tempcube.header.get('CDELT3')
        if astropy.version.major >= 2 or (astropy.version.major == 1
                                          and astropy.version.minor >= 3):
            tempcube.writeto(outname, overwrite=True)
        else:
            tempcube.writeto(outname, clobber=True)
        #print tempcube.get('CDELT3')
        #print "\n",outname
        #os.system('imhead %s | grep CDELT' % outname)

        return