def determine_imageOverlap(f1,
                           f2,
                           plotsave=False,
                           verbose=False,
                           debugmode=False,
                           quietmode=False):
    ''' Determine the max number of pixels in AXIS1 and AXIS2 of the input fits images, print to screen unless suppressed. Plot up the footprint if -p option is on. Right now, only takes in 2 fits images (YOLO).'''

    # Read in f1,f2
    d1, h1 = fits.getdata(f1, header=True)
    d2, h2 = fits.getdata(f2, header=True)
    w1 = wcs.WCS(h1)
    w2 = wcs.WCS(h2)

    # Get the RA and DEC coordinates of the four corners of each image
    four_corners_RADECs1 = get_cornerRADECs(f1)
    four_corners_RADECs2 = get_cornerRADECs(f2)

    # Get polygon of each image corners
    poly1 = Polygon(four_corners_RADECs1)
    poly2 = Polygon(four_corners_RADECs2)

    # Get intersection polygon
    poly_intersect = poly1.intersection(poly2)

    # Get RA DEC of corners of the intersection (overlapping) polygon
    x_intersect, y2_intersect = poly_intersect.exterior.xy

    # Get intersection RA and DEC.
    # Note that the last coordinate is a repeat of the first, so remove it.
    corner_RADECs_intersect = np.transpose(
        np.array([x_intersect[0:-1], y2_intersect[0:-1]]))

    # Do pixel scale checks: are pixels square, are pixel scales of two images similar enough
    # Exits if input images found to be outside what this is coded for; Prints warnings if in debugmode but not exiting.
    perform_pixelscaleChecks(w1, w2, verbose=verbose, debugmode=debugmode)

    # Get XLEN and YLEN- Diff pix scales give diff XLEN, YLEN for same RA,DEC range
    # Get the average XLEN and YLEN for the two input image pixscales
    XLEN1, YLEN1 = get_imagesize(corner_RADECs_intersect, w1)
    XLEN2, YLEN2 = get_imagesize(corner_RADECs_intersect, w2)
    if verbose:
        print(f'XLEN1,YLEN1: {XLEN1},{YLEN1}')
        print(f'XLEN2,YLEN2: {XLEN2},{YLEN2}')
    #XLEN        = int(np.average([XLEN1,XLEN2])) # auto floor
    #YLEN        = int(np.average([YLEN1,YLEN2])) # auto floor
    XLEN = min([XLEN1, XLEN2])  # Take the smallest
    YLEN = min([YLEN1, YLEN2])  # Take the smallest

    #  Print information if not quiet mode, or if verbose
    if not quietmode and not verbose:
        print(f'-IMAGE_SIZE option in SWarp can be set to: {XLEN},{YLEN}')
    printme = f'SWarp Command to align two images: swarp {f1} {f2}  -SUBTRACT_BACK N -RESAMEPLE Y -COMBINE N -CENTER_TYPE MOST -IMAGE_SIZE {XLEN},{YLEN} -RESAMPLE_DIR ./'
    print_verbose_string(printme, verbose=verbose)

    # If plotsave, plot and save.
    if plotsave:
        plot_polygonOverlap(poly1, poly2, quietmode=quietmode)

    return XLEN, YLEN
예제 #2
0
def test_spectralnorm():
    cube = SpectralCube(data, wcs.WCS(h),
                        mask=BooleanArrayMask(mask, wcs=wcs.WCS(h)))
    noiseobj = noise.Noise(cube)
    noiseobj.estimate_noise()
    expected = np.array([ 1.14898322,  0.71345272,  1.21989125])
    assert np.allclose(noiseobj.spectral_norm, expected)
예제 #3
0
def test_spatialnorm():
    cube = SpectralCube(data, wcs.WCS(h),
                        mask=BooleanArrayMask(mask, wcs=wcs.WCS(h)))
    noiseobj = noise.Noise(cube)
    noiseobj.estimate_noise()
    print noiseobj.spatial_norm
    expected = np.array([[ 0.04430196, 0.78314449, 0.07475047, 0.5494684 , 0.05790756],
                         [ 0.32931213, 0.76450342, 1.33944507, 1.06416389, 0.27999452],
                         [ 0.65174339, 0.24128143, 0.27692018, 0.0244925 , 0.11167775],
                         [ 0.60682872, 0.42536813, 0.20018275, 0.78523107, 0.95516435]])

    assert np.allclose(noiseobj.spatial_norm, expected)
