Пример #1
0
def trim_cube(cube, y1=11, y2=70, x1=6, x2=28, outfile=None):
    """Trim spatial dimensions of data cube and adjust WCS accordingly.

    Parameters
    ----------
    cube : DataCube or str
        Data cube to be trimmed
    y1, y2, x1, x2 : int
        Pixels to keep in trimmed cube (1-indexed as might be represented in DS9)
    outfile : str, optional
        File name to write to

    Returns
    -------
    cube : DataCube
        Trimmed data cube
    """
    if isinstance(cube, str):
        cube = DataCube(cube)
    cube.data = cube.data[:, y1 - 1:y2 - 1, x1 - 1:x2 - 1]
    crpix_old = cube.wcs.wcs.crpix

    cube.wcs.wcs.crpix[0] = crpix_old[0] - (x1 - 1)
    cube.wcs.wcs.crpix[1] = crpix_old[1] - (y1 - 1)

    if outfile is not None:
        cube.write(outfile)

    return cube
Пример #2
0
def subtract_master_sky(scicubes,
                        mastersky,
                        outdir=None,
                        suffix='mskysub.fits'):

    if type(scicubes) == list:
        for i, sc in enumerate(scicubes):
            if not isinstance(sc, DataCube):
                cube = DataCube(sc)
                rootfn = sc.split('/')[-1][:-5]
            cubedatsub = cube.data.transpose() - mastersky
            cube.data = cubedatsub.transpose()
            if outdir is not None:
                cube.write(outdir + rootfn + '_' + suffix)
    else:
        if not isinstance(scicubes, DataCube):
            cube = DataCube(scicubes)
            rootfn = scicubes.split('/')[-1][:-5]
        else:
            cube = scicubes
            rootfn = ''
        cubedatsub = cube.data.transpose() - mastersky
        cube.data = cubedatsub.transpose()
        if outdir is not None:
            cube.write(outdir + rootfn + '_' + suffix)
        return cube
Пример #3
0
def trim_cube(cube, y1=11, y2=70, x1=6, x2=28, outfile=None):
    if isinstance(cube, str):
        cube = DataCube(cube)
    cube.data = cube.data[:, y1 - 1:y2 - 1, x1 - 1:x2 - 1]
    crpix_old = cube.wcs.wcs.crpix

    cube.wcs.wcs.crpix[0] = crpix_old[0] - (x1 - 1)
    cube.wcs.wcs.crpix[1] = crpix_old[1] - (y1 - 1)

    if outfile is not None:
        cube.write(outfile)

    return cube
Пример #4
0
def extract_spectrum(cube,pixels,wvslice=None):

    from linetools.spectra.xspectrum1d import XSpectrum1D

    if isinstance(cube,str):
        cube = DataCube(cube)

    if wvslice is not None:
        cube = kt.slice_cube(cube,wvslice[0],wvslice[1])


    dat = cube.data

    # Get rid of NaNs
    dc = dat.copy()
    nans = np.where(np.isnan(dc))
    dc[nans]=0

    # Perform the extraction
    spaxels = []
    for i,px in enumerate(pixels):
        thisspec = dc[:,px[0],px[1]]
        spaxels.append(thisspec)
    spaxels=np.array(spaxels)
    medspec = np.median(spaxels, axis=0)

    # Get the wavelength array
    newwavearr = cube.wavelength

    # Create the spectrum
    try:
        spec = XSpectrum1D(wave = newwavearr,flux=medspec)
    except:
        import pdb; pdb.set_trace()
    return spec
