Example #1
0
def moment1_error(cube, scale, axis=0, how='auto', moment0=None, moment1=None):
    '''
    Compute the first moment error.

    Parameters
    ----------
    cube : SpectralCube
        Data cube.
    scale : SpectralCube or `~astropy.units.Quantity`
        The noise level in the data, either as a single value (with the same
        units as the cube) or a SpectralCube of noise values.
    axis : int
        Axis to compute moment over.
    how : {'auto', 'cube', 'slice'}, optional
        The computational method to use.

    Returns
    -------
    moment1_err :  `~spectral_cube.lower_dimensional_structures.Projection`

    '''

    if how == "auto":
        how = iterator_strategy(cube, 0)

        if how == "ray":
            warn("Automatically selected 'ray' which isn't implemented. Using"
                 " 'slice' instead.")
            how = 'slice'

    # Compute moments if they aren't given.
    if moment0 is None:
        moment0 = cube.moment0(how=how, axis=axis)
    if moment1 is None:
        moment1 = cube.moment1(how=how, axis=axis)

    # Remove velocity offset from centroid to match cube._pix_cen
    # Requires converting to a Quantity
    moment1 = u.Quantity(moment1)
    moment1 -= cube.spectral_axis[0]

    if how == "cube":
        moment1_err = _cube1(cube, axis, scale, moment0, moment1)
    elif how == "slice":
        moment1_err = _slice1(cube, axis, scale, moment0, moment1)
    else:
        raise ValueError("how must be 'cube' or 'slice'.")

    meta = {'moment_order': 1, 'moment_axis': axis, 'moment_method': how}

    cube_meta = cube.meta.copy()
    meta.update(cube_meta)

    new_wcs = drop_axis(cube._wcs, np2wcs[axis])

    return Projection(moment1_err,
                      copy=False,
                      wcs=new_wcs,
                      meta=meta,
                      header=cube._nowcs_header)
Example #2
0
def test_single_gray_hole():
    one_gray_hole = add_holes((200, 200), hole_level=100, nholes=1)
    test_gray_hole = Projection(one_gray_hole, wcs=wcs.WCS())

    test_bubble = BubbleFinder2D(test_gray_hole,
                                 beam=Beam(10),
                                 channel=0,
                                 sigma=40)
    test_bubble.multiscale_bubblefind(edge_find=False)
def load_projection(filename):
    from astropy import wcs
    from astropy.io import fits
    from spectral_cube.lower_dimensional_structures import Projection

    fh = fits.open(filename)

    return Projection(value=fh[0].data,
                      header=fh[0].header,
                      wcs=wcs.WCS(fh[0].header),
                      unit=u.Unit(fh[0].header['BUNIT']),
                     )
def get_mom0(fn,
             vrange=[51, 60] * u.km / u.s,
             exclude_vrange=[40, 75] * u.km / u.s,
             percentile=30,
             iterate=True):
    savename = paths.dpath(
        os.path.join(
            os.path.split(fn)[0], 'moments',
            os.path.split(fn)[1].replace(".fits", "_p30sub.fits")))
    if os.path.exists(savename):
        print("Loading {0} from disk".format(savename))
        fh = fits.open(savename)

        m0 = Projection(
            value=fh[0].data,
            header=fh[0].header,
            wcs=wcs.WCS(fh[0].header),
            unit=u.Unit(fh[0].header['BUNIT']),
        )

    else:
        print("Computing {0} from analysis of {1}".format(savename, fn))
        cube = SpectralCube.read(fn)
        #bm = cube.beams[0]
        #jtok = bm.jtok(cube.wcs.wcs.restfrq*u.Hz)

        slab = cube.spectral_slab(*vrange)
        cube.beam_threshold = 1
        #contguess = cube.spectral_slab(0*u.km/u.s, 40*u.km/u.s).percentile(50, axis=0)
        #contguess = cube.spectral_slab(70*u.km/u.s, 100*u.km/u.s).percentile(50, axis=0)
        mask = (cube.spectral_axis < exclude_vrange[0]) | (cube.spectral_axis >
                                                           exclude_vrange[1])
        masked_cube = cube.with_mask(mask[:, None, None])
        try:
            log.info("Continuum measurement.")
            contguess = masked_cube.percentile(percentile,
                                               axis=0,
                                               iterate_rays=iterate,
                                               progressbar=iterate)
        except ValueError as ex:
            print("skipping {0}".format(fn))
            print(ex)
            raise
        log.info("Subtract the continuum")
        slabsub = (slab - contguess)
        slabsub.beam_threshold = 0.25
        log.info("Compute moment 0")
        m0 = slabsub.moment0()
        log.info("Save results to {0}".format(savename))
        m0.hdu.writeto(savename)

    return m0
Example #5
0
def test_gauss_hole():
    one_gauss_hole, params = add_gaussian_holes(np.ones((200, 200)),
                                                nholes=1,
                                                return_info=True)
    test_gauss_hole = Projection(one_gauss_hole, wcs=wcs.WCS())

    test_bubble = BubbleFinder2D(test_gauss_hole,
                                 beam=Beam(10),
                                 channel=0,
                                 sigma=0.05)
    test_bubble.multiscale_bubblefind(edge_find=True)

    test_bubble.visualize_regions(edges=True)