예제 #4
0
def mask_file(regionfile, infile, outfile, negate=False):
    """
    Created a masked version of file, using a region.


    Parameters
    ----------
    regionfile : str
        A file which can be loaded as a :class:`AegeanTools.regions.Region`.
        The image will be masked according to this region.

    infile : str
        Input FITS image.

    outfile : str
        Output FITS image.

    negate :  bool
        If True then pixels *outside* the region are masked.
        Default = False.

    See Also
    --------
    :func:`AegeanTools.MIMAS.mask_plane`
    """
    # Check that the input file is accessible and then open it
    if not os.path.exists(infile):
        raise AssertionError("Cannot locate fits file {0}".format(infile))
    im = pyfits.open(infile)
    if not os.path.exists(regionfile):
        raise AssertionError(
            "Cannot locate region file {0}".format(regionfile))
    region = Region.load(regionfile)
    try:
        wcs = pywcs.WCS(im[0].header, naxis=2)
    except:  # TODO: figure out what error is being thrown
        wcs = pywcs.WCS(str(im[0].header), naxis=2)

    if len(im[0].data.shape) > 2:
        data = np.squeeze(im[0].data)
    else:
        data = im[0].data

    print(data.shape)
    if len(data.shape) == 3:
        for plane in range(data.shape[0]):
            mask_plane(data[plane], wcs, region, negate)
    else:
        mask_plane(data, wcs, region, negate)
    im[0].data = data
    im.writeto(outfile, overwrite=True)
    logging.info("Wrote {0}".format(outfile))
    return
예제 #5
0
def add_plot(fn: Path, cm, ax, alpha=1):
    """Astrometry.net makes file ".new" with the image and the WCS SIP 2-D polynomial fit coefficients in the FITS header

    We use DECL as "x" and RA as "y".
    pcolormesh() is used as it handles arbitrary pixel shapes.
    Note that pcolormesh() cannot tolerate NaN in X or Y (NaN in C is OK).
    This is handled in https://github.com/scivision/pcolormesh_nan.py.
    """

    with fits.open(fn, mode='readonly', memmap=False) as f:
        img = f[0].data

        yPix, xPix = f[0].shape[-2:]
        x, y = np.meshgrid(range(xPix), range(yPix))  # pixel indices to find RA/dec of
        xy = np.column_stack((x.ravel(order='C'), y.ravel(order='C')))

        radec = wcs.WCS(f[0].header).all_pix2world(xy, 0)

    ra = radec[:, 0].reshape((yPix, xPix), order='C')
    dec = radec[:, 1].reshape((yPix, xPix), order='C')

    ax.set_title(fn.name)
    ax.pcolormesh(ra, dec, img, alpha=alpha, cmap=cm, norm=LogNorm())
    ax.set_ylabel('Right Ascension [deg.]')
    ax.set_xlabel('Declination [deg.]')
예제 #6
0
def test_header_parse():
    from astropy.io import fits
    with get_pkg_data_fileobj('data/header_newlines.fits',
                              encoding='binary') as test_file:
        hdulist = fits.open(test_file)
        w = wcs.WCS(hdulist[0].header)
    assert w.wcs.ctype[0] == 'RA---TAN-SIP'
예제 #7
0
        def format_coord(x, y):
            x = int(x + 0.5)
            y = int(y + 0.5)
            if x < 0 or y < 0: return " "

            try:
                self.img
                try:
                    hdr = self.hdr
                    mywcs = wcs.WCS(hdr)
                    pixcrd = np.array([[x, y]])
                    world = mywcs.wcs_pix2world(pixcrd, 1)
                    try:
                        object = self.hdr['object']
                    except:
                        object = None
                    return "[x,y]=[%4d, %4d] val=%8.5g   [%s %s]=[%10.6f,%10.6f]   OBJECT: %s" % (
                        x, y, self.img[y, x], mywcs.wcs.ctype[0],
                        mywcs.wcs.ctype[1], world[0, 0], world[0, 1], object)
                except:
                    mywcs = None
                try:
                    return "[x,y]\n [%4i, %4i] val=%8.5g OBJECT: %s" % (
                        x, y, self.img[y, x], object)
                except IndexError:
                    return ""
            except:
                return " [%4i, %4i]" % (x, y)
예제 #8
0
def test_sub_segfault():
    # Issue #1960
    header = fits.Header.fromtextfile(
        get_pkg_data_filename('data/sub-segfault.hdr'))
    w = wcs.WCS(header)
    sub = w.sub([wcs.WCSSUB_CELESTIAL])
    gc.collect()
예제 #9
0
def get_cornerRADECs(f):
        d,h       = fits.getdata(f,header=True)
        w         = wcs.WCS(h)
        lenx,leny = np.shape(d)
        four_corners_pixels = [[0,0],[0,lenx-1],[leny-1,lenx-1],[leny-1,0]]
        four_corners_RADEC  = w.all_pix2world(four_corners_pixels,0)
        return four_corners_RADEC
예제 #10
0
def build_a_plane_position(plane):
    from astropy.io import fits
    from astropy.wcs import wcs
    from caom2 import SegmentType, Point, Vertex, Position, shape
    logging.error('do i get here?')
    try:
        z = fits.open('/usr/src/app/draogmims2caom2/draogmims2caom2/tests'
                      '/data/gmims_HBN_Fan.fits')
        w = wcs.WCS(z[0].header)
        points = []
        vertices = []
        segment_type = SegmentType['MOVE']

        for x, y in ([0, 0], [1, 0], [1, 1], [0, 1]):
            v = w.all_pix2world(x * z[0].header['naxis1'],
                                y * z[0].header['naxis2'], 1, 1)
            points.append(Point(float(v[0]), float(v[1])))
            vertices.append(Vertex(float(v[0]), float(v[1]), segment_type))
            segment_type = SegmentType['LINE']
        vertices.append(
            Vertex(points[0].cval1, points[0].cval2, SegmentType['CLOSE']))

        polygon = shape.Polygon(points=points,
                                samples=shape.MultiPolygon(vertices))
        position = Position(time_dependent=False, bounds=polygon)
        plane.position = position
    except Exception as e:
        logging.error('wtf {}'.format(e))