Пример #5
0
def slice_cube(cube, wave1, wave2, outfile=None):
    """Extract portion of cube extracted in wavelength space.

    Parameters
    ----------
    cubefile
    wave1
    wave2
    outfile

    Returns
    -------

    """

    if isinstance(cube, str):
        cube = DataCube(cube)
        dat = cube.data
        wcs = cube.wcs
    else:
        dat = cube.data
        wcs = cube.wcs
    newwavearr = cube.wavelength
    if np.all(newwavearr < 1e-3):
        newwavearr *= 1e10

    tokeep = np.where((newwavearr >= wave1) & (newwavearr <= wave2))[0]
    wslice = slice(tokeep[0], tokeep[-1] + 1)

    sl2 = slice(0, np.shape(dat)[1])
    sl3 = slice(0, np.shape(dat)[2])

    datslice = dat[tokeep, :, :]
    try:
        wcsslice = wcs.slice((wslice, sl2, sl3))
    except:
        import pdb
        pdb.set_trace()

    newhdulist = wcsslice.to_fits()
    newhdulist[0].data = datslice
    if outfile is not None:
        newhdulist.writeto(outfile, overwrite=True)
    return DataCube(newhdulist)
Пример #6
0
def loadRtModel(biconeangle=80,
                incline=40,
                extent=30,
                modeldir='BRP19_conv',
                suffix='spec_conv1p6_rebinxy_wcstp_convspecrb.fits',
                filename=None):
    '''Convolve and rebin a radiative transfer model cube in the spectral direction

    Parameters
    ----------
    biconeangle : int
        Opening angle of the biconical outflow: [10,30,45,60,80]
    incline : int
        Inclination angle of the disk relative to line of sight: [40,60,80]
    extent : int
        Outer extent of outflow (in kpc): [
    Returns
    -------
    modelcube : DataCube
        Radiative transfer model cube
    '''

    if modeldir[-1] != '/':
        modeldir += '/'
    if filename is not None:
        try:
            modelcube = DataCube('{}{}'.format(modeldir, filename))
            return modelcube
        except:
            modelcube = DataCube(filename)
            return modelcube
        else:
            raise ValueError('Model datacube file not found')

    if extent != 30:
        fname = '{}brp19_biconical{}_rw{}_disk_theta{}_{}'.format(
            modeldir, biconeangle, extent, incline, suffix)
    else:
        fname = '{}brp19_biconical{}_disk_theta{}_{}'.format(
            modeldir, biconeangle, incline, suffix)
    modelcube = DataCube(fname)
    return modelcube
Пример #7
0
def trim_cube_relpix(cube,
                     cenpix,
                     dx,
                     dy,
                     zeroindex=True,
                     outfile=None,
                     dims='yxz'):
    """Trim spatial dimensions of data cube relative to some central pixel
    and adjust WCS accordingly.

    Parameters
    ----------
    cube : DataCube or str
        Data cube to be trimmed
    cenpix : tuple
        Central pixel indices as (y,x)
    dx : int
        Number of pixels to keep in the x-direction
    dy : int
        Number of pixels to keep in the y-direction
    zeroindex : bool, optional
        If True, cenpix is true index of central pixel but 0-indexed array
        If False, 1-indexed
    outfile : str, optional
        File name to write to

    Returns
    -------
    cube : DataCube
        Trimmed data cube
    """
    if isinstance(cube, str):
        cube = DataCube(cube)

    if not zeroindex:
        cenpix[0] -= 1.
        cenpix[1] -= 1.

    if dims == 'zyx':
        cube.data = cube.data[:, cenpix[0][0] - dy + 1:cenpix[0][0] + dy - 1,
                              cenpix[1][0] - dx + 1:cenpix[1][0] + dx - 1]
    elif dims == 'yxz':
        cube.data = cube.data[cenpix[0][0] - dy + 1:cenpix[0][0] + dy - 1,
                              cenpix[1][0] - dx + 1:cenpix[1][0] + dx - 1, :]
    elif dims == 'yx':
        cube.data = cube.data[cenpix[0][0] - dy + 1:cenpix[0][0] + dy - 1,
                              cenpix[1][0] - dx + 1:cenpix[1][0] + dx - 1]
    crpix_old = cube.wcs.wcs.crpix

    cube.wcs.wcs.crpix[0] = crpix_old[0] - (dx - 1)
    cube.wcs.wcs.crpix[1] = crpix_old[1] - (dy - 1)

    if outfile is not None:
        cube.write(outfile)

    return cube