def moment0_error(cube, scale, axis=0, how='auto'):
    '''
    Compute the zeroth moment error.

    Parameters
    ----------
    cube : SpectralCube
        Data cube.
    scale : SpectralCube or `~astropy.units.Quantity`
        The noise level in the data, either as a single value (with the same
        units as the cube) or a SpectralCube of noise values.
    axis : int
        Axis to compute moment over.
    how : {'auto', 'cube', 'slice'}, optional
        The computational method to use.

    Returns
    -------
    moment0 :  `~spectral_cube.lower_dimensional_structures.Projection`

    '''

    if how == "auto":
        how = iterator_strategy(cube, 0)

        if how == "ray":
            warn("Automatically selected 'ray' which isn't implemented. Using"
                 " 'slice' instead.")
            how = 'slice'

    if how == "cube":
        moment0_err = _cube0(cube, axis, scale)
    elif how == "slice":
        moment0_err = _slice0(cube, axis, scale)
    else:
        raise ValueError("how must be 'cube' or 'slice'.")

    # Multiply by spectral unit
    moment0_err *= cube.spectral_axis.unit

    meta = {'moment_order': 0,
            'moment_axis': axis,
            'moment_method': how}

    cube_meta = cube.meta.copy()
    meta.update(cube_meta)

    new_wcs = drop_axis(cube._wcs, np2wcs[axis])

    return Projection(moment0_err, copy=False, wcs=new_wcs, meta=meta,
                      header=cube._nowcs_header)
Example #7
0
def test_multiple_shell():
    yy, xx = np.mgrid[-200:200, -200:200]

    beam = Beam(10)

    clean_model = shell_model(amp=1.0, ring_small=None, ratio=1.05)(yy, xx)

    amp = clean_model.max()
    sigma = 0.25 * amp

    noisy_model = clean_model + sigma * np.random.random(yy.shape)
    # smooth_model = convolve_fft(noisy_model, beam.as_kernel(1))

    model = Projection(noisy_model, wcs=wcs.WCS())

    test_bubble = BubbleFinder2D(model, beam=beam, channel=0, sigma=sigma)
    test_bubble.multiscale_bubblefind(edge_find=True)

    ax = test_bubble.visualize_regions(edges=True, show=False)
    ax.contour(model > 3 * sigma, colors='c')

    print(test_bubble.region_params)
Example #8
0
def test_random_gray_holes():
    np.random.seed(375467546)
    gray_holes = add_holes((500, 500),
                           hole_level=100,
                           nholes=40,
                           max_corr=0.1,
                           rad_max=40)
    test_gray_holes = Projection(gray_holes, wcs=wcs.WCS())

    scales = 3 * np.arange(1, 8, np.sqrt(2))

    test_bubble = BubbleFinder2D(test_gray_holes,
                                 beam=Beam(10),
                                 sigma=10,
                                 channel=0,
                                 scales=scales)
    test_bubble.multiscale_bubblefind(edge_find=True, nsig=3, overlap_frac=0.6)

    test_bubble.visualize_regions(edges=True)

    # print(test_bubble.region_params)

    return test_bubble
#         argmax = np.argmax(medfilt(arr, smooth_size))
#         return cube.spectral_axis[argmax]

#     return cube.apply_function(peak_velocity, axis=0, projection=True,
#                                unit=cube.spectral_axis.unit)

def peak_velocity(inputs):

    y, x = inputs
    smooth_size = 31
    argmax = np.argmax(medfilt(subcube[:, y, x].value, smooth_size))
    return subcube.spectral_axis[argmax], y, x


peakvels = Projection(np.zeros(subcube.shape[1:]),
                      wcs=cube.wcs.celestial,
                      unit=cube.spectral_axis.unit)

posns = np.where(subcube.mask.include().sum(0) > 0)

pool = Pool(6)
output = pool.map(peak_velocity, izip(*posns))

pool.close()
pool.join()

for out in output:
    peakvels[out[1], out[2]] = out[0]

