コード例 #1
0
ファイル: analysis_stack.py プロジェクト: aakepley/degas
def makeRadiusBins(galaxy, basemap, outDir, beam=15.0):
    '''
    Create bins for the data

    basemap: map used to create bins (SpectralCube Projection)
    
    outDir: directory to write output bin image

     Date        Programmer      Description of Changes
    ----------------------------------------------------------------------
    10/29/2020  Yiqing Song     Original Code
    12/3/2020   A.A. Kepley     Added more comments plus moved GCR map 
                                calculate up to other code.
    4/15/2021   A.A. Kepley     Changes bins to be beam width apart in radius.
    '''

    minrad = 0.0 + beam / 2.0
    maxrad = np.max(
        basemap).value + beam  # want to add one bin beyond to capture max.

    binedge = np.arange(minrad, maxrad, beam)
    binedge = np.insert(binedge, 0, 0)
    binedge = binedge * basemap.unit
    bins = np.digitize(basemap.value, binedge.value)

    binlabels = ['{0:1.2f}'.format(i) + ' arcsec' for i in binedge]

    # make bins map
    binmap = Projection(bins, wcs=basemap.wcs, header=basemap.header)
    binmap.write(os.path.join(outDir,
                              galaxy['NAME'].upper() + '_binsbyradius.fits'),
                 overwrite=True)

    return binmap, binedge, binlabels
コード例 #2
0
ファイル: analysis_stack.py プロジェクト: aakepley/degas
def mapLTIR(galaxy, mom0cut, regridDir, outDir):
    '''
    make LTIR map

    
    galaxy: line from degas_base.fits table with galaxy information

    mom0cut: S/N cut on mom0

    regridDir: input data directory with all regridded data

    outDir: output data directory

     Date        Programmer      Description of Changes
    ----------------------------------------------------------------------
    12/10/2020  A.A. Kepley      Original code based on mapStellar

    '''

    hdu = fits.open(
        os.path.join(regridDir,
                     galaxy['NAME'] + '_LTIR_gauss15_regrid.fits'))[0]

    data = hdu.data

    data[np.isnan(mom0cut)] = np.nan  #apply SN mask (SN >3)

    LTIRmap = Projection(data, header=hdu.header, wcs=WCS(hdu.header))
    LTIRmap.quicklook()

    plt.savefig(os.path.join(outDir, galaxy['NAME'] + '_LTIR.png'))
    plt.clf()
    plt.close()

    return LTIRmap
コード例 #3
0
ファイル: analysis_stack.py プロジェクト: aakepley/degas
def mapSFR(galaxy, mom0cut, regridDir, outDir):
    '''
    import sfr map from W4+FUV

     Date        Programmer      Description of Changes
    ----------------------------------------------------------------------
    10/29/2020  Yiqing Song     Original Code
    12/3/2020  A.A. Kepley     Added comments and clarified inputs
    '''

    sfrhdu = fits.open(
        os.path.join(regridDir,
                     galaxy['NAME'] + '_sfr_fuvw4_gauss15_regrid.fits'))[0]
    sfr = sfrhdu.data
    sfr[np.isnan(mom0cut)] = np.nan
    w = WCS(sfrhdu.header)

    ## TODO CHECK UNITS HERE
    sfrhdu.header[
        'BUNIT'] = 'MSUN/YR/KPC^2'  #might change when getting new files from Sarah
    sfrmap = Projection(sfr, header=sfrhdu.header, wcs=w)
    sfrmap.quicklook()

    # save plot of map
    plt.savefig(os.path.join(outDir, galaxy['NAME'] + '_sfr.png'))
    plt.clf()
    plt.close()

    return sfrmap
コード例 #4
0
def linear_combine(hires, lores,
                   highresextnum=0,
                   lowresextnum=0,
                   highresscalefactor=1.0,
                   lowresscalefactor=1.0,
                   lowresfwhm=None,
                   return_hdu=False,
                   return_regridded_lores=False,
                   match_units=True,
                   convolve=convolve_fft,
                  ):
    """
    Implement a simple linear combination following Faridani et al 2017
    """

    if isinstance(hires, str):
        proj_hi = Projection.from_hdu(fits.open(hires)[highresextnum])
    else:
        proj_hi = Projection.from_hdu(hires)

    if isinstance(hires, str):
        proj_lo = Projection.from_hdu(fits.open(lores)[lowresextnum])
    else:
        proj_lo = Projection.from_hdu(lores)

    if lowresfwhm is None:
        beam_low = proj_lo.beam
        lowresfwhm = beam_low.major
        log.info("Low-res FWHM: {0}".format(lowresfwhm))
    else:
        beam_low = Beam(major=lowresfwhm)

    if match_units:
        # After this step, the units of im_hi are some sort of surface brightness
        # unit equivalent to that specified in the high-resolution header's units
        # Note that this step does NOT preserve the values of im_lowraw and
        # header_lowraw from above
        # im_lowraw, header_low = match_flux_units(image=proj_lo.value,
        #                                          image_header=proj_lo.header.copy(),
        #                                          target_header=proj_hi.header)
        # proj_lo = Projection(im_lowraw, header=header_low)

        proj_lo = proj_lo.to(proj_hi.unit)

    proj_lo_regrid = proj_lo.reproject(proj_hi.header)

    missing_flux = proj_lo_regrid - proj_hi.convolve_to(beam_low)

    combo = missing_flux + proj_hi

    if return_hdu:
        combo_hdu = fits.PrimaryHDU(data=combo.real, header=proj_hi.header)
        combo = combo_hdu

    if return_regridded_lores:
        return combo, hdu_low
    else:
        return combo
コード例 #5
0
def test_feather_simple(plaw_test_data):

    orig_hdu, lowres_hdu, highres_hdu = plaw_test_data

    # HDU input
    combo = feather_simple(highres_hdu, lowres_hdu)

    # Projection input
    lowres_proj = Projection.from_hdu(lowres_hdu)
    highres_proj = Projection.from_hdu(highres_hdu)

    combo = feather_simple(highres_proj, lowres_proj)
コード例 #6
0
ファイル: analysis_stack.py プロジェクト: aakepley/degas
def mapGCR(galaxy, basemap):
    '''
    Create map of galactic radii

    Date        Programmer      Description of Changes
    ----------------------------------------------------------------------
    10/29/2020  Yiqing Song     Original Code
    12/03/2020  A.A. Kepley     Tweak to how input data is handled and 
                                added comments
    '''

    # get the data we need for the galaxy
    ra = galaxy['RA_DEG']
    dec = galaxy['DEC_DEG']
    inc = np.radians(galaxy['INCL_DEG'])
    pa = np.radians(galaxy['POSANG_DEG'])
    r25 = galaxy['R25_DEG'] * 3600.0  # arcsec
    Dmpc = galaxy['DIST_MPC']

    # get wcs
    w = basemap.wcs

    # get center
    x0, y0 = w.all_world2pix(ra, dec, 0, ra_dec_order=True)

    # get coordinates
    y = np.arange(0, np.shape(basemap)[0], 1)
    x = np.arange(0, np.shape(basemap)[1], 1)

    # create a 2d image of coordinates
    xx, yy = np.meshgrid(x, y)

    # calculate the radius in pixels
    xx_new = x0 + (xx - x0) * np.cos(pa) + (yy - y0) * np.sin(pa)
    yy_new = y0 - (xx - x0) * np.sin(pa) + (yy - y0) * np.cos(pa)
    R = np.sqrt((xx_new - x0)**2 / np.cos(inc)**2 + (yy_new - y0)**2)  #pixels

    # now convert from pixels to actual units
    head = basemap.header
    pxscale = np.radians(np.abs(head['CDELT1']))  #radian/pixel

    R_arcsec = np.degrees(
        R * pxscale) * 3600.0 * u.arcsec  # map of GCR in arcsec
    R_kpc = R * pxscale * Dmpc * 1000 * u.kpc  # map of GCR in kpc
    R_r25 = R_arcsec / r25  # map of GCR in units of R25

    Rarcsec_map = Projection(R_arcsec, header=head, wcs=w)
    Rkpc_map = Projection(R_kpc, header=head, wcs=w)
    Rr25_map = Projection(R_r25, header=head, wcs=w)

    # map of galactocentric radius in unit of kpc, arcmin, in r25
    return Rarcsec_map, Rkpc_map, Rr25_map