Пример #8
0
def extract_spectrum(cube,pixels,wvslice=None,method='median',varcube=None, spatial_scale_xy=None):

    ## KHRR: if spatial_scale_xy is not None, flux in units of cgs / sq. arcsec are assumed
    ## This is now only implemented with the 'sum' method

    from linetools.spectra.xspectrum1d import XSpectrum1D

    if isinstance(cube,str):
        cube = DataCube(cube)

    if wvslice is not None:
        cube = kt.slice_cube(cube,wvslice[0],wvslice[1])
        if varcube is not None:
            varcube = kt.slice_cube(varcube, wvslice[0], wvslice[1])

    ##import pdb;
    #pdb.set_trace()

    dat = cube.data

    # Get rid of NaNs
    dc = dat.copy()
    nans = np.where(np.isnan(dc))
    dc[nans]=0

    # Perform the extraction
    if method == 'median':
        if np.shape(np.array(pixels))==(2,):
            extspec = dc[:,pixels[0],pixels[1]]
        else:
            spaxels = []
            for i,px in enumerate(pixels):
                thisspec = dc[:,px[0],px[1]]
                spaxels.append(thisspec)
            spaxels=np.array(spaxels)
            extspec = np.median(spaxels, axis=0)
            sigspec = -99. * np.ones(np.shape(dc)[0])
    elif method == 'mean':
        if np.shape(np.array(pixels))==(2,):
            extspec = dc[:,pixels[0],pixels[1]]
        else:
            spaxels = []
            for i,px in enumerate(pixels):
                thisspec = dc[:,px[0],px[1]]
                spaxels.append(thisspec)
            spaxels=np.array(spaxels)
            extspec = np.mean(spaxels, axis=0)
            sigspec = -99. * np.ones(np.shape(dc)[0])
    elif method == 'sum':
        if np.shape(np.array(pixels))==(2,):
            extspec = dc[:,pixels[0],pixels[1]]
        else:
            spaxels = []
            for i,px in enumerate(pixels):
                thisspec = dc[:,px[0],px[1]]
                spaxels.append(thisspec)
            spaxels=np.array(spaxels)
            sigspec = -99. * np.ones(np.shape(dc)[0])

            if spatial_scale_xy is None:
                extspec = np.sum(spaxels, axis=0)
            else:
                spxsz = spatial_scale_xy[0] * spatial_scale_xy[1]
                extspec = spxsz * np.sum(spaxels, axis=0)

    else:  # do the weighted mean
        vardat = varcube.data
        vdc = vardat.copy()
        if np.shape(np.array(pixels))==(2,):
            extspec = dc[:,pixels[0],pixels[1]]
        else:
            spaxels = []
            varspaxels = []
            for i, px in enumerate(pixels):
                thisspec = dc[:, px[0], px[1]]
                thisvar = vdc[:, px[0], px[1]]
                spaxels.append(thisspec)
                varspaxels.append(thisvar)
            spaxels = np.array(spaxels)
            ivarspaxels = 1./np.array(varspaxels)
            extspec = np.sum(spaxels*ivarspaxels, axis=0)/np.sum(ivarspaxels,axis=0)
            sigspec = 1./np.sqrt(np.sum(ivarspaxels,axis=0))
    # Get the wavelength array
    newwavearr = cube.wavelength

    # Create the spectrum
    try:
        spec = XSpectrum1D(wave = newwavearr,flux=extspec,sig=sigspec)
    except:
        import pdb; pdb.set_trace()
    return spec