예제 #11
0
def test_iteration():
    world = np.array(
        [[-0.58995335, -0.5], [0.00664326, -0.5], [-0.58995335, -0.25],
         [0.00664326, -0.25], [-0.58995335, 0.], [0.00664326, 0.],
         [-0.58995335, 0.25], [0.00664326, 0.25], [-0.58995335, 0.5],
         [0.00664326, 0.5]], float)

    w = wcs.WCS()
    w.wcs.ctype = ['GLON-CAR', 'GLAT-CAR']
    w.wcs.cdelt = [-0.006666666828, 0.006666666828]
    w.wcs.crpix = [75.907, 74.8485]
    x = w.wcs_world2pix(world, 1)

    expected = np.array(
        [[1.64400000e+02, -1.51498185e-01], [7.49105110e+01, -1.51498185e-01],
         [1.64400000e+02, 3.73485009e+01], [7.49105110e+01, 3.73485009e+01],
         [1.64400000e+02, 7.48485000e+01], [7.49105110e+01, 7.48485000e+01],
         [1.64400000e+02, 1.12348499e+02], [7.49105110e+01, 1.12348499e+02],
         [1.64400000e+02, 1.49848498e+02], [7.49105110e+01, 1.49848498e+02]],
        float)

    assert_array_almost_equal(x, expected)

    w2 = w.wcs_pix2world(x, 1)

    world[:, 0] %= 360.

    assert_array_almost_equal(w2, world)
예제 #12
0
def HDU_to_NDData(hdu):
   """
    Create an N-dimensional dataset from an HDU component.

    Parameters
    ----------
    hdu : HDU object
        HDU to transform into an N-dimensional dataset.

    Returns
    -------
    result: astropy.nddata.NDDataRef with data from the HDU object.
   """
   hdu.verify("fix")
   data=hdu.data
   meta=hdu.header
   mask=np.isnan(data)
   # Hack to correct wrong uppercased units generated by CASA
   try:
     bscale=meta['BSCALE']
   except KeyError:
     bscale=1.0
   try:
     bzero=meta['BZERO']
   except KeyError:
     bzero=0.0
   try:
     bsu=meta['BUNIT']
     bsu=bsu.lower()
     bsu=bsu.replace("jy","Jy")
     bunit=u.Unit(bsu,format="fits")
   except KeyError:
     bunit=u.Unit("u.Jy/u.beam")
   rem_list=[]
   for i in meta.items():
      if i[0].startswith('PC00'):
         rem_list.append(i[0])
   for e in rem_list:
      meta.remove(e)

   mywcs=wcs.WCS(meta)
   # Create astropy units
   if len(data.shape) == 4:
       # Put data in physically-meaninful values, and remove stokes
       # TODO: Stokes is removed by summing (is this correct? maybe is averaging?)
       log.info("4D data detected: assuming RA-DEC-FREQ-STOKES (like CASA-generated ones), and dropping STOKES")
       data=data.sum(axis=0)*bscale+bzero
       mask = np.logical_and.reduce(mask,axis=0)
       mywcs=mywcs.dropaxis(3)
   elif len(data.shape) == 3:
       log.info("3D data detected: assuming RA-DEC-FREQ")
       data=data*bscale+bzero
   elif len(data.shape) == 2:
       log.info("2D data detected: assuming RA-DEC")
       data=data*bscale+bzero
   else:
       log.error("Only 3D data allowed (or 4D in case of polarization)")
       raise TypeError
   return ndd.NDDataRef(data, uncertainty=None, mask=mask,wcs=mywcs, meta=meta, unit=bunit)
예제 #13
0
def test_unit3():
    w = wcs.WCS()
    for idx in (2, -3):
        with pytest.raises(IndexError):
            w.wcs.cunit[idx]
        with pytest.raises(IndexError):
            w.wcs.cunit[idx] = u.m
    with pytest.raises(ValueError):
        w.wcs.cunit = [u.m, u.m, u.m]
예제 #14
0
    def __init__(
        self,
        data=None,
        spec_axis=None,
        pyorder=True,
        hdr=None,
        wcs=None,
        casa_cs=None,
    ):

        # If we have another cube object, then copy it
        if isinstance(data, Cube):
            self.init_from_cube(data)

        # If we have a string then read a file
        if type(data) == type("file.fits"):

            if (data[-4:]).upper() == "FITS":
                # ... if it ends in FITS call astropy
                self.from_fits_file(data)
            else:
                # ... else call CASA
                self.from_casa_image(data, transpose=pyorder)

        # If we have an array, save it
        if type(data) == type(np.array([1, 1])):
            self.data = data

        # Allow the user to force/supply attributes but note that
        # these may already be set by the file reader. If so, respect
        # that.

        if spec_axis != None and self.spec_axis == None:
            self.spec_axis = spec_axis

        if hdr != None and self.hdr == None:
            self.hdr == hdr

        if wcs != None and self.astropy_wcs == None:
            self.astropy_wcs == wcs

        if casa_cs != None and self.casa_cs == None:
            self.casa_cs == wcs

        if self.pyorder == None:
            self.pyorder = pyorder

        # Some filling-out logic

        if self.astropy_wcs == None and self.hdr != None:
            if astropy_ok:
                self.astropy_wcs = wcs.WCS(self.hdr)

        if self.spec_axis == None:
            self.find_spec_axis()