peakvels[peakvels == 0.0 * u.m / u.s] = np.NaN * u.m / u.s
def calc_physics(ra=None,
                 dec=None,
                 r=0.17 * u.pc,
                 dr=0.05 * u.pc,
                 vexp=4 * u.km / u.s,
                 v0=14 * u.km / u.s,
                 cube_12co=None,
                 cube_13co=None,
                 dist=414 * u.pc,
                 snr_cutoff=5.,
                 shell_snr_cutoff=3.,
                 shell=True,
                 plot=False,
                 linewidth_mode='fwhm',
                 average_Tex=True):
    """
    shell_snr_cutoff is the sigma cutoff for extracting the shell
    voxels.
    """
    #print(cube_12co.header['CDELT3'])
    from spectral_cube.lower_dimensional_structures import Projection

    pix_size = (cube_12co.header['CDELT2'] * u.deg).to(u.arcsec)
    vstep = (cube_12co.header['CDELT3'] * (u.m / u.s)).to(u.km / u.s)

    if shell:
        model_pars = {
            'dist': dist,  # pc
            'pix_size': pix_size,  # arcsec
            'vstep': vstep,  # km/s
            'acen': ra.to(u.deg),  # deg
            'dcen': dec.to(u.deg),  # deg
            'thickness': 0.0,  # pc
            'fwhm': 0.0,  # km/s
            'beta': 0.0,  # spectral index
            'R': r,  # pc
            'dr': dr,  # pc
            'vexp': vexp,  # km/s
            'depth_offset': 0.0,  # pc
            'vel_offset': 0.0,  # km/s
            'v0': v0,  # km/s
            'ignore_cloud': 1,  #Ignore cloud.
            'method': 'sample',
            'write_fits': False,
            'samples_per_voxel': 27
        }

        #Extract 12co shell voxels using model.
        model_cube = SpectralCube.read(shell_model.ppv_model(**model_pars))
        #shell_masked, shell_mask = extract_shell(
        #    cube_file=cube_12co, model_pars=model_pars, return_mask=True)
        #Extract subcubes with same ra/dec range as shell voxel cube, but
        #full velocity range.
        subcube_shell_12co = cube_12co.subcube(model_cube.longitude_extrema[1],
                                               model_cube.longitude_extrema[0],
                                               model_cube.latitude_extrema[0],
                                               model_cube.latitude_extrema[1])
        subcube_shell_13co = cube_13co.subcube(model_cube.longitude_extrema[1],
                                               model_cube.longitude_extrema[0],
                                               model_cube.latitude_extrema[0],
                                               model_cube.latitude_extrema[1])
        #print(subcube_shell_12co, subcube_shell_13co, model_cube)
        if plot:
            plt.figure()
            plt.subplot(131)
            plt.imshow(subcube_shell_12co.moment0().data)
            plt.subplot(132)
            plt.imshow(subcube_shell_13co.moment0().data)
            plt.subplot(133)
            plt.imshow(model_cube.moment0().data)
            plt.show()
    else:
        subcube_shell_12co = cube_12co
        subcube_shell_13co = cube_13co

    rms_12co = rms_map(cube=subcube_shell_12co)
    rms_13co = rms_map(cube=subcube_shell_13co)

    ###
    ### Use 13co if 3sigma detected, otherwise use corrected 12co if 3sigma detected.
    mask_use_13co = (subcube_shell_13co >= shell_snr_cutoff * rms_13co)
    mask_use_12co = (~mask_use_13co) & (subcube_shell_12co >=
                                        shell_snr_cutoff * rms_12co)

    ### Excitation Temperature
    Tex = cube_Tex(subcube_shell_12co,
                   average_first=True,
                   plot=False,
                   average=average_Tex)
    print("Tex is {}".format(Tex))
    ### Correct 12co for opacity.
    subcube_shell_12co_correct = opacity_correct(subcube_shell_12co,
                                                 cube_thin=subcube_shell_13co,
                                                 snr_cutoff=snr_cutoff,
                                                 plot_ratio='ratio.png')
    #print(subcube_shell_12co_correct)

    subcube_shell_12co_correct = subcube_shell_12co_correct.with_mask(
        mask_use_12co)
    subcube_shell_13co = subcube_shell_13co.with_mask(mask_use_13co)

    # if plot:
    #     plt.figure()
    #     plt.subplot(121)
    #     plt.imshow(subcube_shell_12co_correct.moment0().data)
    #     plt.subplot(122)
    #     plt.imshow(subcube_shell_13co.moment0().data)
    #     plt.show()

    if shell:
        ### Extract shell voxels from opacity-corrected 12co
        shell_12co_correct = extract_shell(subcube_shell_12co_correct,
                                           keep_latlon=True,
                                           model_cube=model_cube)
        shell_13co = extract_shell(subcube_shell_13co,
                                   keep_latlon=True,
                                   model_cube=model_cube)
    else:
        shell_12co_correct = subcube_shell_12co_correct
        shell_13co = subcube_shell_13co

    # if plot:
    #     plt.figure()
    #     plt.subplot(121)
    #     plt.imshow(shell_12co_correct.moment0().data)
    #     plt.subplot(122)
    #     plt.imshow(shell_13co.moment0().data)
    #     plt.show()
    ###
    ### Use 13co if 3sigma detected, otherwise use corrected 12co if 3sigma detected.
    # mask_use_13co = (shell_13co >= shell_snr_cutoff * rms_13co)
    # mask_use_12co = (~mask_use_13co) & (subcube_shell_12co >= shell_snr_cutoff * rms_12co)

    ### Calculate column density of H2 from 13co where 13co is 3sig,
    ### otherwise use opacity-corrected 12co.

    shell_nH2_12co = column_density_H2(shell_12co_correct,
                                       Tex=Tex,
                                       molecule="12co")
    shell_nH2_13co = column_density_H2(shell_13co, Tex=Tex, molecule="13co")

    #print(shell_nH2_12co.shape, shell_nH2_13co.shape)
    print(np.nansum([shell_nH2_12co, shell_nH2_13co], axis=0),
          shell_nH2_12co.unit)
    shell_nH2 = Projection(np.nansum([shell_nH2_12co, shell_nH2_13co], axis=0),
                           header=shell_nH2_12co.header,
                           wcs=shell_nH2_12co.wcs,
                           unit=shell_nH2_12co.unit,
                           dtype=shell_nH2_12co.dtype,
                           meta=shell_nH2_12co.meta,
                           mask=shell_nH2_12co.mask)

    #print(shell_nH2.shape)

    # if plot:
    #     plt.figure()
    #     plt.subplot(131)
    #     plt.title("H2 from 12co")
    #     plt.imshow(shell_nH2_12co.data)
    #     plt.subplot(132)
    #     plt.title("H2 from 13co")
    #     plt.imshow(shell_nH2_13co.data)
    #     plt.subplot(133)
    #     plt.title("Total H2")
    #     plt.imshow(shell_nH2)

    ### Calculate Mass, Momentum, and Energy of Shell!
    if shell:
        shell_mass = mass(shell_nH2,
                          distance=414 * u.pc,
                          molecule='H2',
                          mass_unit=u.Msun)
        shell_momentum = momentum(shell_mass, vexp)
        shell_energy = energy(shell_mass, vexp)
        shell_luminosity = (shell_energy / (r / vexp)).to(u.erg / u.s)
    else:

        mass_map = mass(shell_nH2,
                        distance=414 * u.pc,
                        molecule='H2',
                        mass_unit=u.Msun,
                        return_map=True)
        if linewidth_mode == "fwhm":
            vel_map = subcube_shell_13co.linewidth_fwhm()
        elif linewidth_mode == "sigma":
            vel_map = subcube_shell_13co.linewidth_sigma()
        elif linewidth_mode == "sigma3D":
            vel_map = 3.**0.5 * subcube_shell_13co.linewidth_sigma()

        # plt.figure()
        # plt.imshow(vel_map)
        # plt.show()
        #vel_average = np.nanmean(vel_map.value)
        shell_mass = u.Quantity(np.nansum(mass_map))
        shell_momentum = u.Quantity(np.nansum(mass_map * vel_map))
        #shell_momentum = vel
        shell_energy = 0.5 * u.Quantity(np.nansum(
            mass_map * vel_map * vel_map))
        #shell_energy = 0.5 * shell_mass
        #print(u.Quantity(0.5*shell_mass*u.Quantity(np.nanmean(vel_map))**2.).to(u.erg))
        if plot:
            from aplpy import FITSFigure
            from astropy.io import fits
            hdu = shell_nH2.hdu
            hdu.data = np.log10(shell_nH2.data)
            fig = FITSFigure(hdu.data)
            fig.show_colorscale(vmin=21.5, vmax=23.65, interpolation='none')
            fig.add_colorbar()
            # plt.imshow(np.log10(shell_nH2.value), interpolation='none',
            #     vmin=21.5, vmax=23.648)
            # plt.colorbar()
            # plt.title("log(n(H2) [cm^-2])")

            #plt.show()
            plt.savefig("../subregions/berneregion_lognH2.png")

            hdu = fits.open("../berne_Nh_2.fits")[0]
            hdu.data = np.log10(hdu.data)
            fig = FITSFigure(hdu.data)
            fig.show_colorscale(vmin=21.5, vmax=23.65, interpolation='none')
            fig.add_colorbar()

            #plt.show()
            plt.savefig("../subregions/berne_lognH2.png")

            # plt.figure()
            # plt.imshow(vel_map.to(u.km/u.s).value, interpolation='none')
            # #energy_map = (0.5*mass_map*vel_map*vel_map).to(u.erg).value
            # vels = vel_map.to(u.km/u.s).value.flatten()
            # plt.figure()
            # plt.hist(vels[vels>0], normed=True, log=True, bins=40)
            # plt.xlabel("Velocity FWHM (km/s)")
            # plt.ylabel("PDF")
            # plt.title('Velocity FWHM PDF')
            # plt.show()
        # plt.figure()
        # plt.imshow(vel_map.data)
        # plt.colorbar()
        # plt.show()

    return shell_mass, shell_momentum, shell_energy