Пример #9
0
def rtModel_conv_rb_spec(input,
                         outfil=None,
                         specR=1800.,
                         zgal=0.6942,
                         restlam=2796.35,
                         dlam_rb=None,
                         fmt=['lam', 'y', 'x'],
                         return_cube=True):
    '''Convolve and rebin a radiative transfer model cube in the spectral direction

    Parameters
    ----------
    input : str or DataCube
        Input filename or DataCube to convolve/rebin spectrally
    outfil : str, optional
        Output filename
    specR : float, optional
        Resolving power of spectrum
    zgal : float, optional
        Redshift of object
    restlam : float, optional
        Reference rest-frame wavelength for calculating kernel sigma
    dlam_rb : float, optional
        New wavelength bin size; if None, do not rebin
    fmt : list, optional
        Axis order of data cube, must have 'x', 'y', and 'lam' in some order
    return_cube : bool, optional
        If True, return DataCube object

    Returns
    -------
    newwave : array
        Wavelength vector (same as that of input cube if dlam_rb is None)
    specconv_cube : 3D array
        Datacube with convolved spaxels (spatial, spatial, spectral)
    '''
    from linetools.spectra.xspectrum1d import XSpectrum1D

    dlam_obs = restlam * (1.0 + zgal) / specR
    dlam_rest = dlam_obs / (1.0 + zgal
                            )  # FWHM of resolution element in Angstroms

    if isinstance(input, str):
        ### Assume data format is as the output of
        ### KR's read_spec_output.read_fullfits_conv_rebin()
        hdu = fits.open(input)
        data_pad = hdu[0].data  # Original data, just padded
        cubedat = hdu[1].data  # Spatially convolved data
        wave = hdu[2].data  # Wavelength array
        nx, ny, nlam = cubedat.shape
        cubewcs = None
    else:
        wave = input.wavelength / (1. + zgal)
        cubedat = input.data
        cubewcs = input.wcs

    ### Establish dimensions of input cube
    xs = fmt.index('x')
    ys = fmt.index('y')
    sp = fmt.index('lam')
    cdims = cubedat.shape
    nlam = cdims[sp]
    nx = cdims[xs]
    ny = cdims[ys]

    ### Rearrange the cube (temporarily) : (y,x,lam)
    cubedat_tp = np.transpose(cubedat, axes=[ys, xs, sp])
    fmt_internal = ['y', 'x', 'lam']

    ### Set up kernel to convolve spaxels
    dwv = np.abs(wave[1] - wave[0])
    fwhm_specpix = dlam_rest / dwv  # FWHM in number of pixels
    stddev_specpix = fwhm_specpix / (2.0 * (2.0 * np.log(2.0))**0.5)
    spec_kernel = Gaussian1DKernel(stddev_specpix)

    ### Rebin, if desired, and convolve
    if dlam_rb is None:
        specconv_cube = np.zeros((ny, nx, nlam))
        newwave = wave
        for spaxx in range(nx):
            for spaxy in range(ny):
                spax_spec = cubedat_tp[spaxy, spaxx, :]
                conv_spec = convolve(spax_spec,
                                     spec_kernel,
                                     normalize_kernel=True)
                specconv_cube[spaxy, spaxx, :] = conv_spec
    else:
        waveq = wave * u.Angstrom
        newwave = np.arange(int(wave[0]), int(wave[-1]), dlam_rb) * u.Angstrom
        specconv_cube = np.zeros((ny, nx, len(newwave)))
        for spaxx in range(nx):
            for spaxy in range(ny):
                spax_spec = cubedat_tp[spaxy, spaxx, :]
                conv_spec = convolve(spax_spec,
                                     spec_kernel,
                                     normalize_kernel=True)
                # Use the linetools rebinning method
                csX1d = XSpectrum1D(wave=waveq, flux=conv_spec)
                cs_rb = csX1d.rebin(newwave)
                try:
                    specconv_cube[spaxy, spaxx, :] = cs_rb.flux
                except:
                    import pdb
                    pdb.set_trace()

    if cubewcs is not None:
        cubewcs.wcs.pc[2, 2] = dlam_rb  ### Probably shouldn't be hard-coded

    ### Transpose back to input dimensions
    axs = ['a'] * 3
    for cc in fmt_internal:
        axs[fmt.index(cc)] = fmt_internal.index(cc)
    newdat = np.transpose(specconv_cube, axes=axs)

    if return_cube:
        newcube = DataCube(wavelength=newwave,
                           data=newdat,
                           include_wcs=cubewcs)
        return newwave, newcube
    else:
        return newwave, specconv_cube