예제 #15
0
파일: img.py 프로젝트: pabell/ximpol
 def __init__(self, file_path, build_cdf=True):
     """Constructor.
     """
     logger.info('Reading FITS image from %s...' % file_path)
     self.hdu_list = fits.open(file_path)
     self.hdu_list.info()
     self.wcs = wcs.WCS(self.hdu_list['PRIMARY'].header)
     self.data = self.hdu_list['PRIMARY'].data.transpose()
     self.vmin = None
     self.vmax = None
     if build_cdf:
         self.build_cdf()
예제 #16
0
def fits2radec(
    fitsfn: Path, WCSfn: Path = None, solve: bool = False, args: str = None
) -> xarray.Dataset:

    fitsfn = Path(fitsfn).expanduser()

    if WCSfn is None:
        if fitsfn.suffix in (".fits", ".new"):
            # using .wcs will also work but gives a spurious warning
            WCSfn = fitsfn.with_suffix(".wcs")
        elif fitsfn.suffix == ".wcs":
            WCSfn = fitsfn
        else:
            raise ValueError(f"please convert {fitsfn} to GRAYSCALE .fits")

    if solve:
        if not doSolve(fitsfn, args):
            logging.error(f"{fitsfn} was not solved")
            return None

    if not WCSfn.is_file():
        WCSfn = WCSfn.parent / (WCSfn.stem + "_stack.wcs")
    if not WCSfn.is_file():
        logging.error(f"it appears {fitsfn} was not solved as {WCSfn} is not found")
        return None

    with fits.open(fitsfn, mode="readonly") as f:
        yPix, xPix = f[0].shape[-2:]

    x, y = meshgrid(range(xPix), range(yPix))  # pixel indices to find RA/dec of
    xy = column_stack((x.ravel(order="C"), y.ravel(order="C")))
    # %% use astropy.wcs to register pixels to RA/DEC
    """
    http://docs.astropy.org/en/stable/api/astropy.wcs.WCS.html#astropy.wcs.WCS
    naxis=[0,1] is to take x,y axes in case a color photo was input e.g. to astrometry.net cloud solver
    """
    with fits.open(WCSfn, mode="readonly") as f:
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            radec = wcs.WCS(f[0].header).all_pix2world(xy, 0)
            # radec = wcs.WCS(hdul[0].header,naxis=[0,1]).all_pix2world(xy, 0)

    ra = radec[:, 0].reshape((yPix, xPix), order="C")
    dec = radec[:, 1].reshape((yPix, xPix), order="C")
    # %% collect output
    radec = xarray.Dataset(
        {"ra": (("y", "x"), ra), "dec": (("y", "x"), dec)},
        {"x": range(xPix), "y": range(yPix)},
        attrs={"filename": str(fitsfn)},
    )

    return radec
예제 #17
0
def get_wcs(fits_filename):
    """ Finds and returns the WCS for an image. If Primary Header WCS no good, searches each index until a good one
        is found. If none found, raises a ValueError
    """
    # Try just opening the initial header
    wcs_init = wcs.WCS(fits_filename)
    ra, dec = wcs_init.axis_type_names
    if ra.upper() == "RA" and dec.upper() == "DEC":
        return wcs_init

    else:
        hdu_list = fits.open(fits_filename)
        for n in hdu_list:
            try:
                wcs_slice = wcs.WCS(n.header)
                ra, dec = wcs_slice.axis_type_names
                if ra.upper() == "RA" and dec.upper() == "DEC":
                    return wcs_slice
            except:
                continue
        hdu_list.close()

    raise ValueError
예제 #18
0
def test_against_wcslib(inp):
    w = wcs.WCS()
    crval = [202.4823228, 47.17511893]
    w.wcs.crval = crval
    w.wcs.ctype = ['RA---TAN', 'DEC--TAN']

    lonpole = 180
    tan = models.Pix2Sky_TAN()
    n2c = models.RotateNative2Celestial(crval[0], crval[1], lonpole)
    c2n = models.RotateCelestial2Native(crval[0], crval[1], lonpole)
    m = tan | n2c
    minv = c2n | tan.inverse

    radec = w.wcs_pix2world(inp[0], inp[1], 1)
    xy = w.wcs_world2pix(radec[0], radec[1], 1)

    assert_allclose(m(*inp), radec, atol=1e-12)
    assert_allclose(minv(*radec), xy, atol=1e-12)