def chem_plot_single(linere, yslice=slice(367,467), xslice=slice(114,214),
                     vrange=[51,60]*u.km/u.s, sourcename='e2',
                     filelist=glob.glob(paths.dpath('12m/cutouts/*e2e8*fits')),
                     # 5,8 -> 12.8,8
                     # 6,8 -> 12.0,8.6
                     # 5,9 -> 15.0,8.0
                     # 6,9 -> 15,9.6
                     #plotgrid=(6,9), figsize=(15.0, 9.6),
                     figsize=(12.0, 8.6),
                     suffix="",
                     vmax_m0=5.0,
                     vmax_max=150,
                     maxbeam=0.5*u.arcsec,
                     contourlevels=None,
                     filetype='pdf',
                    ):

    text_fontsize = 4.5 if filetype=='png' else 9

    for ii in range(1,7):
        if not all(pl.figure(ii, figsize=figsize).get_size_inches() == figsize):
            pl.close(ii)

    fig1 = pl.figure(1, figsize=figsize)
    fig1.clf()

    fig2 = pl.figure(2, figsize=figsize)
    fig2.clf()

    fig3 = pl.figure(3, figsize=figsize)
    fig3.clf()

    fig4 = pl.figure(4, figsize=figsize)
    fig4.clf()

    fig5 = pl.figure(5, figsize=figsize)
    fig5.clf()

    fig6 = pl.figure(6, figsize=figsize)
    fig6.clf()

    figcounter = 0

    for ii,fn in enumerate(ProgressBar(filelist)):

        linename = linere.search(fn).groups()[0]
        if linename not in labeldict:
            print()
            print("Skipping {0} because it's not in the label dict".format(linename))
            continue
        label = labeldict[linename]

        # cache the results for use in other work, later use, ...
        m0fitsfn = paths.dpath("chemslices/chemical_m0_slabs_{0}_{1}{2}.fits".format(sourcename, linename, suffix))
        m1fitsfn = paths.dpath("chemslices/chemical_m1_slabs_{0}_{1}{2}.fits".format(sourcename, linename, suffix))
        m2fitsfn = paths.dpath("chemslices/chemical_m2_slabs_{0}_{1}{2}.fits".format(sourcename, linename, suffix))
        maxfitsfn = paths.dpath("chemslices/chemical_max_slabs_{0}_{1}{2}.fits".format(sourcename, linename, suffix))
        maxsubfitsfn = paths.dpath("chemslices/chemical_max_sub_slabs_{0}_{1}{2}.fits".format(sourcename, linename, suffix))
        madstdfitsfn = paths.dpath("chemslices/chemical_madstd_slabs_{0}_{1}{2}.fits".format(sourcename, linename, suffix))
        if not (os.path.exists(m0fitsfn) and
                os.path.exists(m2fitsfn) and
                os.path.exists(maxfitsfn) and
                os.path.exists(madstdfitsfn)):
            print()
            print("Extracting max/m0/m1/m2 for {0}".format(fn))
            cube = SpectralCube.read(fn)[:,yslice,xslice]
            goodbeams = np.array([bm.major < maxbeam for bm in cube.beams], dtype='bool')
            if np.count_nonzero(goodbeams) < 5:
                print()
                print("Skipping {0} because it has too few good beams.".format(fn))
                continue

            cube = cube.with_mask(goodbeams[:,None,None])
            cube = cube.minimal_subcube()


            if cube.shape[0] == 0:
                print()
                print("Skipping {0} because it was masked out".format(fn))
                continue

            bm = cube.beams[0]
            restfreq = cube.wcs.wcs.restfrq
            cube = cube.to(u.K, bm.jtok_equiv(restfreq*u.Hz))

            slab = cube.spectral_slab(*vrange)
            cube.beam_threshold = 1
            #contguess = cube.spectral_slab(0*u.km/u.s, 40*u.km/u.s).percentile(50, axis=0)
            #contguess = cube.spectral_slab(70*u.km/u.s, 100*u.km/u.s).percentile(50, axis=0)
            mask = (cube.spectral_axis<40*u.km/u.s) | (cube.spectral_axis > 75*u.km/u.s)
            try:
                contguess = cube.with_mask(mask[:,None,None]).percentile(30, axis=0)
            except ValueError as ex:
                print()
                print("skipping {0}".format(fn))
                print(ex)
                continue
            slabsub = (slab-contguess)
            slab.beam_threshold = 0.25
            slabsub.beam_threshold = 0.25
            m0 = slabsub.moment0()
            m1 = slabsub.moment1()
            m2 = slabsub.moment2()
            max_sub = slabsub.max(axis=0)
            max = slab.max(axis=0)
            madstd = cube.with_mask(mask[:,None,None]).apply_function(mad_std,
                                                                      axis=0,
                                                                      projection=True,
                                                                      progressbar=True,
                                                                      unit=cube.unit,)

            m0.write(m0fitsfn, overwrite=True)
            m1.write(m1fitsfn, overwrite=True)
            m2.write(m2fitsfn, overwrite=True)
            max.write(maxfitsfn, overwrite=True)
            max_sub.write(maxsubfitsfn, overwrite=True)
            madstd.write(madstdfitsfn, overwrite=True)
            maxfh = max.hdu
        else:
            m0fh = fits.open(m0fitsfn)
            m1fh = fits.open(m1fitsfn)
            m2fh = fits.open(m2fitsfn)
            maxfh = fits.open(maxfitsfn)[0]
            maxsubfh = fits.open(maxsubfitsfn)
            madstdfh = fits.open(madstdfitsfn)

            m0 = Projection(value=m0fh[0].data, header=m0fh[0].header,
                            wcs=wcs.WCS(m0fh[0].header),
                            unit=u.Unit(m0fh[0].header['BUNIT']),)
            m1 = Projection(value=m1fh[0].data, header=m1fh[0].header,
                            wcs=wcs.WCS(m1fh[0].header),
                            unit=u.Unit(m1fh[0].header['BUNIT']),)
            m2 = Projection(value=m2fh[0].data, header=m2fh[0].header,
                            wcs=wcs.WCS(m2fh[0].header),
                            unit=u.Unit(m2fh[0].header['BUNIT']),)
            max = Projection(value=maxfh.data, header=maxfh.header,
                             wcs=wcs.WCS(maxfh.header),
                             unit=u.Unit(maxfh.header['BUNIT']),)
            max_sub = Projection(value=maxsubfh[0].data,
                                 header=maxsubfh[0].header,
                                 wcs=wcs.WCS(maxsubfh[0].header),
                                 unit=u.Unit(maxsubfh[0].header['BUNIT']),)
            madstd = Projection(value=madstdfh[0].data,
                                header=madstdfh[0].header,
                                wcs=wcs.WCS(madstdfh[0].header),
                                unit=u.Unit(madstdfh[0].header['BUNIT']),)

            bm = radio_beam.Beam.from_fits_header(m0fh[0].header)
            restfreq = m0fh[0].header['RESTFRQ']

        jtok = bm.jtok(restfreq*u.Hz)


        fig1 = pl.figure(1, figsize=figsize)
        fig1.clf()
        ax1 = fig1.gca()

        im1 = ax1.imshow(m0.value, vmin=-1.25*jtok.value, vmax=vmax_m0*jtok.value,
                         cmap=pl.cm.bone_r, interpolation='nearest', origin='lower')
        ax1.text(3, 0.87*m0.shape[0], label, fontsize=text_fontsize)
        ax1.set_xticklabels([])
        ax1.set_yticklabels([])
        ax1.set_xticks([])
        ax1.set_yticks([])
        ax1.set_aspect('equal')
        cb = pl.colorbar(mappable=im1)

        cb.set_label("Flux Density (K km s$^{-1}$)", fontsize=12)
        fig1.savefig(paths.fpath("chemical_slabs/{3}_chemical_m0_slab_{0}{1}.{2}"
                                 .format(sourcename, suffix, filetype,
                                         linename)),
                     bbox_inches='tight', dpi=300)


        fig2 = pl.figure(2, figsize=figsize)
        fig2.clf()
        ax2 = fig2.gca()

        im2 = ax2.imshow(m1.value, vmin=vrange[0].value, vmax=vrange[1].value,
                         cmap='seismic', interpolation='nearest', origin='lower')
        ax2.text(3, 0.87*m0.shape[0], label, fontsize=text_fontsize, color='g')
        ax2.set_xticklabels([])
        ax2.set_yticklabels([])
        ax2.set_xticks([])
        ax2.set_yticks([])
        ax2.set_aspect('equal')
        cb = pl.colorbar(mappable=im2)

        cb.set_label("Velocity (km s$^{-1}$)", fontsize=12)
        fig2.savefig(paths.fpath("chemical_slabs/{3}_chemical_m1_slab_{0}{1}.{2}"
                                 .format(sourcename, suffix, filetype,
                                         linename)),
                     bbox_inches='tight', dpi=300)

        fig3 = pl.figure(3, figsize=figsize)
        fig3.clf()
        ax3 = fig3.gca()

        im3 = ax3.imshow(max_sub.value, vmin=-10, vmax=vmax_max,
                         cmap=pl.cm.bone_r, interpolation='nearest', origin='lower')
        # add a contour to show the regions that are "saturated" above T_max
        if contourlevels is None:
            contourlevels = [vmax_max, 300, 400, 500]
        qcs = ax3.contour(max_sub.value, levels=contourlevels, colors=['r','g','b','y'])
        #print("levels: {0} = {1}".format(qcs.levels, contourlevels))
        ax3.text(3, 0.87*m0.shape[0], label, fontsize=text_fontsize, color='r')
        ax3.set_xticklabels([])
        ax3.set_yticklabels([])
        ax3.set_xticks([])
        ax3.set_yticks([])
        ax3.set_aspect('equal')
        cb = pl.colorbar(mappable=im3)

        cb.set_label("Peak Brightness (K)", fontsize=12)
        fig3.savefig(paths.fpath("chemical_slabs/{3}_chemical_max_contsub_slab_{0}{1}.{2}"
                                 .format(sourcename, suffix, filetype,
                                         linename)),
                     bbox_inches='tight', dpi=300)

        fig5 = pl.figure(5, figsize=figsize)
        fig5.clf()
        ax5 = fig5.gca()

        im5 = ax5.imshow(max.value, vmin=-10, vmax=vmax_max,
                         cmap=pl.cm.bone_r, interpolation='nearest', origin='lower')
        # add a contour to show the regions that are "saturated" above T_max
        qcs = ax5.contour(max.value, levels=contourlevels, colors=['r','g','b','y'])
        if False: # debug
            print("levels: {0} = {1}".format(qcs.levels, contourlevels))
        ax5.text(3, 0.87*m0.shape[0], label, fontsize=text_fontsize, color='r')
        ax5.set_xticklabels([])
        ax5.set_yticklabels([])
        ax5.set_xticks([])
        ax5.set_yticks([])
        ax5.set_aspect('equal')
        cb = pl.colorbar(mappable=im5)

        cb.set_label("Peak Brightness (K)", fontsize=12)
        fig5.savefig(paths.fpath("chemical_slabs/{3}_chemical_max_slab_{0}{1}.{2}"
                                 .format(sourcename, suffix, filetype,
                                         linename)),
                     bbox_inches='tight', dpi=300)

        fig4 = pl.figure(4, figsize=figsize)
        fig4.clf()
        ax4 = fig4.gca()

        im4 = ax4.imshow(madstd.value,
                         cmap=pl.cm.bone_r, interpolation='nearest', origin='lower')
        ax4.text(3, 0.87*m0.shape[0], label, fontsize=text_fontsize, color='r')
        ax4.set_xticklabels([])
        ax4.set_yticklabels([])
        ax4.set_xticks([])
        ax4.set_yticks([])
        ax4.set_aspect('equal')
        cb = pl.colorbar(mappable=im4)

        cb.set_label("MAD StdDev (K)", fontsize=12)
        fig4.savefig(paths.fpath("chemical_slabs/{3}_chemical_madstd_slab_{0}{1}.{2}"
                                 .format(sourcename, suffix, filetype,
                                         linename)),
                     bbox_inches='tight', dpi=300)

        fig6 = pl.figure(6, figsize=figsize)
        fig6.clf()
        ax6 = fig6.gca()

        im6 = ax6.imshow((m2**0.5).to(u.km/u.s).value * SIGMA2FWHM, vmin=0, vmax=15,
                         cmap='viridis', interpolation='nearest', origin='lower')
        ax6.text(3, 0.87*m0.shape[0], label, fontsize=text_fontsize, color='k')
        ax6.set_xticklabels([])
        ax6.set_yticklabels([])
        ax6.set_xticks([])
        ax6.set_yticks([])
        ax6.set_aspect('equal')
        cb = pl.colorbar(mappable=im6)

        cb.set_label("Velocity Dispersion (km s$^{-1}$)", fontsize=12)
        fig6.savefig(paths.fpath("chemical_slabs/{3}_chemical_m2_slab_{0}{1}.{2}"
                                 .format(sourcename, suffix, filetype,
                                         linename)),
                     bbox_inches='tight', dpi=300)

        figcounter += 1


    ax5 = fig5.gca()
    ax5.cla()

    cont = get_cont(maxfh.header)

    im5 = ax5.imshow(cont.value, vmin=-10, vmax=vmax_max,
                     cmap=pl.cm.bone_r, interpolation='nearest', origin='lower')
    # add a contour to show the regions that are "saturated" above T_max
    ax5.contour(cont.value, levels=contourlevels, colors=['r','g','b','y'])
    ax5.text(3, 0.87*m0.shape[0], 'Continuum', fontsize=text_fontsize, color='r')
    ax5.set_xticklabels([])
    ax5.set_yticklabels([])
    ax5.set_aspect('equal')

    fig5.savefig(paths.fpath("cont_max_slab_{0}{1}.{2}"
                             .format(sourcename, suffix, filetype)),
                 bbox_inches='tight', dpi=300)