Пример #10
0
def addWcsRtModel(inp,
                  ref,
                  outfile,
                  spatial_scale=0.2,
                  zgal=0.6942,
                  center=('12 36 19.811', '+62 12 51.831'),
                  PA=27):

    ### Load in the model file
    inpdat = fits.open(inp)
    rtcube = DataCube(inp, include_wcs=False)
    rtcube.wavelength = inpdat[2].data
    rtcube.data = inpdat[1].data
    wavearr = rtcube.wavelength

    ### Load in the reference file if necessary
    if not isinstance(ref, DataCube):
        refcube = DataCube(ref)
    else:
        refcube = inp
    refdat = refcube.data
    refwave = refcube.wavelength
    nbhdu = transform.narrowband(refcube, 4000., 5000.)
    refnb = nbhdu.data
    refwcs = WCS(nbhdu.header)

    ### Rearrange the cube
    newdat = np.transpose(rtcube.data, axes=[2, 1, 0])

    ### Get the pixel scale in the spectral dimension
    diff = wavearr[1:] - wavearr[:-1]
    if not np.all(diff == diff[0]):
        raise ValueError('Wavelength array not uniformly sampled')
    spectral_scale = diff[0]

    ### Set scale and reference positions
    wave1 = wavearr[0] * (1. + zgal)
    spectral_scale *= (1. + zgal)

    ### Get the bright pixel from reference cube
    brightpix, brightcoords = utils.bright_pix_coords(refnb, refwcs)

    ### Create the new WCS
    newwcs = WCS(naxis=3)
    spatscaledeg = spatial_scale * cosmo.arcsec_per_kpc_proper(zgal) / 3600.
    print(spatscaledeg)
    if center is not None:
        cencoords = SkyCoord(center[0], center[1], unit=(u.hourangle, u.deg))
    else:
        cencoords = brightcoords
    newwcs.wcs.crpix = np.array([150.5, 150.5, 1])
    newwcs.wcs.crval = np.array([cencoords.ra.deg, cencoords.dec.deg, wave1])
    newwcs.wcs.cdelt = np.array([8.0226e-6, 8.0226e-6, spectral_scale])
    newwcs.wcs.cunit = ['deg', 'deg', 'Angstrom']
    newwcs.wcs.ctype = ('RA---TAN', 'DEC--TAN', 'VAC')
    rotangle = np.radians(PA)  # Assuming PA given in degrees
    psmat = np.array([[
        newwcs.wcs.cdelt[0] * np.cos(rotangle),
        -newwcs.wcs.cdelt[1] * np.sin(rotangle), 0.
    ],
                      [
                          newwcs.wcs.cdelt[0] * np.sin(rotangle),
                          newwcs.wcs.cdelt[1] * np.cos(rotangle), 0.
                      ], [0., 0., 1.]])
    newwcs.wcs.cd = psmat

    newhdu = newwcs.to_fits()
    newhdu[0].header['PC3_3'] = spectral_scale
    newhdu[0].data = newdat

    newhdu.writeto(outfile, overwrite=True)