コード例 #7
0
ファイル: conftest.py プロジェクト: e-koch/uvcombine
def image_sz512as_pl1p5_fwhm2as_scale1as(tmp_path):

    pixel_scale = 1 * units.arcsec
    restfreq = 100 * units.GHz

    highres_major = 2 * units.arcsec

    # Generate input image
    input_hdu = generate_test_fits(imsize=512, powerlaw=1.5,
                                beamfwhm=highres_major,
                                pixel_scale=pixel_scale,
                                restfreq=restfreq,
                                brightness_unit=units.Jy / units.sr)

    input_fn = tmp_path / "input_image_sz512as_pl1.5_fwhm2as_scale1as.fits"
    input_hdu.writeto(input_fn, overwrite=True)

    input_proj = Projection.from_hdu(input_hdu).to(units.Jy / units.beam)

    # Make Interferometric image
    intf_data = interferometrically_observe_image(image=input_hdu.data,
                                                pixel_scale=pixel_scale,
                                                largest_angular_scale=40*units.arcsec,
                                                smallest_angular_scale=highres_major)[0].real
    intf_hdu = fits.PrimaryHDU(data=intf_data.value if hasattr(intf_data, "value") else intf_data,
                                header=input_hdu.header)
    intf_proj = Projection.from_hdu(intf_hdu).to(units.Jy / units.beam)
    intf_fn = tmp_path / "input_image_sz512as_pl1.5_fwhm2as_scale1as_intf2to40as.fits"
    intf_proj.write(intf_fn, overwrite=True)

    # Make SD image
    sd_header = input_hdu.header.copy()

    major = 15*units.arcsec
    # Eff SD diam (to compare with CASA in troubleshooting)

    sd_beam = Beam(major=major)
    sd_header.update(sd_beam.to_header_keywords())

    sd_fn = tmp_path / "input_image_sz512as_pl1.5_fwhm2as_scale1as_sd15as.fits"
    sd_data = singledish_observe_image(input_hdu.data,
                                    pixel_scale=pixel_scale,
                                    beam=sd_beam,
                                    boundary='wrap')

    sd_hdu = fits.PrimaryHDU(data=sd_data.value if hasattr(sd_data, "value") else sd_data,
                            header=sd_header)
    sd_hdu.header.update(sd_beam.to_header_keywords())
    sd_proj = Projection.from_hdu(sd_hdu).to(units.Jy / units.beam)
    sd_proj.write(sd_fn, overwrite=True)

    return tmp_path, input_fn, intf_fn, sd_fn
コード例 #8
0
ファイル: analysis_stack.py プロジェクト: aakepley/degas
def makeBins(galaxy, basemap, bintype, outDir):
    '''
    Create bins for the data

    basemap: map used to create bins (SpectralCube Projection)

    bintype: type of bins ('intensity','stellarmass', 'radius')
    
    outDir: directory to write output bin image

     Date        Programmer      Description of Changes
    ----------------------------------------------------------------------
    10/29/2020  Yiqing Song     Original Code
    12/3/2020   A.A. Kepley     Added more comments plus moved GCR map 
                                calculate up to other code.
    '''

    if bintype == 'intensity' or bintype == 'stellarmass':
        #Bin the basemap by brightness
        binnum = int(
            np.log(np.nanmax(basemap.value) / np.nanmin(basemap.value))) + 1
        binedge = np.nanmin(basemap.value) * np.logspace(
            0, binnum, num=binnum + 1,
            base=np.e)  #create bins based on dynamic range of mom0
        bins = np.digitize(
            basemap.value, binedge
        )  #this will automatically add an extra bin in the end for nan values
        binlabels = [""] + [
            '{0:1.2f}'.format(i) + basemap.unit.to_string() for i in binedge
        ]  #need to add units to stellarmass map!!
    elif bintype == 'radius':
        binnum = 5
        binedge = np.zeros(binnum + 1)
        binedge[1:] = np.logspace(-1, np.log10(0.5), num=binnum,
                                  base=10)  #create bins based on r25
        bins = np.digitize(
            basemap, binedge
        )  #this will automatically add an extra bin in the end for nan values
        binlabels = [""] + ['{0:1.2f}'.format(i) + 'R25' for i in binedge]
    else:
        raise Exception(
            "bintype should either be 'radius' or 'intensity' or 'stellarmass' "
        )
    # Blank NaN values
    bins[bins == len(binedge)] = 0
    # make bins map
    binmap = Projection(bins, wcs=basemap.wcs, header=basemap.header)
    binmap.write(os.path.join(
        outDir, galaxy['NAME'].upper() + '_binsby' + bintype + '.fits'),
                 overwrite=True)
    return binmap, binedge, binlabels
コード例 #9
0
def mapStellar(galaxy,mom0cut,plotdir='./',stellardatadir='./'):
    stellarhdu=fits.open(stellardatadir+galaxy+'_w1_stellarmass_regrid.fits')[0]
    starmask=fits.getdata(stellardatadir+galaxy+'_w1_gauss15_stars_regrid.fits')
    stellar=stellarhdu.data
    stellar[starmask==1.0]=np.nan
    stellar[np.isnan(mom0cut)]=np.nan
    w=WCS(stellarhdu.header)
    stellarhdu.header['BUNIT']='Msun/pc^2' #not the correct unit!!
    stellarmap=Projection(stellar,header=stellarhdu.header,wcs=w) 
    stellarmap.quicklook()
    plt.savefig(plotdir+galaxy+'_stellarmass.png')
    plt.clf()
    plt.close()
    return stellarmap
コード例 #10
0
def convert_and_reproject(name, template=None, unit=None, order=1):
    """
    Helper for moment1 hybrid routine. Reads in data, makes sure it is
    a projection, converts units, and reprojects as necessary.
    """

    # Ensure inputs are Projections
    if name is not None:
        if type(name) is Projection:
            data = name
        elif type(name) is str:
            hdu_list = fits.open(name)
            data = Projection.from_hdu(hdu_list[0])
        else:
            print("Input is not a string or a Projection")
            raise ValueError

        if unit is not None:
            data = data.to(unit)
        if template is not None:
            data = data.reproject(template.header, order=order)
    else:
        data = None

    return (data)
コード例 #11
0
def mapSFR(galaxy,mom0cut,plotdir='./',sfrdatadir='./'):
    sfrhdu=fits.open(sfrdatadir+galaxy+'_w4fuv_sfr_regrid.fits')[0]
    starmask_fuv=fits.getdata(sfrdatadir+galaxy+'_fuv_gauss15_stars_regrid.fits')
    starmask_nuv=fits.getdata(sfrdatadir+galaxy+'_nuv_gauss15_stars_regrid.fits')
    sfr=sfrhdu.data
    sfr[starmask_fuv==1.0]=np.nan #mask out stars from fuv and nuv
    sfr[starmask_nuv==1.0]=np.nan
    sfr[np.isnan(mom0cut)]=np.nan
    w=WCS(sfrhdu.header)
    sfrhdu.header['BUNIT']='MSUN/YR/KPC^2'  
    sfrmap=Projection(sfr,header=sfrhdu.header,wcs=w) 
    sfrmap.quicklook()
    plt.savefig(plotdir+galaxy+'_sfr.png')
    plt.clf()
    plt.close()
    return sfrmap
コード例 #12
0
ファイル: galaxytools.py プロジェクト: e-koch/galaxies
def sfr_get(gal,hdr=None):
    if isinstance(gal,Galaxy):
        name = gal.name.lower()
    elif isinstance(gal,str):
        name = gal.lower()
    else:
        raise ValueError("'gal' must be a str or galaxy!")

    if name=='m33':
        filename = fits.open('notphangsdata/cube.fits')[13]
    else:
        filename = 'phangsdata/sfr/'+name+'_sfr_fuvw4.fits'
    if os.path.isfile(filename):
        sfr_map = Projection.from_hdu(fits.open(filename))
    else:
        print('WARNING: No SFR map was found!')
        sfr_map = None
        return sfr_map
    
    if hdr!=None:
        sfr = sfr_map.reproject(hdr) # Msun/yr/kpc^2. See header.
                                     # https://www.aanda.org/articles/aa/pdf/2015/06/aa23518-14.pdf
    else:
        sfr = sfr_map
    return sfr
コード例 #13
0
ファイル: analysis_stack.py プロジェクト: aakepley/degas
def mapStellar(galaxy, mom0cut, regridDir, outDir):
    '''
    make stellarmass map

    
    galaxy: line from degas_base.fits table with galaxy information

    mom0cut: S/N cut on mom0

    regridDir: input data directory with all regridded data

    outDir: output data directory

     Date        Programmer      Description of Changes
    ----------------------------------------------------------------------
    10/29/2020  Yiqing Song     Original Code
    12/3/2020   A.A. Kepley     Added comments and clarified inputs

    '''

    # open the stellar mass

    ## TODO : NEED TO UPDATE WITH NEW ANCILLAR DATA FROM SARAH
    stellarhdu = fits.open(
        os.path.join(regridDir,
                     galaxy['NAME'] + '_mstar_gauss15_regrid.fits'))[0]

    stellar = stellarhdu.data
    #stellar[starmask==1.0]=np.nan #apply star mask ## AAK: I think I can skip this.
    stellar[np.isnan(mom0cut)] = np.nan  #apply SN mask (SN >3)
    w = WCS(stellarhdu.header)
    # stellarhdu.header['BUNIT']='Msun/pc^2' #not the correct unit!!  ## AAK: I think units are okay for the newdata

    stellarmap = Projection(stellar, header=stellarhdu.header, wcs=w)
    stellarmap.quicklook()

    plt.savefig(os.path.join(outDir, galaxy['NAME'] + '_stellarmass.png'))
    plt.clf()
    plt.close()

    return stellarmap