def chem_plot(linere, yslice=slice(367,467), xslice=slice(114,214), vrange=[51,60]*u.km/u.s,
              sourcename='e2', filelist=glob.glob(paths.dpath('12m/cutouts/*e2e8*fits')),
              suffix="", plotgrid=(5,8), figsize=(12.8,8),
              vmax_m0=5.0,
              vmax_max=150,
              maxbeam=0.5*u.arcsec,
             ):
    nplots = np.product(plotgrid)

    for ii in (1,2):
        if not all(pl.figure(ii, figsize=figsize).get_size_inches() == figsize):
            pl.close(ii)

    fig1 = pl.figure(1, figsize=figsize)
    fig1.clf()
    gs1 = gridspec.GridSpec(*plotgrid)
    gs1.update(wspace=0.0, hspace=0.0)

    fig2 = pl.figure(2, figsize=figsize)
    fig2.clf()
    gs2 = gridspec.GridSpec(*plotgrid)
    gs2.update(wspace=0.0, hspace=0.0)

    fig3 = pl.figure(3, figsize=figsize)
    fig3.clf()
    gs3 = gridspec.GridSpec(*plotgrid)
    gs3.update(wspace=0.0, hspace=0.0)

    fig4 = pl.figure(4, figsize=figsize)
    fig4.clf()
    gs4 = gridspec.GridSpec(*plotgrid)
    gs4.update(wspace=0.0, hspace=0.0)

    figcounter = 0

    for ii,fn in enumerate(ProgressBar(filelist)):

        linename = linere.search(fn).groups()[0]
        if linename not in labeldict:
            print("Skipping {0} because it's not in the label dict".format(linename))
            continue
        label = labeldict[linename]

        # cache the results for use in other work, later use, ...
        m0fitsfn = paths.dpath("chemslices/chemical_m0_slabs_{0}_{1}{2}.fits".format(sourcename, linename, suffix))
        m1fitsfn = paths.dpath("chemslices/chemical_m1_slabs_{0}_{1}{2}.fits".format(sourcename, linename, suffix))
        maxfitsfn = paths.dpath("chemslices/chemical_max_slabs_{0}_{1}{2}.fits".format(sourcename, linename, suffix))
        madstdfitsfn = paths.dpath("chemslices/chemical_madstd_slabs_{0}_{1}{2}.fits".format(sourcename, linename, suffix))
        if not (os.path.exists(m0fitsfn) and
                os.path.exists(maxfitsfn) and
                os.path.exists(madstdfitsfn)):
            print("Extracting max/m0/m1 for {0}".format(fn))
            cube = SpectralCube.read(fn)[:,yslice,xslice]
            goodbeams = np.array([bm.major < maxbeam for bm in cube.beams], dtype='bool')
            cube = cube.with_mask(goodbeams[:,None,None])
            cube = cube.minimal_subcube()

            if cube.shape[0] == 0:
                print("Skipping {0} because it was masked out".format(fn))
                continue

            bm = cube.beams[0]
            restfreq = cube.wcs.wcs.restfrq
            cube = cube.to(u.K, bm.jtok_equiv(restfreq*u.Hz))

            slab = cube.spectral_slab(*vrange)
            cube.beam_threshold = 1
            #contguess = cube.spectral_slab(0*u.km/u.s, 40*u.km/u.s).percentile(50, axis=0)
            #contguess = cube.spectral_slab(70*u.km/u.s, 100*u.km/u.s).percentile(50, axis=0)
            mask = (cube.spectral_axis<40*u.km/u.s) | (cube.spectral_axis > 75*u.km/u.s)
            try:
                contguess = cube.with_mask(mask[:,None,None]).percentile(30, axis=0)
            except ValueError as ex:
                print("skipping {0}".format(fn))
                print(ex)
                continue
            slabsub = (slab-contguess)
            slabsub.beam_threshold = 0.25
            m0 = slabsub.moment0()
            m1 = slabsub.moment1()
            max = slabsub.max(axis=0)
            madstd = cube.with_mask(mask[:,None,None]).apply_function(mad_std,
                                                                      axis=0,
                                                                      projection=True,
                                                                      progressbar=True,
                                                                      unit=cube.unit,)

            m0.write(m0fitsfn, overwrite=True)
            m1.write(m1fitsfn, overwrite=True)
            max.write(maxfitsfn, overwrite=True)
            madstd.write(madstdfitsfn, overwrite=True)
        else:
            m0fh = fits.open(m0fitsfn)
            m1fh = fits.open(m1fitsfn)
            maxfh = fits.open(maxfitsfn)
            madstdfh = fits.open(madstdfitsfn)

            m0 = Projection(value=m0fh[0].data, header=m0fh[0].header,
                            wcs=wcs.WCS(m0fh[0].header),
                            unit=u.Unit(m0fh[0].header['BUNIT']),)
            m1 = Projection(value=m1fh[0].data, header=m1fh[0].header,
                            wcs=wcs.WCS(m1fh[0].header),
                            unit=u.Unit(m1fh[0].header['BUNIT']),)
            max = Projection(value=maxfh[0].data, header=maxfh[0].header,
                             wcs=wcs.WCS(maxfh[0].header),
                             unit=u.Unit(maxfh[0].header['BUNIT']),)
            madstd = Projection(value=madstdfh[0].data,
                                header=madstdfh[0].header,
                                wcs=wcs.WCS(madstdfh[0].header),
                                unit=u.Unit(madstdfh[0].header['BUNIT']),)

            bm = radio_beam.Beam.from_fits_header(m0fh[0].header)
            restfreq = m0fh[0].header['RESTFRQ']

        jtok = bm.jtok(restfreq*u.Hz)

        if figcounter>=nplots:
            print("Skipping {0}".format(fn))
            break

        ax1 = fig1.add_subplot(gs1[figcounter])

        im1 = ax1.imshow(m0.value, vmin=-1.25*jtok.value, vmax=vmax_m0*jtok.value,
                         cmap=pl.cm.bone_r, interpolation='nearest')
        ax1.text(3, 0.87*m0.shape[0], label, fontsize=9)
        ax1.set_xticklabels([])
        ax1.set_yticklabels([])
        ax1.set_aspect('equal')

        ax2 = fig2.add_subplot(gs2[figcounter])

        im2 = ax2.imshow(m1.value, vmin=vrange[0].value, vmax=vrange[1].value,
                         cmap=pl.cm.viridis, interpolation='nearest')
        ax2.text(3, 0.87*m0.shape[0], label, fontsize=9, color='w')
        ax2.set_xticklabels([])
        ax2.set_yticklabels([])
        ax2.set_aspect('equal')

        ax3 = fig3.add_subplot(gs2[figcounter])

        im3 = ax3.imshow(max.value, vmin=-10, vmax=vmax_max,
                         cmap=pl.cm.bone_r, interpolation='nearest')
        ax3.text(3, 0.87*m0.shape[0], label, fontsize=9, color='r')
        ax3.set_xticklabels([])
        ax3.set_yticklabels([])
        ax3.set_aspect('equal')

        ax4 = fig4.add_subplot(gs2[figcounter])

        im4 = ax4.imshow(madstd.value,
                         cmap=pl.cm.bone_r, interpolation='nearest')
        ax4.text(3, 0.87*m0.shape[0], label, fontsize=9, color='r')
        ax4.set_xticklabels([])
        ax4.set_yticklabels([])
        ax4.set_aspect('equal')

        figcounter += 1

    cbs = {}
    for ii,fig, im, gs in ((1,fig1,im1,gs1), (2,fig2,im2,gs2),
                           (3,fig3,im3,gs3), (4,fig4,im4,gs4),):
        bottom,top,left,right = gs.get_grid_positions(fig)
        cbar_ax = fig.add_axes([np.max(right)+0.01, np.min(bottom),
                                0.05, np.max(top)-np.min(bottom)])
        cbs[ii] = pl.colorbar(mappable=im, cax=cbar_ax)
        cbs[ii].ax.tick_params(labelsize=12)

    cbs[1].set_label("Flux Density (K km s$^{-1}$)", fontsize=12)
    cbs[2].set_label("Velocity (km s$^{-1}$)", fontsize=12)
    cbs[3].set_label("Peak Brightness (K)", fontsize=12)
    cbs[4].set_label("MAD StdDev (K)", fontsize=12)

    pl.draw()
    pl.show()

    fig1.savefig(paths.fpath("chemical_m0_slabs_{0}{1}.png".format(sourcename,
                                                                   suffix)),
                 bbox_inches='tight', dpi=150)

    fig2.savefig(paths.fpath("chemical_m1_slabs_{0}{1}.png".format(sourcename,
                                                                   suffix)),
                 bbox_inches='tight', dpi=150)

    fig3.savefig(paths.fpath("chemical_max_slabs_{0}{1}.png".format(sourcename,
                                                                    suffix)),
                 bbox_inches='tight', dpi=150)

    fig4.savefig(paths.fpath("chemical_madstd_slabs_{0}{1}.png".format(sourcename,
                                                                       suffix)),
                 bbox_inches='tight', dpi=150)