Пример #11
0
def align_cubes(cubelist, obj_align, interp_method='nearest'):
    ra_obj = obj_align.ra.deg
    dec_obj = obj_align.dec.deg
    wobjs = []
    cenpixs = []
    interps = []
    for i, cube in enumerate(cubelist):
        if isinstance(cube, str):
            cube = DataCube(cube)
            dat = cube.data
            thisw = cube.wcs
        else:
            dat = cube.data
            thisw = cube.wcs

        if i == 0:
            cubedim = np.shape(dat)
            print(cubedim)
            inp = (np.arange(cubedim[0]), np.arange(cubedim[1]),
                   np.arange(cubedim[2]))
        wobjs.append(thisw)
        cp = thisw.wcs_world2pix([[ra_obj, dec_obj, 1]], 1)  # (ra,dec,lambda)
        cenpixs.append(cp[0])
        try:
            thisinterp = RegularGridInterpolator((inp[0], inp[1], inp[2]),
                                                 dat,
                                                 method=interp_method,
                                                 bounds_error=False)
        except:
            import pdb
            pdb.set_trace()
        interps.append(thisinterp)

    ### Must now figure out dimensions of new cube!
    cenpixs = np.array(cenpixs)
    try:
        xmin = np.min(cenpixs[:, 0])
    except:
        import pdb
        pdb.set_trace()
    #import pdb; pdb.set_trace()
    xmax = np.max(cenpixs[:, 0])
    ymin = np.min(cenpixs[:, 1])
    ymax = np.max(cenpixs[:, 1])
    xdiff = np.ceil(xmax - xmin)
    ydiff = np.ceil(ymax - ymin)

    ### Generate new data cubes with bigger sizes but that will align
    newcubedims = (cubedim[0], int(cubedim[1] + xdiff),
                   int((cubedim[2] + ydiff)))
    # Modify original header to put object coords in center
    newhdr = cube.header.copy()
    newhdr['CRVAL1'] = ra_obj
    newhdr['CRVAL2'] = dec_obj
    newhdr['CRPIX1'] = (newcubedims[2] + 1.) / 2.
    newhdr['CRPIX2'] = (newcubedims[1] + 1.) / 2.
    newwcs = WCS(newhdr)

    newcubes = []
    # Find coordinates of each pixel in newcube
    idxs = (np.arange(newcubedims[0]), np.arange(newcubedims[1]),
            np.arange(newcubedims[2]))
    idxgrid = np.meshgrid(idxs[0], idxs[1], idxs[2], indexing='ij')
    newcoords = newwcs.wcs_pix2world(idxgrid[2] + 1, idxgrid[1] + 1,
                                     idxgrid[0], 1)

    #pixs = newwcs.wcs_world2pix(coords[0], coords[1], coords[2], 1)
    #pixs = np.array(pixs)

    for i, terp in enumerate(interps):
        # What pixels in the old cube would correspond to the new cubes coords?
        thiscubepix_newcoords = wobjs[i].wcs_world2pix(newcoords[0],
                                                       newcoords[1],
                                                       newcoords[2], 0)
        thiscubepix_newcoords = np.array(thiscubepix_newcoords)
        tcp_nc_x, tcp_nc_y, tcp_nc_wave = thiscubepix_newcoords
        # What would the new pixel values and flux in the single cube be?
        newflux = terp((tcp_nc_wave, tcp_nc_y, tcp_nc_x))
        newcubes.append(newflux)

    return newcubes, newwcs