예제 #19
0
def read_fits(fits_filename):
    """
    Function to read the FITS file and store the image array and WCS

    Inputs:
        fits_filename:        Name of the FITS filename
    Outputs:
        wcs_info:             WCS of the FITS image
        image_array:          Array of the FITS image
    """
    list_of_hdu = fits.open(fits_filename)

    # Get the image array
    image_array = fits.getdata(fits_filename)
    image_array = image_array[0][0]

    # Get the WCS of the image
    wcs_info = wcs.WCS(list_of_hdu[0].header, list_of_hdu).celestial

    return image_array, wcs_info
예제 #20
0
def load_fits(filepath):
    hdulist = fits.open(filepath)
    hduobject = hdulist[0]
    hduobject.verify("fix")
    bscale = 1.0
    bunit = units.Unit('u.Jy/u.beam')
    bzero = 0.0
    mask = numpy.isnan(hduobject.data)
    if 'BSCALE' in hduobject.header:
        bscale = hduobject.header['BSCALE']
    if 'BZERO' in hduobject.header:
        bzero = hduobject.header['BZERO']
    if 'BUNIT' in hduobject.header:
        unit = hduobject.header['BUNIT'].lower().replace('jy', 'Jy')
        bunit = units.Unit(unit, format='fits')
    for item in hduobject.header.items():
        if item[0].startswith('PC00'):
            hduobject.header.remove(item[0])
    coordinateSystem = wcs.WCS(hduobject.header)
    if len(hduobject.data.shape) == 4:
        log.info(
            '4D Detected: Assuming RA-DEC-FREQ-STOKES, and dropping STOKES')
        coordinateSystem = coordinateSystem.dropaxis(3)
        hduobject.data = hduobject.data.sum(axis=0) * bscale + bzero
        mask = numpy.logical_and.reduce(mask, axis=0)
    elif len(hduobject.data.shape) == 3:
        log.info('3D Detected: Assuming RA-DEC-FREQ')
        hduobject.data = (hduobject.data * bscale) + bzero
    elif len(hduobject.data.shape) == 2:
        log.info('2D Detected: Assuming RA-DEC')
        hduobject.data = (hduobject.data * bscale) + bzero
    else:
        log.error('Only 2-4D data allowed')
        raise TypeError('Only 2-4D data allowed')
    hdulist.close()
    return astropy.nddata.NDDataRef(hduobject.data,
                                    uncertainty=None,
                                    mask=mask,
                                    wcs=coordinateSystem,
                                    meta=hduobject.header,
                                    unit=bunit)
예제 #21
0
def fits2radec(fitsfn: Path, solve: bool=False, args: str=None) -> xarray.Dataset:

    fitsfn = Path(fitsfn).expanduser()

    if fitsfn.suffix == '.fits':
        WCSfn = fitsfn.with_suffix('.wcs')  # using .wcs will also work but gives a spurious warning
    elif fitsfn.suffix == '.wcs':
        WCSfn = fitsfn
    else:
        raise ValueError(f'please convert {fitsfn} to GRAYSCALE .fits e.g. with ImageJ or ImageMagick')

    if solve:
        doSolve(fitsfn, args)

    with fits.open(fitsfn, mode='readonly') as f:
        yPix, xPix = f[0].shape[-2:]

    x, y = meshgrid(range(xPix), range(yPix))  # pixel indices to find RA/dec of
    xy = column_stack((x.ravel(order='C'), y.ravel(order='C')))
# %% use astropy.wcs to register pixels to RA/DEC
    """
    http://docs.astropy.org/en/stable/api/astropy.wcs.WCS.html#astropy.wcs.WCS
    naxis=[0,1] is to take x,y axes in case a color photo was input e.g. to astrometry.net cloud solver
    """
    try:
        with fits.open(WCSfn, mode='readonly') as f:
            # radec = wcs.WCS(hdul[0].header,naxis=[0,1]).all_pix2world(xy, 0)
            radec = wcs.WCS(f[0].header).all_pix2world(xy, 0)
    except OSError:
        raise OSError(f'It appears the WCS solution is not present, was the FITS image solved?  looking for: {WCSfn}')

    ra = radec[:, 0].reshape((yPix, xPix), order='C')
    dec = radec[:, 1].reshape((yPix, xPix), order='C')
# %% collect output
    radec = xarray.Dataset({'ra': (('y', 'x'), ra),
                            'dec': (('y', 'x'), dec), },
                           {'x': range(xPix), 'y': range(yPix)},
                           attrs={'filename': fitsfn})

    return radec
예제 #22
0
def mask2mim(maskfile, mimfile, threshold=1.0, maxdepth=8):
    """
    Use a fits file as a mask to create a region file.

    Pixels in mask file that are equal or above the threshold will be included in the reigon,
    while those that are below the threshold will not.

    Parameters
    ----------
    maskfile : str
        Input file in fits format.

    mimfile : str
        Output filename

    threshold : float
        threshold value for separating include/exclude values

    maxdepth : int
        Maximum depth (resolution) of the healpix pixels

    """
    hdu = pyfits.open(maskfile)
    wcs = pywcs.WCS(hdu[0].header)

    x, y = np.where(hdu[0].data >= threshold)
    ra, dec = wcs.all_pix2world(y, x, 0)
    sky = np.radians(Region.radec2sky(ra, dec))
    vec = Region.sky2vec(sky)
    x, y, z = np.transpose(vec)
    pix = hp.vec2pix(2**maxdepth, x, y, z, nest=True)

    region = Region(maxdepth=maxdepth)
    region.add_pixels(pix, depth=maxdepth)
    region._renorm()
    save_region(region, mimfile)
    logging.info("Converted {0} -> {1}".format(maskfile, mimfile))
    return