Example #13
0
    return radprof, sdprof, sdprof_sigma


if __name__ == "__main__":
    import matplotlib.pyplot as p

    from paths import (fourteenB_HI_data_path, arecibo_HI_data_path,
                       c_hi_analysispath, paper1_figures_path,
                       data_path)

    from constants import moment0_name, lwidth_name
    from galaxy_params import gal

    lwidth_hdu = fits.open(fourteenB_HI_data_path(lwidth_name))[0]
    lwidth = Projection(lwidth_hdu.data, wcs=WCS(lwidth_hdu.header),
                        unit=u.m / u.s)
    lwidth.meta["beam"] = Beam.from_fits_header(lwidth_hdu.header)

    # Create a radial profile of the HI vel disp out to 8 kpc.
    # Beyond 8 kpc, noise is dominant. It may be some reflection of the
    # warp, but I don't trust it right now.
    rs, sd, sd_sigma = radial_profile(gal, lwidth, max_rad=8 * u.kpc)

    sd = sd.to(u.km / u.s)
    sd_sigma = sd_sigma.to(u.km / u.s)

    p.errorbar(rs.value, sd.value,
               yerr=sd_sigma.value, fmt="-", color="b",
               drawstyle='steps-mid')
    p.xlabel("R (kpc)")
    p.ylabel("HI Velocity Dispersion (km/s)")