Пример #12
0
def white_light_offset(icubelist,
                       outputdir_nb='nb_off/',
                       outputdir_cubes='corrCubes/',
                       waverange=[4000., 5500.],
                       slicer='M',
                       write_aligned_nb=True,
                       cube_prefix='newBrightOffset_',
                       varcubelist=None,
                       pixrange=None,
                       trim=True,
                       nb_subgrad=True):
    import os

    ### make narrowband output directory if necessary
    if not os.path.isdir(outputdir_nb):
        os.makedirs(outputdir_nb)

    if isinstance(icubelist[0], DataCube):
        pass
    else:
        cl = [DataCube(cc) for cc in icubelist]
        icubelist = cl

    ### prep variance cubes if provided
    if varcubelist is not None:
        if isinstance(varcubelist[0], DataCube):
            pass
        else:
            vcl = [DataCube(cc) for cc in varcubelist]
            varcubelist = vcl

    ### choose range of pixels appropriate for slicer

    if slicer in ['M', 'medium', 'Medium']:
        if pixrange is None:
            pixrange = [20, 79, 7, 29]
        trimrange = [20, 79, 7, 29]
    elif slicer in ['L', 'large', 'Large']:
        if pixrange is None:
            pixrange = [16, 80, 4, 25]
        trimrange = [16, 80, 4, 25]

    ### trim cubes if desired
    if trim is True:
        tricubelist = []
        trvcubelist = []
        for i, cc in enumerate(icubelist):
            tcube = trim_cube(cc, trimrange[0] + 1, trimrange[1] + 1,
                              trimrange[2] + 1, trimrange[3] + 1)
            vcube = trim_cube(varcubelist[i], trimrange[0] + 1,
                              trimrange[1] + 1, trimrange[2] + 1,
                              trimrange[3] + 1)
            tricubelist.append(tcube)
            trvcubelist.append(vcube)
        icubelist = tricubelist
        varcubelist = trvcubelist

    ### create narrowband images
    nbimages = []
    for cube in icubelist:
        nbout = outputdir_nb + 'nb_' + cube.filename.split('/')[-1]
        nb = narrowband(cube, waverange[0], waverange[1], outfile=nbout)
        if nb_subgrad:
            nbsubdat, nbsubwcs = subtract_gradient(nbout,
                                                   degree=1,
                                                   trim=None,
                                                   outfile=nbout)
            nbsub = DataCube(nbout)
            nbimages.append(nbsub)
        else:
            nbimages.append(nb)
    ### pick one of the narrowband images to use as reference
    refnb = nbimages[0]
    refdat = refnb.data
    refwcs = WCS(refnb.header)

    ### perform the offset
    for i, cube in enumerate(icubelist):
        thisnbw = WCS(nbimages[i].header)
        thisnbdat = nbimages[i].data
        neww = change_coord_alignmax(refwcs,
                                     thisnbw,
                                     refdat,
                                     thisnbdat,
                                     range_mod=pixrange,
                                     range_ref=pixrange)
        cube.wcs.wcs.crval[0] = neww.wcs.crval[0]
        cube.wcs.wcs.crval[1] = neww.wcs.crval[1]
        cube.wcs.wcs.crpix[0] = neww.wcs.crpix[0]
        cube.wcs.wcs.crpix[1] = neww.wcs.crpix[1]
        if not os.path.isdir(outputdir_cubes):
            os.makedirs(outputdir_cubes)
        cube.write(outputdir_cubes + cube_prefix +
                   cube.filename.split('/')[-1])
        ### offset variance cube if provided
        if varcubelist is not None:
            vcube = varcubelist[i]
            vcube.wcs.wcs.crval[0] = neww.wcs.crval[0]
            vcube.wcs.wcs.crval[1] = neww.wcs.crval[1]
            vcube.wcs.wcs.crpix[0] = neww.wcs.crpix[0]
            vcube.wcs.wcs.crpix[1] = neww.wcs.crpix[1]
            vcube.write(outputdir_cubes + cube_prefix +
                        vcube.filename.split('/')[-1])
        ### if desired, write out white light images from corrected cubes
        if write_aligned_nb:
            aligned_nb_outdir = outputdir_cubes + 'nb/'
            if not os.path.isdir(aligned_nb_outdir):
                os.makedirs(aligned_nb_outdir)
            narrowband(cube,
                       waverange[0],
                       waverange[1],
                       outfile=aligned_nb_outdir + 'nb_' +
                       cube.filename.split('/')[-1])
        ##########
    if varcubelist is not None:
        for i, cube in enumerate(varcubelist):
            try:
                thisnbw = WCS(nbimages[i].header)
            except:
                import pdb
                pdb.set_trace()
            thisnbdat = nbimages[i].data
            neww = change_coord_alignmax(refwcs,
                                         thisnbw,
                                         refdat,
                                         thisnbdat,
                                         range_mod=pixrange,
                                         range_ref=pixrange)
            cube.wcs.wcs.crval[0] = neww.wcs.crval[0]
            cube.wcs.wcs.crval[1] = neww.wcs.crval[1]
            cube.wcs.wcs.crpix[0] = neww.wcs.crpix[0]
            cube.wcs.wcs.crpix[1] = neww.wcs.crpix[1]
            if not os.path.isdir(outputdir_cubes):
                os.makedirs(outputdir_cubes)
            cube.write(outputdir_cubes + cube_prefix +
                       cube.filename.split('/')[-1])
    brightcoords = SkyCoord(neww.wcs.crval[0], neww.wcs.crval[1], unit='deg')
    return brightcoords