コード例 #14
0
def makeBins(galaxy, basemap,  bintype):
    if bintype=='intensity' or bintype=='stellarmass':
        #Bin the basemap by brightness
        binnum=int(np.log(np.nanmax(basemap.value)/np.nanmin(basemap.value)))+1
        binedge = np.nanmin(basemap.value)*np.logspace(0, binnum, num=binnum+1, base=np.e) #create bins based on dynamic range of mom0
        bins = np.digitize(basemap.value, binedge) #this will automatically add an extra bin in the end for nan values
        binlabels=[""]+['{0:1.2f}'.format(i)+basemap.unit.to_string() for i in binedge] #need to add units to stellarmass map!!
    elif bintype=='radius':
        R_arcmin, R_kpc, R_r25=mapGCR(galaxy,basemap) #can choose from 3 different  Rmaps
        binnum=5
        binedge = np.zeros(binnum+1)
        binedge[1:]=np.logspace(-1, np.log10(0.5), num=binnum,base=10)#create bins based on r25
        bins = np.digitize(R_r25, binedge) #this will automatically add an extra bin in the end for nan values
        binlabels=[""]+['{0:1.2f}'.format(i)+'R25' for i in binedge]
    else:
        raise Exception ("bintype should either be 'radius' or 'intensity' or 'stellarmass' ")
    # Blank NaN values
    bins[bins==len(binedge)] = 0 
    # make bins map 
    binmap=Projection(bins,wcs=basemap.wcs,header=basemap.header)
    binmap.write(datadir+galaxy.upper()+'_binsby'+bintype+'.fits', overwrite=True)
    return binmap, binedge, binlabels
コード例 #15
0
ファイル: test_input_types.py プロジェクト: e-koch/FilFinder
def test_SC_inputs():

    hdr['BUNIT'] = 'K'
    hdu = PrimaryHDU(img, header=hdr)

    proj = Projection.from_hdu(hdu)

    output = input_data(proj)

    npt.assert_equal(img, output["data"].value)
    assert output['data'].unit == u.K
    npt.assert_equal(proj.header, output["header"])

    slic = Slice.from_hdu(hdu)

    output = input_data(slic)

    npt.assert_equal(img, output["data"].value)
    assert output['data'].unit == u.K
    npt.assert_equal(slic.header, output["header"])
コード例 #16
0
ファイル: test_input_types.py プロジェクト: samdf96/FilFinder
def test_SC_inputs():

    hdr['BUNIT'] = 'K'
    hdu = PrimaryHDU(img, header=hdr)

    proj = Projection.from_hdu(hdu)

    output = input_data(proj)

    npt.assert_equal(img, output["data"].value)
    assert output['data'].unit == u.K
    npt.assert_equal(proj.header, output["header"])

    slic = Slice.from_hdu(hdu)

    output = input_data(slic)

    npt.assert_equal(img, output["data"].value)
    assert output['data'].unit == u.K
    npt.assert_equal(slic.header, output["header"])
コード例 #17
0
def test_pspec(plotname="pspec_rnoise_beamsmooth_apodizetukey.pdf",
               size=256,
               powerlaw=3.,
               run_kwargs={
                   'verbose': False,
                   'apodize_kernel': 'tukey'
               },
               plot_kwargs={'fit_color': 'black'},
               beam_smooth=True,
               pixel_scale=2 * u.arcsec,
               bmin=8.09 * u.arcsec,
               bmaj=10.01 * u.arcsec,
               bpa=-12.9 * u.deg,
               restfreq=1.4 * u.GHz,
               bunit=u.K):
    from spectral_cube import Projection
    from radio_beam import Beam

    rnoise_img = make_extended(size, powerlaw)
    # Create a FITS HDU
    rnoise_hdu = create_fits_hdu(rnoise_img, 2 * u.arcsec, 2 * u.arcsec,
                                 rnoise_img.shape, 1.4 * u.GHz, u.K)

    pspec = PowerSpectrum(rnoise_hdu)

    if beam_smooth:
        pencil_beam = Beam(0 * u.deg)
        rnoise_proj = Projection.from_hdu(rnoise_hdu).with_beam(pencil_beam)
        new_beam = Beam(bmaj, bmin, bpa)
        rnoise_conv = rnoise_proj.convolve_to(new_beam)

        # hdr = fits.Header(header)
        # rnoise_hdu = fits.PrimaryHDU(rnoise_img, header=hdr)
        pspec = PowerSpectrum(rnoise_conv)

    pspec.run(**run_kwargs)
    pspec.plot_fit(save_name=plotname, **plot_kwargs)

    return pspec