예제 #23
0
    def from_fits_file(self,
                       filename=None,
                       skipdata=False,
                       skipvalid=False,
                       skiphdr=False):
        """
        Read in a cube from a FITS file using astropy.
        """

        # Require astropy to be loaded.
        if astropy_ok == False:
            print "Cannot read FITS files without astropy."
            return

        # ... record the filename
        self.filename = filename

        # ... open the file
        hdulist = fits.open(filename)

        # ... read the data - assume first extension
        if skipdata == False:
            self.data = hdulist[0].data

        # ... note where data is valid
        if skipvalid == False:
            self.valid = np.isfinite(self.data)

        # ... astropy always reads in pyorder
        self.pyorder = True

        # ... note the header and WCS information
        if skiphdr == False:
            self.astropy_wcs = wcs.WCS(hdulist[0].header)
            self.hdr = hdulist[0].header
            # ... figure out the spectral axis
            self.find_spec_axis()
예제 #24
0
def test_scalegen():

    cube = SpectralCube(data, wcs.WCS(h),
                        mask=BooleanArrayMask(mask, wcs=wcs.WCS(h)))
    noiseobj = noise.Noise(cube)
    assert np.isclose(noiseobj.scale, 1.1382529312849043)
예제 #25
0
def plot_fits_map(data,
                  header,
                  stretch='auto',
                  exponent=2,
                  scaleFrac=0.9,
                  cmapName='gist_heat',
                  zMin=None,
                  zMax=None,
                  annEllipseLst=[],
                  annPolyLst=[],
                  bunit=None,
                  lw=1.0,
                  interpolation='Nearest',
                  fig=None,
                  dpi=100,
                  doColbar=True):
    """
    Plot a colourscale image of a FITS map.
    
    annEllipseLst is a list of lists:
        annEllipseLst[0][i] = x_deg
        annEllipseLst[1][i] = y_deg
        annEllipseLst[2][i] = minor_deg
        annEllipseLst[3][i] = major_deg
        annEllipseLst[4][i] = pa_deg
        annEllipseLst[5][i] = colour ... optional, default to 'g'
        
    annPolyLst is also a list of lists:
        annPolyLst[0][i] = list of polygon coords = [[x1,y1], [x2, y2] ...]
        annPolyLst[1][i] = colour of polygon e.g., 'w'
    """

    # Strip unused dimensions from the array
    data, header = strip_fits_dims(data, header, 2, 5)

    # Parse the WCS information
    w = mkWCSDict(header)
    wcs = pw.WCS(w['header2D'])

    # Calculate the image vmin and vmax by measuring the range in the inner
    # 'scale_frac' of the image
    s = data.shape
    boxMaxX = int(s[-1] / 2.0 + s[-1] * scaleFrac / 2.0 + 1.0)
    boxMinX = int(s[-1] / 2.0 - s[-1] * scaleFrac / 2.0 + 1.0)
    boxMaxY = int(s[-2] / 2.0 + s[-2] * scaleFrac / 2.0 + 1.0)
    boxMinY = int(s[-2] / 2.0 - s[-2] * scaleFrac / 2.0 + 1.0)
    dataSample = data[boxMinY:boxMaxY, boxMinX:boxMaxX]
    measures = calc_stats(dataSample)
    sigma = abs(measures['max'] / measures['madfm'])
    if stretch == 'auto':
        if sigma <= 20:
            vMin = measures['madfm'] * (-1.5)
            vMax = measures['madfm'] * 10.0
            stretch = 'linear'
        elif sigma > 20:
            vMin = measures['madfm'] * (-3.0)
            vMax = measures['madfm'] * 40.0
            stretch = 'linear'
        elif sigma > 500:
            vMin = measures['madfm'] * (-7.0)
            vMax = measures['madfm'] * 200.0
            stretch = 'sqrt'
    if not zMax is None:
        vMax = max(zMax, measures['max'])
    if not zMax is None:
        vMin = zMin

    # Set the colourscale using an normalizer object
    normalizer = APLpyNormalize(stretch=stretch,
                                exponent=exponent,
                                vmin=vMin,
                                vmax=vMax)

    # Setup the figure
    if fig is None:
        fig = plt.figure(facecolor='w', figsize=(9.5, 8))
    ax = fig.add_axes([0.1, 0.08, 0.9, 0.87])
    if w['coord_type'] == 'EQU':
        ax.set_xlabel('Right Ascension')
        ax.set_ylabel('Declination')
    elif w['coord_type'] == 'GAL':
        ax.set_xlabel('Galactic Longitude (deg)')
        ax.set_ylabel('Galactic Latitude (deg)')
    else:
        ax.set_xlabel('Unknown')
        ax.set_ylabel('Unknown')
    cosY = m.cos(m.radians(w['ycent']))
    aspect = abs(w['ydelt'] / (w['xdelt'] * cosY))

    # Set the format of the major tick mark and labels
    if w['coord_type'] == 'EQU':
        f = 15.0
        majorFormatterX = FuncFormatter(label_format_hms)
        minorFormatterX = None
        majorFormatterY = FuncFormatter(label_format_dms)
        minorFormattery = None
    else:
        f = 1.0
        majorFormatterX = FuncFormatter(label_format_deg)
        minorFormatterX = None
        majorFormatterY = FuncFormatter(label_format_deg)
        minorFormattery = None
    ax.xaxis.set_major_formatter(majorFormatterX)
    ax.yaxis.set_major_formatter(majorFormatterY)

    # Set the location of the the major tick marks
    #xrangeArcmin = abs(w['xmax']-w['xmin'])*(60.0*f)
    #xmultiple = m.ceil(xrangeArcmin/3.0)/(60.0*f)
    #yrangeArcmin = abs(w['ymax']-w['ymin'])*60.0
    #ymultiple = m.ceil(yrangeArcmin/3.0)/60.0
    #majorLocatorX = MultipleLocator(xmultiple)
    #ax.xaxis.set_major_locator(majorLocatorX)
    #majorLocatorY = MultipleLocator(ymultiple)
    #ax.yaxis.set_major_locator(majorLocatorY)

    ax.xaxis.set_major_locator(MaxNLocator(5))
    ax.yaxis.set_major_locator(MaxNLocator(5))

    # Print the image to the axis
    im = ax.imshow(data,
                   interpolation=interpolation,
                   origin='lower',
                   aspect=aspect,
                   extent=[w['xmax'], w['xmin'], w['ymin'], w['ymax']],
                   cmap=plt.get_cmap(cmapName),
                   norm=normalizer)

    # Add the colorbar
    if doColbar:
        cbar = fig.colorbar(im, pad=0.0)
        if 'BUNIT' in header:
            cbar.set_label(header['BUNIT'])
        else:
            cbar.set_label('Unknown')
        if not bunit is None:
            cbar.set_label(bunit)

    # Format the colourbar labels - TODO

    # Set white ticks
    ax.tick_params(pad=5)
    for line in ax.xaxis.get_ticklines() + ax.get_yticklines():
        line.set_markeredgewidth(1)
        line.set_color('w')

    # Create the ellipse source annotations
    if len(annEllipseLst) > 0:
        if len(annEllipseLst) >= 5:
            srcXLst = np.array(annEllipseLst[0])
            srcYLst = np.array(annEllipseLst[1])
            srcMinLst = np.array(annEllipseLst[2])
            srcMajLst = np.array(annEllipseLst[3])
            srcPALst = np.array(annEllipseLst[4])
        if len(annEllipseLst) >= 6:
            if type(annEllipseLst[5]) is str:
                srcEColLst = [annEllipseLst[5]] * len(srcXLst)
            elif type(annEllipseLst[5]) is list:
                srcEColLst = annEllipseLst[5]
            else:
                rcEColLst = ['g'] * len(srcXLst)
        else:
            srcEColLst = ['g'] * len(srcXLst)
        for i in range(len(srcXLst)):
            try:
                el = Ellipse((srcXLst[i], srcYLst[i]),
                             srcMinLst[i],
                             srcMajLst[i],
                             angle=180.0 - srcPALst[i],
                             edgecolor=srcEColLst[i],
                             linewidth=lw,
                             facecolor='none')
                ax.add_artist(el)
            except Exception:
                pass

    # Create the polygon source annotations
    if len(annPolyLst) > 0:
        annPolyCoordLst = annPolyLst[0]
        if len(annPolyLst) > 1:
            if type(annPolyLst[1]) is str:
                annPolyColorLst = [annPolyLst[1]] * len(annPolyCoordLst)
            elif type(annPolyLst[1]) is list:
                annPolyColorLst = annPolyLst[1]
            else:
                annPolyColorLst = ['g'] * len(annPolyCoordLst)
        else:
            annPolyColorLst = ['g'] * len(annPolyCoordLst)
        for i in range(len(annPolyCoordLst)):
            cpoly = Polygon(annPolyCoordLst[i], animated=False, linewidth=lw)
            cpoly.set_edgecolor(annPolyColorLst[i])
            cpoly.set_facecolor('none')
            ax.add_patch(cpoly)

    return fig