Пример #13
0
def addWcsRtModel(inp,
                  ref,
                  outfile,
                  spatial_scale_xy=[0.679, 0.290],
                  zgal=0.6942,
                  center=('12 36 19.811', '+62 12 51.831'),
                  PA=27):

    ### Load in the model file
    inpdat = fits.open(inp)
    rtcube = DataCube(inp, include_wcs=False)
    rtcube.wavelength = inpdat[2].data
    rtcube.data = inpdat[1].data
    wavearr = rtcube.wavelength

    ### Load in the reference file if necessary
    if not isinstance(ref, DataCube):
        refcube = DataCube(ref)
    else:
        refcube = inp
    refdat = refcube.data
    refwave = refcube.wavelength
    nbhdu = transform.narrowband(refcube, 4000., 5000.)
    refnb = nbhdu.data
    refwcs = WCS(nbhdu.header)

    ### Rearrange the cube and find brightest pixel
    newdat = np.transpose(rtcube.data, axes=[2, 1, 0])
    sumdat = np.sum(newdat, axis=0)
    maxdat = np.max(sumdat)
    brightmodpix = np.where(sumdat == maxdat)
    print(brightmodpix)

    ### Get the pixel scale in the spectral dimension
    diff = wavearr[1:] - wavearr[:-1]
    if not np.all(np.abs(diff - diff[0]) < 1e-3):
        import pdb
        pdb.set_trace()
        raise ValueError('Wavelength array not uniformly sampled')
    spectral_scale = diff[0]

    ### Set scale and reference position in model
    wave1 = wavearr[0] * (1. + zgal)
    spectral_scale *= (1. + zgal)

    ### Get the bright pixel from reference cube
    brightpix, brightcoords = utils.bright_pix_coords(refnb, refwcs)

    ### Create the new WCS
    newwcs = WCS(naxis=3)

    if center is not None:
        cencoords = SkyCoord(center[0], center[1], unit=(u.hourangle, u.deg))
    else:
        cencoords = brightcoords
    # coordinates are (y, x, lam) and '1' indexed in FITS files
    newwcs.wcs.crpix = np.array(
        [brightmodpix[1][0] + 1, brightmodpix[0][0] + 1, 1])
    newwcs.wcs.crval = np.array([cencoords.ra.deg, cencoords.dec.deg, wave1])
    newwcs.wcs.cdelt = np.array([
        spatial_scale_xy[0] / 3600., spatial_scale_xy[1] / 3600.,
        spectral_scale
    ])
    newwcs.wcs.cunit = ['deg', 'deg', 'Angstrom']
    newwcs.wcs.ctype = ('RA---TAN', 'DEC--TAN', 'VAC')
    rotangle = np.radians(PA)  # Assuming PA given in degrees
    psmat = np.array([[
        newwcs.wcs.cdelt[0] * np.cos(rotangle),
        -newwcs.wcs.cdelt[1] * np.sin(rotangle), 0.
    ],
                      [
                          newwcs.wcs.cdelt[0] * np.sin(rotangle),
                          newwcs.wcs.cdelt[1] * np.cos(rotangle), 0.
                      ], [0., 0., 1.]])
    newwcs.wcs.cd = psmat

    newhdu = newwcs.to_fits()
    newhdu[0].header['PC3_3'] = spectral_scale
    newhdu[0].data = newdat

    newhdu.writeto(outfile, overwrite=True)
Пример #14
0
def subtract_master_sky(scicubes, mastersky, suffix='mskysub.fits'):
    for i, sc in enumerate(scicubes):
        cube = DataCube(sc)
        cubedatsub = cube.data.transpose() - mastersky
        cube.data = cubedatsub.transpose()
        cube.write(sc.split('/')[-1][:-5] + '_' + suffix)