コード例 #18
0
    beamfwhm = 3 * u.arcsec
    imshape = rnoise_img.shape
    restfreq = 1.4 * u.GHz
    bunit = u.K

    plaw_hdu = create_fits_hdu(rnoise_img, pixel_scale, beamfwhm, imshape,
                               restfreq, bunit)

    pspec = PowerSpectrum(plaw_hdu)
    pspec.run(verbose=True, radial_pspec_kwargs={'binsize': 1.0},
              fit_kwargs={'weighted_fit': False}, fit_2D=False,
              low_cut=1. / (60 * u.pix),
              save_name=osjoin(fig_path, "rednoise_pspec_slope3.png"))

    pencil_beam = Beam(0 * u.deg)
    plaw_proj = Projection.from_hdu(plaw_hdu)
    plaw_proj = plaw_proj.with_beam(pencil_beam)

    new_beam = Beam(3 * plaw_hdu.header['CDELT2'] * u.deg)
    plaw_conv = plaw_proj.convolve_to(new_beam)

    plaw_conv.quicklook()
    plt.savefig('images/rednoise_slope3_img_smoothed.png')
    plt.close()

    pspec2 = PowerSpectrum(plaw_conv)
    pspec2.run(verbose=True, xunit=u.pix**-1, fit_2D=False,
               low_cut=0.025 / u.pix, high_cut=0.1 / u.pix,
               radial_pspec_kwargs={'binsize': 1.0},
               apodize_kernel='tukey')
    plt.axvline(np.log10(1 / 3.), color=col_pal[3], linewidth=8, alpha=0.8,
コード例 #19
0
ファイル: spitzer_plots.py プロジェクト: ALMA-IMF/reduction
        fig = show_fov_on_spitzer(**pfxs, fieldid=fieldid, spitzerpath='spitzer_datapath', contour_level={'B3':[100], 'B6': [100]}, mips=True)
        fig.savefig(f'mips_datapath/fov_plots/{fieldid}_field_of_view_plot_mips.png', bbox_inches='tight')
        fig = show_fov_on_spitzer(**pfxs, fieldid=fieldid, spitzerpath='spitzer_datapath', contour_level=contour_levels[fieldid], mips=True, zoom=2)
        fig.savefig(f'mips_datapath/fov_contour_plots/{fieldid}_field_of_view_contour_plot_mips.png', bbox_inches='tight', dpi=300)

        field = prefixes[fieldid]['finaliter_prefix_b3'].split("/")[0]
        for (line, band, spw, color) in (('n2hp', 'B3', 'spw0', 'cyan'), ('sio', 'B6', 'spw1', 'blue')):
            fn = f'{basepath}/moments/{field}/{field}_{band}_{spw}_12M_{spw}.JvM.image.pbcor.fits.{line}.m0.fits'
            #pbfn = f'{basepath}/{field}/{band}/linecubes_12m/{field}_{band}_{spw}_12M_{line}.pb'
            pbfn = f'{basepath}/{field}_{band}_{spw}_12M_{line}.pb'
            if os.path.exists(fn):
                print(line, band, spw, fn, pbfn)

                fh = fits.open(fn)
                pb = SpectralCube.read(pbfn, format='casa_image')
                pbv,_ = reproject.reproject_interp(pb[10].hdu, fh[0].header)

                # 10th channel is arbitrary but avoids edge channel
                data = fh[0].data * pbv

                m0 = Projection(data, wcs=wcs.WCS(fh[0].header))
                std = stats.mad_std(data, ignore_nan=True)
                levels = np.array([3, 5, 10, 20, 30])*std
                fig = show_contours_on_spitzer(image=m0, fieldid=fieldid, mips=True, spitzerpath='spitzer_datapath', contour_levels=levels, zoom=2, line=line, color=color)
                fig.savefig(f'mips_datapath/m0_contour_plots/{field}_{line}_contour_plot_mips.png', bbox_inches='tight', dpi=300)
                fig = show_contours_on_spitzer(image=m0, fieldid=fieldid, mips=False, spitzerpath='spitzer_datapath', contour_levels=levels, zoom=2, line=line, color=color)
                fig.savefig(f'spitzer_datapath/m0_contour_plots/{field}_{line}_contour_plot.png', bbox_inches='tight', dpi=300)
            else:
                print(f"{line, band, spw}: {fn} does not exist")
コード例 #20
0
from spectral_cube import SpectralCube, Projection

import paths
import files
import regions

import pylab as pl

regs = regions.read_ds9(paths.rpath('sio_masers.reg'))
v2maser = regs[2]

bluefile = paths.Fpath('SgrB2_N_SiO_blue_20to50kms.fits')
redfile = paths.Fpath('SgrB2_N_SiO_blue_77to100kms.fits')
if os.path.exists(bluefile):
    blue = Projection.from_hdu(fits.open(bluefile))
    red = Projection.from_hdu(fits.open(redfile))
else:

    siocube = (SpectralCube.read(
        '/Volumes/external/sgrb2/full_SgrB2N_spw0_lines_cutoutN_medsub.fits').
               with_spectral_unit(u.km / u.s,
                                  velocity_convention='radio',
                                  rest_value=217.10498 * u.GHz).spectral_slab(
                                      -200 * u.km / u.s, 250 * u.km / u.s))
    siocube.spectral_slab(0 * u.km / u.s, 120 * u.km / u.s).write(
        'SgrB2_N_SiO_medsub_cutout.fits', overwrite=True)

    blue = siocube.spectral_slab(20 * u.km / u.s, 50 * u.km / u.s).moment0()
    blue.write(bluefile, overwrite=True)
コード例 #21
0
        mask_hdu.data.sum(0) > 10)

    del maskint_hdu, mask_hdu

    # Load in PB plane to account for varying uncertainty
    pb = fits.open(fourteenA_HI_file_dict['PB'], mode='denywrite')
    pb_plane = pb[0].data[0].copy()
    del pb

    # Need peak temp and centroid maps.

    # peak_name = fourteenA_wEBHIS_HI_file_dict['PeakTemp']
    # peaktemp = Projection.from_hdu(fits.open(peak_name))

    vcent_name = fourteenA_wEBHIS_HI_file_dict['Moment1']
    vcent = Projection.from_hdu(fits.open(vcent_name)).to(u.km / u.s)

    noise_val = 0.72 * u.K

    # Set max number of gaussians to something ridiculous.
    # Just so we don't have a failure putting into the output array
    max_comp = 30

    err_map = noise_val / pb_plane

    params_name = fourteenA_HI_data_wEBHIS_path(
        "individ_multigaussian_gausspy_fits.fits", no_check=True)

    if run_fit:

        agd_kwargs = {
コード例 #22
0
def write_ew(cube,
             outfile=None,
             errorfile=None,
             rms=None,
             channel_correlation=None,
             overwrite=True,
             unit=None,
             return_products=True):
    """
    Write out linewidth (equivalent-width-based) map for a SpectralCube
    
    Keywords:
    ---------
    
    cube : SpectralCube
        (Masked) spectral cube to write a EW-based velocity dispersion map
    
    outfile : str
        File name of output file
        
    errorfile : str
        File name of map for the uncertainty
        
    rms : SpectralCube
        Root-mean-square estimate of the error.  This must have an estimate
        the noise level at all positions where there is signal, and only at 
        those positions.
        
    channel_correlation : np.array
        One-dimensional array containing the channel-to-channel 
        normalize correlation coefficients
        
    overwrite : bool
        Set to True (the default) to overwrite existing maps if present. 
        
    unit : astropy.Unit
        Preferred unit for moment masks
            
    return_products : bool
        Return products calculated in the map
    """

    maxmap = cube.max(axis=0)
    mom0 = cube.moment0()
    sigma_ew = mom0 / maxmap / np.sqrt(2 * np.pi)
    spaxis = cube.spectral_axis.value

    if errorfile is not None and rms is None:
        logger.error("Equivalent width error requested but no RMS provided")
    sigma_ewerr_projection = None
    if rms is not None:
        argmaxmap = cube.argmax(axis=0)
        rms_at_max = np.take_along_axis(rms.filled_data[:],
                                        argmaxmap[np.newaxis, :, :], 0).value

        sigma_ew_err = np.empty(sigma_ew.shape)
        sigma_ew_err.fill(np.nan)
        rms = rms.with_mask(cube._mask.include(), inherit_mask=False)
        dv = np.abs(spaxis[1] - spaxis[0])

        if channel_correlation is None:

            term1 = (np.nansum((rms.filled_data[:].value)**2, axis=0) * dv**2 /
                     (2 * np.pi * maxmap.value**2))
            term2 = (sigma_ew.value**2 - sigma_ew.value * dv /
                     np.sqrt(2 * np.pi)) * np.squeeze(rms_at_max)**2
            sigma_ew_err = (term1 + term2)**0.5

        else:
            yy, xx = np.where(np.isfinite(sigma_ew))
            for y, x in zip(yy, xx):
                slc = (slice(None), slice(y, y + 1,
                                          None), slice(x, x + 1, None))
                mask = np.squeeze(cube.mask.include(view=slc))
                index = np.where(mask)[0]
                rms_spec = rms.flattened(slc).value
                spec = cube.flattened(slc).value
                covar = build_covariance(
                    spectrum=spec,
                    rms=rms_spec,
                    channel_correlation=channel_correlation,
                    index=index)
                sigma_ew_err[y, x] = (
                    np.sum(covar) * dv**2 /
                    (2 * np.pi * maxmap[y, x].value**2) +
                    (sigma_ew[y, x].value**2 - sigma_ew[y, x].value * dv /
                     np.sqrt(2 * np.pi)) * rms_at_max[0, y, x]**2)**0.5

        sigma_ew_err = u.Quantity(sigma_ew_err,
                                  cube.spectral_axis.unit,
                                  copy=False)
        if unit is not None:
            sigma_ew_err = sigma_ew_err.to(unit)

        sigma_ewerr_projection = Projection(sigma_ew_err,
                                            wcs=sigma_ew.wcs,
                                            header=sigma_ew.header,
                                            meta=sigma_ew.meta)

        if outfile is not None:
            sigma_ewerr_projection = update_metadata(sigma_ewerr_projection,
                                                     cube,
                                                     error=True)
            writer(sigma_ewerr_projection, errorfile, overwrite=overwrite)
            # sigma_ewerr_projection.write(errorfile, overwrite=overwrite)

    # Do the conversion here to not mess up errors in units.
    if unit is not None:
        sigma_ew = sigma_ew.to(unit)
    if outfile is not None:
        sigma_ew = update_metadata(sigma_ew, cube)
        writer(sigma_ew, outfile, overwrite=overwrite)
        # sigma_ew.write(outfile, overwrite=True)

    if return_products and sigma_ewerr_projection is not None:
        return (sigma_ew, sigma_ewerr_projection)
    elif return_products and sigma_ewerr_projection is None:
        return (sigma_ew)
コード例 #23
0
def write_tmax(cubein,
               outfile=None,
               errorfile=None,
               rms=None,
               channel_correlation=None,
               overwrite=True,
               unit=None,
               window=None,
               return_products=True):
    """
    Write out Tmax map for a SpectralCube
    
    Keywords:
    ---------
    
    cube : SpectralCube
        (Masked) spectral cube to write a Tmax map
    
    outfile : str
        File name of output file
        
    errorfile : str
        File name of map for the uncertainty
        
    rms : SpectralCube
        Root-mean-square estimate of the error.  This must have an estimate
        the noise level at all positions where there is signal, and only at 
        those positions.
        
    channel_correlation : np.array
        One-dimensional array containing the channel-to-channel 
        normalize correlation coefficients
        
    overwrite : bool
        Set to True (the default) to overwrite existing maps if present. 
        
    unit : astropy.Unit
        Preferred unit for moment masks
        
    window : astropy.Quantity
        Spectral window over which the data should be smoothed
            
    return_products : bool
        Return products calculated in the map
    """

    # hack the mask to span the spectral range of the mask but lose spatial information.

    mask = cubein.get_mask_array()
    mask_spec = np.any(mask, axis=(1, 2))
    lo = np.min(np.where(mask_spec))
    hi = np.max(np.where(mask_spec))
    mask = np.zeros_like(mask, dtype='bool')
    mask[lo:hi, :, :] = True
    mask *= np.isfinite(cubein.unmasked_data[:])
    new_cube = cubein.with_mask(mask, inherit_mask=False)

    # spectral smoothing if desired

    if window is not None:
        window = u.Quantity(window)

        from astropy.convolution import Box1DKernel
        dv = channel_width(new_cube)
        nChan = (window / dv).to(u.dimensionless_unscaled).value
        if nChan > 1:
            cube = new_cube.spectral_smooth(Box1DKernel(nChan))
            rmsfac = 1 / np.sqrt(nChan)
        else:
            cube = new_cube
            rmsfac = 1.0
    else:
        cube = new_cube
        rmsfac = 1.0

    maxmap = cube.max(axis=0)

    if errorfile is not None and rms is None:
        logger.error("Tmax error requested but no RMS provided")

    if rms is not None:
        argmaxmap = cube.argmax(axis=0)
        rms = rms.with_mask(cube._mask.include(), inherit_mask=False)

        rms_at_max = np.take_along_axis(rms.filled_data[:],
                                        argmaxmap[np.newaxis, :, :], 0).value
        # rmsfac accounts for smoothing leading to reduction in rms
        # assuming channels are (nearly) independent
        rms_at_max = np.squeeze(rms_at_max) * rmsfac
        rms_at_max = u.Quantity(rms_at_max, cube.unit, copy=False)
        if unit is not None:
            rms_at_max = rms_at_max.to(unit)
        tmaxerr_projection = Projection(rms_at_max,
                                        wcs=maxmap.wcs,
                                        header=maxmap.header,
                                        meta=maxmap.meta)
        if errorfile is not None:
            tmaxerr_projection = update_metadata(tmaxerr_projection,
                                                 cube,
                                                 error=True)
            writer(tmaxerr_projection, errorfile, overwrite=overwrite)
            # tmaxerr_projection.write(errorfile, overwrite=overwrite)

    if unit is not None:
        maxmap = maxmap.to(unit)
    if outfile is not None:
        maxmap = update_metadata(maxmap, cube)
        writer(maxmap, outfile, overwrite=overwrite)
        # maxmap.write(outfile, overwrite=True)

    if return_products and tmaxerr_projection is not None:
        return (maxmap, tmaxerr_projection)
    elif return_products and tmaxerr_projection is None:
        return (maxmap)
コード例 #24
0
def write_moment2(cube,
                  rms=None,
                  channel_correlation=None,
                  outfile=None,
                  errorfile=None,
                  overwrite=True,
                  unit=None,
                  return_products=True):
    """
    Write out linewidth (moment2-based) map for a SpectralCube
    
    Keywords:
    ---------
    
    cube : SpectralCube
        (Masked) spectral cube to write a Moment 2 (velocity 
        dispersion) map
    
    outfile : str
        File name of output file
        
    errorfile : str
        File name of map for the uncertainty
        
    rms : SpectralCube
        Root-mean-square estimate of the error.  This must have an estimate
        the noise level at all positions where there is signal, and only at 
        those positions.
        
    channel_correlation : np.array
        One-dimensional array containing the channel-to-channel 
        normalize correlation coefficients
        
    overwrite : bool
        Set to True (the default) to overwrite existing maps if present. 
        
    unit : astropy.Unit
        Preferred unit for moment masks
    
    return_products : bool
        Return products calculated in the map
    """

    mom2 = cube.linewidth_sigma()
    spaxis = cube.spectral_axis.value

    if errorfile is not None and rms is None:
        logger.error("Moment 2 error requested but no RMS provided")

    if rms is not None:

        mom2err = np.empty(mom2.shape)
        mom2err.fill(np.nan)
        rms = rms.with_mask(cube._mask.include(), inherit_mask=False)
        valid = np.isfinite(mom2)

        if channel_correlation is None:
            sum_T = cube.sum(axis=0).value
            mom1 = cube.moment1().value
            vval = spaxis
            numer = np.nansum(rms.filled_data[:].value**2 * (
                (vval[:, np.newaxis, np.newaxis] - mom1[np.newaxis, :, :])**2 -
                (mom2.value)[np.newaxis, :, :]**2)**2,
                              axis=0)
            mom2err = (numer / sum_T**2)**0.25
        else:
            yy, xx = np.where(valid)
            for y, x in zip(yy, xx):
                slc = (slice(None), slice(y, y + 1,
                                          None), slice(x, x + 1, None))
                mask = np.squeeze(cube.mask.include(view=slc))
                index = np.where(mask)[0]

                rms_spec = rms.flattened(slc).value
                spec = cube.flattened(slc).value
                covar = build_covariance(
                    spectrum=spec,
                    rms=rms_spec,
                    channel_correlation=channel_correlation,
                    index=index)

                vval = spaxis[index]
                sum_T = np.sum(spec)
                sum_vT = np.sum(spec * vval)
                vbar = sum_vT / sum_T
                vdisp = (vval - vbar)**2
                wtvdisp = np.sum(spec * vdisp)
                # Dear future self: There is no crossterm (error term from
                # vbar) since dispersion is at a minimum around vbar
                jacobian = (vdisp / sum_T - wtvdisp / sum_T**2)
                mom2err[y, x] = np.dot(np.dot(jacobian[np.newaxis, :], covar),
                                       jacobian[:, np.newaxis])**0.25
        mom2err = u.Quantity(mom2err, cube.spectral_axis.unit, copy=False)
        if unit is not None:
            mom2err = mom2err.to(unit)
        mom2err_proj = Projection(mom2err,
                                  wcs=mom2.wcs,
                                  header=mom2.header,
                                  meta=mom2.meta)
        if errorfile is not None:
            mom2err_proj = update_metadata(mom2err_proj, cube, error=True)
            writer(mom2err_proj, errorfile, overwrite=overwrite)
            # mom2err_proj.write(errorfile, overwrite=overwrite)

    if unit is not None:
        mom2 = mom2.to(unit)
    if outfile is not None:
        mom2 = update_metadata(mom2, cube)
        writer(mom2, outfile, overwrite=overwrite)
        # mom2.write(outfile, overwrite=True)

    if return_products and mom2err_proj is not None:
        return (mom2, mom2err_proj)
    elif return_products and mom2err_proj is None:
        return (mom2)
コード例 #25
0
def write_moment1_hybrid(cube,
                         rms=None,
                         channel_correlation=None,
                         outfile=None,
                         errorfile=None,
                         overwrite=True,
                         unit=None,
                         return_products=True,
                         strict_mom1=None,
                         strict_emom1=None,
                         broad_mom1=None,
                         broad_emom1=None,
                         broad_mom0=None,
                         broad_emom0=None,
                         vfield_prior=None,
                         vfield_reject_thresh='30km/s',
                         mom0_thresh=2.0,
                         context=None):
    """Write out moment1 map using combination of other moment maps.
    This is a secondary moment that needs to be calculated in the
    context of other moments.
    
    Keywords:
    ---------
    
    cube : SpectralCube
        Included to keep same call signature but not used

    rms : SpectralCube
        Included to keep the same call signature but not used.
        
    channel_correlation : np.array
        Included to keep the same call signature but not used.
    
    outfile : str
        File name of output file
        
    errorfile : str
        File name of map for the uncertainty       

    overwrite : bool
        Set to True (the default) to overwrite existing maps if present. 
        
    unit : astropy.Unit
        Preferred unit for moment masks
        
    return_products : bool
        Return products calculated in the map

    strict_mom1 : str
        Moment tag for velocity field to be used as a high confidence map

    broad_mom1 : str
        Moment tag for velocity field for low confidence map

    broad_mom0 : str
        Moment tag to be used as an estimate of the signal for a S/N
        cut on where the broad_mom1 is valid.  Also finds a noise
        estimate of the same and uses this for the Noise component

    vfield_prior : str
        Moment tag for low-resolution prior map of velocity field

    vfield_reject_thresh : astropy.units.Quantity
        The maximum difference between the broad field and the prior
        field in units that can convert to that of the velocity field.

     mom0_thresh : float
        S/N threshold for using a broad_mom0 estimate in the map
    """

    # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # Read in and align the data and tuning parameters
    # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

    # The threshold for outlier rejection from the prior velocity field
    vfield_reject_thresh = u.Quantity(vfield_reject_thresh)

    # Read the high confidence velocity map and error
    mom1strict = convert_and_reproject(strict_mom1, unit=unit)
    mom1strict_error = convert_and_reproject(strict_emom1, unit=unit)

    # Read the intensity map to be used as a prior
    mom0broad = convert_and_reproject(broad_mom0, template=mom1strict)
    mom0broad_error = convert_and_reproject(broad_emom0, template=mom1strict)

    # This broad moment 1 map will be used as a candidate velocity field
    mom1broad = convert_and_reproject(broad_mom1,
                                      template=mom1strict,
                                      unit=unit)
    mom1broad_error = convert_and_reproject(broad_emom1,
                                            template=mom1strict,
                                            unit=unit)

    # This prior velocity field will be used to reject outliers
    mom1prior = convert_and_reproject(vfield_prior,
                                      template=mom1strict,
                                      unit=unit)

    # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # Hybridize the low and high confidence moment maps
    # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

    # Start with the high quality strict mask
    mom1hybrid = mom1strict.value

    # Candidate entries are places with a broad value
    valid_broad_mom1 = np.isfinite(mom1broad.value)

    # ... but not any strict value
    valid_broad_mom1[np.isfinite(mom1strict)] = False

    # If thresholding on intensity, apply that cut:
    if (mom0broad is not None):

        if (mom0broad_error is not None):
            # ... either as signal-to-noise
            valid_broad_mom1 *= \
                (mom0broad.value > (mom0_thresh* mom0broad_error.value))
        else:
            # ... or a simple intensity cut
            valid_broad_mom1 *= \
                (mom0broad.value > mom0_thresh)

    # Thresholding on offset from vfield prior
    if mom1prior is not None:

        valid_broad_mom1 = (
            valid_broad_mom1 *
            (np.abs(mom1broad - mom1prior) < vfield_reject_thresh))

    # Fill in the still-valid locations in the hybrid
    mom1hybrid[valid_broad_mom1] = (mom1broad.value)[valid_broad_mom1]
    mom1hybrid = u.Quantity(mom1hybrid, unit)
    if unit is not None:
        mom1hybrid = mom1hybrid.to(unit)

    # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # Attach to WCS and write to disk
    # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

    # Attach to WCS
    mom1hybrid_proj = Projection(mom1hybrid,
                                 wcs=mom1strict.wcs,
                                 header=mom1strict.header,
                                 meta=mom1strict.meta)

    # Write to disk
    if outfile is not None:
        writer(mom1hybrid_proj, outfile, overwrite=overwrite)
        # mom1hybrid_proj.write(outfile,
        #                      overwrite=overwrite)

    # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # Propagate errors from the input map to an error map
    # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

    mom1hybrid_error_proj = None

    print(type(mom1broad_error), type(mom1strict_error))

    if (type(mom1broad_error) is Projection
            and type(mom1strict_error) is Projection):

        mom1hybrid_error = mom1broad_error
        mom1hybrid_error[~np.isfinite(mom1hybrid.value)] = np.nan

        strictvals = np.isfinite(mom1strict_error.value)
        mom1hybrid_error[strictvals] = mom1strict_error[strictvals]

        if unit is not None:
            mom1hybrid_error = mom1hybrid_error.to(unit)

        mom1hybrid_error_proj = Projection(mom1hybrid_error,
                                           wcs=mom1strict.wcs,
                                           header=mom1strict.header,
                                           meta=mom1strict.meta)

        if errorfile is not None:
            mom1hybrid_error_proj = update_metadata(mom1hybrid_error_proj,
                                                    cube,
                                                    error=True)
            writer(mom1hybrid_error_proj, errorfile, overwrite=overwrite)
            # mom1hybrid_error_proj.write(errorfile,
            #                            overwrite=overwrite)

    # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # Return if requested
    # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

    if return_products:
        if mom1hybrid_error_proj is not None:
            return (mom1hybrid_proj, mom1hybrid_error_proj)
        elif mom1hybrid_error_proj is None:
            return (mom1hybrid_proj)

    return ()
コード例 #26
0
ファイル: test_casa.py プロジェクト: e-koch/uvcombine
def test_casafeather(image_sz512as_pl1p5_fwhm2as_scale1as, sdfactor,
                     lowpassfilterSD):

    tmp_path, input_fn, intf_fn, sd_fn = image_sz512as_pl1p5_fwhm2as_scale1as

    intf_hdu = fits.open(intf_fn)[0]
    sd_hdu = fits.open(sd_fn)[0]

    # Grab the rest frequency set in the header
    restfreq = (intf_hdu.header['RESTFRQ'] * units.Hz).to(units.GHz)

    # Feathering with CASA

    intf_fn_image = intf_fn.parent / intf_fn.name.replace(".fits", ".image")
    sd_fn_image = sd_fn.parent / sd_fn.name.replace(".fits", ".image")

    # CASA needs a posix string to work
    importfits(fitsimage=intf_fn.as_posix(),
               imagename=intf_fn_image.as_posix(),
               defaultaxes=True,
               defaultaxesvalues=['', '', f'{restfreq.value}GHz', 'I'])
    importfits(fitsimage=sd_fn.as_posix(),
               imagename=sd_fn_image.as_posix(),
               defaultaxes=True,
               defaultaxesvalues=['', '', f'{restfreq.value}GHz', 'I'])

    output_name = tmp_path / 'casafeathered.image'

    feather(
        imagename=output_name.as_posix(),
        highres=intf_fn_image.as_posix(),
        lowres=sd_fn_image.as_posix(),
        sdfactor=sdfactor,
        lowpassfiltersd=lowpassfilterSD,
    )

    # Right now read as spectralcube despite being a 2D image.
    casa_feather_proj = SpectralCube.read(output_name)[0]

    # Feathering with uvcombine
    feathered_hdu = feather_simple(hires=intf_hdu,
                                   lores=sd_hdu,
                                   lowresscalefactor=sdfactor,
                                   lowpassfilterSD=lowpassfilterSD,
                                   deconvSD=False,
                                   return_hdu=True)

    uvcomb_feather_proj = Projection.from_hdu(feathered_hdu)

    diff = (casa_feather_proj - uvcomb_feather_proj).value

    # By-hand checks. Keep so we remember.
    # print("Proof that we have exactly reimplemented CASA's feather: ")
    # print("((casa-uvcombine)**2 / casa**2).sum() = {0}"
    #       .format(((diff**2)/(casa_feather_proj.value**2)).sum()))
    # print("Maximum of abs(diff): {0}".format(np.abs(diff).max()))

    # Check for agreement within 0.05%
    if lowpassfilterSD:
        # assert np.abs(diff / casa_feather_proj.value).max() < 2e-4
        assert np.abs(np.median(diff / casa_feather_proj.value)) < 5e-4
    else:
        # assert np.abs(diff / casa_feather_proj.value).max() < 1e-7
        assert np.abs(np.median(diff / casa_feather_proj.value)) < 5e-4
コード例 #27
0
    for res_type in res_types:

        print("Resolution {}".format(res_type))

        if res_type == 'orig':
            filename = "{0}_{1}_mjysr_cutout.fits".format(gal.lower(), name)
        else:
            filename = "{0}_{1}_{2}_mjysr_cutout.fits".format(gal.lower(), name, res_type)

        if not os.path.exists(osjoin(data_path, gal, filename)):
            print("Could not find {}. Skipping".format(filename))
            continue

        hdu = fits.open(osjoin(data_path, gal, filename))
        proj = Projection.from_hdu(fits.PrimaryHDU(hdu[0].data.squeeze(),
                                                   hdu[0].header))
        # Attach equiv Gaussian beam
        # if res_type == 'orig':
        #     proj = proj.with_beam(names[name])

        # With and without 30 Dor
        for slice_name in lmc_mips24_slice:

            slicer = lmc_mips24_slice[slice_name]

            if res_type == 'orig':
                save_name = "{0}_{1}_{2}_mjysr.pspec.pkl".format(gal.lower(),
                                                                 name, slice_name)
            else:
                save_name = "{0}_{1}_{2}_{3}_mjysr.pspec.pkl".format(gal.lower(),
                                                                     name,
コード例 #28
0
ファイル: cube.py プロジェクト: heh15/Arp240
def convolve_projection(proj, newbeam, res_tol=0.0, min_coverage=0.8,
                        append_raw=False, verbose=False,
                        suppress_error=False):
    """
    Convolve a 2D image to a specified beam.

    Very similar to `convolve_cube()`, but this function deals with
    2D images (i.e., projections) rather than 3D cubes.

    Parameters
    ----------
    proj : ~spectral_cube.Projection object
        Input 2D image
    newbeam : radio_beam.Beam object
        Target beam to convolve to
    res_tol : float, optional
        Tolerance on the difference between input/output resolution
        By default, a convolution is performed on the input image
        whenever its native resolution is different from (sharper than)
        the target resolution. Use this keyword to specify a tolerance
        on resolution, within which no convolution will be performed.
        For example, res_tol=0.1 will allow a 10% tolerance.
    min_coverage : float or None, optional
        When the convolution meets NaN values or edges, the output is
        calculated based on beam-weighted average. This keyword specifies
        the minimum beam covering fraction of valid (np.finite) values.
        All pixels with less beam covering fraction will be assigned NaNs.
        Default is 80% beam covering fraction (min_coverage=0.8).
        If the user would rather use the interpolation strategy in
        `astropy.convolution.convolve_fft`, set this keyword to None.
        Note that the NaN pixels will be kept as NaN.
    append_raw : bool, optional
        Whether to append the raw convolved image and weight image
        Default is not to append.
    verbose : bool, optional
        Whether to print the detailed processing information in terminal
        Default is to not print.
    suppress_error : bool, optional
        Whether to suppress the error when convolution is unsuccessful
        Default is to not suppress.

    Returns
    -------
    outproj : Projection object or tuple
        Convolved 2D image (when append_raw=False), or a tuple
        comprising 3 images (when append_raw=True)
    """

    from functools import partial
    from astropy.convolution import convolve_fft

    if min_coverage is None:
        # Skip coverage check and preserve NaN values.
        # This uses the default interpolation strategy
        # implemented in 'astropy.convolution.convolve_fft'
        convolve_func = partial(convolve_fft, preserve_nan=True,
                                allow_huge=True, quiet=~verbose)
    else:
        # Do coverage check to determine the mask on the output
        convolve_func = partial(convolve_fft, nan_treatment='fill',
                                boundary='fill', fill_value=0.,
                                allow_huge=True, quiet=~verbose)

    if (res_tol > 0) and (newbeam.major != newbeam.minor):
        raise ValueError("You cannot specify a non-zero resolution "
                         "torelance if the target beam is not round")

    tol = newbeam.major * np.array([1-res_tol, 1+res_tol])
    if ((tol[0] < proj.beam.major < tol[1]) and
        (tol[0] < proj.beam.minor < tol[1])):
        if verbose:
            print("Native resolution within tolerance - "
                  "Copying original image...")
        my_append_raw = False
        newproj = proj.copy()
    else:
        if verbose:
            print("Convolving image...")
        try:
            convproj = proj.convolve_to(newbeam,
                                        convolve=convolve_func)
            if min_coverage is not None:
                # divide the raw convolved image by the weight image
                my_append_raw = True
                wtproj = Projection(
                    np.isfinite(proj.data).astype('float'),
                    wcs=proj.wcs, beam=proj.beam)
                wtproj = wtproj.convolve_to(newbeam,
                                            convolve=convolve_func)
                newproj = convproj / wtproj.hdu.data
                # mask all pixels w/ weight smaller than min_coverage
                threshold = min_coverage * u.dimensionless_unscaled
                newproj[wtproj < threshold] = np.nan
            else:
                my_append_raw = False
                newproj = convproj
        except ValueError as err:
            if suppress_error:
                return
            else:
                raise ValueError(
                    "Unsuccessful convolution: {}\nOld: {}\nNew: {}"
                    "".format(err, proj.beam, newbeam))

    if append_raw and my_append_raw:
        return newproj, convproj, wtproj
    else:
        return newproj
from astropy import wcs
from astropy.io import fits
from astropy import stats
import paths
import pylab as pl
from scipy.ndimage import map_coordinates
import scipy.signal
import reproject

from files import b3_hires_cont, b6_hires_cont, b7_hires_cont
from constants import source, extraction_path, origin, central_freqs

# vmap produced by stacked_line_search.py
vmap_name = paths.dpath('disk_velocity_map.fits')
hdu = fits.open(vmap_name)[0]
vmap = Projection.from_hdu(hdu)

b3beam = radio_beam.Beam.from_fits_header(
    fits.getheader(paths.dpath(b3_hires_cont)))

print("per-band continuum measurements in the spectral extraction aperture: ")
for ii, contfn in enumerate((b3_hires_cont, b6_hires_cont, b7_hires_cont)):
    band = contfn[14:16]

    conthdu = fits.open(paths.dpath(contfn))[0]

    ww = wcs.WCS(conthdu.header)

    #vmap_proj,_ = reproject.reproject_interp(vmap.hdu,
    #                                         ww,
    #                                         shape_out=conthdu.data.shape)
コード例 #30
0
ファイル: _testing_data.py プロジェクト: Astroua/TurbuStat
sc1 = SpectralCube(data=cube1, wcs=WCS(header))
mask = LazyMask(np.isfinite, sc1)
sc1 = sc1.with_mask(mask)
# Set the scale for the purposes of the tests
props1 = Moments(sc1, scale=0.003031065017916262 * u.Unit(""))
# props1.make_mask(mask=mask)
props1.make_moments()
props1.make_moment_errors()

dataset1 = props1.to_dict()

moment0_hdu1 = fits.PrimaryHDU(dataset1["moment0"][0],
                               header=dataset1["moment0"][1])

moment0_proj = Projection.from_hdu(moment0_hdu1)

##############################################################################

path2 = os.path.join(turb_path, "data/dataset2.npz")

dataset2 = np.load(path2)

cube2 = np.empty((500, 32, 32))

count = 0
for posn, kept in zip(*dataset2["channels"]):
    posn = int(posn)
    if kept:
        cube2[posn, :, :] = dataset2["cube"][count, :, :]
        count += 1
コード例 #31
0
    (r'Ratio Fit: $\sigma_{\rm CO} = 0.56\, \sigma_{\rm HI}$',
     r'$\sigma_{\rm CO} = \sigma_{\rm HI}$'),
    frameon=True,
    loc=(0.56, 0.6),
)

# plt.tight_layout()
plt.subplots_adjust(hspace=0.03, wspace=0.03)

plt.savefig(osjoin(fig_path, "sigma_HI_vs_H2_w_fit_cornerplot.png"))
plt.savefig(osjoin(fig_path, "sigma_HI_vs_H2_w_fit_cornerplot.pdf"))
plt.close()

# What does this relation look like for line widths from the second moment
co_lwidth = Projection.from_hdu(
    fits.open(
        iram_co21_14B088_data_path("m33.co21_iram.14B-088_HI.lwidth.fits"))[0])
hi_lwidth = Projection.from_hdu(
    fits.open(fourteenB_wGBT_HI_file_dict['LWidth'])[0])

co_lwidth_vals = co_lwidth.value[tab['ypts'][good_pts],
                                 tab['xpts'][good_pts]] / 1000.
hi_lwidth_vals = hi_lwidth.value[tab['ypts'][good_pts],
                                 tab['xpts'][good_pts]] / 1000.

# How bad is the relation between the 2nd moment line widths

hist2d(hi_lwidth_vals, co_lwidth_vals, bins=13, data_kwargs={"alpha": 0.5})
plt.plot([4, 16], [4. * slope_ratio, 16. * slope_ratio],
         '--',
         color=sb.color_palette()[1],
コード例 #32
0
def write_vquad(cubein,
                outfile=None,
                errorfile=None,
                rms=None,
                channel_correlation=None,
                overwrite=True,
                unit=None,
                window=None,
                maxshift=0.5,
                return_products=True):
    """
    Write out velocity map at max brightness temp for a 
    SpectralCube using the quadratic peak interpolation
    
    Keywords:
    ---------
    
    cube : SpectralCube
        (Masked) spectral cube to write a Vmax map
    
    outfile : str
        File name of output file
        
    errorfile : str
        File name of map for the uncertainty
        
    rms : SpectralCube
        Root-mean-square estimate of the error.  This must have an estimate
        the noise level at all positions where there is signal, and only at 
        those positions.
        
    channel_correlation : np.array
        One-dimensional array containing the channel-to-channel 
        normalize correlation coefficients
        
    overwrite : bool
        Set to True (the default) to overwrite existing maps if present. 
        
    unit : astropy.Unit
        Preferred unit for moment masks
    
    window : astropy.Quantity
        Spectral window over which the data should be smoothed
    
    maxshift : np.float
        Maximum number of channels that the algorithm can shift the 
        peak estimator (default = 0.5).  Set to None to suppress clipping.
    
    return_products : bool
        Return products calculated in the map
    """

    from scipy.interpolate import interp1d

    if type(window) is u.Quantity:
        from astropy.convolution import Box1DKernel
        dv = channel_width(cubein)
        nChan = (window / dv).to(u.dimensionless_unscaled).value
        if nChan > 1:
            cube = cubein.spectral_smooth(Box1DKernel(nChan))
        else:
            cube = cubein
    else:
        cube = cubein

    spaxis = cube.spectral_axis.value
    pixinterp = interp1d(np.arange(spaxis.size), spaxis)
    maxmap = cube.max(axis=0)
    argmaxmap = cube.argmax(axis=0)
    argmaxmap = np.clip(argmaxmap, 1, cube.shape[0] - 2)
    Tup = np.take_along_axis(cube.filled_data[:],
                             argmaxmap[np.newaxis, :, :] + 1, 0).value
    Tdown = np.take_along_axis(cube.filled_data[:],
                               argmaxmap[np.newaxis, :, :] - 1, 0).value
    Tup = np.squeeze(np.nan_to_num(Tup))
    Tup[Tup < 0] = 0
    Tdown = np.squeeze(np.nan_to_num(Tdown))
    Tdown[Tdown < 0] = 0

    delta = -1 * ((Tup - Tdown) / (Tup + Tdown - 2 * maxmap.value))
    if maxshift is not None:
        delta = np.clip(delta, -maxshift, maxshift)
    peakchan = argmaxmap + delta

    vmaxmap = np.empty(maxmap.shape)
    vmaxmap.fill(np.nan)
    good = np.isfinite(maxmap)
    vmaxmap[good] = u.Quantity(pixinterp(peakchan[good]), unit)

    vmaxmap[~np.isfinite(maxmap)] = np.nan

    if errorfile is not None and rms is None:
        logger.error("Vquad error requested but no RMS provided")

    if rms is not None:
        rms = rms.with_mask(cube._mask.include(), inherit_mask=False)

        dv = channel_width(cube)
        RMSup = np.take_along_axis(rms.filled_data[:],
                                   argmaxmap[np.newaxis, :, :] + 1, 0).value
        RMSdown = np.take_along_axis(rms.filled_data[:],
                                     argmaxmap[np.newaxis, :, :] - 1, 0).value
        RMSmax = np.take_along_axis(rms.filled_data[:],
                                    argmaxmap[np.newaxis, :, :], 0).value
        denom = (Tup + Tdown - 2 * maxmap.value)
        j1 = (1 / denom - (Tup - Tdown) / denom**2)
        j2 = (2 * (Tup - Tdown) / denom**2)
        j3 = (-1 / denom - (Tup - Tdown) / denom**2)
        jacobian = np.r_[j1[np.newaxis, :, :], j2[np.newaxis, :, :],
                         j3[np.newaxis, :, :]]
        if ((channel_correlation is None) or len(channel_correlation) == 1):
            covar = np.r_[RMSup, RMSmax, RMSdown]
            covar = covar**2
            error = np.einsum('i...,i...', jacobian**2, covar)
        else:
            if len(channel_correlation) == 2:
                ccor = np.r_[channel_correlation, np.array([0])]
            else:
                ccor = channel_correlation[0:3]
            corrmat = ccor[np.array([[0, 1, 2], [1, 0, 1], [2, 1, 0]])]
            rmsvec = np.r_[RMSup, RMSmax, RMSdown]
            # They never should have taught me how to do this.
            covar = np.einsum('ij,ilm,jlm->ijlm', corrmat, rmsvec, rmsvec)
            error = np.einsum('ilm,jlm,ijlm->lm', jacobian, jacobian, covar)
        if maxshift is not None:
            error = np.clip(error, -maxshift, maxshift)
        vquaderr = error * dv
        if unit is not None:
            vquaderr = vquaderr.to(unit)

        vquaderr_projection = Projection(vquaderr,
                                         wcs=maxmap.wcs,
                                         header=maxmap.header,
                                         meta=maxmap.meta)
        if errorfile is not None:
            vquaderr_projection = update_metadata(vquaderr_projection,
                                                  cube,
                                                  error=True)
            writer(vquaderr_projection, errorfile, overwrite=overwrite)
            # vquaderr_projection.write(errorfile, overwrite=overwrite)

    vmaxmap = u.Quantity(vmaxmap, cube.spectral_axis.unit)
    if unit is not None:
        vmaxmap = vmaxmap.to(unit)
    vmaxmap_projection = Projection(vmaxmap,
                                    wcs=maxmap.wcs,
                                    header=maxmap.header,
                                    meta=maxmap.meta)
    if outfile is not None:
        vmaxmap_projection = update_metadata(vmaxmap_projection, cube)
        writer(vmaxmap_projection, outfile, overwrite=overwrite)
        # vmaxmap_projection.write(outfile, overwrite=overwrite)

    if return_products and vquaderr_projection is not None:
        return (vmaxmap_projection, vquaderr_projection)
    elif return_products and vquaderr_projection is None:
        return (vmaxmap_projection)
コード例 #33
0
    for gal in gals:

        dist = gals[gal]

        # Load in the dust column density maps to set the allowed
        # spatial region

        filename_coldens = glob(
            osjoin(data_path, gal, "*dust.surface.density*.fits"))

        hdu_coldens = fits.open(filename_coldens[0])

        pad_size = 0.5 * u.arcmin

        proj_coldens = Projection.from_hdu(
            fits.PrimaryHDU(hdu_coldens[0].data[0].squeeze(),
                            hdu_coldens[0].header))

        # Get minimal size
        proj_coldens = proj_coldens[nd.find_objects(
            np.isfinite(proj_coldens))[0]]

        # Get spatial extents.
        # NOTE: extrema for 2D objects broken in spectral-cube! Need to fix...
        lat, lon = proj_coldens.spatial_coordinate_map
        lat_min = lat.min() - pad_size
        lat_max = lat.max() + pad_size
        lon_min = lon.min() - pad_size
        lon_max = lon.max() + pad_size

        def spat_mask_maker(lat_map, lon_map):
コード例 #34
0
def write_moment0(cube,
                  rms=None,
                  channel_correlation=None,
                  outfile=None,
                  errorfile=None,
                  overwrite=True,
                  unit=None,
                  include_limits=True,
                  line_width=10 * u.km / u.s,
                  return_products=True):
    """Write out moment0 map for a SpectralCube
    
    Keywords:
    ---------
    
    cube : SpectralCube
        (Masked) spectral cube to write a moment0 map
    
    outfile : str
        File name of output file
        
    errorfile : str
        File name of map for the uncertainty
        
    rms : SpectralCube
        Root-mean-square estimate of the error.  This must have an estimate
        the noise level at all positions where there is signal, and only at 
        those positions.
        
    channel_correlation : np.array
        One-dimensional array containing the channel-to-channel 
        normalize correlation coefficients
        
    overwrite : bool
        Set to True (the default) to overwrite existing maps if present. 
        
    unit : astropy.Unit
        Preferred unit for moment masks
    
    include_limits : bool
        If true: For masked lines of sight inside the data, set the
        moment0 value to 0 and the error to a value of 1sigma over
        line_width as specified below.

    line_width : astropy.Quantity
        Assumed line width for moment0 upper limit.  Default = 10 km/s

    return_products : bool
        Return products calculated in the map

    """

    # Spectral cube collapse routine. Applies the masked, automatically
    mom0 = cube.moment0()
    valid = np.isfinite(mom0)
    if include_limits:
        observed = np.any(np.isfinite(cube._data), axis=0)
        mom0[np.logical_and(np.isnan(mom0), observed)] = 0.0

    # Handle the error.
    mom0err_proj = None

    if errorfile is not None and rms is None:
        logger.error("Moment 0 error requested but no RMS provided")

    if rms is not None:
        # Initialize the error map
        mom0err = np.empty(mom0.shape)
        mom0err.fill(np.nan)

        # Note the channel width
        dv = channel_width(cube)
        if include_limits:
            rmsmed = np.nanmedian(rms.filled_data[:].value, axis=0)
            mom0err[observed] = (rmsmed[observed] * (np.abs(
                line_width / dv).to(u.dimensionless_unscaled).value)**0.5)

        # Make a masked version of the noise cube
        rms = rms.with_mask(cube._mask.include(), inherit_mask=False)

        if channel_correlation is None:
            sumofsq = (rms * rms).sum(axis=0)
            mom0err[valid] = np.sqrt(sumofsq[valid])
        else:
            # Iterates over the cube one ray at a time
            yy, xx = np.where(valid)
            for y, x in zip(yy, xx):
                slc = (slice(None), slice(y, y + 1,
                                          None), slice(x, x + 1, None))
                mask = np.squeeze(cube.mask.include(view=slc))
                index = np.where(mask)[0]

                # One dimensional versions of the data and noise
                rms_spec = rms.flattened(slc).value
                spec = cube.flattened(slc).value

                # Build a covariance matrix given the channel correlation
                covar = build_covariance(
                    spectrum=spec,
                    rms=rms_spec,
                    channel_correlation=channel_correlation,
                    index=index)

                # Collapse the covariance matrix into an integrated moment map
                mom0err[y, x] = (np.sum(covar))**0.5

        # Multiply by the channel width and assign correct units
        mom0err = u.Quantity(mom0err * dv.value,
                             cube.unit * dv.unit,
                             copy=False)

        # Convert units if request
        if unit is not None:
            mom0err = mom0err.to(unit)

        # Convert from an array into a spectral-cube projection that
        # shares metadata with the moment map
        mom0err_proj = Projection(mom0err,
                                  wcs=mom0.wcs,
                                  header=mom0.header,
                                  meta=mom0.meta)

        # Write to disk if requested
        if errorfile is not None:
            mom0err_proj = update_metadata(mom0err_proj, cube, error=True)
            writer(mom0err_proj, errorfile, overwrite=overwrite)
            # mom0err_proj.write(errorfile, overwrite=overwrite)
    else:
        mom0err_proj = None

    # Convert units if requested
    if unit is not None:
        mom0 = mom0.to(unit)

    # If requested, write to disk
    if outfile is not None:
        mom0 = update_metadata(mom0, cube)
        writer(mom0, outfile, overwrite=overwrite)
        # mom0.write(outfile, overwrite=overwrite)

    # If requested, return
    if return_products:
        return (mom0, mom0err_proj)