예제 #26
0
    starnames = a['name'].data
    radecstrs = []
    for k in range(len(a)):
        cstr = '{}h{}m{}s {}d{}m{}s'.format(a['rah'][k], a['ram'][k],
                                            a['ras'][k], a['decd'][k],
                                            a['decm'][k], a['decs'][k])
        radecstrs.append(cstr)

    print(starnames)
    print(radecstrs)

    # get the large fits file and wcs info
    filename = 'F475W_mosaic.fits.gz'
    cband = 'F475W'
    hdulist = fits.open(filename)
    image_wcs = wcs.WCS(hdulist[0].header)
    image = hdulist[0].data

    # size to extract in (ra, dec) arcsec
    size = (10., 10.)

    for k, cradec in enumerate(radecstrs):
        pimage = get_postage_stamp(cradec, size, image, image_wcs)

        if pimage is not None:
            print(pimage.wcs)

            ohdu = fits.PrimaryHDU(pimage.data, header=pimage.wcs.to_header())
            ohdul = fits.HDUList([ohdu])
            ohdul.writeto('%s_%s_pstamp.fits' % (starnames[k], cband),
                          overwrite=True)
예제 #27
0
def test_unit2():
    w = wcs.WCS()
    myunit = u.Unit("FOOBAR", parse_strict="warn")
    w.wcs.cunit[0] = myunit