Example #14
0
    from spectral_cube.lower_dimensional_structures import Projection
    from astropy.wcs import WCS
    from radio_beam import Beam
    from astropy.io import fits

    import os

    from paths import (fourteenB_HI_data_path, arecibo_HI_data_path,
                       c_hi_analysispath, paper1_figures_path,
                       data_path)

    from constants import hi_freq, moment0_name
    from galaxy_params import gal

    mom0_hdu = fits.open(fourteenB_HI_data_path(moment0_name))[0]
    mom0 = Projection(mom0_hdu.data, wcs=WCS(mom0_hdu.header),
                      unit=u.Jy * u.m / u.s)
    mom0.meta["beam"] = Beam.from_fits_header(mom0_hdu.header)

    # Bin size in pc
    dr = 100 * u.pc

    # Create a radial profile of HI
    rs, sd, sd_sigma = surfdens_radial_profile(gal, mom0=mom0, dr=dr,
                                               restfreq=hi_freq)
    rs_n, sd_n, sd_sigma_n = \
        surfdens_radial_profile(gal, mom0=mom0,
                                pa_bounds=Angle([0.5 * np.pi * u.rad,
                                                -0.5 * np.pi * u.rad]),
                                dr=dr, restfreq=hi_freq)
    rs_s, sd_s, sd_sigma_s = \
        surfdens_radial_profile(gal, mom0=mom0,
Example #15
0
        # raise ValueError("Fit failed.")

    return fit, err, model, profile


if __name__ == "__main__":

    from analysis.paths import (fourteenB_HI_data_path, paper1_figures_path,
                                iram_co21_data_path)
    from analysis.constants import moment0_name
    from analysis.galaxy_params import gal

    mom0_fits = fits.open(fourteenB_HI_data_path(moment0_name))[0]
    beam = Beam.from_fits_header(mom0_fits.header)
    mom0 = Projection(mom0_fits.data * beam.jtok(hi_freq) / 1000. *
                      u.km / u.s,
                      wcs=WCS(mom0_fits.header))
    mom0.meta['beam'] = beam

    # Create the bubble mask instead of letting FilFinder to do it.
    bub = BubbleFinder2D(mom0, sigma=80. * beam.jtok(hi_freq) / 1000.)

    # fils = fil_finder_2D(mom0.value, mom0.header, 10, distance=0.84e6)
    # fils.mask = ~(bub.mask.copy())
    # fils.medskel()
    # fils.analyze_skeletons()
    # # So at least on of the radial profiles fails. BUT the second fit is to a
    # # skeleton that is essentially the entire disk, so plot without interactivity
    # # and save the plot and the parameters shown in verbose mode.
    # p.ioff()
    # fils.find_widths(verbose=True, max_distance=500, auto_cut=False, try_nonparam=False)