예제 #28
0
def test_unit():
    w = wcs.WCS()
    w.wcs.cunit[0] = u.erg
    assert w.wcs.cunit[0] == u.erg

    assert repr(w.wcs.cunit) == "['erg', '']"
예제 #29
0
        if phot_band == "radio":
            sep_pattern = [400, 400]
            corner_coord = cent_coord.directional_offset_by(
                pa_pattern * u.deg, sep_pattern * u.arcsec)
        else:
            sep_pattern = [300, 300]
            corner_coord = cent_coord.directional_offset_by(
                pa_pattern * u.deg, sep_pattern * u.arcsec)
            # Name the section based on Source_Name and phot_band
        crop_img_name = BASE_OUT + "/" + prefilt_out["Source_Name"][
            ii] + "_" + phot_band + ".fits"
        img_to_crop = img_dict[phot_band]

        if not os.path.exists(crop_img_name):
            hdul = fits.open(img_to_crop)
            img_wcs = wcs.WCS(hdul[0].header, hdul).celestial

            print(crop_img_name)

            xc, yc = img_wcs.all_world2pix(corner_coord.ra, corner_coord.dec,
                                           0)
            xc = np.sort(xc)
            yc = np.sort(yc)

            xr = slice(int(np.round(xc[0])), int(np.floor(xc[1])))
            yr = slice(int(np.round(yc[0])), int(np.floor(yc[1])))

            if phot_band != "radio":
                crop_write_fits(hdul, img_wcs, hdul[0].data, xr, yr,
                                crop_img_name)
            else:
예제 #30
0
def match_crop_fits(filename_indx):
    """
    Use the funtions defined previously to find the overlapping
    region between two images and crop both the images to the
    overlapping image.

    This assumes that the WCS information in the FITS header
    is accurate.

    Parameters:
    -----------
    filename_indx : The index into the list of filenames to
                    select the file that needs to be processed
    """

    wht_img = wht_list[filename_indx]
    coadd_img = coadd_list[filename_indx]

    print("Matching " + coadd_img)

    # Open wht image and store image data and WCS information
    wht_hdu = fits.open(wht_img)
    wht_wcs = wcs.WCS(wht_hdu[wcs_hext].header, wht_hdu).celestial
    wht_data = wht_hdu[img_hext].data

    # Open the image and store image data and WCS information
    coadd_hdu = fits.open(coadd_img)
    coadd_wcs = wcs.WCS(coadd_hdu[wcs_hext].header, coadd_hdu).celestial
    coadd_data = coadd_hdu[img_hext].data

    img_c_ra, img_c_dec = world_extent(coadd_wcs, coadd_hdu[wcs_hext].header)

    wht_c_ra, wht_c_dec = world_extent(wht_wcs, wht_hdu[wcs_hext].header)

    # Compute the corners of the ectangle that define the
    # overlapping region from the images
    ov_ra = np.zeros(4)
    ov_dec = np.zeros(4)

    # The left corners
    ov_ra[0:2] = np.min([img_c_ra[0:2], wht_c_ra[0:2]], axis=0)
    ov_dec[0:2] = np.max([img_c_dec[0:2], wht_c_dec[0:2]], axis=0)

    ov_ra[2:] = np.max([img_c_ra[2:], wht_c_ra[2:]], axis=0)
    ov_dec[2:] = np.min([img_c_dec[2:], wht_c_dec[2:]], axis=0)

    # Compute the pixel (x,y) coordinates at these overlapping
    # world coordinates
    img_ovx, img_ovy = coadd_wcs.all_world2pix(ov_ra, ov_dec, 1)
    wht_ovx, wht_ovy = wht_wcs.all_world2pix(ov_ra, ov_dec, 1)

    # Define the range of the x and y-axis of overlapping region
    # and check that they are of the same size
    wht_xr = np.round(np.array([wht_ovx[1], wht_ovx[2]])).astype(int)
    img_xr = np.round(np.array([img_ovx[1], img_ovx[2]])).astype(int)

    wht_yr = np.round(np.array([wht_ovy[0], wht_ovy[2]])).astype(int)
    img_yr = np.round(np.array([img_ovy[0], img_ovy[2]])).astype(int)

    # Now check that the area of the overlapping images
    # will be the same
    check_imsize(wht_xr, wht_yr, img_xr, img_yr)

    # Write the cropped, overlapping images to file
    crop_write_fits(coadd_hdu, coadd_wcs, coadd_data, img_xr, img_yr,
                    coadd_outlist[filename_indx])
    crop_write_fits(wht_hdu, wht_wcs, wht_data, wht_xr, wht_yr,
                    wht_outlist[filename_indx])

    return